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