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: 114120 $")
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_update_source(pvt->rtp);
00920 res = 0;
00921 break;
00922 case AST_CONTROL_SRCCHANGE:
00923 ast_rtp_change_source(pvt->rtp);
00924 res = 0;
00925 break;
00926 case AST_CONTROL_PROCEEDING:
00927 case -1:
00928 break;
00929 default:
00930 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);
00931 break;
00932 }
00933
00934 if (h323debug)
00935 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);
00936 if (token)
00937 free(token);
00938 oh323_update_info(c);
00939
00940 return res;
00941 }
00942
00943 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00944 {
00945 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
00946
00947 ast_mutex_lock(&pvt->lock);
00948 if (pvt->owner != oldchan) {
00949 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
00950 return -1;
00951 }
00952 pvt->owner = newchan;
00953 ast_mutex_unlock(&pvt->lock);
00954 return 0;
00955 }
00956
00957 static int __oh323_rtp_create(struct oh323_pvt *pvt)
00958 {
00959 struct in_addr our_addr;
00960
00961 if (pvt->rtp)
00962 return 0;
00963
00964 if (ast_find_ourip(&our_addr, bindaddr)) {
00965 ast_mutex_unlock(&pvt->lock);
00966 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
00967 return -1;
00968 }
00969 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr);
00970 if (!pvt->rtp) {
00971 ast_mutex_unlock(&pvt->lock);
00972 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
00973 return -1;
00974 }
00975 if (h323debug)
00976 ast_log(LOG_DEBUG, "Created RTP channel\n");
00977
00978 ast_rtp_settos(pvt->rtp, tos);
00979
00980 if (h323debug)
00981 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
00982 ast_rtp_setnat(pvt->rtp, pvt->options.nat);
00983
00984 if (pvt->dtmf_pt > 0)
00985 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0);
00986
00987 if (pvt->peercapability)
00988 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);
00989
00990 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
00991 ast_jb_configure(pvt->owner, &global_jbconf);
00992 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp);
00993 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp);
00994 ast_queue_frame(pvt->owner, &ast_null_frame);
00995 ast_channel_unlock(pvt->owner);
00996 } else
00997 pvt->update_rtp_info = 1;
00998
00999 return 0;
01000 }
01001
01002
01003 static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host)
01004 {
01005 struct ast_channel *ch;
01006 char *cid_num, *cid_name;
01007 int fmt;
01008
01009 if (!ast_strlen_zero(pvt->options.cid_num))
01010 cid_num = pvt->options.cid_num;
01011 else
01012 cid_num = pvt->cd.call_source_e164;
01013
01014 if (!ast_strlen_zero(pvt->options.cid_name))
01015 cid_name = pvt->options.cid_name;
01016 else
01017 cid_name = pvt->cd.call_source_name;
01018
01019
01020 ast_mutex_unlock(&pvt->lock);
01021 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host);
01022
01023 ast_module_ref(ast_module_info->self);
01024 ast_mutex_lock(&pvt->lock);
01025 if (ch) {
01026 ch->tech = &oh323_tech;
01027 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
01028 fmt = global_options.capability;
01029 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1);
01030 pvt->nativeformats = ch->nativeformats;
01031 fmt = ast_best_codec(ch->nativeformats);
01032 ch->writeformat = fmt;
01033 ch->rawwriteformat = fmt;
01034 ch->readformat = fmt;
01035 ch->rawreadformat = fmt;
01036 #if 0
01037 ch->fds[0] = ast_rtp_fd(pvt->rtp);
01038 ch->fds[1] = ast_rtcp_fd(pvt->rtp);
01039 #endif
01040 #ifdef VIDEO_SUPPORT
01041 if (pvt->vrtp) {
01042 ch->fds[2] = ast_rtp_fd(pvt->vrtp);
01043 ch->fds[3] = ast_rtcp_fd(pvt->vrtp);
01044 }
01045 #endif
01046 #ifdef T38_SUPPORT
01047 if (pvt->udptl) {
01048 ch->fds[4] = ast_udptl_fd(pvt->udptl);
01049 }
01050 #endif
01051 if (state == AST_STATE_RING) {
01052 ch->rings = 1;
01053 }
01054
01055 if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
01056 pvt->vad = ast_dsp_new();
01057 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);
01058 }
01059
01060 ch->tech_pvt = pvt;
01061
01062 pvt->owner = ch;
01063
01064 ast_copy_string(ch->context, pvt->context, sizeof(ch->context));
01065 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten));
01066 ch->priority = 1;
01067 if (!ast_strlen_zero(pvt->accountcode)) {
01068 ast_string_field_set(ch, accountcode, pvt->accountcode);
01069 }
01070 if (pvt->amaflags) {
01071 ch->amaflags = pvt->amaflags;
01072 }
01073
01074
01075
01076 ch->cid.cid_ani = ast_strdup(cid_num);
01077
01078 if (pvt->cd.redirect_reason >= 0) {
01079 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number);
01080 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
01081 }
01082 ch->cid.cid_pres = pvt->cd.presentation;
01083 ch->cid.cid_ton = pvt->cd.type_of_number;
01084
01085 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
01086 ch->cid.cid_dnid = strdup(pvt->exten);
01087 }
01088 if (pvt->cd.transfer_capability >= 0)
01089 ch->transfercapability = pvt->cd.transfer_capability;
01090 if (state != AST_STATE_DOWN) {
01091 if (ast_pbx_start(ch)) {
01092 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
01093 ast_hangup(ch);
01094 ch = NULL;
01095 }
01096 }
01097 } else {
01098 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
01099 }
01100 return ch;
01101 }
01102
01103 static struct oh323_pvt *oh323_alloc(int callid)
01104 {
01105 struct oh323_pvt *pvt;
01106
01107 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt));
01108 if (!pvt) {
01109 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
01110 return NULL;
01111 }
01112 memset(pvt, 0, sizeof(struct oh323_pvt));
01113 pvt->cd.redirect_reason = -1;
01114 pvt->cd.transfer_capability = -1;
01115
01116 if (!callid) {
01117 if ((pvt->cd).call_token == NULL) {
01118 (pvt->cd).call_token = (char *)malloc(128);
01119 }
01120 if (!pvt->cd.call_token) {
01121 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
01122 ast_rtp_destroy(pvt->rtp);
01123 free(pvt);
01124 return NULL;
01125 }
01126 memset((char *)(pvt->cd).call_token, 0, 128);
01127 pvt->cd.call_reference = callid;
01128 }
01129 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01130 pvt->jointcapability = pvt->options.capability;
01131 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01132 pvt->nonCodecCapability |= AST_RTP_DTMF;
01133 } else {
01134 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01135 }
01136 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
01137 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;
01138 ast_mutex_init(&pvt->lock);
01139
01140 ast_mutex_lock(&iflock);
01141 pvt->next = iflist;
01142 iflist = pvt;
01143 ast_mutex_unlock(&iflock);
01144 return pvt;
01145 }
01146
01147 static struct oh323_pvt *find_call_locked(int call_reference, const char *token)
01148 {
01149 struct oh323_pvt *pvt;
01150
01151 ast_mutex_lock(&iflock);
01152 pvt = iflist;
01153 while(pvt) {
01154 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
01155
01156 if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
01157 ast_mutex_lock(&pvt->lock);
01158 ast_mutex_unlock(&iflock);
01159 return pvt;
01160 } else if (token == NULL) {
01161 ast_log(LOG_WARNING, "Call Token is NULL\n");
01162 ast_mutex_lock(&pvt->lock);
01163 ast_mutex_unlock(&iflock);
01164 return pvt;
01165 }
01166 }
01167 pvt = pvt->next;
01168 }
01169 ast_mutex_unlock(&iflock);
01170 return NULL;
01171 }
01172
01173 static int update_state(struct oh323_pvt *pvt, int state, int signal)
01174 {
01175 if (!pvt)
01176 return 0;
01177 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01178 if (state >= 0)
01179 ast_setstate(pvt->owner, state);
01180 if (signal >= 0)
01181 ast_queue_control(pvt->owner, signal);
01182 ast_channel_unlock(pvt->owner);
01183 return 1;
01184 }
01185 else {
01186 if (state >= 0)
01187 pvt->newstate = state;
01188 if (signal >= 0)
01189 pvt->newcontrol = signal;
01190 return 0;
01191 }
01192 }
01193
01194 static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01195 {
01196 struct oh323_alias *alias;
01197 int found = 0;
01198
01199 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
01200
01201 if (alias)
01202 found++;
01203 else {
01204 if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias))))
01205 return NULL;
01206 ASTOBJ_INIT(alias);
01207 }
01208 if (!found && name)
01209 ast_copy_string(alias->name, name, sizeof(alias->name));
01210 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01211 if (!strcasecmp(v->name, "e164")) {
01212 ast_copy_string(alias->e164, v->value, sizeof(alias->e164));
01213 } else if (!strcasecmp(v->name, "prefix")) {
01214 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));
01215 } else if (!strcasecmp(v->name, "context")) {
01216 ast_copy_string(alias->context, v->value, sizeof(alias->context));
01217 } else if (!strcasecmp(v->name, "secret")) {
01218 ast_copy_string(alias->secret, v->value, sizeof(alias->secret));
01219 } else {
01220 if (strcasecmp(v->value, "h323")) {
01221 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);
01222 }
01223 }
01224 }
01225 ASTOBJ_UNMARK(alias);
01226 return alias;
01227 }
01228
01229 static struct oh323_alias *realtime_alias(const char *alias)
01230 {
01231 struct ast_variable *var, *tmp;
01232 struct oh323_alias *a;
01233
01234 var = ast_load_realtime("h323", "name", alias, NULL);
01235
01236 if (!var)
01237 return NULL;
01238
01239 for (tmp = var; tmp; tmp = tmp->next) {
01240 if (!strcasecmp(tmp->name, "type") &&
01241 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {
01242 ast_variables_destroy(var);
01243 return NULL;
01244 }
01245 }
01246
01247 a = build_alias(alias, var, NULL, 1);
01248
01249 ast_variables_destroy(var);
01250
01251 return a;
01252 }
01253
01254 #define DEPRECATED(_v, _new_opt) \
01255 ast_log(LOG_WARNING, "Option %s found at line %d has beed deprecated. Use %s instead.\n", (_v)->name, (_v)->lineno, (_new_opt))
01256
01257 static int update_common_options(struct ast_variable *v, struct call_options *options)
01258 {
01259 int tmp;
01260
01261 if (!strcasecmp(v->name, "allow")) {
01262 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
01263 } else if (!strcasecmp(v->name, "disallow")) {
01264 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
01265 } else if (!strcasecmp(v->name, "dtmfmode")) {
01266 if (!strcasecmp(v->value, "inband")) {
01267 options->dtmfmode = H323_DTMF_INBAND;
01268 } else if (!strcasecmp(v->value, "rfc2833")) {
01269 options->dtmfmode = H323_DTMF_RFC2833;
01270 } else {
01271 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
01272 options->dtmfmode = H323_DTMF_RFC2833;
01273 }
01274 } else if (!strcasecmp(v->name, "dtmfcodec")) {
01275 tmp = atoi(v->value);
01276 if (tmp < 96)
01277 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
01278 else
01279 options->dtmfcodec = tmp;
01280 } else if (!strcasecmp(v->name, "bridge")) {
01281 options->bridge = ast_true(v->value);
01282 } else if (!strcasecmp(v->name, "nat")) {
01283 options->nat = ast_true(v->value);
01284 } else if (!strcasecmp(v->name, "noFastStart")) {
01285 DEPRECATED(v, "fastStart");
01286 options->fastStart = !ast_true(v->value);
01287 } else if (!strcasecmp(v->name, "fastStart")) {
01288 options->fastStart = ast_true(v->value);
01289 } else if (!strcasecmp(v->name, "noH245Tunneling")) {
01290 DEPRECATED(v, "h245Tunneling");
01291 options->h245Tunneling = !ast_true(v->value);
01292 } else if (!strcasecmp(v->name, "h245Tunneling")) {
01293 options->h245Tunneling = ast_true(v->value);
01294 } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
01295 DEPRECATED(v, "silenceSuppression");
01296 options->silenceSuppression = !ast_true(v->value);
01297 } else if (!strcasecmp(v->name, "silenceSuppression")) {
01298 options->silenceSuppression = ast_true(v->value);
01299 } else if (!strcasecmp(v->name, "progress_setup")) {
01300 tmp = atoi(v->value);
01301 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
01302 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01303 tmp = 0;
01304 }
01305 options->progress_setup = tmp;
01306 } else if (!strcasecmp(v->name, "progress_alert")) {
01307 tmp = atoi(v->value);
01308 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {
01309 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01310 tmp = 0;
01311 }
01312 options->progress_alert = tmp;
01313 } else if (!strcasecmp(v->name, "progress_audio")) {
01314 options->progress_audio = ast_true(v->value);
01315 } else if (!strcasecmp(v->name, "callerid")) {
01316 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));
01317 } else if (!strcasecmp(v->name, "fullname")) {
01318 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));
01319 } else if (!strcasecmp(v->name, "cid_number")) {
01320 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));
01321 } else if (!strcasecmp(v->name, "tunneling")) {
01322 if (!strcasecmp(v->value, "none"))
01323 options->tunnelOptions = 0;
01324 else if (!strcasecmp(v->value, "cisco"))
01325 options->tunnelOptions |= H323_TUNNEL_CISCO;
01326 else if (!strcasecmp(v->value, "qsig"))
01327 options->tunnelOptions |= H323_TUNNEL_QSIG;
01328 else
01329 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
01330 } else
01331 return 1;
01332
01333 return 0;
01334 }
01335 #undef DEPRECATED
01336
01337 static struct oh323_user *build_user(char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01338 {
01339 struct oh323_user *user;
01340 struct ast_ha *oldha;
01341 int found = 0;
01342 int format;
01343
01344 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);
01345
01346 if (user)
01347 found++;
01348 else {
01349 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user))))
01350 return NULL;
01351 ASTOBJ_INIT(user);
01352 }
01353 oldha = user->ha;
01354 user->ha = (struct ast_ha *)NULL;
01355 memcpy(&user->options, &global_options, sizeof(user->options));
01356
01357 ast_copy_string(user->context, default_context, sizeof(user->context));
01358 if (user && !found)
01359 ast_copy_string(user->name, name, sizeof(user->name));
01360
01361 #if 0
01362 if (user->chanvars) {
01363 ast_variables_destroy(user->chanvars);
01364 user->chanvars = NULL;
01365 }
01366 #endif
01367
01368 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01369 if (!update_common_options(v, &user->options))
01370 continue;
01371 if (!strcasecmp(v->name, "context")) {
01372 ast_copy_string(user->context, v->value, sizeof(user->context));
01373 } else if (!strcasecmp(v->name, "secret")) {
01374 ast_copy_string(user->secret, v->value, sizeof(user->secret));
01375 } else if (!strcasecmp(v->name, "accountcode")) {
01376 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
01377 } else if (!strcasecmp(v->name, "host")) {
01378 if (!strcasecmp(v->value, "dynamic")) {
01379 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
01380 ASTOBJ_UNREF(user, oh323_destroy_user);
01381 return NULL;
01382 } else if (ast_get_ip(&user->addr, v->value)) {
01383 ASTOBJ_UNREF(user, oh323_destroy_user);
01384 return NULL;
01385 }
01386
01387 user->host = 1;
01388 } else if (!strcasecmp(v->name, "amaflags")) {
01389 format = ast_cdr_amaflags2int(v->value);
01390 if (format < 0) {
01391 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
01392 } else {
01393 user->amaflags = format;
01394 }
01395 } else if (!strcasecmp(v->name, "permit") ||
01396 !strcasecmp(v->name, "deny")) {
01397 user->ha = ast_append_ha(v->name, v->value, user->ha);
01398 }
01399 }
01400 ASTOBJ_UNMARK(user);
01401 ast_free_ha(oldha);
01402 return user;
01403 }
01404
01405 static struct oh323_user *realtime_user(const call_details_t *cd)
01406 {
01407 struct ast_variable *var, *tmp;
01408 struct oh323_user *user;
01409 char *username;
01410
01411 if (userbyalias)
01412 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL);
01413 else {
01414 username = (char *)NULL;
01415 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL);
01416 }
01417
01418 if (!var)
01419 return NULL;
01420
01421 for (tmp = var; tmp; tmp = tmp->next) {
01422 if (!strcasecmp(tmp->name, "type") &&
01423 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {
01424 ast_variables_destroy(var);
01425 return NULL;
01426 } else if (!username && !strcasecmp(tmp->name, "name"))
01427 username = tmp->value;
01428 }
01429
01430 if (!username) {
01431 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);
01432 ast_variables_destroy(var);
01433 return NULL;
01434 }
01435
01436 user = build_user(username, var, NULL, 1);
01437
01438 ast_variables_destroy(var);
01439
01440 return user;
01441 }
01442
01443 static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01444 {
01445 struct oh323_peer *peer;
01446 struct ast_ha *oldha;
01447 int found = 0;
01448
01449 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
01450
01451 if (peer)
01452 found++;
01453 else {
01454 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer))))
01455 return NULL;
01456 ASTOBJ_INIT(peer);
01457 }
01458 oldha = peer->ha;
01459 peer->ha = NULL;
01460 memcpy(&peer->options, &global_options, sizeof(peer->options));
01461 peer->addr.sin_port = htons(h323_signalling_port);
01462 peer->addr.sin_family = AF_INET;
01463 if (!found && name)
01464 ast_copy_string(peer->name, name, sizeof(peer->name));
01465
01466 #if 0
01467 if (peer->chanvars) {
01468 ast_variables_destroy(peer->chanvars);
01469 peer->chanvars = NULL;
01470 }
01471 #endif
01472
01473 peer->mailbox[0] = '\0';
01474
01475 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01476 if (!update_common_options(v, &peer->options))
01477 continue;
01478 if (!strcasecmp(v->name, "host")) {
01479 if (!strcasecmp(v->value, "dynamic")) {
01480 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
01481 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01482 return NULL;
01483 }
01484 if (ast_get_ip(&peer->addr, v->value)) {
01485 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
01486 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01487 return NULL;
01488 }
01489 } else if (!strcasecmp(v->name, "port")) {
01490 peer->addr.sin_port = htons(atoi(v->value));
01491 } else if (!strcasecmp(v->name, "permit") ||
01492 !strcasecmp(v->name, "deny")) {
01493 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
01494 } else if (!strcasecmp(v->name, "mailbox")) {
01495 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
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 );