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