00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifdef __cplusplus
00042 extern "C" {
00043 #endif
00044
00045 #include "asterisk.h"
00046
00047 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 75619 $")
00048
00049 #ifdef __cplusplus
00050 }
00051 #endif
00052
00053 #include <sys/socket.h>
00054 #include <sys/signal.h>
00055 #include <sys/param.h>
00056 #if defined(BSD)
00057 #ifndef IPTOS_MINCOST
00058 #define IPTOS_MINCOST 0x02
00059 #endif
00060 #endif
00061 #include <arpa/inet.h>
00062 #include <net/if.h>
00063 #include <netinet/in.h>
00064 #include <netinet/in_systm.h>
00065 #include <netinet/ip.h>
00066 #include <unistd.h>
00067 #include <stdlib.h>
00068 #include <netdb.h>
00069 #include <stdio.h>
00070 #include <string.h>
00071 #include <errno.h>
00072 #include <fcntl.h>
00073
00074 #ifdef __cplusplus
00075 extern "C" {
00076 #endif
00077
00078 #include "asterisk/lock.h"
00079 #include "asterisk/logger.h"
00080 #include "asterisk/channel.h"
00081 #include "asterisk/config.h"
00082 #include "asterisk/module.h"
00083 #include "asterisk/musiconhold.h"
00084 #include "asterisk/pbx.h"
00085 #include "asterisk/options.h"
00086 #include "asterisk/utils.h"
00087 #include "asterisk/lock.h"
00088 #include "asterisk/sched.h"
00089 #include "asterisk/io.h"
00090 #include "asterisk/rtp.h"
00091 #include "asterisk/acl.h"
00092 #include "asterisk/callerid.h"
00093 #include "asterisk/cli.h"
00094 #include "asterisk/dsp.h"
00095 #include "asterisk/causes.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/abstract_jb.h"
00098 #include "asterisk/astobj.h"
00099
00100 #ifdef __cplusplus
00101 }
00102 #endif
00103
00104 #include "h323/chan_h323.h"
00105
00106 receive_digit_cb on_receive_digit;
00107 on_rtp_cb on_external_rtp_create;
00108 start_rtp_cb on_start_rtp_channel;
00109 setup_incoming_cb on_incoming_call;
00110 setup_outbound_cb on_outgoing_call;
00111 chan_ringing_cb on_chan_ringing;
00112 con_established_cb on_connection_established;
00113 clear_con_cb on_connection_cleared;
00114 answer_call_cb on_answer_call;
00115 progress_cb on_progress;
00116 rfc2833_cb on_set_rfc2833_payload;
00117 hangup_cb on_hangup;
00118 setcapabilities_cb on_setcapabilities;
00119 setpeercapabilities_cb on_setpeercapabilities;
00120
00121
00122 int h323debug;
00123
00124
00125 static struct ast_jb_conf default_jbconf =
00126 {
00127 .flags = 0,
00128 .max_size = -1,
00129 .resync_threshold = -1,
00130 .impl = ""
00131 };
00132 static struct ast_jb_conf global_jbconf;
00133
00134
00135 static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
00136 static const char config[] = "h323.conf";
00137 static char default_context[AST_MAX_CONTEXT] = "default";
00138 static struct sockaddr_in bindaddr;
00139
00140 #define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261)
00141
00142
00143 static int h323_signalling_port = 1720;
00144 static char gatekeeper[100];
00145 static int gatekeeper_disable = 1;
00146 static int gatekeeper_discover = 0;
00147 static int gkroute = 0;
00148
00149 static int userbyalias = 1;
00150 static int acceptAnonymous = 1;
00151 static int tos = 0;
00152 static char secret[50];
00153 static unsigned int unique = 0;
00154
00155 static call_options_t global_options;
00156
00157
00158 struct oh323_pvt {
00159 ast_mutex_t lock;
00160 call_options_t options;
00161 int alreadygone;
00162 int needdestroy;
00163 call_details_t cd;
00164 struct ast_channel *owner;
00165 struct sockaddr_in sa;
00166 struct sockaddr_in redirip;
00167 int nonCodecCapability;
00168 int outgoing;
00169 char exten[AST_MAX_EXTENSION];
00170 char context[AST_MAX_CONTEXT];
00171 char accountcode[256];
00172 char rdnis[80];
00173 int amaflags;
00174 struct ast_rtp *rtp;
00175 struct ast_dsp *vad;
00176 int nativeformats;
00177 int needhangup;
00178 int hangupcause;
00179 int newstate;
00180 int newcontrol;
00181 int newdigit;
00182 int newduration;
00183 int pref_codec;
00184 int peercapability;
00185 int jointcapability;
00186 struct ast_codec_pref peer_prefs;
00187 int dtmf_pt;
00188 int curDTMF;
00189 int DTMFsched;
00190 int update_rtp_info;
00191 int recvonly;
00192 int txDtmfDigit;
00193 int noInbandDtmf;
00194 int connection_established;
00195 int got_progress;
00196 struct oh323_pvt *next;
00197 } *iflist = NULL;
00198
00199 static struct ast_user_list {
00200 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user);
00201 } userl;
00202
00203 static struct ast_peer_list {
00204 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer);
00205 } peerl;
00206
00207 static struct ast_alias_list {
00208 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias);
00209 } aliasl;
00210
00211
00212 static struct sched_context *sched;
00213 static struct io_context *io;
00214
00215
00216 AST_MUTEX_DEFINE_STATIC(iflock);
00217
00218
00219
00220 AST_MUTEX_DEFINE_STATIC(monlock);
00221
00222
00223 AST_MUTEX_DEFINE_STATIC(caplock);
00224
00225
00226 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
00227 static int h323_reloading = 0;
00228
00229
00230
00231 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00232 static int restart_monitor(void);
00233 static int h323_do_reload(void);
00234
00235 static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause);
00236 static int oh323_digit_begin(struct ast_channel *c, char digit);
00237 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00238 static int oh323_call(struct ast_channel *c, char *dest, int timeout);
00239 static int oh323_hangup(struct ast_channel *c);
00240 static int oh323_answer(struct ast_channel *c);
00241 static struct ast_frame *oh323_read(struct ast_channel *c);
00242 static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
00243 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00244 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00245
00246 static const struct ast_channel_tech oh323_tech = {
00247 .type = "H323",
00248 .description = tdesc,
00249 .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
00250 .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
00251 .requester = oh323_request,
00252 .send_digit_begin = oh323_digit_begin,
00253 .send_digit_end = oh323_digit_end,
00254 .call = oh323_call,
00255 .hangup = oh323_hangup,
00256 .answer = oh323_answer,
00257 .read = oh323_read,
00258 .write = oh323_write,
00259 .indicate = oh323_indicate,
00260 .fixup = oh323_fixup,
00261
00262 #if 0
00263 .bridge = ast_rtp_bridge,
00264 #endif
00265 };
00266
00267 static const char* redirectingreason2str(int redirectingreason)
00268 {
00269 switch (redirectingreason) {
00270 case 0:
00271 return "UNKNOWN";
00272 case 1:
00273 return "BUSY";
00274 case 2:
00275 return "NO_REPLY";
00276 case 0xF:
00277 return "UNCONDITIONAL";
00278 default:
00279 return "NOREDIRECT";
00280 }
00281 }
00282
00283 static void oh323_destroy_alias(struct oh323_alias *alias)
00284 {
00285 if (h323debug)
00286 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name);
00287 free(alias);
00288 }
00289
00290 static void oh323_destroy_user(struct oh323_user *user)
00291 {
00292 if (h323debug)
00293 ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name);
00294 ast_free_ha(user->ha);
00295 free(user);
00296 }
00297
00298 static void oh323_destroy_peer(struct oh323_peer *peer)
00299 {
00300 if (h323debug)
00301 ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name);
00302 ast_free_ha(peer->ha);
00303 free(peer);
00304 }
00305
00306 static int oh323_simulate_dtmf_end(void *data)
00307 {
00308 struct oh323_pvt *pvt = data;
00309
00310 if (pvt) {
00311 ast_mutex_lock(&pvt->lock);
00312
00313 while(pvt->owner && ast_channel_trylock(pvt->owner)) {
00314 ast_mutex_unlock(&pvt->lock);
00315 usleep(1);
00316 ast_mutex_lock(&pvt->lock);
00317 }
00318
00319 if (pvt->owner) {
00320 struct ast_frame f = {
00321 .frametype = AST_FRAME_DTMF_END,
00322 .subclass = pvt->curDTMF,
00323 .samples = 0,
00324 .src = "SIMULATE_DTMF_END",
00325 };
00326 ast_queue_frame(pvt->owner, &f);
00327 ast_channel_unlock(pvt->owner);
00328 }
00329
00330 pvt->DTMFsched = -1;
00331 ast_mutex_unlock(&pvt->lock);
00332 }
00333
00334 return 0;
00335 }
00336
00337
00338 static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
00339 {
00340 if (c->nativeformats != pvt->nativeformats) {
00341 if (h323debug)
00342 ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name);
00343 c->nativeformats = pvt->nativeformats;
00344 ast_set_read_format(c, c->readformat);
00345 ast_set_write_format(c, c->writeformat);
00346 }
00347 if (pvt->needhangup) {
00348 if (h323debug)
00349 ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name);
00350 c->_softhangup |= AST_SOFTHANGUP_DEV;
00351 c->hangupcause = pvt->hangupcause;
00352 ast_queue_hangup(c);
00353 pvt->needhangup = 0;
00354 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
00355 }
00356 if (pvt->newstate >= 0) {
00357 ast_setstate(c, pvt->newstate);
00358 pvt->newstate = -1;
00359 }
00360 if (pvt->newcontrol >= 0) {
00361 ast_queue_control(c, pvt->newcontrol);
00362 pvt->newcontrol = -1;
00363 }
00364 if (pvt->newdigit >= 0) {
00365 struct ast_frame f = {
00366 .frametype = AST_FRAME_DTMF_END,
00367 .subclass = pvt->newdigit,
00368 .samples = pvt->newduration * 8,
00369 .len = pvt->newduration,
00370 .src = "UPDATE_INFO",
00371 };
00372 if (pvt->newdigit == ' ') {
00373 f.subclass = pvt->curDTMF;
00374 if (pvt->DTMFsched >= 0) {
00375 ast_sched_del(sched, pvt->DTMFsched);
00376 pvt->DTMFsched = -1;
00377 }
00378 } else {
00379 if (pvt->newduration) {
00380 f.frametype = AST_FRAME_DTMF_BEGIN;
00381 if (pvt->DTMFsched >= 0)
00382 ast_sched_del(sched, pvt->DTMFsched);
00383 pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt);
00384 if (h323debug)
00385 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
00386 }
00387 pvt->curDTMF = pvt->newdigit;
00388 }
00389 ast_queue_frame(c, &f);
00390 pvt->newdigit = -1;
00391 }
00392 if (pvt->update_rtp_info > 0) {
00393 if (pvt->rtp) {
00394 ast_jb_configure(c, &global_jbconf);
00395 c->fds[0] = ast_rtp_fd(pvt->rtp);
00396 c->fds[1] = ast_rtcp_fd(pvt->rtp);
00397 ast_queue_frame(pvt->owner, &ast_null_frame);
00398 }
00399 pvt->update_rtp_info = -1;
00400 }
00401 }
00402
00403
00404 static void oh323_update_info(struct ast_channel *c)
00405 {
00406 struct oh323_pvt *pvt = c->tech_pvt;
00407
00408 if (pvt) {
00409 ast_mutex_lock(&pvt->lock);
00410 __oh323_update_info(c, pvt);
00411 ast_mutex_unlock(&pvt->lock);
00412 }
00413 }
00414
00415 static void cleanup_call_details(call_details_t *cd)
00416 {
00417 if (cd->call_token) {
00418 free(cd->call_token);
00419 cd->call_token = NULL;
00420 }
00421 if (cd->call_source_aliases) {
00422 free(cd->call_source_aliases);
00423 cd->call_source_aliases = NULL;
00424 }
00425 if (cd->call_dest_alias) {
00426 free(cd->call_dest_alias);
00427 cd->call_dest_alias = NULL;
00428 }
00429 if (cd->call_source_name) {
00430 free(cd->call_source_name);
00431 cd->call_source_name = NULL;
00432 }
00433 if (cd->call_source_e164) {
00434 free(cd->call_source_e164);
00435 cd->call_source_e164 = NULL;
00436 }
00437 if (cd->call_dest_e164) {
00438 free(cd->call_dest_e164);
00439 cd->call_dest_e164 = NULL;
00440 }
00441 if (cd->sourceIp) {
00442 free(cd->sourceIp);
00443 cd->sourceIp = NULL;
00444 }
00445 if (cd->redirect_number) {
00446 free(cd->redirect_number);
00447 cd->redirect_number = NULL;
00448 }
00449 }
00450
00451 static void __oh323_destroy(struct oh323_pvt *pvt)
00452 {
00453 struct oh323_pvt *cur, *prev = NULL;
00454
00455 if (pvt->DTMFsched >= 0) {
00456 ast_sched_del(sched, pvt->DTMFsched);
00457 pvt->DTMFsched = -1;
00458 }
00459
00460 if (pvt->rtp) {
00461 ast_rtp_destroy(pvt->rtp);
00462 }
00463
00464
00465 if (pvt->vad) {
00466 ast_dsp_free(pvt->vad);
00467 }
00468 cleanup_call_details(&pvt->cd);
00469
00470
00471 if (pvt->owner) {
00472 ast_channel_lock(pvt->owner);
00473 if (h323debug)
00474 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name);
00475 pvt->owner->tech_pvt = NULL;
00476 ast_channel_unlock(pvt->owner);
00477 }
00478 cur = iflist;
00479 while(cur) {
00480 if (cur == pvt) {
00481 if (prev)
00482 prev->next = cur->next;
00483 else
00484 iflist = cur->next;
00485 break;
00486 }
00487 prev = cur;
00488 cur = cur->next;
00489 }
00490 if (!cur) {
00491 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
00492 } else {
00493 ast_mutex_unlock(&pvt->lock);
00494 ast_mutex_destroy(&pvt->lock);
00495 free(pvt);
00496 }
00497 }
00498
00499 static void oh323_destroy(struct oh323_pvt *pvt)
00500 {
00501 if (h323debug) {
00502 ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>"));
00503 }
00504 ast_mutex_lock(&iflock);
00505 ast_mutex_lock(&pvt->lock);
00506 __oh323_destroy(pvt);
00507 ast_mutex_unlock(&iflock);
00508 }
00509
00510 static int oh323_digit_begin(struct ast_channel *c, char digit)
00511 {
00512 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00513 char *token;
00514
00515 if (!pvt) {
00516 ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00517 return -1;
00518 }
00519 ast_mutex_lock(&pvt->lock);
00520 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
00521
00522 if (h323debug) {
00523 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name);
00524 }
00525 ast_rtp_senddigit_begin(pvt->rtp, digit);
00526 ast_mutex_unlock(&pvt->lock);
00527 } else if (pvt->txDtmfDigit != digit) {
00528
00529 if (h323debug) {
00530 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name);
00531 }
00532 pvt->txDtmfDigit = digit;
00533 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00534 ast_mutex_unlock(&pvt->lock);
00535 h323_send_tone(token, digit);
00536 if (token) {
00537 free(token);
00538 }
00539 } else
00540 ast_mutex_unlock(&pvt->lock);
00541 oh323_update_info(c);
00542 return 0;
00543 }
00544
00545
00546
00547
00548
00549 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
00550 {
00551 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00552 char *token;
00553
00554 if (!pvt) {
00555 ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00556 return -1;
00557 }
00558 ast_mutex_lock(&pvt->lock);
00559 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
00560
00561 if (h323debug) {
00562 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration);
00563 }
00564 ast_rtp_senddigit_end(pvt->rtp, digit);
00565 ast_mutex_unlock(&pvt->lock);
00566 } else {
00567
00568 if (h323debug) {
00569 ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration);
00570 }
00571 pvt->txDtmfDigit = ' ';
00572 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00573 ast_mutex_unlock(&pvt->lock);
00574 h323_send_tone(token, ' ');
00575 if (token) {
00576 free(token);
00577 }
00578 }
00579 oh323_update_info(c);
00580 return 0;
00581 }
00582
00583
00584
00585
00586
00587
00588 static int oh323_call(struct ast_channel *c, char *dest, int timeout)
00589 {
00590 int res = 0;
00591 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00592 const char *addr;
00593 char called_addr[1024];
00594
00595 if (h323debug) {
00596 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name);
00597 }
00598 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
00599 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name);
00600 return -1;
00601 }
00602 ast_mutex_lock(&pvt->lock);
00603 if (!gatekeeper_disable) {
00604 if (ast_strlen_zero(pvt->exten)) {
00605 ast_copy_string(called_addr, dest, sizeof(called_addr));
00606 } else {
00607 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
00608 }
00609 } else {
00610 res = htons(pvt->sa.sin_port);
00611 addr = ast_inet_ntoa(pvt->sa.sin_addr);
00612 if (ast_strlen_zero(pvt->exten)) {
00613 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
00614 } else {
00615 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res);
00616 }
00617 }
00618
00619 called_addr[sizeof(called_addr) - 1] = '\0';
00620
00621 if (c->cid.cid_num)
00622 ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num));
00623
00624 if (c->cid.cid_name)
00625 ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name));
00626
00627 if (c->cid.cid_rdnis) {
00628 ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis));
00629 }
00630
00631 pvt->options.presentation = c->cid.cid_pres;
00632 pvt->options.type_of_number = c->cid.cid_ton;
00633
00634 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
00635 if (!strcasecmp(addr, "UNKNOWN"))
00636 pvt->options.redirect_reason = 0;
00637 else if (!strcasecmp(addr, "BUSY"))
00638 pvt->options.redirect_reason = 1;
00639 else if (!strcasecmp(addr, "NO_REPLY"))
00640 pvt->options.redirect_reason = 2;
00641 else if (!strcasecmp(addr, "UNCONDITIONAL"))
00642 pvt->options.redirect_reason = 15;
00643 else
00644 pvt->options.redirect_reason = -1;
00645 } else
00646 pvt->options.redirect_reason = -1;
00647
00648 pvt->options.transfer_capability = c->transfercapability;
00649
00650
00651 pvt->outgoing = 1;
00652
00653 if (option_verbose > 2)
00654 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability));
00655 if (h323debug)
00656 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
00657 ast_mutex_unlock(&pvt->lock);
00658 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
00659 if (res) {
00660 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
00661 return -1;
00662 }
00663 oh323_update_info(c);
00664 return 0;
00665 }
00666
00667 static int oh323_answer(struct ast_channel *c)
00668 {
00669 int res;
00670 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00671 char *token;
00672
00673 if (h323debug)
00674 ast_log(LOG_DEBUG, "Answering on %s\n", c->name);
00675
00676 ast_mutex_lock(&pvt->lock);
00677 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00678 ast_mutex_unlock(&pvt->lock);
00679 res = h323_answering_call(token, 0);
00680 if (token)
00681 free(token);
00682
00683 oh323_update_info(c);
00684 if (c->_state != AST_STATE_UP) {
00685 ast_setstate(c, AST_STATE_UP);
00686 }
00687 return res;
00688 }
00689
00690 static int oh323_hangup(struct ast_channel *c)
00691 {
00692 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00693 int q931cause = AST_CAUSE_NORMAL_CLEARING;
00694 char *call_token;
00695
00696
00697 if (h323debug)
00698 ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name);
00699
00700 if (!c->tech_pvt) {
00701 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
00702 return 0;
00703 }
00704 ast_mutex_lock(&pvt->lock);
00705
00706 if (pvt->owner != c) {
00707 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n");
00708 ast_mutex_unlock(&pvt->lock);
00709 return 0;
00710 }
00711
00712 pvt->owner = NULL;
00713 c->tech_pvt = NULL;
00714
00715 if (c->hangupcause) {
00716 q931cause = c->hangupcause;
00717 } else {
00718 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS");
00719 if (cause) {
00720 if (!strcmp(cause, "CONGESTION")) {
00721 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
00722 } else if (!strcmp(cause, "BUSY")) {
00723 q931cause = AST_CAUSE_USER_BUSY;
00724 } else if (!strcmp(cause, "CHANISUNVAIL")) {
00725 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
00726 } else if (!strcmp(cause, "NOANSWER")) {
00727 q931cause = AST_CAUSE_NO_ANSWER;
00728 } else if (!strcmp(cause, "CANCEL")) {
00729 q931cause = AST_CAUSE_CALL_REJECTED;
00730 }
00731 }
00732 }
00733
00734
00735 if (!pvt->alreadygone && !pvt->hangupcause) {
00736 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00737 if (call_token) {
00738
00739 ast_mutex_unlock(&pvt->lock);
00740 if (h323_clear_call(call_token, q931cause)) {
00741 ast_log(LOG_WARNING, "ClearCall failed.\n");
00742 }
00743 free(call_token);
00744 ast_mutex_lock(&pvt->lock);
00745 }
00746 }
00747 pvt->needdestroy = 1;
00748 ast_mutex_unlock(&pvt->lock);
00749
00750
00751 ast_module_unref(ast_module_info->self);
00752
00753 return 0;
00754 }
00755
00756 static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
00757 {
00758
00759 struct ast_frame *f;
00760
00761
00762 if (pvt->options.nat) {
00763 ast_rtp_setnat(pvt->rtp, pvt->options.nat);
00764 pvt->options.nat = 0;
00765 }
00766
00767 f = ast_rtp_read(pvt->rtp);
00768
00769 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
00770 return &ast_null_frame;
00771 }
00772 if (pvt->owner) {
00773
00774 if (f->frametype == AST_FRAME_VOICE) {
00775 if (f->subclass != pvt->owner->nativeformats) {
00776
00777 if (ast_channel_trylock(pvt->owner)) {
00778 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
00779 return &ast_null_frame;
00780 }
00781 if (h323debug)
00782 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
00783 pvt->owner->nativeformats = f->subclass;
00784 pvt->nativeformats = f->subclass;
00785 ast_set_read_format(pvt->owner, pvt->owner->readformat);
00786 ast_set_write_format(pvt->owner, pvt->owner->writeformat);
00787 ast_channel_unlock(pvt->owner);
00788 }
00789
00790 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
00791 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) {
00792 if (!ast_channel_trylock(pvt->owner)) {
00793 f = ast_dsp_process(pvt->owner, pvt->vad, f);
00794 ast_channel_unlock(pvt->owner);
00795 }
00796 else
00797 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
00798 } else if (pvt->nativeformats && !pvt->noInbandDtmf) {
00799 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass));
00800 pvt->noInbandDtmf = 1;
00801 }
00802 if (f &&(f->frametype == AST_FRAME_DTMF)) {
00803 if (h323debug)
00804 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass);
00805 }
00806 }
00807 }
00808 }
00809 return f;
00810 }
00811
00812 static struct ast_frame *oh323_read(struct ast_channel *c)
00813 {
00814 struct ast_frame *fr;
00815 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00816 ast_mutex_lock(&pvt->lock);
00817 __oh323_update_info(c, pvt);
00818 switch(c->fdno) {
00819 case 0:
00820 fr = oh323_rtp_read(pvt);
00821 break;
00822 case 1:
00823 if (pvt->rtp)
00824 fr = ast_rtcp_read(pvt->rtp);
00825 else
00826 fr = &ast_null_frame;
00827 break;
00828 default:
00829 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name);
00830 fr = &ast_null_frame;
00831 break;
00832 }
00833 ast_mutex_unlock(&pvt->lock);
00834 return fr;
00835 }
00836
00837 static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
00838 {
00839 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00840 int res = 0;
00841 if (frame->frametype != AST_FRAME_VOICE) {
00842 if (frame->frametype == AST_FRAME_IMAGE) {
00843 return 0;
00844 } else {
00845 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
00846 return 0;
00847 }
00848 } else {
00849 if (!(frame->subclass & c->nativeformats)) {
00850 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
00851 frame->subclass, c->nativeformats, c->readformat, c->writeformat);
00852 return 0;
00853 }
00854 }
00855 if (pvt) {
00856 ast_mutex_lock(&pvt->lock);
00857 if (pvt->rtp && !pvt->recvonly)
00858 res = ast_rtp_write(pvt->rtp, frame);
00859 __oh323_update_info(c, pvt);
00860 ast_mutex_unlock(&pvt->lock);
00861 }
00862 return res;
00863 }
00864
00865 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
00866 {
00867
00868 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00869 char *token = (char *)NULL;
00870 int res = -1;
00871 int got_progress;
00872
00873 ast_mutex_lock(&pvt->lock);
00874 token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL);
00875 got_progress = pvt->got_progress;
00876 if (condition == AST_CONTROL_PROGRESS)
00877 pvt->got_progress = 1;
00878 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION))
00879 pvt->alreadygone = 1;
00880 ast_mutex_unlock(&pvt->lock);
00881
00882 if (h323debug)
00883 ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token);
00884
00885 switch(condition) {
00886 case AST_CONTROL_RINGING:
00887 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
00888 h323_send_alerting(token);
00889 res = (got_progress ? 0 : -1);
00890 }
00891 break;
00892 case AST_CONTROL_PROGRESS:
00893 if (c->_state != AST_STATE_UP) {
00894
00895 if (!got_progress)
00896 h323_send_progress(token);
00897 res = 0;
00898 }
00899 break;
00900 case AST_CONTROL_BUSY:
00901 if (c->_state != AST_STATE_UP) {
00902 h323_answering_call(token, 1);
00903 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00904 res = 0;
00905 }
00906 break;
00907 case AST_CONTROL_CONGESTION:
00908 if (c->_state != AST_STATE_UP) {
00909 h323_answering_call(token, 1);
00910 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00911 res = 0;
00912 }
00913 break;
00914 case AST_CONTROL_HOLD:
00915 ast_moh_start(c, data, NULL);
00916 res = 0;
00917 break;
00918 case AST_CONTROL_UNHOLD:
00919 ast_moh_stop(c);
00920 res = 0;
00921 break;
00922 case AST_CONTROL_PROCEEDING:
00923 case -1:
00924 break;
00925 default:
00926 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);
00927 break;
00928 }
00929
00930 if (h323debug)
00931 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);
00932 if (token)
00933 free(token);
00934 oh323_update_info(c);
00935
00936 return res;
00937 }
00938
00939 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00940 {
00941 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
00942
00943 ast_mutex_lock(&pvt->lock);
00944 if (pvt->owner != oldchan) {
00945 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
00946 return -1;
00947 }
00948 pvt->owner = newchan;
00949 ast_mutex_unlock(&pvt->lock);
00950 return 0;
00951 }
00952
00953 static int __oh323_rtp_create(struct oh323_pvt *pvt)
00954 {
00955 struct in_addr our_addr;
00956
00957 if (pvt->rtp)
00958 return 0;
00959
00960 if (ast_find_ourip(&our_addr, bindaddr)) {
00961 ast_mutex_unlock(&pvt->lock);
00962 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
00963 return -1;
00964 }
00965 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr);
00966 if (!pvt->rtp) {
00967 ast_mutex_unlock(&pvt->lock);
00968 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
00969 return -1;
00970 }
00971 if (h323debug)
00972 ast_log(LOG_DEBUG, "Created RTP channel\n");
00973
00974 ast_rtp_settos(pvt->rtp, tos);
00975
00976 if (h323debug)
00977 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
00978 ast_rtp_setnat(pvt->rtp, pvt->options.nat);
00979
00980 if (pvt->dtmf_pt > 0)
00981 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0);
00982
00983 if (pvt->peercapability)
00984 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);
00985
00986 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
00987 ast_jb_configure(pvt->owner, &global_jbconf);
00988 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp);
00989 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp);
00990 ast_queue_frame(pvt->owner, &ast_null_frame);
00991 ast_channel_unlock(pvt->owner);
00992 } else
00993 pvt->update_rtp_info = 1;
00994
00995 return 0;
00996 }
00997
00998
00999 static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host)
01000 {
01001 struct ast_channel *ch;
01002 char *cid_num, *cid_name;
01003 int fmt;
01004
01005 if (!ast_strlen_zero(pvt->options.cid_num))
01006 cid_num = pvt->options.cid_num;
01007 else
01008 cid_num = pvt->cd.call_source_e164;
01009
01010 if (!ast_strlen_zero(pvt->options.cid_name))
01011 cid_name = pvt->options.cid_name;
01012 else
01013 cid_name = pvt->cd.call_source_name;
01014
01015
01016 ast_mutex_unlock(&pvt->lock);
01017 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host);
01018
01019 ast_module_ref(ast_module_info->self);
01020 ast_mutex_lock(&pvt->lock);
01021 if (ch) {
01022 ch->tech = &oh323_tech;
01023 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
01024 fmt = global_options.capability;
01025 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1);
01026 pvt->nativeformats = ch->nativeformats;
01027 fmt = ast_best_codec(ch->nativeformats);
01028 ch->writeformat = fmt;
01029 ch->rawwriteformat = fmt;
01030 ch->readformat = fmt;
01031 ch->rawreadformat = fmt;
01032 #if 0
01033 ch->fds[0] = ast_rtp_fd(pvt->rtp);
01034 ch->fds[1] = ast_rtcp_fd(pvt->rtp);
01035 #endif
01036 #ifdef VIDEO_SUPPORT
01037 if (pvt->vrtp) {
01038 ch->fds[2] = ast_rtp_fd(pvt->vrtp);
01039 ch->fds[3] = ast_rtcp_fd(pvt->vrtp);
01040 }
01041 #endif
01042 #ifdef T38_SUPPORT
01043 if (pvt->udptl) {
01044 ch->fds[4] = ast_udptl_fd(pvt->udptl);
01045 }
01046 #endif
01047 if (state == AST_STATE_RING) {
01048 ch->rings = 1;
01049 }
01050
01051 if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
01052 pvt->vad = ast_dsp_new();
01053 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);
01054 }
01055
01056 ch->tech_pvt = pvt;
01057
01058 pvt->owner = ch;
01059
01060 ast_copy_string(ch->context, pvt->context, sizeof(ch->context));
01061 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten));
01062 ch->priority = 1;
01063 if (!ast_strlen_zero(pvt->accountcode)) {
01064 ast_string_field_set(ch, accountcode, pvt->accountcode);
01065 }
01066 if (pvt->amaflags) {
01067 ch->amaflags = pvt->amaflags;
01068 }
01069
01070
01071
01072 ch->cid.cid_num = ast_strdup(cid_num);
01073 ch->cid.cid_ani = ast_strdup(cid_num);
01074 ch->cid.cid_name = ast_strdup(cid_name);
01075
01076 if (pvt->cd.redirect_reason >= 0) {
01077 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number);
01078 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
01079 }
01080 ch->cid.cid_pres = pvt->cd.presentation;
01081 ch->cid.cid_ton = pvt->cd.type_of_number;
01082
01083 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
01084 ch->cid.cid_dnid = strdup(pvt->exten);
01085 }
01086 if (pvt->cd.transfer_capability >= 0)
01087 ch->transfercapability = pvt->cd.transfer_capability;
01088 if (state != AST_STATE_DOWN) {
01089 if (ast_pbx_start(ch)) {
01090 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
01091 ast_hangup(ch);
01092 ch = NULL;
01093 }
01094 }
01095 } else {
01096 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
01097 }
01098 return ch;
01099 }
01100
01101 static struct oh323_pvt *oh323_alloc(int callid)
01102 {
01103 struct oh323_pvt *pvt;
01104
01105 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt));
01106 if (!pvt) {
01107 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
01108 return NULL;
01109 }
01110 memset(pvt, 0, sizeof(struct oh323_pvt));
01111 pvt->cd.redirect_reason = -1;
01112 pvt->cd.transfer_capability = -1;
01113
01114 if (!callid) {
01115 if ((pvt->cd).call_token == NULL) {
01116 (pvt->cd).call_token = (char *)malloc(128);
01117 }
01118 if (!pvt->cd.call_token) {
01119 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
01120 ast_rtp_destroy(pvt->rtp);
01121 free(pvt);
01122 return NULL;
01123 }
01124 memset((char *)(pvt->cd).call_token, 0, 128);
01125 pvt->cd.call_reference = callid;
01126 }
01127 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01128 pvt->jointcapability = pvt->options.capability;
01129 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01130 pvt->nonCodecCapability |= AST_RTP_DTMF;
01131 } else {
01132 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01133 }
01134 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
01135 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;
01136 ast_mutex_init(&pvt->lock);
01137
01138 ast_mutex_lock(&iflock);
01139 pvt->next = iflist;
01140 iflist = pvt;
01141 ast_mutex_unlock(&iflock);
01142 return pvt;
01143 }
01144
01145 static struct oh323_pvt *find_call_locked(int call_reference, const char *token)
01146 {
01147 struct oh323_pvt *pvt;
01148
01149 ast_mutex_lock(&iflock);
01150 pvt = iflist;
01151 while(pvt) {
01152 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
01153
01154 if ((token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
01155 ast_mutex_lock(&pvt->lock);
01156 ast_mutex_unlock(&iflock);
01157 return pvt;
01158 } else if (token == NULL) {
01159 ast_log(LOG_WARNING, "Call Token is NULL\n");
01160 ast_mutex_lock(&pvt->lock);
01161 ast_mutex_unlock(&iflock);
01162 return pvt;
01163 }
01164 }
01165 pvt = pvt->next;
01166 }
01167 ast_mutex_unlock(&iflock);
01168 return NULL;
01169 }
01170
01171 static int update_state(struct oh323_pvt *pvt, int state, int signal)
01172 {
01173 if (!pvt)
01174 return 0;
01175 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01176 if (state >= 0)
01177 ast_setstate(pvt->owner, state);
01178 if (signal >= 0)
01179 ast_queue_control(pvt->owner, signal);
01180 ast_channel_unlock(pvt->owner);
01181 return 1;
01182 }
01183 else {
01184 if (state >= 0)
01185 pvt->newstate = state;
01186 if (signal >= 0)
01187 pvt->newcontrol = signal;
01188 return 0;
01189 }
01190 }
01191
01192 static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01193 {
01194 struct oh323_alias *alias;
01195 int found = 0;
01196
01197 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
01198
01199 if (alias)
01200 found++;
01201 else {
01202 if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias))))
01203 return NULL;
01204 ASTOBJ_INIT(alias);
01205 }
01206 if (!found && name)
01207 ast_copy_string(alias->name, name, sizeof(alias->name));
01208 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01209 if (!strcasecmp(v->name, "e164")) {
01210 ast_copy_string(alias->e164, v->value, sizeof(alias->e164));
01211 } else if (!strcasecmp(v->name, "prefix")) {
01212 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));
01213 } else if (!strcasecmp(v->name, "context")) {
01214 ast_copy_string(alias->context, v->value, sizeof(alias->context));
01215 } else if (!strcasecmp(v->name, "secret")) {
01216 ast_copy_string(alias->secret, v->value, sizeof(alias->secret));
01217 } else {
01218 if (strcasecmp(v->value, "h323")) {
01219 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);
01220 }
01221 }
01222 }
01223 ASTOBJ_UNMARK(alias);
01224 return alias;
01225 }
01226
01227 static struct oh323_alias *realtime_alias(const char *alias)
01228 {
01229 struct ast_variable *var, *tmp;
01230 struct oh323_alias *a;
01231
01232 var = ast_load_realtime("h323", "name", alias, NULL);
01233
01234 if (!var)
01235 return NULL;
01236
01237 for (tmp = var; tmp; tmp = tmp->next) {
01238 if (!strcasecmp(tmp->name, "type") &&
01239 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {
01240 ast_variables_destroy(var);
01241 return NULL;
01242 }
01243 }
01244
01245 a = build_alias(alias, var, NULL, 1);
01246
01247 ast_variables_destroy(var);
01248
01249 return a;
01250 }
01251
01252 #define DEPRECATED(_v, _new_opt) \
01253 ast_log(LOG_WARNING, "Option %s found at line %d has beed deprecated. Use %s instead.\n", (_v)->name, (_v)->lineno, (_new_opt))
01254
01255 static int update_common_options(struct ast_variable *v, struct call_options *options)
01256 {
01257 int tmp;
01258
01259 if (!strcasecmp(v->name, "allow")) {
01260 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
01261 } else if (!strcasecmp(v->name, "disallow")) {
01262 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
01263 } else if (!strcasecmp(v->name, "dtmfmode")) {
01264 if (!strcasecmp(v->value, "inband")) {
01265 options->dtmfmode = H323_DTMF_INBAND;
01266 } else if (!strcasecmp(v->value, "rfc2833")) {
01267 options->dtmfmode = H323_DTMF_RFC2833;
01268 } else {
01269 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
01270 options->dtmfmode = H323_DTMF_RFC2833;
01271 }
01272 } else if (!strcasecmp(v->name, "dtmfcodec")) {
01273 tmp = atoi(v->value);
01274 if (tmp < 96)
01275 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
01276 else
01277 options->dtmfcodec = tmp;
01278 } else if (!strcasecmp(v->name, "bridge")) {
01279 options->bridge = ast_true(v->value);
01280 } else if (!strcasecmp(v->name, "nat")) {
01281 options->nat = ast_true(v->value);
01282 } else if (!strcasecmp(v->name, "noFastStart")) {
01283 DEPRECATED(v, "fastStart");
01284 options->fastStart = !ast_true(v->value);
01285 } else if (!strcasecmp(v->name, "fastStart")) {
01286 options->fastStart = ast_true(v->value);
01287 } else if (!strcasecmp(v->name, "noH245Tunneling")) {
01288 DEPRECATED(v, "h245Tunneling");
01289 options->h245Tunneling = !ast_true(v->value);
01290 } else if (!strcasecmp(v->name, "h245Tunneling")) {
01291 options->h245Tunneling = ast_true(v->value);
01292 } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
01293 DEPRECATED(v, "silenceSuppression");
01294 options->silenceSuppression = !ast_true(v->value);
01295 } else if (!strcasecmp(v->name, "silenceSuppression")) {
01296 options->silenceSuppression = ast_true(v->value);
01297 } else if (!strcasecmp(v->name, "progress_setup")) {
01298 tmp = atoi(v->value);
01299 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
01300 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01301 tmp = 0;
01302 }
01303 options->progress_setup = tmp;
01304 } else if (!strcasecmp(v->name, "progress_alert")) {
01305 tmp = atoi(v->value);
01306 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {
01307 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01308 tmp = 0;
01309 }
01310 options->progress_alert = tmp;
01311 } else if (!strcasecmp(v->name, "progress_audio")) {
01312 options->progress_audio = ast_true(v->value);
01313 } else if (!strcasecmp(v->name, "callerid")) {
01314 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));
01315 } else if (!strcasecmp(v->name, "fullname")) {
01316 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));
01317 } else if (!strcasecmp(v->name, "cid_number")) {
01318 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));
01319 } else if (!strcasecmp(v->name, "tunneling")) {
01320 if (!strcasecmp(v->value, "none"))
01321 options->tunnelOptions = 0;
01322 else if (!strcasecmp(v->value, "cisco"))
01323 options->tunnelOptions |= H323_TUNNEL_CISCO;
01324 else if (!strcasecmp(v->value, "qsig"))
01325 options->tunnelOptions |= H323_TUNNEL_QSIG;
01326 else
01327 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
01328 } else
01329 return 1;
01330
01331 return 0;
01332 }
01333 #undef DEPRECATED
01334
01335 static struct oh323_user *build_user(char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01336 {
01337 struct oh323_user *user;
01338 struct ast_ha *oldha;
01339 int found = 0;
01340 int format;
01341
01342 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);
01343
01344 if (user)
01345 found++;
01346 else {
01347 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user))))
01348 return NULL;
01349 ASTOBJ_INIT(user);
01350 }
01351 oldha = user->ha;
01352 user->ha = (struct ast_ha *)NULL;
01353 memcpy(&user->options, &global_options, sizeof(user->options));
01354
01355 ast_copy_string(user->context, default_context, sizeof(user->context));
01356 if (user && !found)
01357 ast_copy_string(user->name, name, sizeof(user->name));
01358
01359 #if 0
01360 if (user->chanvars) {
01361 ast_variables_destroy(user->chanvars);
01362 user->chanvars = NULL;
01363 }
01364 #endif
01365
01366 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01367 if (!update_common_options(v, &user->options))
01368 continue;
01369 if (!strcasecmp(v->name, "context")) {
01370 ast_copy_string(user->context, v->value, sizeof(user->context));
01371 } else if (!strcasecmp(v->name, "secret")) {
01372 ast_copy_string(user->secret, v->value, sizeof(user->secret));
01373 } else if (!strcasecmp(v->name, "accountcode")) {
01374 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
01375 } else if (!strcasecmp(v->name, "host")) {
01376 if (!strcasecmp(v->value, "dynamic")) {
01377 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
01378 ASTOBJ_UNREF(user, oh323_destroy_user);
01379 return NULL;
01380 } else if (ast_get_ip(&user->addr, v->value)) {
01381 ASTOBJ_UNREF(user, oh323_destroy_user);
01382 return NULL;
01383 }
01384
01385 user->host = 1;
01386 } else if (!strcasecmp(v->name, "amaflags")) {
01387 format = ast_cdr_amaflags2int(v->value);
01388 if (format < 0) {
01389 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
01390 } else {
01391 user->amaflags = format;
01392 }
01393 } else if (!strcasecmp(v->name, "permit") ||
01394 !strcasecmp(v->name, "deny")) {
01395 user->ha = ast_append_ha(v->name, v->value, user->ha);
01396 }
01397 }
01398 ASTOBJ_UNMARK(user);
01399 ast_free_ha(oldha);
01400 return user;
01401 }
01402
01403 static struct oh323_user *realtime_user(const call_details_t *cd)
01404 {
01405 struct ast_variable *var, *tmp;
01406 struct oh323_user *user;
01407 char *username;
01408
01409 if (userbyalias)
01410 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL);
01411 else {
01412 username = (char *)NULL;
01413 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL);
01414 }
01415
01416 if (!var)
01417 return NULL;
01418
01419 for (tmp = var; tmp; tmp = tmp->next) {
01420 if (!strcasecmp(tmp->name, "type") &&
01421 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {
01422 ast_variables_destroy(var);
01423 return NULL;
01424 } else if (!username && !strcasecmp(tmp->name, "name"))
01425 username = tmp->value;
01426 }
01427
01428 if (!username) {
01429 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);
01430 ast_variables_destroy(var);
01431 return NULL;
01432 }
01433
01434 user = build_user(username, var, NULL, 1);
01435
01436 ast_variables_destroy(var);
01437
01438 return user;
01439 }
01440
01441 static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01442 {
01443 struct oh323_peer *peer;
01444 struct ast_ha *oldha;
01445 int found = 0;
01446
01447 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
01448
01449 if (peer)
01450 found++;
01451 else {
01452 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer))))
01453 return NULL;
01454 ASTOBJ_INIT(peer);
01455 }
01456 oldha = peer->ha;
01457 peer->ha = NULL;
01458 memcpy(&peer->options, &global_options, sizeof(peer->options));
01459 peer->addr.sin_port = htons(h323_signalling_port);
01460 peer->addr.sin_family = AF_INET;
01461 if (!found && name)
01462 ast_copy_string(peer->name, name, sizeof(peer->name));
01463
01464 #if 0
01465 if (peer->chanvars) {
01466 ast_variables_destroy(peer->chanvars);
01467 peer->chanvars = NULL;
01468 }
01469 #endif
01470
01471 peer->mailbox[0] = '\0';
01472
01473 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01474 if (!update_common_options(v, &peer->options))
01475 continue;
01476 if (!strcasecmp(v->name, "host")) {
01477 if (!strcasecmp(v->value, "dynamic")) {
01478 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
01479 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01480 return NULL;
01481 }
01482 if (ast_get_ip(&peer->addr, v->value)) {
01483 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
01484 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01485 return NULL;
01486 }
01487 } else if (!strcasecmp(v->name, "port")) {
01488 peer->addr.sin_port = htons(atoi(v->value));
01489 } else if (!strcasecmp(v->name, "permit") ||
01490 !strcasecmp(v->name, "deny")) {
01491 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
01492 } else if (!strcasecmp(v->name, "mailbox")) {
01493 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
01494 }
01495 }
01496 ASTOBJ_UNMARK(peer);
01497 ast_free_ha(oldha);
01498 return peer;
01499 }
01500
01501 static struct oh323_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
01502 {
01503 struct oh323_peer *peer;
01504 struct ast_variable *var;
01505 struct ast_variable *tmp;
01506 const char *addr;
01507
01508
01509 if (peername)
01510 var = ast_load_realtime("h323", "name", peername, addr = NULL);
01511 else if (sin)
01512 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL);
01513 else
01514 return NULL;
01515
01516 if (!var)
01517 return NULL;
01518
01519 for (tmp = var; tmp; tmp = tmp->next) {
01520
01521 if (!strcasecmp(tmp->name, "type") &&
01522 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) {
01523 ast_variables_destroy(var);
01524 return NULL;
01525 } else if (!peername && !strcasecmp(tmp->name, "name")) {
01526 peername = tmp->value;
01527 }
01528 }
01529
01530 if (!peername) {
01531 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr);
01532 ast_variables_destroy(var);
01533 return NULL;
01534 }
01535
01536
01537 peer = build_peer(peername, var, NULL, 1);
01538
01539 ast_variables_destroy(var);
01540
01541 return peer;
01542 }
01543
01544 static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
01545 {
01546 return strcmp(ast_inet_ntoa(inaddr), addr);
01547 }
01548
01549 static struct oh323_user *find_user(const call_details_t *cd, int realtime)
01550 {
01551 struct oh323_user *u;
01552
01553 if (userbyalias)
01554 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases);
01555 else
01556 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str);
01557
01558 if (!u && realtime)
01559 u = realtime_user(cd);
01560
01561 if (!u && h323debug)
01562 ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp);
01563
01564 return u;
01565 }
01566
01567 static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
01568 {
01569 int res;
01570
01571 if (!sin)
01572 res = -1;
01573 else
01574 res = inaddrcmp(&addr , sin);
01575
01576 return res;
01577 }
01578
01579 static struct oh323_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
01580 {
01581 struct oh323_peer *p;
01582
01583 if (peer)
01584 p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
01585 else
01586 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);
01587
01588 if (!p && realtime)
01589 p = realtime_peer(peer, sin);
01590
01591 if (!p && h323debug)
01592 ast_log(LOG_DEBUG, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>"));
01593
01594 return p;
01595 }
01596
01597 static int create_addr(struct oh323_pvt *pvt, char *opeer)
01598 {
01599 struct hostent *hp;
01600 struct ast_hostent ahp;
01601 struct oh323_peer *p;
01602 int portno;
01603 int found = 0;
01604 char *port;
01605 char *hostn;
01606 char peer[256] = "";
01607
01608 ast_copy_string(peer, opeer, sizeof(peer));
01609 port = strchr(peer, ':');
01610 if (port) {
01611 *port = '\0';
01612 port++;
01613 }
01614 pvt->sa.sin_family = AF_INET;
01615 p = find_peer(peer, NULL, 1);
01616 if (p) {
01617 found++;
01618 memcpy(&pvt->options, &p->options, sizeof(pvt->options));
01619 pvt->jointcapability = pvt->options.capability;
01620 if (pvt->options.dtmfmode) {
01621 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01622 pvt->nonCodecCapability |= AST_RTP_DTMF;
01623 } else {
01624 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01625 }
01626 }
01627 if (p->addr.sin_addr.s_addr) {
01628 pvt->sa.sin_addr = p->addr.sin_addr;
01629 pvt->sa.sin_port = p->addr.sin_port;
01630 }
01631 ASTOBJ_UNREF(p, oh323_destroy_peer);
01632 }
01633 if (!p && !found) {
01634 hostn = peer;
01635 if (port) {
01636 portno = atoi(port);
01637 } else {
01638 portno = h323_signalling_port;
01639 }
01640 hp = ast_gethostbyname(hostn, &ahp);
01641 if (hp) {
01642 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
01643 pvt->sa.sin_port = htons(portno);
01644
01645 p = find_peer(NULL, &pvt->sa, 1);
01646 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options));
01647 pvt->jointcapability = pvt->options.capability;
01648 if (p) {
01649 ASTOBJ_UNREF(p, oh323_destroy_peer);
01650 }
01651 if (pvt->options.dtmfmode) {
01652 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01653 pvt->nonCodecCapability |= AST_RTP_DTMF;
01654 } else {
01655 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01656 }
01657 }
01658 return 0;
01659 } else {
01660 ast_log(LOG_WARNING, "No such host: %s\n", peer);
01661 return -1;
01662 }
01663 } else if (!found) {
01664 return -1;
01665 } else {
01666 return 0;
01667 }
01668 }
01669 static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause)
01670 {
01671 int oldformat;
01672 struct oh323_pvt *pvt;
01673 struct ast_channel *tmpc = NULL;
01674 char *dest = (char *)data;
01675 char *ext, *host;
01676 char *h323id = NULL;
01677 char tmp[256], tmp1[256];
01678
01679 if (h323debug)
01680 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);
01681
01682 pvt = oh323_alloc(0);
01683 if (!pvt) {
01684 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
01685 return NULL;
01686 }
01687 oldformat = format;
01688 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
01689 if (!format) {
01690 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
01691 oh323_destroy(pvt);
01692 if (cause)
01693 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
01694 return NULL;
01695 }
01696 ast_copy_string(tmp, dest, sizeof(tmp));
01697 host = strchr(tmp, '@');
01698 if (host) {
01699 *host = '\0';
01700 host++;
01701 ext = tmp;
01702 } else {
01703 ext = strrchr(tmp, '/');
01704 if (ext)
01705 *ext++ = '\0';
01706 host = tmp;
01707 }
01708 strtok_r(host, "/", &(h323id));
01709 if (!ast_strlen_zero(h323id)) {
01710 h323_set_id(h323id);
01711 }
01712 if (ext) {
01713 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten));
01714 }
01715 if (h323debug)
01716 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host);
01717
01718 if (gatekeeper_disable) {
01719 if (create_addr(pvt, host)) {
01720 oh323_destroy(pvt);
01721 if (cause)
01722 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01723 return NULL;
01724 }
01725 }
01726 else {
01727 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01728 pvt->jointcapability = pvt->options.capability;
01729 if (pvt->options.dtmfmode) {
01730 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01731 pvt->nonCodecCapability |= AST_RTP_DTMF;
01732 } else {
01733 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01734 }
01735 }
01736 }
01737
01738 ast_mutex_lock(&caplock);
01739
01740 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
01741 tmp1[sizeof(tmp1)-1] = '\0';
01742 ast_mutex_unlock(&caplock);
01743
01744 ast_mutex_lock(&pvt->lock);
01745 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1);
01746 ast_mutex_unlock(&pvt->lock);
01747 if (!tmpc) {
01748 oh323_destroy(pvt);
01749 if (cause)
01750 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
01751 }
01752 ast_update_use_count();
01753 restart_monitor();
01754 return tmpc;
01755 }
01756
01757
01758 static struct oh323_alias *find_alias(const char *source_aliases, int realtime)
01759 {
01760 struct oh323_alias *a;
01761
01762 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
01763
01764 if (!a && realtime)
01765 a = realtime_alias(source_aliases);
01766
01767 return a;
01768 }
01769
01770
01771
01772
01773
01774 static int receive_digit(unsigned call_reference, char digit, const char *token, int duration)
01775 {
01776 struct oh323_pvt *pvt;
01777 int res;
01778
01779 pvt = find_call_locked(call_reference, token);
01780 if (!pvt) {
01781 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token);
01782 return -1;
01783 }
01784 if (h323debug)
01785 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token);
01786
01787 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01788 if (digit == '!')
01789 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH);
01790 else {
01791 struct ast_frame f = {
01792 .frametype = AST_FRAME_DTMF_END,
01793 .subclass = digit,
01794 .samples = duration * 8,
01795 .len = duration,
01796 .src = "SEND_DIGIT",
01797 };
01798 if (digit == ' ') {
01799 f.subclass = pvt->curDTMF;
01800 if (pvt->DTMFsched >= 0) {
01801 ast_sched_del(sched, pvt->DTMFsched);
01802 pvt->DTMFsched = -1;
01803 }
01804 } else {
01805 if (pvt->DTMFsched >= 0) {
01806
01807 ast_sched_del(sched, pvt->DTMFsched);
01808 pvt->DTMFsched = -1;
01809 f.subclass = pvt->curDTMF;
01810 f.samples = f.len = 0;
01811 ast_queue_frame(pvt->owner, &f);
01812
01813 f.subclass = digit;
01814 f.samples = duration * 8;
01815 f.len = duration;
01816 }
01817 if (duration) {
01818 f.frametype = AST_FRAME_DTMF_BEGIN;
01819 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt);
01820 if (h323debug)
01821 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched);
01822 }
01823 pvt->curDTMF = digit;
01824 }
01825 res = ast_queue_frame(pvt->owner, &f);
01826 }
01827 ast_channel_unlock(pvt->owner);
01828 } else {
01829 if (digit == '!')
01830 pvt->newcontrol = AST_CONTROL_FLASH;
01831 else {
01832 pvt->newduration = duration;
01833 pvt->newdigit = digit;
01834 }
01835 res = 0;
01836 }
01837 ast_mutex_unlock(&pvt->lock);
01838 return res;
01839 }
01840
01841
01842
01843
01844
01845
01846 static struct rtp_info *external_rtp_create(unsigned call_reference, const char * token)
01847 {
01848 struct oh323_pvt *pvt;
01849 struct sockaddr_in us;
01850 struct rtp_info *info;
01851
01852 info = (struct rtp_info *)malloc(sizeof(struct rtp_info));
01853 if (!info) {
01854 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
01855 return NULL;
01856 }
01857 pvt = find_call_locked(call_reference, token);
01858 if (!pvt) {
01859 free(info);
01860 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
01861 return NULL;
01862 }
01863 if (!pvt->rtp)
01864 __oh323_rtp_create(pvt);
01865 if (!pvt->rtp) {
01866 ast_mutex_unlock(&pvt->lock);
01867 free(info);
01868 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference);
01869 return NULL;
01870 }
01871
01872 ast_rtp_get_us(pvt->rtp, &us);
01873 ast_mutex_unlock(&pvt->lock);
01874
01875 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
01876 info->port = ntohs(us.sin_port);
01877 if (h323debug)
01878 ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
01879 return info;
01880 }
01881
01882
01883
01884
01885 struct rtpPayloadType {
01886 int isAstFormat;
01887 int code;
01888 };
01889
01890
01891
01892
01893
01894
01895 static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
01896 {
01897 struct oh323_pvt *pvt;
01898 struct sockaddr_in them;
01899 struct rtpPayloadType rtptype;
01900 int nativeformats_changed;
01901 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE;
01902
01903 if (h323debug)
01904 ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token);
01905
01906
01907 pvt = find_call_locked(call_reference, token);
01908 if (!pvt) {
01909 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
01910 return;
01911 }
01912 if (pvt->alreadygone) {
01913 ast_mutex_unlock(&pvt->lock);
01914 return;
01915 }
01916
01917 if (!pvt->rtp)
01918 __oh323_rtp_create(pvt);
01919
01920 them.sin_family = AF_INET;
01921
01922 them.sin_addr.s_addr = inet_addr(remoteIp);
01923 them.sin_port = htons(remotePort);
01924
01925 if (them.sin_addr.s_addr) {
01926 ast_rtp_set_peer(pvt->rtp, &them);
01927 if (pvt->recvonly) {
01928 pvt->recvonly = 0;
01929 rtp_change = NEED_UNHOLD;
01930 }
01931 } else {
01932 ast_rtp_stop(pvt->rtp);
01933 if (!pvt->recvonly) {
01934 pvt->recvonly = 1;
01935 rtp_change = NEED_HOLD;
01936 }
01937 }
01938
01939
01940 nativeformats_changed = 0;
01941 if (pt != 128 && pvt->rtp) {
01942 rtptype = ast_rtp_lookup_pt(pvt->rtp, pt);
01943 if (h323debug)
01944 ast_log(LOG_DEBUG, "Native format is set to %d from %d by RTP payload type %d\n", rtptype.code, pvt->nativeformats, pt);
01945 if (pvt->nativeformats != rtptype.code) {
01946 pvt->nativeformats = rtptype.code;
01947 nativeformats_changed = 1;
01948 }
01949 } else if (h323debug)
01950 ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
01951
01952
01953 if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
01954 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01955
01956 if (pvt->owner->nativeformats != pvt->nativeformats) {
01957 if (h323debug)
01958 ast_log(LOG_DEBUG, "Native format changed to %d from %d, read format is %d, write format is %d\n", pvt->nativeformats, pvt->owner->nativeformats, pvt->owner->readformat, pvt->owner->writeformat);
01959 pvt->owner->nativeformats = pvt->nativeformats;
01960 ast_set_read_format(pvt->owner, pvt->owner->readformat);
01961 ast_set_write_format(pvt->owner, pvt->owner->writeformat);
01962 }
01963 if (pvt->options.progress_audio)
01964 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
01965 switch (rtp_change) {
01966 case NEED_HOLD:
01967 ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
01968 break;
01969 case NEED_UNHOLD:
01970 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
01971 break;
01972 default:
01973 break;
01974 }
01975 ast_channel_unlock(pvt->owner);
01976 }
01977 else {
01978 if (pvt->options.progress_audio)
01979 pvt->newcontrol = AST_CONTROL_PROGRESS;
01980 else if (rtp_change == NEED_HOLD)
01981 pvt->newcontrol = AST_CONTROL_HOLD;
01982 else if (rtp_change == NEED_UNHOLD)
01983 pvt->newcontrol = AST_CONTROL_UNHOLD;
01984 if (h323debug)
01985 ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token);
01986 }
01987 }
01988 ast_mutex_unlock(&pvt->lock);
01989
01990 if (h323debug)
01991 ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token);
01992
01993 return;
01994 }
01995
01996
01997
01998
01999
02000 static void connection_made(unsigned call_reference, const char *token)
02001 {
02002 struct oh323_pvt *pvt;
02003
02004 if (h323debug)
02005 ast_log(LOG_DEBUG, "Call %s answered\n", token);
02006
02007 pvt = find_call_locked(call_reference, token);
02008 if (!pvt) {
02009 ast_log(LOG_ERROR, "Something is wrong: connection\n");
02010 return;
02011 }
02012
02013
02014 if (!pvt->outgoing) {
02015 ast_mutex_unlock(&pvt->lock);
02016 return;
02017 }
02018
02019 if (!pvt->connection_established) {
02020 pvt->connection_established = 1;
02021 update_state(pvt, -1, AST_CONTROL_ANSWER);
02022 }
02023 ast_mutex_unlock(&pvt->lock);
02024 return;
02025 }
02026
02027 static int progress(unsigned call_reference, const char *token, int inband)
02028 {
02029 struct oh323_pvt *pvt;
02030
02031 if (h323debug)
02032 ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
02033
02034 pvt = find_call_locked(call_reference, token);
02035 if (!pvt) {
02036 ast_log(LOG_ERROR, "Private structure not found in progress.\n");
02037 return -1;
02038 }
02039 if (!pvt->owner) {
02040 ast_mutex_unlock(&pvt->lock);
02041 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
02042 return -1;
02043 }
02044 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
02045 ast_mutex_unlock(&pvt->lock);
02046
02047 return 0;
02048 }
02049
02050
02051
02052
02053
02054
02055 static call_options_t *setup_incoming_call(call_details_t *cd)
02056 {
02057 struct oh323_pvt *pvt;
02058 struct oh323_user *user = NULL;
02059 struct oh323_alias *alias = NULL;
02060
02061 if (h323debug)
02062 ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token);
02063
02064
02065 pvt = oh323_alloc(cd->call_reference);
02066
02067 if (!pvt) {
02068 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
02069 cleanup_call_details(cd);
02070 return NULL;
02071 }
02072
02073
02074 memcpy(&pvt->cd, cd, sizeof(pvt->cd));
02075 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
02076 pvt->jointcapability = pvt->options.capability;
02077
02078 if (h323debug) {
02079 ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n");
02080 ast_verbose(VERBOSE_PREFIX_3 " \tCall token: [%s]\n", pvt->cd.call_token);
02081 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party name: [%s]\n", pvt->cd.call_source_name);
02082 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party number: [%s]\n", pvt->cd.call_source_e164);
02083 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias);
02084 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164);
02085 if (pvt->cd.redirect_reason >= 0)
02086 ast_verbose(VERBOSE_PREFIX_3 " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason);
02087 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party IP: [%s]\n", pvt->cd.sourceIp);
02088 }
02089
02090
02091 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) {
02092 if (!ast_strlen_zero(cd->call_dest_e164)) {
02093 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02094 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02095 } else {
02096 alias = find_alias(cd->call_dest_alias, 1);
02097 if (!alias) {
02098 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
02099 oh323_destroy(pvt);
02100 return NULL;
02101 }
02102 ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten));
02103 ast_copy_string(pvt->context, alias->context, sizeof(pvt->context));
02104 }
02105 } else {
02106
02107
02108 user = find_user(cd, 1);
02109 if (!user) {
02110 if (!acceptAnonymous) {
02111 ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
02112 oh323_destroy(pvt);
02113 return NULL;
02114 }
02115 if (ast_strlen_zero(default_context)) {
02116 ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
02117 oh323_destroy(pvt);
02118 return NULL;
02119 }
02120 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02121 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
02122 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02123 } else {
02124 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
02125 }
02126 if (h323debug)
02127 ast_log(LOG_DEBUG, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten);
02128 } else {
02129 if (user->host) {
02130 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) {
02131 if (ast_strlen_zero(user->context)) {
02132 if (ast_strlen_zero(default_context)) {
02133 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
02134 oh323_destroy(pvt);
02135 ASTOBJ_UNREF(user, oh323_destroy_user);
02136 return NULL;
02137 }
02138 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02139 } else {
02140 ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
02141 }
02142 pvt->exten[0] = 'i';
02143 pvt->exten[1] = '\0';
02144 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
02145 oh323_destroy(pvt);
02146 ASTOBJ_UNREF(user, oh323_destroy_user);
02147 return NULL;
02148 }
02149 }
02150 ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
02151 memcpy(&pvt->options, &user->options, sizeof(pvt->options));
02152 pvt->jointcapability = pvt->options.capability;
02153 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
02154 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02155 } else {
02156 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
02157 }
02158 if (!ast_strlen_zero(user->accountcode)) {
02159 ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode));
02160 }
02161 if (user->amaflags) {
02162 pvt->amaflags = user->amaflags;
02163 }
02164 ASTOBJ_UNREF(user, oh323_destroy_user);
02165 }
02166 }
02167 return &pvt->options;
02168 }
02169
02170
02171
02172
02173
02174
02175 static int answer_call(unsigned call_reference, const char *token)
02176 {
02177 struct oh323_pvt *pvt;
02178 struct ast_channel *c = NULL;
02179 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten;
02180 char tmp_exten[sizeof(pvt->exten)];
02181
02182 if (h323debug)
02183 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token);
02184
02185
02186 pvt = find_call_locked(call_reference, token);
02187 if (!pvt) {
02188 ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
02189 return 0;
02190 }
02191
02192 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten));
02193
02194
02195 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) {
02196 if (tmp_exten[0] == 's')
02197 try_exten = ext_s;
02198 else if (tmp_exten[0] == 'i')
02199 try_exten = ext_i;
02200 else
02201 try_exten = ext_original;
02202 } else
02203 try_exten = ext_original;
02204 do {
02205 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL))
02206 break;
02207 switch (try_exten) {
02208 case ext_original:
02209 tmp_exten[0] = 's';
02210 tmp_exten[1] = '\0';
02211 try_exten = ext_s;
02212 break;
02213 case ext_s:
02214 tmp_exten[0] = 'i';
02215 try_exten = ext_i;
02216 break;
02217 case ext_i:
02218 try_exten = ext_notexists;
02219 break;
02220 default:
02221 break;
02222 }
02223 } while (try_exten != ext_notexists);
02224
02225
02226 if (try_exten == ext_notexists) {
02227 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context);
02228 ast_mutex_unlock(&pvt->lock);
02229 h323_clear_call(token, AST_CAUSE_UNALLOCATED);
02230 return 0;
02231 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) {
02232 if (h323debug)
02233 ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context);
02234 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten));
02235 }
02236
02237
02238 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token);
02239
02240
02241 ast_mutex_unlock(&pvt->lock);
02242 if (!c) {
02243 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
02244 return 0;
02245 }
02246 return 1;
02247 }
02248
02249
02250
02251
02252
02253
02254 static int setup_outgoing_call(call_details_t *cd)
02255 {
02256
02257 cleanup_call_details(cd);
02258
02259 return 1;
02260 }
02261
02262
02263
02264
02265
02266 static void chan_ringing(unsigned call_reference, const char *token)
02267 {
02268 struct oh323_pvt *pvt;
02269
02270 if (h323debug)
02271 ast_log(LOG_DEBUG, "Ringing on %s\n", token);
02272
02273 pvt = find_call_locked(call_reference, token);
02274 if (!pvt) {
02275 ast_log(LOG_ERROR, "Something is wrong: ringing\n");
02276 return;
02277 }
02278 if (!pvt->owner) {
02279 ast_mutex_unlock(&pvt->lock);
02280 ast_log(LOG_ERROR, "Channel has no owner\n");
02281 return;
02282 }
02283 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING);
02284 ast_mutex_unlock(&pvt->lock);
02285 return;
02286 }
02287
02288
02289
02290
02291
02292 static void cleanup_connection(unsigned call_reference, const char *call_token)
02293 {
02294 struct oh323_pvt *pvt;
02295
02296 if (h323debug)
02297 ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token);
02298
02299 while (1) {
02300 pvt = find_call_locked(call_reference, call_token);
02301 if (!pvt) {
02302 if (h323debug)
02303 ast_log(LOG_DEBUG, "No connection for %s\n", call_token);
02304 return;
02305 }
02306 if (!pvt->owner || !ast_channel_trylock(pvt->owner))
02307 break;
02308 #if 1
02309 #ifdef DEBUG_THREADS
02310 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s, locked at %ld/%d by %s (%s:%d)\n", call_token, pvt->owner->lock.thread[0], pvt->owner->lock.reentrancy, pvt->owner->lock.func[0], pvt->owner->lock.file[0], pvt->owner->lock.lineno[0]);
02311 #else
02312 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
02313 #endif
02314 #endif
02315 ast_mutex_unlock(&pvt->lock);
02316 usleep(1);
02317 }
02318 if (pvt->rtp) {
02319
02320 ast_rtp_destroy(pvt->rtp);
02321 pvt->rtp = NULL;
02322 }
02323
02324 if (pvt->vad) {
02325 ast_dsp_free(pvt->vad);
02326 pvt->vad = NULL;
02327 }
02328 cleanup_call_details(&pvt->cd);
02329 pvt->alreadygone = 1;
02330
02331 if (pvt->owner) {
02332 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
02333 ast_queue_hangup(pvt->owner);
02334 ast_channel_unlock(pvt->owner);
02335 }
02336 ast_mutex_unlock(&pvt->lock);
02337 if (h323debug)
02338 ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token);
02339 return;
02340 }
02341
02342 static void hangup_connection(unsigned int call_reference, const char *token, int cause)
02343 {
02344 struct oh323_pvt *pvt;
02345
02346 if (h323debug) {
02347 ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause);
02348 }
02349
02350 pvt = find_call_locked(call_reference, token);
02351 if (!pvt) {
02352 if (h323debug) {
02353 ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token);
02354 }
02355 return;
02356 }
02357 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02358 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
02359 pvt->owner->hangupcause = pvt->hangupcause = cause;
02360 ast_queue_hangup(pvt->owner);
02361 ast_channel_unlock(pvt->owner);
02362 }
02363 else {
02364 pvt->needhangup = 1;
02365 pvt->hangupcause = cause;
02366 if (h323debug)
02367 ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token);
02368 }
02369 ast_mutex_unlock(&pvt->lock);
02370 }
02371
02372 static void set_dtmf_payload(unsigned call_reference, const char *token, int payload)
02373 {
02374 struct oh323_pvt *pvt;
02375
02376 if (h323debug)
02377 ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token);
02378
02379 pvt = find_call_locked(call_reference, token);
02380 if (!pvt) {
02381 return;
02382 }
02383 if (pvt->rtp) {
02384 ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0);
02385 }
02386 pvt->dtmf_pt = payload;
02387 ast_mutex_unlock(&pvt->lock);
02388 if (h323debug)
02389 ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload);
02390 }
02391
02392 static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)
02393 {
02394 struct oh323_pvt *pvt;
02395
02396 if (h323debug)
02397 ast_log(LOG_DEBUG, "Got remote capabilities from connection %s\n", token);
02398
02399 pvt = find_call_locked(call_reference, token);
02400 if (!pvt)
02401 return;
02402 pvt->peercapability = capabilities;
02403 pvt->jointcapability = pvt->options.capability & capabilities;
02404 if (prefs) {
02405 memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs));
02406 if (h323debug) {
02407 int i;
02408 for (i = 0; i < 32; ++i) {
02409 if (!prefs->order[i])
02410 break;
02411 ast_log(LOG_DEBUG, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]);
02412 }
02413 }
02414 if (pvt->rtp)
02415 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);
02416 }
02417 ast_mutex_unlock(&pvt->lock);
02418 }
02419
02420 static void set_local_capabilities(unsigned call_reference, const char *token)
02421 {
02422 struct oh323_pvt *pvt;
02423 int capability, dtmfmode, pref_codec;
02424 struct ast_codec_pref prefs;
02425
02426 if (h323debug)
02427 ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token);
02428
02429 pvt = find_call_locked(call_reference, token);
02430 if (!pvt)
02431 return;
02432 capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability;
02433 dtmfmode = pvt->options.dtmfmode;
02434 prefs = pvt->options.prefs;
02435 pref_codec = pvt->pref_codec;
02436 ast_mutex_unlock(&pvt->lock);
02437 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
02438
02439 if (h323debug)
02440 ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
02441 }
02442
02443 static void *do_monitor(void *data)
02444 {
02445 int res;
02446 int reloading;
02447 struct oh323_pvt *oh323 = NULL;
02448
02449 for(;;) {
02450
02451 ast_mutex_lock(&h323_reload_lock);
02452 reloading = h323_reloading;
02453 h323_reloading = 0;
02454 ast_mutex_unlock(&h323_reload_lock);
02455 if (reloading) {
02456 if (option_verbose > 0) {
02457 ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n");
02458 }
02459 h323_do_reload();
02460 }
02461
02462 if (!ast_mutex_trylock(&iflock)) {
02463 #if 1
02464 do {
02465 for (oh323 = iflist; oh323; oh323 = oh323->next) {
02466 if (!ast_mutex_trylock(&oh323->lock)) {
02467 if (oh323->needdestroy) {
02468 __oh323_destroy(oh323);
02469 break;
02470 }
02471 ast_mutex_unlock(&oh323->lock);
02472 }
02473 }
02474 } while ( 0);
02475 #else
02476 restartsearch:
02477 oh323 = iflist;
02478 while(oh323) {
02479 if (!ast_mutex_trylock(&oh323->lock)) {
02480 if (oh323->needdestroy) {
02481 __oh323_destroy(oh323);
02482 goto restartsearch;
02483 }
02484 ast_mutex_unlock(&oh323->lock);
02485 oh323 = oh323->next;
02486 }
02487 }
02488 #endif
02489 ast_mutex_unlock(&iflock);
02490 } else
02491 oh323 = (struct oh323_pvt *)1;
02492 pthread_testcancel();
02493
02494 res = ast_sched_wait(sched);
02495 if ((res < 0) || (res > 1000)) {
02496 res = 1000;
02497 }
02498
02499 if (oh323)
02500 res = 1;
02501 res = ast_io_wait(io, res);
02502 pthread_testcancel();
02503 ast_mutex_lock(&monlock);
02504 if (res >= 0) {
02505 ast_sched_runq(sched);
02506 }
02507 ast_mutex_unlock(&monlock);
02508 }
02509
02510 return NULL;
02511 }
02512
02513 static int restart_monitor(void)
02514 {
02515 pthread_attr_t attr;
02516
02517 if (ast_mutex_lock(&monlock)) {
02518 ast_log(LOG_WARNING, "Unable to lock monitor\n");
02519 return -1;
02520 }
02521 if (monitor_thread == AST_PTHREADT_STOP) {
02522 ast_mutex_unlock(&monlock);
02523 return 0;
02524 }
02525 if (monitor_thread == pthread_self()) {
02526 ast_mutex_unlock(&monlock);
02527 ast_log(LOG_WARNING, "Cannot kill myself\n");
02528 return -1;
02529 }
02530 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
02531
02532 pthread_kill(monitor_thread, SIGURG);
02533 } else {
02534 pthread_attr_init(&attr);
02535 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02536
02537 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
02538 monitor_thread = AST_PTHREADT_NULL;
02539 ast_mutex_unlock(&monlock);
02540 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
02541 pthread_attr_destroy(&attr);
02542 return -1;
02543 }
02544 pthread_attr_destroy(&attr);
02545 }
02546 ast_mutex_unlock(&monlock);
02547 return 0;
02548 }
02549
02550 static int h323_do_trace(int fd, int argc, char *argv[])
02551 {
02552 if (argc != 4) {
02553 return RESULT_SHOWUSAGE;
02554 }
02555 h323_debug(1, atoi(argv[3]));
02556 ast_cli(fd, "H.323 trace set to level %s\n", argv[2]);
02557 return RESULT_SUCCESS;
02558 }
02559
02560 static int h323_no_trace(int fd, int argc, char *argv[])
02561 {
02562 if (argc < 3 || argc > 4) {
02563 return RESULT_SHOWUSAGE;
02564 }
02565 h323_debug(0,0);
02566 ast_cli(fd, "H.323 trace disabled\n");
02567 return RESULT_SUCCESS;
02568 }
02569
02570 static int h323_do_debug(int fd, int argc, char *argv[])
02571 {
02572 if (argc < 2 || argc > 3) {
02573 return RESULT_SHOWUSAGE;
02574 }
02575 h323debug = 1;
02576 ast_cli(fd, "H.323 debug enabled\n");
02577 return RESULT_SUCCESS;
02578 }
02579
02580 static int h323_no_debug(int fd, int argc, char *argv[])
02581 {
02582 if (argc < 3 || argc > 4) {
02583 return RESULT_SHOWUSAGE;
02584 }
02585 h323debug = 0;
02586 ast_cli(fd, "H.323 debug disabled\n");
02587 return RESULT_SUCCESS;
02588 }
02589
02590 static int h323_gk_cycle(int fd, int argc, char *argv[])
02591 {
02592 if (argc != 3) {
02593 return RESULT_SHOWUSAGE;
02594 }
02595 h323_gk_urq();
02596
02597
02598 if (!gatekeeper_disable) {
02599 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
02600 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
02601 }
02602 }
02603 return RESULT_SUCCESS;
02604 }
02605
02606 static int h323_ep_hangup(int fd, int argc, char *argv[])
02607 {
02608 if (argc != 3) {
02609 return RESULT_SHOWUSAGE;
02610 }
02611 if (h323_soft_hangup(argv[2])) {
02612 ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]);
02613 } else {
02614 ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]);
02615 }
02616 return RESULT_SUCCESS;
02617 }
02618
02619 static int h323_tokens_show(int fd, int argc, char *argv[])
02620 {
02621 if (argc != 3) {
02622 return RESULT_SHOWUSAGE;
02623 }
02624 h323_show_tokens();
02625 return RESULT_SUCCESS;
02626 }
02627
02628 static char trace_usage[] =
02629 "Usage: h.323 trace <level num>\n"
02630 " Enables H.323 stack tracing for debugging purposes\n";
02631
02632 static char no_trace_usage[] =
02633 "Usage: h.323 trace off\n"
02634 " Disables H.323 stack tracing for debugging purposes\n";
02635
02636 static char debug_usage[] =
02637 "Usage: h.323 debug\n"
02638 " Enables H.323 debug output\n";
02639
02640 static char no_debug_usage[] =
02641 "Usage: h.323 debug off\n"
02642 " Disables H.323 debug output\n";
02643
02644 static char show_cycle_usage[] =
02645 "Usage: h.323 gk cycle\n"
02646 " Manually re-register with the Gatekeper (Currently Disabled)\n";
02647
02648 static char show_hangup_usage[] =
02649 "Usage: h.323 hangup <token>\n"
02650 " Manually try to hang up call identified by <token>\n";
02651
02652 static char show_tokens_usage[] =
02653 "Usage: h.323 show tokens\n"
02654 " Print out all active call tokens\n";
02655
02656 static char h323_reload_usage[] =
02657 "Usage: h323 reload\n"
02658 " Reloads H.323 configuration from h323.conf\n";
02659
02660 static struct ast_cli_entry cli_h323_no_trace_deprecated = {
02661 { "h.323", "no", "trace", NULL },
02662 h323_no_trace, "Disable H.323 Stack Tracing",
02663 no_trace_usage };
02664
02665 static struct ast_cli_entry cli_h323_no_debug_deprecated = {
02666 { "h.323", "no", "debug", NULL },
02667 h323_no_debug, "Disable H.323 debug",
02668 no_debug_usage };
02669
02670 static struct ast_cli_entry cli_h323_debug_deprecated = {
02671 { "h.323", "debug", NULL },
02672 h323_do_debug, "Enable H.323 debug",
02673 debug_usage };
02674
02675 static struct ast_cli_entry cli_h323_trace_deprecated = {
02676 { "h.323", "trace", NULL },
02677 h323_do_trace, "Enable H.323 Stack Tracing",
02678 trace_usage };
02679
02680 static struct ast_cli_entry cli_h323_gk_cycle_deprecated = {
02681 { "h.323", "gk", "cycle", NULL },
02682 h323_gk_cycle, "Manually re-register with the Gatekeper",
02683 show_cycle_usage };
02684
02685 static struct ast_cli_entry cli_h323[] = {
02686 { { "h323", "set", "trace", NULL },
02687 h323_do_trace, "Enable H.323 Stack Tracing",
02688 trace_usage, NULL, &cli_h323_trace_deprecated },
02689
02690 { { "h323", "set", "trace", "off", NULL },
02691 h323_no_trace, "Disable H.323 Stack Tracing",
02692 no_trace_usage, NULL, &cli_h323_no_trace_deprecated },
02693
02694 { { "h323", "set", "debug", NULL },
02695 h323_do_debug, "Enable H.323 debug",
02696 debug_usage, NULL, &cli_h323_debug_deprecated },
02697
02698 { { "h323", "set", "debug", "off", NULL },
02699 h323_no_debug, "Disable H.323 debug",
02700 no_debug_usage, NULL, &cli_h323_no_debug_deprecated },
02701
02702 { { "h323", "cycle", "gk", NULL },
02703 h323_gk_cycle, "Manually re-register with the Gatekeper",
02704 show_cycle_usage, NULL, &cli_h323_gk_cycle_deprecated },
02705
02706 { { "h323", "hangup", NULL },
02707 h323_ep_hangup, "Manually try to hang up a call",
02708 show_hangup_usage },
02709
02710 { { "h323", "show", "tokens", NULL },
02711 h323_tokens_show, "Show all active call tokens",
02712 show_tokens_usage },
02713 };
02714
02715 static int reload_config(int is_reload)
02716 {
02717 int format;
02718 struct ast_config *cfg, *ucfg;
02719 struct ast_variable *v;
02720 struct oh323_peer *peer = NULL;
02721 struct oh323_user *user = NULL;
02722 struct oh323_alias *alias = NULL;
02723 struct ast_hostent ahp; struct hostent *hp;
02724 char *cat;
02725 const char *utype;
02726 int is_user, is_peer, is_alias;
02727 char _gatekeeper[100];
02728 int gk_discover, gk_disable, gk_changed;
02729
02730 cfg = ast_config_load(config);
02731
02732
02733 if (!cfg) {
02734 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
02735 return 1;
02736 }
02737
02738
02739 if (!h323_end_point_exist()) {
02740 h323_end_point_create();
02741 }
02742 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper));
02743 gk_discover = gatekeeper_discover;
02744 gk_disable = gatekeeper_disable;
02745 memset(&bindaddr, 0, sizeof(bindaddr));
02746 memset(&global_options, 0, sizeof(global_options));
02747 global_options.fastStart = 1;
02748 global_options.h245Tunneling = 1;
02749 global_options.dtmfcodec = 101;
02750 global_options.dtmfmode = H323_DTMF_RFC2833;
02751 global_options.capability = GLOBAL_CAPABILITY;
02752 global_options.bridge = 1;
02753 strcpy(default_context, "default");
02754 h323_signalling_port = 1720;
02755 gatekeeper_disable = 1;
02756 gatekeeper_discover = 0;
02757 gkroute = 0;
02758 userbyalias = 1;
02759 acceptAnonymous = 1;
02760 tos = 0;
02761
02762
02763 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
02764
02765
02766 ucfg = ast_config_load("users.conf");
02767 if (ucfg) {
02768 struct ast_variable *gen;
02769 int genhas_h323;
02770 const char *has_h323;
02771
02772 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323"));
02773 gen = ast_variable_browse(ucfg, "general");
02774 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) {
02775 if (strcasecmp(cat, "general")) {
02776 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323");
02777 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) {
02778 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
02779 if (user) {
02780 ASTOBJ_CONTAINER_LINK(&userl, user);
02781 ASTOBJ_UNREF(user, oh323_destroy_user);
02782 }
02783 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
02784 if (peer) {
02785 ASTOBJ_CONTAINER_LINK(&peerl, peer);
02786 ASTOBJ_UNREF(peer, oh323_destroy_peer);
02787 }
02788 }
02789 }
02790 }
02791 ast_config_destroy(ucfg);
02792 }
02793
02794 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
02795
02796 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
02797 continue;
02798
02799 if (!strcasecmp(v->name, "port")) {
02800 h323_signalling_port = (int)strtol(v->value, NULL, 10);
02801 } else if (!strcasecmp(v->name, "bindaddr")) {
02802 if (!(hp = ast_gethostbyname(v->value, &ahp))) {
02803 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
02804 } else {
02805 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
02806 }
02807 } else if (!strcasecmp(v->name, "tos")) {
02808 if (sscanf(v->value, "%d", &format)) {
02809 tos = format & 0xff;
02810 } else if (!strcasecmp(v->value, "lowdelay")) {
02811 tos = IPTOS_LOWDELAY;
02812 } else if (!strcasecmp(v->value, "throughput")) {
02813 tos = IPTOS_THROUGHPUT;
02814 } else if (!strcasecmp(v->value, "reliability")) {
02815 tos = IPTOS_RELIABILITY;
02816 } else if (!strcasecmp(v->value, "mincost")) {
02817 tos = IPTOS_MINCOST;
02818 } else if (!strcasecmp(v->value, "none")) {
02819 tos = 0;
02820 } else {
02821 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
02822 }
02823 } else if (!strcasecmp(v->name, "gatekeeper")) {
02824 if (!strcasecmp(v->value, "DISABLE")) {
02825 gatekeeper_disable = 1;
02826 } else if (!strcasecmp(v->value, "DISCOVER")) {
02827 gatekeeper_disable = 0;
02828 gatekeeper_discover = 1;
02829 } else {
02830 gatekeeper_disable = 0;
02831 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper));
02832 }
02833 } else if (!strcasecmp(v->name, "secret")) {
02834 ast_copy_string(secret, v->value, sizeof(secret));
02835 } else if (!strcasecmp(v->name, "AllowGKRouted")) {
02836 gkroute = ast_true(v->value);
02837 } else if (!strcasecmp(v->name, "context")) {
02838 ast_copy_string(default_context, v->value, sizeof(default_context));
02839 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context);
02840 } else if (!strcasecmp(v->name, "UserByAlias")) {
02841 userbyalias = ast_true(v->value);
02842 } else if (!strcasecmp(v->name, "AcceptAnonymous")) {
02843 acceptAnonymous = ast_true(v->value);
02844 } else if (!update_common_options(v, &global_options)) {
02845
02846 }
02847 }
02848
02849 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
02850 if (strcasecmp(cat, "general")) {
02851 utype = ast_variable_retrieve(cfg, cat, "type");
02852 if (utype) {
02853 is_user = is_peer = is_alias = 0;
02854 if (!strcasecmp(utype, "user"))
02855 is_user = 1;
02856 else if (!strcasecmp(utype, "peer"))
02857 is_peer = 1;
02858 else if (!strcasecmp(utype, "friend"))
02859 is_user = is_peer = 1;
02860 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias"))
02861 is_alias = 1;
02862 else {
02863 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
02864 continue;
02865 }
02866 if (is_user) {
02867 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
02868 if (user) {
02869 ASTOBJ_CONTAINER_LINK(&userl, user);
02870 ASTOBJ_UNREF(user, oh323_destroy_user);
02871 }
02872 }
02873 if (is_peer) {
02874 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
02875 if (peer) {
02876 ASTOBJ_CONTAINER_LINK(&peerl, peer);
02877 ASTOBJ_UNREF(peer, oh323_destroy_peer);
02878 }
02879 }
02880 if (is_alias) {
02881 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0);
02882 if (alias) {
02883 ASTOBJ_CONTAINER_LINK(&aliasl, alias);
02884 ASTOBJ_UNREF(alias, oh323_destroy_alias);
02885 }
02886 }
02887 } else {
02888 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
02889 }
02890 }
02891 }
02892 ast_config_destroy(cfg);
02893
02894
02895 ASTOBJ_CONTAINER_WRLOCK(&aliasl);
02896 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
02897 ASTOBJ_RDLOCK(iterator);
02898 if (h323_set_alias(iterator)) {
02899 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
02900 ASTOBJ_UNLOCK(iterator);
02901 continue;
02902 }
02903 ASTOBJ_UNLOCK(iterator);
02904 } while (0) );
02905 ASTOBJ_CONTAINER_UNLOCK(&aliasl);
02906
02907
02908 gk_changed = 0;
02909 if (gatekeeper_disable != gk_disable)
02910 gk_changed = is_reload;
02911 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover))
02912 gk_changed = is_reload;
02913 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0))
02914 gk_changed = is_reload;
02915 if (gk_changed) {
02916 if(!gk_disable)
02917 h323_gk_urq();
02918 if (!gatekeeper_disable) {
02919 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
02920 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
02921 gatekeeper_disable = 1;
02922 }
02923 }
02924 }
02925 return 0;
02926 }
02927
02928 static void delete_users(void)
02929 {
02930 int pruned = 0;
02931
02932
02933 ASTOBJ_CONTAINER_WRLOCK(&userl);
02934 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
02935 ASTOBJ_RDLOCK(iterator);
02936 ASTOBJ_MARK(iterator);
02937 ++pruned;
02938 ASTOBJ_UNLOCK(iterator);
02939 } while (0) );
02940 if (pruned) {
02941 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user);
02942 }
02943 ASTOBJ_CONTAINER_UNLOCK(&userl);
02944
02945 ASTOBJ_CONTAINER_WRLOCK(&peerl);
02946 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
02947 ASTOBJ_RDLOCK(iterator);
02948 ASTOBJ_MARK(iterator);
02949 ASTOBJ_UNLOCK(iterator);
02950 } while (0) );
02951 ASTOBJ_CONTAINER_UNLOCK(&peerl);
02952 }
02953
02954 static void delete_aliases(void)
02955 {
02956 int pruned = 0;
02957
02958
02959 ASTOBJ_CONTAINER_WRLOCK(&aliasl);
02960 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
02961 ASTOBJ_RDLOCK(iterator);
02962 ASTOBJ_MARK(iterator);
02963 ++pruned;
02964 ASTOBJ_UNLOCK(iterator);
02965 } while (0) );
02966 if (pruned) {
02967 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias);
02968 }
02969 ASTOBJ_CONTAINER_UNLOCK(&aliasl);
02970 }
02971
02972 static void prune_peers(void)
02973 {
02974
02975 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer);
02976 }
02977
02978 static int h323_reload(int fd, int argc, char *argv[])
02979 {
02980 ast_mutex_lock(&h323_reload_lock);
02981 if (h323_reloading) {
02982 ast_verbose("Previous H.323 reload not yet done\n");
02983 } else {
02984 h323_reloading = 1;
02985 }
02986 ast_mutex_unlock(&h323_reload_lock);
02987 restart_monitor();
02988 return 0;
02989 }
02990
02991 static int h323_do_reload(void)
02992 {
02993 delete_users();
02994 delete_aliases();
02995 prune_peers();
02996 reload_config(1);
02997 return 0;
02998 }
02999
03000 static int reload(void)
03001 {
03002 if (!sched || !io) {
03003 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
03004 return 0;
03005 }
03006 return h323_reload(0, 0, NULL);
03007 }
03008
03009 static struct ast_cli_entry cli_h323_reload =
03010 { { "h.323", "reload", NULL },
03011 h323_reload, "Reload H.323 configuration",
03012 h323_reload_usage
03013 };
03014
03015 static enum ast_rtp_get_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
03016 {
03017 struct oh323_pvt *pvt;
03018 enum ast_rtp_get_result res = AST_RTP_GET_FAILED;
03019
03020 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt))
03021 return res;
03022
03023 ast_mutex_lock(&pvt->lock);
03024 if (pvt->rtp && pvt->options.bridge) {
03025 *rtp = pvt->rtp;
03026 res = AST_RTP_TRY_NATIVE;
03027 }
03028 ast_mutex_unlock(&pvt->lock);
03029
03030 return res;
03031 }
03032
03033 static enum ast_rtp_get_result oh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
03034 {
03035 return AST_RTP_GET_FAILED;
03036 }
03037
03038 static char *convertcap(int cap)
03039 {
03040 switch (cap) {
03041 case AST_FORMAT_G723_1:
03042 return "G.723";
03043 case AST_FORMAT_GSM:
03044 return "GSM";
03045 case AST_FORMAT_ULAW:
03046 return "ULAW";
03047 case AST_FORMAT_ALAW:
03048 return "ALAW";
03049 case AST_FORMAT_G722:
03050 return "G.722";
03051 case AST_FORMAT_ADPCM:
03052 return "G.728";
03053 case AST_FORMAT_G729A:
03054 return "G.729";
03055 case AST_FORMAT_SPEEX:
03056 return "SPEEX";
03057 case AST_FORMAT_ILBC:
03058 return "ILBC";
03059 default:
03060 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap);
03061 return NULL;
03062 }
03063 }
03064
03065 static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
03066 {
03067
03068 struct oh323_pvt *pvt;
03069 struct sockaddr_in them;
03070 struct sockaddr_in us;
03071 char *mode;
03072
03073 if (!rtp) {
03074 return 0;
03075 }
03076
03077 mode = convertcap(chan->writeformat);
03078 pvt = (struct oh323_pvt *) chan->tech_pvt;
03079 if (!pvt) {
03080 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
03081 return -1;
03082 }
03083 ast_rtp_get_peer(rtp, &them);
03084 ast_rtp_get_us(rtp, &us);
03085 #if 0
03086 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode);
03087 #endif
03088 return 0;
03089 }
03090
03091 static struct ast_rtp_protocol oh323_rtp = {
03092 .type = "H323",
03093 .get_rtp_info = oh323_get_rtp_peer,
03094 .get_vrtp_info = oh323_get_vrtp_peer,
03095 .set_rtp_peer = oh323_set_rtp_peer,
03096 };
03097
03098 static enum ast_module_load_result load_module(void)
03099 {
03100 int res;
03101
03102 h323debug = 0;
03103 sched = sched_context_create();
03104 if (!sched) {
03105 ast_log(LOG_WARNING, "Unable to create schedule context\n");
03106 return AST_MODULE_LOAD_FAILURE;
03107 }
03108 io = io_context_create();
03109 if (!io) {
03110 ast_log(LOG_WARNING, "Unable to create I/O context\n");
03111 return AST_MODULE_LOAD_FAILURE;
03112 }
03113 ast_cli_register(&cli_h323_reload);
03114 ASTOBJ_CONTAINER_INIT(&userl);
03115 ASTOBJ_CONTAINER_INIT(&peerl);
03116 ASTOBJ_CONTAINER_INIT(&aliasl);
03117 res = reload_config(0);
03118 if (res) {
03119
03120 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
03121 ast_cli_unregister(&cli_h323_reload);
03122 io_context_destroy(io);
03123 io = NULL;
03124 sched_context_destroy(sched);
03125 sched = NULL;
03126 ASTOBJ_CONTAINER_DESTROY(&userl);
03127 ASTOBJ_CONTAINER_DESTROY(&peerl);
03128 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03129 return AST_MODULE_LOAD_DECLINE;
03130 } else {
03131
03132 if (ast_channel_register(&oh323_tech)) {
03133 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n");
03134 ast_cli_unregister(&cli_h323_reload);
03135 h323_end_process();
03136 io_context_destroy(io);
03137 sched_context_destroy(sched);
03138
03139 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03140 ASTOBJ_CONTAINER_DESTROY(&userl);
03141 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03142 ASTOBJ_CONTAINER_DESTROY(&peerl);
03143 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03144 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03145
03146 return AST_MODULE_LOAD_FAILURE;
03147 }
03148 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03149
03150 ast_rtp_proto_register(&oh323_rtp);
03151
03152
03153 h323_callback_register(setup_incoming_call,
03154 setup_outgoing_call,
03155 external_rtp_create,
03156 setup_rtp_connection,
03157 cleanup_connection,
03158 chan_ringing,
03159 connection_made,
03160 receive_digit,
03161 answer_call,
03162 progress,
03163 set_dtmf_payload,
03164 hangup_connection,
03165 set_local_capabilities,
03166 set_peer_capabilities);
03167
03168 if (h323_start_listener(h323_signalling_port, bindaddr)) {
03169 ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
03170 ast_rtp_proto_unregister(&oh323_rtp);
03171 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03172 ast_cli_unregister(&cli_h323_reload);
03173 h323_end_process();
03174 io_context_destroy(io);
03175 sched_context_destroy(sched);
03176
03177 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03178 ASTOBJ_CONTAINER_DESTROY(&userl);
03179 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03180 ASTOBJ_CONTAINER_DESTROY(&peerl);
03181 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03182 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03183
03184 return AST_MODULE_LOAD_FAILURE;
03185 }
03186
03187 if (!gatekeeper_disable) {
03188 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
03189 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
03190 gatekeeper_disable = 1;
03191 res = AST_MODULE_LOAD_SUCCESS;
03192 }
03193 }
03194
03195 restart_monitor();
03196 }
03197 return res;
03198 }
03199
03200 static int unload_module(void)
03201 {
03202 struct oh323_pvt *p, *pl;
03203
03204
03205 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03206 ast_cli_unregister(&cli_h323_reload);
03207
03208 ast_channel_unregister(&oh323_tech);
03209 ast_rtp_proto_unregister(&oh323_rtp);
03210
03211 if (!ast_mutex_lock(&iflock)) {
03212
03213 p = iflist;
03214 while(p) {
03215 if (p->owner) {
03216 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
03217 }
03218 p = p->next;
03219 }
03220 iflist = NULL;
03221 ast_mutex_unlock(&iflock);
03222 } else {
03223 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
03224 return -1;
03225 }
03226 if (!ast_mutex_lock(&monlock)) {
03227 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
03228
03229 if (monitor_thread != pthread_self())
03230 pthread_cancel(monitor_thread);
03231 pthread_kill(monitor_thread, SIGURG);
03232 pthread_join(monitor_thread, NULL);
03233 }
03234 monitor_thread = AST_PTHREADT_STOP;
03235 ast_mutex_unlock(&monlock);
03236 } else {
03237 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
03238 return -1;
03239 }
03240 if (!ast_mutex_lock(&iflock)) {
03241
03242 p = iflist;
03243 while(p) {
03244 pl = p;
03245 p = p->next;
03246
03247 ast_mutex_destroy(&pl->lock);
03248 free(pl);
03249 }
03250 iflist = NULL;
03251 ast_mutex_unlock(&iflock);
03252 } else {
03253 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
03254 return -1;
03255 }
03256 if (!gatekeeper_disable)
03257 h323_gk_urq();
03258 h323_end_process();
03259 if (io)
03260 io_context_destroy(io);
03261 if (sched)
03262 sched_context_destroy(sched);
03263
03264 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03265 ASTOBJ_CONTAINER_DESTROY(&userl);
03266 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03267 ASTOBJ_CONTAINER_DESTROY(&peerl);
03268 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03269 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03270
03271 return 0;
03272 }
03273
03274 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "The NuFone Network's OpenH323 Channel Driver",
03275 .load = load_module,
03276 .unload = unload_module,
03277 .reload = reload,
03278 );