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