2 * Copyright (C) 2004-2005 by Objective Systems, Inc.
4 * This software is furnished under an open source license and may be
5 * used and copied only in accordance with the terms of this license.
6 * The text of the license may generally be found in the root
7 * directory of this installation in the COPYING file. It
8 * can also be viewed online at the following URL:
10 * http://www.obj-sys.com/open/license.html
12 * Any redistributions of this file including modified versions must
13 * maintain this copyright notice.
15 *****************************************************************************/
17 /* Reworked version I, Nov-2009, by Alexandr Anikin, may@telecom-service.ru */
21 <defaultenabled>no</defaultenabled>
22 <support_level>extended</support_level>
25 #include "chan_ooh323.h"
28 #define FORMAT_STRING_SIZE 512
31 #define DEFAULT_CONTEXT "default"
32 #define DEFAULT_H323ID "Asterisk PBX"
33 #define DEFAULT_LOGFILE "/var/log/asterisk/h323_log"
34 #define DEFAULT_H323ACCNT "ast_h323"
37 #define H323_SILENCESUPPRESSION (1<<0)
38 #define H323_GKROUTED (1<<1)
39 #define H323_TUNNELING (1<<2)
40 #define H323_FASTSTART (1<<3)
41 #define H323_OUTGOING (1<<4)
42 #define H323_ALREADYGONE (1<<5)
43 #define H323_NEEDDESTROY (1<<6)
44 #define H323_DISABLEGK (1<<7)
45 #define H323_NEEDSTART (1<<8)
48 #define T38TOAUDIOTIMEOUT 30
49 #define T38_DISABLED 0
53 #define FAXDETECT_CNG 1
54 #define FAXDETECT_T38 2
56 /* Channel description */
57 static const char type[] = "OOH323";
58 static const char tdesc[] = "Objective Systems H323 Channel Driver";
59 static const char config[] = "ooh323.conf";
61 struct ast_module *myself;
63 static struct ast_jb_conf default_jbconf =
67 .resync_threshold = -1,
70 static struct ast_jb_conf global_jbconf;
72 /* Channel Definition */
73 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
74 const struct ast_channel *requestor, void *data, int *cause);
75 static int ooh323_digit_begin(struct ast_channel *ast, char digit);
76 static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
77 static int ooh323_call(struct ast_channel *ast, char *dest, int timeout);
78 static int ooh323_hangup(struct ast_channel *ast);
79 static int ooh323_answer(struct ast_channel *ast);
80 static struct ast_frame *ooh323_read(struct ast_channel *ast);
81 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f);
82 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
83 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
84 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
85 static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
86 static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
88 static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
89 static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
90 static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
91 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active);
93 static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan);
94 static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
96 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
98 struct ooh323_peer *find_friend(const char *name, int port);
101 static struct ast_channel_tech ooh323_tech = {
103 .description = tdesc,
104 .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
105 .requester = ooh323_request,
106 .send_digit_begin = ooh323_digit_begin,
107 .send_digit_end = ooh323_digit_end,
109 .hangup = ooh323_hangup,
110 .answer = ooh323_answer,
112 .write = ooh323_write,
113 .exception = ooh323_read,
114 .indicate = ooh323_indicate,
115 .fixup = ooh323_fixup,
117 .queryoption = ooh323_queryoption,
118 .bridge = ast_rtp_instance_bridge, /* XXX chan unlocked ? */
119 .early_bridge = ast_rtp_instance_early_bridge,
120 .func_channel_read = function_ooh323_read,
121 .func_channel_write = function_ooh323_write,
124 static struct ast_rtp_glue ooh323_rtp = {
126 .get_rtp_info = ooh323_get_rtp_peer,
127 .get_vrtp_info = ooh323_get_vrtp_peer,
128 .update_peer = ooh323_set_rtp_peer,
131 static struct ast_udptl_protocol ooh323_udptl = {
133 get_udptl_info: ooh323_get_udptl_peer,
134 set_udptl_peer: ooh323_set_udptl_peer,
141 /* H.323 channel private structure */
142 static struct ooh323_pvt {
143 ast_mutex_t lock; /* Channel private lock */
144 struct ast_rtp_instance *rtp;
145 struct ast_rtp_instance *vrtp; /* Placeholder for now */
147 int t38support; /* T.38 mode - disable, transparent, faxgw */
151 struct ast_udptl *udptl;
155 struct ast_sockaddr udptlredirip;
159 struct ast_channel *owner; /* Master Channel */
161 char *user; /* cooperating user/peer */
167 unsigned int call_reference;
173 char caller_h323id[AST_MAX_EXTENSION];
174 char caller_dialedDigits[AST_MAX_EXTENSION];
175 char caller_email[AST_MAX_EXTENSION];
176 char caller_url[256];
177 char callee_h323id[AST_MAX_EXTENSION];
178 char callee_dialedDigits[AST_MAX_EXTENSION];
179 char callee_email[AST_MAX_EXTENSION];
180 char callee_url[AST_MAX_EXTENSION];
183 struct ast_format readformat; /* negotiated read format */
184 struct ast_format writeformat; /* negotiated write format */
185 struct ast_format_cap *cap;
186 struct ast_codec_pref prefs;
189 char exten[AST_MAX_EXTENSION]; /* Requested extension */
190 char context[AST_MAX_EXTENSION]; /* Context where to start */
191 char accountcode[256]; /* Account code */
194 int progsent; /* progress is sent */
195 int alertsent; /* alerting is sent */
196 int g729onlyA; /* G.729 only A */
198 struct OOH323Regex *rtpmask; /* rtp ip regexp */
199 char rtpmaskstr[120];
200 int rtdrcount, rtdrinterval; /* roundtripdelayreq */
201 int faststart, h245tunneling; /* faststart & h245 tunneling */
202 struct ooh323_pvt *next; /* Next entity */
205 /* Protect the channel/interface list (ooh323_pvt) */
206 AST_MUTEX_DEFINE_STATIC(iflock);
208 /* Profile of H.323 user registered with PBX*/
212 char context[AST_MAX_EXTENSION];
215 char accountcode[20];
217 struct ast_format_cap *cap;
218 struct ast_codec_pref prefs;
224 int mUseIP; /* Use IP address or H323-ID to search user */
225 char mIP[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
226 struct OOH323Regex *rtpmask;
227 char rtpmaskstr[120];
228 int rtdrcount, rtdrinterval;
229 int faststart, h245tunneling;
231 struct ooh323_user *next;
234 /* Profile of valid asterisk peers */
238 unsigned outgoinglimit;
240 struct ast_format_cap *cap;
241 struct ast_codec_pref prefs;
242 char accountcode[20];
248 int mFriend; /* indicates defined as friend */
249 char ip[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
251 char *h323id; /* H323-ID alias, which asterisk will register with gk to reach this peer*/
252 char *email; /* Email alias, which asterisk will register with gk to reach this peer*/
253 char *url; /* url alias, which asterisk will register with gk to reach this peer*/
254 char *e164; /* e164 alias, which asterisk will register with gk to reach this peer*/
256 struct OOH323Regex *rtpmask;
257 char rtpmaskstr[120];
258 int rtdrcount,rtdrinterval;
259 int faststart, h245tunneling;
261 struct ooh323_peer *next;
265 /* List of H.323 users known to PBX */
266 static struct ast_user_list {
267 struct ooh323_user *users;
271 static struct ast_peer_list {
272 struct ooh323_peer *peers;
276 /* Mutex to protect H.323 reload process */
277 static int h323_reloading = 0;
278 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
280 /* Mutex to protect usage counter */
281 static int usecnt = 0;
282 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
284 AST_MUTEX_DEFINE_STATIC(ooh323c_cmd_lock);
286 static long callnumber = 0;
287 AST_MUTEX_DEFINE_STATIC(ooh323c_cn_lock);
289 /* stack callbacks */
290 int onAlerting(ooCallData *call);
291 int onProgress(ooCallData *call);
292 int onNewCallCreated(ooCallData *call);
293 int onOutgoingCall(ooCallData *call);
294 int onCallEstablished(ooCallData *call);
295 int onCallCleared(ooCallData *call);
296 void onModeChanged(ooCallData *call, int t38mode);
298 static char gLogFile[256] = DEFAULT_LOGFILE;
299 static int gPort = 1720;
300 static char gIP[2+8*4+7]; /* Max for IPv6 addr */
301 struct ast_sockaddr bindaddr;
303 static char gCallerID[AST_MAX_EXTENSION] = "";
304 static struct ooAliases *gAliasList;
305 static struct ast_format_cap *gCap;
306 static struct ast_codec_pref gPrefs;
307 static int gDTMFMode = H323_DTMF_RFC2833;
308 static int gDTMFCodec = 101;
309 static int gFAXdetect = FAXDETECT_CNG;
310 static int gT38Support = T38_FAXGW;
311 static char gGatekeeper[100];
312 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
314 static int gIsGateway = 0;
315 static int gFastStart = 1;
316 static int gTunneling = 1;
317 static int gBeMaster = 0;
318 static int gMediaWaitForConnect = 0;
320 static int gRTPTimeout = 60;
321 static int g729onlyA = 0;
322 static char gAccountcode[80] = DEFAULT_H323ACCNT;
323 static int gAMAFLAGS;
324 static char gContext[AST_MAX_EXTENSION] = DEFAULT_CONTEXT;
325 static int gIncomingLimit = 1024;
326 static int gOutgoingLimit = 1024;
327 OOBOOL gH323Debug = FALSE;
328 static int gTRCLVL = OOTRCLVLERR;
329 static int gRTDRCount = 0, gRTDRInterval = 0;
331 static int t35countrycode = 0;
332 static int t35extensions = 0;
333 static int manufacturer = 0;
334 static char vendor[AST_MAX_EXTENSION] = "";
335 static char version[AST_MAX_EXTENSION] = "";
337 static struct ooh323_config
343 /** Asterisk RTP stuff*/
344 static struct ast_sched_context *sched;
345 static struct io_context *io;
347 /* Protect the monitoring thread, so only one process can kill or start it,
348 and not when it's doing something critical. */
349 AST_MUTEX_DEFINE_STATIC(monlock);
352 /* This is the thread for the monitor which checks for input on the channels
353 which are not currently in use. */
354 static pthread_t monitor_thread = AST_PTHREADT_NULL;
357 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
358 const char *host, struct ast_format_cap *cap, const char *linkedid)
360 struct ast_channel *ch = NULL;
361 struct ast_format tmpfmt;
365 ast_verbose("--- ooh323_new - %s\n", host);
367 ast_format_clear(&tmpfmt);
368 /* Don't hold a h323 pvt lock while we allocate a channel */
369 ast_mutex_unlock(&i->lock);
370 ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,
371 i->accountcode, i->exten, i->context, linkedid, i->amaflags,
372 "OOH323/%s-%ld", host, callnumber);
373 ast_mutex_lock(&ooh323c_cn_lock);
375 ast_mutex_unlock(&ooh323c_cn_lock);
377 ast_mutex_lock(&i->lock);
380 ast_channel_lock(ch);
381 ch->tech = &ooh323_tech;
384 ast_best_codec(cap, &tmpfmt);
386 ast_codec_pref_index(&i->prefs, 0, &tmpfmt);
388 ast_format_cap_add(ch->nativeformats, &tmpfmt);
389 ast_format_copy(&ch->rawwriteformat, &tmpfmt);
390 ast_format_copy(&ch->rawreadformat, &tmpfmt);
392 ast_jb_configure(ch, &global_jbconf);
394 if (state == AST_STATE_RING)
397 ch->adsicpe = AST_ADSI_UNAVAILABLE;
398 ast_set_write_format(ch, &tmpfmt);
399 ast_set_read_format(ch, &tmpfmt);
402 ast_module_ref(myself);
404 /* Allocate dsp for in-band DTMF support */
405 if ((i->dtmfmode & H323_DTMF_INBAND) || (i->faxdetect & FAXDETECT_CNG)) {
406 i->vad = ast_dsp_new();
410 if (i->dtmfmode & H323_DTMF_INBAND) {
411 features |= DSP_FEATURE_DIGIT_DETECT;
412 if (i->dtmfmode & H323_DTMF_INBANDRELAX) {
413 ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
418 if (i->faxdetect & FAXDETECT_CNG) {
419 features |= DSP_FEATURE_FAX_DETECT;
420 ast_dsp_set_faxmode(i->vad,
421 DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
425 ast_dsp_set_features(i->vad, features);
428 ast_mutex_lock(&usecnt_lock);
430 ast_mutex_unlock(&usecnt_lock);
432 /* Notify the module monitors that use count for resource has changed*/
433 ast_update_use_count();
435 ast_copy_string(ch->context, i->context, sizeof(ch->context));
436 ast_copy_string(ch->exten, i->exten, sizeof(ch->exten));
440 if(!ast_test_flag(i, H323_OUTGOING)) {
442 if (!ast_strlen_zero(i->caller_h323id)) {
443 pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
446 if (!ast_strlen_zero(i->caller_dialedDigits)) {
447 pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS",
448 i->caller_dialedDigits);
450 if (!ast_strlen_zero(i->caller_email)) {
451 pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL",
454 if (!ast_strlen_zero(i->caller_url)) {
455 pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url);
459 if (!ast_strlen_zero(i->accountcode))
460 ast_string_field_set(ch, accountcode, i->accountcode);
463 ch->amaflags = i->amaflags;
465 ast_setstate(ch, state);
466 if (state != AST_STATE_DOWN) {
467 if (ast_pbx_start(ch)) {
468 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
469 ast_channel_unlock(ch);
475 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", "Channel: %s\r\nChanneltype: %s\r\n"
476 "CallRef: %d\r\n", ch->name, "OOH323", i->call_reference);
478 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
481 if(ch) ast_channel_unlock(ch);
484 ast_verbose("+++ h323_new\n");
491 static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
493 struct ooh323_pvt *pvt = NULL;
496 ast_verbose("--- ooh323_alloc\n");
498 if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
499 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
502 if (!(pvt->cap = ast_format_cap_alloc_nolock())) {
504 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
508 ast_mutex_init(&pvt->lock);
509 ast_mutex_lock(&pvt->lock);
513 pvt->faxdetected = 0;
514 pvt->faxdetect = gFAXdetect;
515 pvt->t38support = gT38Support;
516 pvt->rtptimeout = gRTPTimeout;
517 pvt->rtdrinterval = gRTDRInterval;
518 pvt->rtdrcount = gRTDRCount;
519 pvt->g729onlyA = g729onlyA;
521 pvt->call_reference = callref;
523 pvt->callToken = strdup(callToken);
525 /* whether to use gk for this call */
526 if (gRasGkMode == RasNoGatekeeper)
527 OO_SETFLAG(pvt->flags, H323_DISABLEGK);
529 pvt->dtmfmode = gDTMFMode;
530 pvt->dtmfcodec = gDTMFCodec;
531 ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
532 ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
534 pvt->amaflags = gAMAFLAGS;
535 ast_format_cap_copy(pvt->cap, gCap);
536 memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
538 ast_mutex_unlock(&pvt->lock);
539 /* Add to interface list */
540 ast_mutex_lock(&iflock);
543 ast_mutex_unlock(&iflock);
546 ast_verbose("+++ ooh323_alloc\n");
553 Possible data values - peername, exten/peername, exten@ip
555 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
556 const struct ast_channel *requestor, void *data, int *cause)
559 struct ast_channel *chan = NULL;
560 struct ooh323_pvt *p = NULL;
561 struct ooh323_peer *peer = NULL;
565 char formats[FORMAT_STRING_SIZE];
569 ast_verbose("--- ooh323_request - data %s format %s\n", (char*)data,
570 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
572 if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
573 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
577 p = ooh323_alloc(0,0); /* Initial callRef is zero */
580 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char*)data);
583 ast_mutex_lock(&p->lock);
585 /* This is an outgoing call, since ooh323_request is called */
586 ast_set_flag(p, H323_OUTGOING);
589 ast_copy_string(tmp, data, sizeof(tmp));
591 dest = strchr(tmp, '/');
598 } else if ((dest = strchr(tmp, '@'))) {
608 if ((sport = strchr(dest, ':'))) {
616 peer = find_peer(dest, port);
618 ast_mutex_lock(&iflock);
619 ast_mutex_unlock(&p->lock);
621 ast_mutex_unlock(&iflock);
622 ast_log(LOG_ERROR, "Destination format is not supported\n");
627 p->username = strdup(peer->name);
628 p->host = strdup(peer->ip);
629 p->port = peer->port;
630 /* Disable gk as we are going to call a known peer*/
631 /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
634 ast_copy_string(p->exten, ext, sizeof(p->exten));
636 ast_format_cap_copy(p->cap, peer->cap);
637 memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
638 p->g729onlyA = peer->g729onlyA;
639 p->dtmfmode |= peer->dtmfmode;
640 p->dtmfcodec = peer->dtmfcodec;
641 p->faxdetect = peer->faxdetect;
642 p->t38support = peer->t38support;
643 p->rtptimeout = peer->rtptimeout;
644 p->faststart = peer->faststart;
645 p->h245tunneling = peer->h245tunneling;
646 if (peer->rtpmask && peer->rtpmaskstr[0]) {
647 p->rtpmask = peer->rtpmask;
648 ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
651 if (peer->rtdrinterval) {
652 p->rtdrinterval = peer->rtdrinterval;
653 p->rtdrcount = peer->rtdrcount;
656 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
657 p->amaflags = peer->amaflags;
659 if (gRasGkMode == RasNoGatekeeper) {
660 /* no gk and no peer */
661 ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
662 ast_mutex_lock(&iflock);
663 ast_mutex_unlock(&p->lock);
665 ast_mutex_unlock(&iflock);
668 p->g729onlyA = g729onlyA;
669 p->dtmfmode = gDTMFMode;
670 p->dtmfcodec = gDTMFCodec;
671 p->faxdetect = gFAXdetect;
672 p->t38support = gT38Support;
673 p->rtptimeout = gRTPTimeout;
674 ast_format_cap_copy(p->cap, gCap);
675 p->rtdrinterval = gRTDRInterval;
676 p->rtdrcount = gRTDRCount;
677 p->faststart = gFastStart;
678 p->h245tunneling = gTunneling;
680 memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));
681 p->username = strdup(dest);
683 p->host = strdup(dest);
688 ast_copy_string(p->exten, ext, sizeof(p->exten));
693 chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
694 requestor ? requestor->linkedid : NULL);
696 ast_mutex_unlock(&p->lock);
699 ast_mutex_lock(&iflock);
701 ast_mutex_unlock(&iflock);
703 ast_mutex_lock(&p->lock);
704 p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
706 ast_mutex_unlock(&p->lock);
707 ast_mutex_lock(&iflock);
709 ast_mutex_unlock(&iflock);
710 ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
714 ast_mutex_unlock(&p->lock);
715 ast_mutex_lock(&ooh323c_cmd_lock);
716 ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
717 ast_mutex_unlock(&ooh323c_cmd_lock);
722 ast_verbose("+++ ooh323_request\n");
729 static struct ooh323_pvt* find_call(ooCallData *call)
731 struct ooh323_pvt *p;
734 ast_verbose("--- find_call\n");
736 ast_mutex_lock(&iflock);
738 for (p = iflist; p; p = p->next) {
739 if (p->callToken && !strcmp(p->callToken, call->callToken)) {
743 ast_mutex_unlock(&iflock);
746 ast_verbose("+++ find_call\n");
751 struct ooh323_user *find_user(const char * name, const char* ip)
753 struct ooh323_user *user;
756 ast_verbose("--- find_user: %s, %s\n",name,ip);
758 ast_mutex_lock(&userl.lock);
760 for (user = userl.users; user; user = user->next) {
761 if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
764 if (name && !strcmp(user->name, name)) {
769 ast_mutex_unlock(&userl.lock);
772 ast_verbose("+++ find_user\n");
777 struct ooh323_peer *find_friend(const char *name, int port)
779 struct ooh323_peer *peer;
782 ast_verbose("--- find_friend \"%s\"\n", name);
785 ast_mutex_lock(&peerl.lock);
786 for (peer = peerl.peers; peer; peer = peer->next) {
788 ast_verbose(" comparing with \"%s\"\n", peer->ip);
790 if (!strcmp(peer->ip, name)) {
791 if (port <= 0 || (port > 0 && peer->port == port)) {
796 ast_mutex_unlock(&peerl.lock);
800 ast_verbose(" found matching friend\n");
802 ast_verbose("+++ find_friend \"%s\"\n", name);
809 struct ooh323_peer *find_peer(const char * name, int port)
811 struct ooh323_peer *peer;
814 ast_verbose("--- find_peer \"%s\"\n", name);
817 ast_mutex_lock(&peerl.lock);
818 for (peer = peerl.peers; peer; peer = peer->next) {
820 ast_verbose(" comparing with \"%s\"\n", peer->ip);
822 if (!strcasecmp(peer->name, name))
824 if (peer->h323id && !strcasecmp(peer->h323id, name))
826 if (peer->e164 && !strcasecmp(peer->e164, name))
829 if (!strcmp(peer->ip, name)) {
830 if (port > 0 && peer->port == port) { break; }
831 else if (port <= 0) { break; }
835 ast_mutex_unlock(&peerl.lock);
839 ast_verbose(" found matching peer\n");
841 ast_verbose("+++ find_peer \"%s\"\n", name);
847 static int ooh323_digit_begin(struct ast_channel *chan, char digit)
850 struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
853 ast_verbose("--- ooh323_digit_begin\n");
856 ast_log(LOG_ERROR, "No private structure for call\n");
859 ast_mutex_lock(&p->lock);
861 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
862 ast_rtp_instance_dtmf_begin(p->rtp, digit);
863 } else if (((p->dtmfmode & H323_DTMF_Q931) ||
864 (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
865 (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
868 ooSendDTMFDigit(p->callToken, dtmf);
870 ast_mutex_unlock(&p->lock);
872 ast_verbose("+++ ooh323_digit_begin\n");
877 static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
879 struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
882 ast_verbose("--- ooh323_digit_end\n");
885 ast_log(LOG_ERROR, "No private structure for call\n");
888 ast_mutex_lock(&p->lock);
889 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) )
890 ast_rtp_instance_dtmf_end(p->rtp, digit);
892 ast_mutex_unlock(&p->lock);
894 ast_verbose("+++ ooh323_digit_end\n");
900 static int ooh323_call(struct ast_channel *ast, char *dest, int timeout)
902 struct ooh323_pvt *p = ast->tech_pvt;
903 char destination[256];
905 const char *val = NULL;
906 ooCallOptions opts = {
910 .callMode = OO_CALLMODE_AUDIOCALL,
915 ast_verbose("--- ooh323_call- %s\n", dest);
918 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
919 ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
920 "reserved\n", ast->name);
923 ast_mutex_lock(&p->lock);
924 ast_set_flag(p, H323_OUTGOING);
925 if (ast->connected.id.number.valid && ast->connected.id.number.str) {
926 free(p->callerid_num);
927 p->callerid_num = strdup(ast->connected.id.number.str);
930 if (ast->connected.id.name.valid && ast->connected.id.name.str) {
931 free(p->callerid_name);
932 p->callerid_name = strdup(ast->connected.id.name.str);
933 } else if (ast->connected.id.number.valid && ast->connected.id.number.str) {
934 free(p->callerid_name);
935 p->callerid_name = strdup(ast->connected.id.number.str);
937 ast->connected.id.name.valid = 1;
938 free(ast->connected.id.name.str);
939 ast->connected.id.name.str = strdup(gCallerID);
940 free(p->callerid_name);
941 p->callerid_name = strdup(ast->connected.id.name.str);
947 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
948 ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
951 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
952 ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
954 p->callerid_num = strdup(val);
957 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
958 ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
961 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
962 ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
965 if (p->host && p->port != 0)
966 snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
968 snprintf(destination, sizeof(destination), "%s", p->host);
970 ast_copy_string(destination, dest, sizeof(destination));
972 destination[sizeof(destination)-1]='\0';
974 opts.transfercap = ast->transfercapability;
975 opts.fastStart = p->faststart;
976 opts.tunneling = p->h245tunneling;
978 for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
980 if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
981 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
983 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
986 ast_mutex_unlock(&p->lock);
988 ast_log(LOG_ERROR, "Failed to make call\n");
989 return -1; /* ToDO: cleanup */
992 ast_verbose("+++ ooh323_call\n");
997 static int ooh323_hangup(struct ast_channel *ast)
999 struct ooh323_pvt *p = ast->tech_pvt;
1000 int q931cause = AST_CAUSE_NORMAL_CLEARING;
1003 ast_verbose("--- ooh323_hangup\n");
1006 ast_mutex_lock(&p->lock);
1008 if (ast->hangupcause) {
1009 q931cause = ast->hangupcause;
1011 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
1013 if (!strcmp(cause, "CONGESTION")) {
1014 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1015 } else if (!strcmp(cause, "BUSY")) {
1016 q931cause = AST_CAUSE_USER_BUSY;
1017 } else if (!strcmp(cause, "CHANISUNVAIL")) {
1018 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1019 } else if (!strcmp(cause, "NOANSWER")) {
1020 q931cause = AST_CAUSE_NO_ANSWER;
1021 } else if (!strcmp(cause, "CANCEL")) {
1022 q931cause = AST_CAUSE_CALL_REJECTED;
1030 ast_verbose(" hanging %s with cause: %d\n", p->username, q931cause);
1031 ast->tech_pvt = NULL;
1032 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1033 ooHangCall(p->callToken,
1034 ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
1035 ast_set_flag(p, H323_ALREADYGONE);
1036 /* ast_mutex_unlock(&p->lock); */
1038 ast_set_flag(p, H323_NEEDDESTROY);
1039 /* detach channel here */
1041 p->owner->tech_pvt = NULL;
1043 ast_module_unref(myself);
1046 ast_mutex_unlock(&p->lock);
1047 ast_mutex_lock(&usecnt_lock);
1049 ast_mutex_unlock(&usecnt_lock);
1051 /* Notify the module monitors that use count for resource has changed */
1052 ast_update_use_count();
1055 ast_debug(1, "No call to hangup\n" );
1059 ast_verbose("+++ ooh323_hangup\n");
1064 static int ooh323_answer(struct ast_channel *ast)
1066 struct ooh323_pvt *p = ast->tech_pvt;
1067 char *callToken = (char *)NULL;
1070 ast_verbose("--- ooh323_answer\n");
1074 ast_mutex_lock(&p->lock);
1075 callToken = (p->callToken ? strdup(p->callToken) : NULL);
1076 if (ast->_state != AST_STATE_UP) {
1077 ast_channel_lock(ast);
1078 if (!p->alertsent) {
1080 ast_debug(1, "Sending forced ringback for %s, res = %d\n",
1081 callToken, ooManualRingback(callToken));
1083 ooManualRingback(callToken);
1087 ast_setstate(ast, AST_STATE_UP);
1089 ast_debug(1, "ooh323_answer(%s)\n", ast->name);
1090 ast_channel_unlock(ast);
1091 ooAnswerCall(p->callToken);
1096 ast_mutex_unlock(&p->lock);
1100 ast_verbose("+++ ooh323_answer\n");
1105 static struct ast_frame *ooh323_read(struct ast_channel *ast)
1107 struct ast_frame *fr;
1108 static struct ast_frame null_frame = { AST_FRAME_NULL, };
1109 struct ooh323_pvt *p = ast->tech_pvt;
1111 if (!p) return &null_frame;
1113 ast_mutex_lock(&p->lock);
1115 fr = ooh323_rtp_read(ast, p);
1118 /* time(&p->lastrtprx); */
1119 ast_mutex_unlock(&p->lock);
1123 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
1125 struct ooh323_pvt *p = ast->tech_pvt;
1130 ast_mutex_lock(&p->lock);
1132 if (f->frametype == AST_FRAME_MODEM) {
1133 ast_debug(1, "Send UDPTL %d/%d len %d for %s\n",
1134 f->frametype, f->subclass.integer, f->datalen, ast->name);
1136 res = ast_udptl_write(p->udptl, f);
1137 ast_mutex_unlock(&p->lock);
1142 if (f->frametype == AST_FRAME_VOICE) {
1143 /* sending progress for first */
1144 if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
1146 ooManualProgress(p->callToken);
1151 if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
1152 if (!(ast_format_cap_is_empty(ast->nativeformats))) {
1153 ast_log(LOG_WARNING,
1154 "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1155 ast_getformatname(&f->subclass.format),
1156 ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
1157 ast_getformatname(&ast->readformat),
1158 ast_getformatname(&ast->writeformat));
1160 ast_set_write_format(ast, &f->subclass.format);
1162 /* ast_set_write_format(ast, f->subclass);
1163 ast->nativeformats = f->subclass; */
1165 ast_mutex_unlock(&p->lock);
1170 res = ast_rtp_instance_write(p->rtp, f);
1172 ast_mutex_unlock(&p->lock);
1174 } else if (f->frametype == AST_FRAME_IMAGE) {
1175 ast_mutex_unlock(&p->lock);
1178 ast_log(LOG_WARNING, "Can't send %d type frames with OOH323 write\n",
1180 ast_mutex_unlock(&p->lock);
1189 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1192 struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
1193 char *callToken = (char *)NULL;
1198 ast_mutex_lock(&p->lock);
1199 callToken = (p->callToken ? strdup(p->callToken) : NULL);
1200 ast_mutex_unlock(&p->lock);
1204 ast_verbose(" ooh323_indicate - No callToken\n");
1209 ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken);
1211 ast_mutex_lock(&p->lock);
1212 switch (condition) {
1213 case AST_CONTROL_INCOMPLETE:
1214 /* While h323 does support overlapped dialing, this channel driver does not
1215 * at this time. Treat a response of Incomplete as if it were congestion.
1217 case AST_CONTROL_CONGESTION:
1218 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1219 ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
1220 ast_set_flag(p, H323_ALREADYGONE);
1223 case AST_CONTROL_BUSY:
1224 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1225 ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
1226 ast_set_flag(p, H323_ALREADYGONE);
1229 case AST_CONTROL_HOLD:
1230 ast_moh_start(ast, data, NULL);
1232 case AST_CONTROL_UNHOLD:
1235 case AST_CONTROL_PROGRESS:
1236 if (ast->_state != AST_STATE_UP) {
1239 ast_debug(1, "Sending manual progress for %s, res = %d\n", callToken,
1240 ooManualProgress(callToken));
1242 ooManualProgress(callToken);
1248 case AST_CONTROL_RINGING:
1249 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) {
1250 if (!p->alertsent) {
1252 ast_debug(1, "Sending manual ringback for %s, res = %d\n",
1254 ooManualRingback(callToken));
1256 ooManualRingback(callToken);
1263 case AST_CONTROL_SRCUPDATE:
1265 ast_rtp_instance_update_source(p->rtp);
1268 case AST_CONTROL_SRCCHANGE:
1270 ast_rtp_instance_change_source(p->rtp);
1273 case AST_CONTROL_CONNECTED_LINE:
1274 if (!ast->connected.id.name.valid
1275 || ast_strlen_zero(ast->connected.id.name.str)) {
1279 ast_debug(1, "Sending connected line info for %s (%s)\n",
1280 callToken, ast->connected.id.name.str);
1282 ooSetANI(callToken, ast->connected.id.name.str);
1285 case AST_CONTROL_T38_PARAMETERS:
1286 if (p->t38support != T38_ENABLED) {
1287 struct ast_control_t38_parameters parameters = { .request_response = 0 };
1288 parameters.request_response = AST_T38_REFUSED;
1289 ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
1290 ¶meters, sizeof(parameters));
1293 if (datalen != sizeof(struct ast_control_t38_parameters)) {
1294 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
1295 "Expected %d, got %d\n",
1296 (int)sizeof(enum ast_control_t38), (int)datalen);
1298 const struct ast_control_t38_parameters *parameters = data;
1299 struct ast_control_t38_parameters our_parameters;
1300 enum ast_control_t38 message = parameters->request_response;
1303 case AST_T38_NEGOTIATED:
1308 case AST_T38_REQUEST_NEGOTIATE:
1311 /* T.38 already negotiated */
1312 our_parameters.request_response = AST_T38_NEGOTIATED;
1313 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1314 our_parameters.rate = AST_T38_RATE_14400;
1315 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1316 } else if (!p->chmodepend) {
1318 ooRequestChangeMode(p->callToken, 1);
1323 case AST_T38_REQUEST_TERMINATE:
1326 /* T.38 already terminated */
1327 our_parameters.request_response = AST_T38_TERMINATED;
1328 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1329 } else if (!p->chmodepend) {
1331 ooRequestChangeMode(p->callToken, 0);
1336 case AST_T38_REQUEST_PARMS:
1337 our_parameters.request_response = AST_T38_REQUEST_PARMS;
1338 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1339 our_parameters.rate = AST_T38_RATE_14400;
1340 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1341 res = AST_T38_REQUEST_PARMS;
1351 case AST_CONTROL_PROCEEDING:
1355 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
1356 condition, callToken);
1359 ast_mutex_unlock(&p->lock);
1362 ast_verbose("++++ ooh323_indicate %d on %s\n", condition, callToken);
1368 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1371 struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
1373 enum ast_t38_state state = T38_STATE_UNAVAILABLE;
1378 ast_mutex_lock(&p->lock);
1381 ast_verbose("----- ooh323_queryoption %d on channel %s\n", option, ast->name);
1385 case AST_OPTION_T38_STATE:
1387 if (*datalen != sizeof(enum ast_t38_state)) {
1388 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
1389 " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
1393 if (p->t38support != T38_DISABLED) {
1395 state = (p->chmodepend) ? T38_STATE_NEGOTIATING : T38_STATE_NEGOTIATED;
1397 state = T38_STATE_UNKNOWN;
1401 *((enum ast_t38_state *) data) = state;
1406 case AST_OPTION_DIGIT_DETECT:
1409 *cp = p->vad ? 1 : 0;
1410 ast_debug(1, "Reporting digit detection %sabled on %s\n",
1411 *cp ? "en" : "dis", ast->name);
1421 ast_verbose("+++++ ooh323_queryoption %d on channel %s\n", option, ast->name);
1423 ast_mutex_unlock(&p->lock);
1430 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1432 struct ooh323_pvt *p = newchan->tech_pvt;
1437 ast_verbose("--- ooh323c ooh323_fixup\n");
1439 ast_mutex_lock(&p->lock);
1440 if (p->owner != oldchan) {
1441 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
1442 ast_mutex_unlock(&p->lock);
1446 if (p->owner == oldchan) {
1452 ast_mutex_unlock(&p->lock);
1455 ast_verbose("+++ ooh323c ooh323_fixup \n");
1461 void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
1463 struct ooh323_pvt *p = NULL;
1464 char formats[FORMAT_STRING_SIZE];
1467 ast_verbose("--- ooh323_update_writeformat %s/%d\n",
1468 ast_getformatname(fmt), txframes);
1470 p = find_call(call);
1472 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1476 ast_mutex_lock(&p->lock);
1478 ast_format_copy(&(p->writeformat), fmt);
1481 while (p->owner && ast_channel_trylock(p->owner)) {
1482 ast_debug(1,"Failed to grab lock, trying again\n");
1483 DEADLOCK_AVOIDANCE(&p->lock);
1486 ast_mutex_unlock(&p->lock);
1487 ast_log(LOG_ERROR, "Channel has no owner\n");
1491 ast_verbose("Writeformat before update %s/%s\n",
1492 ast_getformatname(&p->owner->writeformat),
1493 ast_getformatname_multiple(formats, sizeof(formats), p->owner->nativeformats));
1495 ast_codec_pref_setsize(&p->prefs, fmt, txframes);
1496 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
1497 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
1498 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1499 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
1501 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
1502 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1503 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
1506 ast_format_cap_set(p->owner->nativeformats, fmt);
1507 ast_set_write_format(p->owner, &p->owner->writeformat);
1508 ast_set_read_format(p->owner, &p->owner->readformat);
1509 ast_channel_unlock(p->owner);
1511 ast_log(LOG_ERROR, "No owner found\n");
1514 ast_mutex_unlock(&p->lock);
1517 ast_verbose("+++ ooh323_update_writeformat\n");
1520 void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
1522 struct ooh323_pvt *p = NULL;
1525 ast_verbose("--- ooh323_update_readformat %s\n",
1526 ast_getformatname(fmt));
1528 p = find_call(call);
1530 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1534 ast_mutex_lock(&p->lock);
1536 ast_format_copy(&(p->readformat), fmt);
1539 while (p->owner && ast_channel_trylock(p->owner)) {
1540 ast_debug(1,"Failed to grab lock, trying again\n");
1541 DEADLOCK_AVOIDANCE(&p->lock);
1544 ast_mutex_unlock(&p->lock);
1545 ast_log(LOG_ERROR, "Channel has no owner\n");
1550 ast_verbose("Readformat before update %s\n",
1551 ast_getformatname(&p->owner->readformat));
1552 ast_format_cap_set(p->owner->nativeformats, fmt);
1553 ast_set_read_format(p->owner, &p->owner->readformat);
1554 ast_channel_unlock(p->owner);
1556 ast_log(LOG_ERROR, "No owner found\n");
1558 ast_mutex_unlock(&p->lock);
1561 ast_verbose("+++ ooh323_update_readformat\n");
1565 int onAlerting(ooCallData *call)
1567 struct ooh323_pvt *p = NULL;
1568 struct ast_channel *c = NULL;
1571 ast_verbose("--- onAlerting %s\n", call->callToken);
1573 p = find_call(call);
1576 ast_log(LOG_ERROR, "No matching call found\n");
1579 ast_mutex_lock(&p->lock);
1581 ast_mutex_unlock(&p->lock);
1582 ast_log(LOG_ERROR, "Channel has no owner\n");
1585 while (p->owner && ast_channel_trylock(p->owner)) {
1586 ast_debug(1, "Failed to grab lock, trying again\n");
1587 DEADLOCK_AVOIDANCE(&p->lock);
1590 ast_mutex_unlock(&p->lock);
1591 ast_log(LOG_ERROR, "Channel has no owner\n");
1596 if (call->remoteDisplayName) {
1597 struct ast_party_connected_line connected;
1598 struct ast_set_party_connected_line update_connected;
1600 memset(&update_connected, 0, sizeof(update_connected));
1601 update_connected.id.name = 1;
1602 ast_party_connected_line_init(&connected);
1603 connected.id.name.valid = 1;
1604 connected.id.name.str = (char *) call->remoteDisplayName;
1605 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1606 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1608 if (c->_state != AST_STATE_UP)
1609 ast_setstate(c, AST_STATE_RINGING);
1611 ast_queue_control(c, AST_CONTROL_RINGING);
1612 ast_channel_unlock(c);
1613 ast_mutex_unlock(&p->lock);
1616 ast_verbose("+++ onAlerting %s\n", call->callToken);
1621 int onProgress(ooCallData *call)
1623 struct ooh323_pvt *p = NULL;
1624 struct ast_channel *c = NULL;
1627 ast_verbose("--- onProgress %s\n", call->callToken);
1629 p = find_call(call);
1632 ast_log(LOG_ERROR, "No matching call found\n");
1635 ast_mutex_lock(&p->lock);
1637 ast_mutex_unlock(&p->lock);
1638 ast_log(LOG_ERROR, "Channel has no owner\n");
1641 while (p->owner && ast_channel_trylock(p->owner)) {
1642 ast_debug(1, "Failed to grab lock, trying again\n");
1643 DEADLOCK_AVOIDANCE(&p->lock);
1646 ast_mutex_unlock(&p->lock);
1647 ast_log(LOG_ERROR, "Channel has no owner\n");
1652 if (call->remoteDisplayName) {
1653 struct ast_party_connected_line connected;
1654 struct ast_set_party_connected_line update_connected;
1656 memset(&update_connected, 0, sizeof(update_connected));
1657 update_connected.id.name = 1;
1658 ast_party_connected_line_init(&connected);
1659 connected.id.name.valid = 1;
1660 connected.id.name.str = (char *) call->remoteDisplayName;
1661 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1662 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1664 if (c->_state != AST_STATE_UP)
1665 ast_setstate(c, AST_STATE_RINGING);
1667 ast_queue_control(c, AST_CONTROL_PROGRESS);
1668 ast_channel_unlock(c);
1669 ast_mutex_unlock(&p->lock);
1672 ast_verbose("+++ onProgress %s\n", call->callToken);
1678 * Callback for sending digits from H.323 up to asterisk
1681 int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
1683 struct ooh323_pvt *p = NULL;
1687 ast_debug(1, "Received Digit: %c\n", digit[0]);
1688 p = find_call(call);
1690 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1694 ast_log(LOG_ERROR, "Channel has no owner\n");
1697 ast_mutex_lock(&p->lock);
1698 memset(&f, 0, sizeof(f));
1699 f.frametype = AST_FRAME_DTMF;
1700 f.subclass.integer = digit[0];
1706 f.src = "SEND_DIGIT";
1708 while (p->owner && ast_channel_trylock(p->owner)) {
1709 ast_debug(1, "Failed to grab lock, trying again\n");
1710 DEADLOCK_AVOIDANCE(&p->lock);
1713 ast_mutex_unlock(&p->lock);
1714 ast_log(LOG_ERROR, "Channel has no owner\n");
1717 res = ast_queue_frame(p->owner, &f);
1718 ast_channel_unlock(p->owner);
1719 ast_mutex_unlock(&p->lock);
1723 int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
1725 struct ooh323_pvt *p = NULL;
1726 struct ooh323_user *user = NULL;
1727 struct ast_channel *c = NULL;
1728 ooAliases *alias = NULL;
1730 char number [OO_MAX_NUMBER_LENGTH];
1733 ast_verbose("--- ooh323_onReceivedSetup %s\n", call->callToken);
1736 if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
1737 ast_log(LOG_ERROR, "Failed to create a new call.\n");
1740 ast_mutex_lock(&p->lock);
1741 ast_clear_flag(p, H323_OUTGOING);
1744 if (call->remoteDisplayName) {
1745 p->callerid_name = strdup(call->remoteDisplayName);
1748 if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
1749 p->callerid_num = strdup(number);
1752 if (call->remoteAliases) {
1753 for (alias = call->remoteAliases; alias; alias = alias->next) {
1754 if (alias->type == T_H225AliasAddress_h323_ID) {
1755 if (!p->callerid_name) {
1756 p->callerid_name = strdup(alias->value);
1758 ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
1760 else if(alias->type == T_H225AliasAddress_dialedDigits)
1762 if(!p->callerid_num)
1763 p->callerid_num = strdup(alias->value);
1764 ast_copy_string(p->caller_dialedDigits, alias->value,
1765 sizeof(p->caller_dialedDigits));
1767 else if(alias->type == T_H225AliasAddress_email_ID)
1769 ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
1771 else if(alias->type == T_H225AliasAddress_url_ID)
1773 ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
1779 if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
1780 strncpy(p->exten, number, sizeof(p->exten)-1);
1782 update_our_aliases(call, p);
1783 if (!ast_strlen_zero(p->callee_dialedDigits)) {
1784 ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
1785 } else if(!ast_strlen_zero(p->callee_h323id)) {
1786 ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
1787 } else if(!ast_strlen_zero(p->callee_email)) {
1788 ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
1789 if ((at = strchr(p->exten, '@'))) {
1795 /* if no extension found, set to default 's' */
1796 if (ast_strlen_zero(p->exten)) {
1801 user = find_user(p->callerid_name, call->remoteIP);
1802 if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
1803 ast_mutex_lock(&user->lock);
1804 p->username = strdup(user->name);
1805 p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
1806 ast_strdup(user->name);
1807 ast_copy_string(p->context, user->context, sizeof(p->context));
1808 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
1809 p->amaflags = user->amaflags;
1810 ast_format_cap_copy(p->cap, user->cap);
1811 p->g729onlyA = user->g729onlyA;
1812 memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
1813 p->dtmfmode |= user->dtmfmode;
1814 p->dtmfcodec = user->dtmfcodec;
1815 p->faxdetect = user->faxdetect;
1816 p->t38support = user->t38support;
1817 p->rtptimeout = user->rtptimeout;
1818 p->h245tunneling = user->h245tunneling;
1819 p->faststart = user->faststart;
1822 OO_SETFLAG(call->flags, OO_M_FASTSTART);
1824 OO_CLRFLAG(call->flags, OO_M_FASTSTART);
1825 /* if we disable h245tun for this user then we clear flag */
1826 /* in any other case we don't must touch this */
1827 /* ie if we receive setup without h245tun but enabled
1828 we can't enable it per call */
1829 if (!p->h245tunneling)
1830 OO_CLRFLAG(call->flags, OO_M_TUNNELING);
1832 if (user->rtpmask && user->rtpmaskstr[0]) {
1833 p->rtpmask = user->rtpmask;
1834 ast_copy_string(p->rtpmaskstr, user->rtpmaskstr,
1835 sizeof(p->rtpmaskstr));
1837 if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
1838 p->rtdrcount = user->rtdrcount;
1839 p->rtdrinterval = user->rtdrinterval;
1841 if (user->incominglimit) user->inUse++;
1842 ast_mutex_unlock(&user->lock);
1844 if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
1845 p->username = strdup(call->remoteIP);
1847 ast_mutex_unlock(&p->lock);
1848 ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
1850 ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
1851 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1854 ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
1855 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1857 ast_set_flag(p, H323_NEEDDESTROY);
1862 ooh323c_set_capability_for_call(call, &p->prefs, p->cap, p->dtmfmode, p->dtmfcodec,
1863 p->t38support, p->g729onlyA);
1865 c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL);
1867 ast_mutex_unlock(&p->lock);
1868 ast_log(LOG_ERROR, "Could not create ast_channel\n");
1871 if (!configure_local_rtp(p, call)) {
1872 ast_mutex_unlock(&p->lock);
1873 ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
1877 ast_mutex_unlock(&p->lock);
1880 ast_verbose("+++ ooh323_onReceivedSetup - Determined context %s, "
1881 "extension %s\n", p->context, p->exten);
1888 int onOutgoingCall(ooCallData *call)
1890 struct ooh323_pvt *p = NULL;
1894 ast_verbose("--- onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
1896 if (!strcmp(call->callType, "outgoing")) {
1897 p = find_call(call);
1899 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1902 ast_mutex_lock(&p->lock);
1904 if (!ast_strlen_zero(p->callerid_name)) {
1905 ooCallSetCallerId(call, p->callerid_name);
1907 if (!ast_strlen_zero(p->callerid_num)) {
1909 while (*(p->callerid_num + i) != '\0') {
1910 if(!isdigit(*(p->callerid_num+i))) { break; }
1913 if(*(p->callerid_num+i) == '\0')
1914 ooCallSetCallingPartyNumber(call, p->callerid_num);
1916 if(!p->callerid_name)
1917 ooCallSetCallerId(call, p->callerid_num);
1921 if (!ast_strlen_zero(p->caller_h323id))
1922 ooCallAddAliasH323ID(call, p->caller_h323id);
1924 if (!ast_strlen_zero(p->caller_dialedDigits)) {
1926 ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits);
1928 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
1929 } else if (!ast_strlen_zero(p->callerid_num)) {
1930 if (ooIsDailedDigit(p->callerid_num)) {
1932 ast_verbose("setting callid number %s\n", p->callerid_num);
1934 ooCallAddAliasDialedDigits(call, p->callerid_num);
1935 } else if (ast_strlen_zero(p->caller_h323id)) {
1936 ooCallAddAliasH323ID(call, p->callerid_num);
1939 if (p->rtpmask && p->rtpmaskstr[0]) {
1940 call->rtpMask = p->rtpmask;
1941 ast_mutex_lock(&call->rtpMask->lock);
1942 call->rtpMask->inuse++;
1943 ast_mutex_unlock(&call->rtpMask->lock);
1944 ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
1947 if (!configure_local_rtp(p, call)) {
1948 ast_mutex_unlock(&p->lock);
1952 ast_mutex_unlock(&p->lock);
1956 ast_verbose("+++ onOutgoingCall %s\n", call->callToken);
1961 int onNewCallCreated(ooCallData *call)
1963 struct ooh323_pvt *p = NULL;
1967 ast_verbose("--- onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
1969 ast_mutex_lock(&call->Lock);
1970 if (ooh323c_start_call_thread(call)) {
1971 ast_log(LOG_ERROR,"Failed to create call thread.\n");
1972 ast_mutex_unlock(&call->Lock);
1976 if (!strcmp(call->callType, "outgoing")) {
1977 p = find_call(call);
1979 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1980 ast_mutex_unlock(&call->Lock);
1983 ast_mutex_lock(&p->lock);
1985 if (!ast_strlen_zero(p->callerid_name)) {
1986 ooCallSetCallerId(call, p->callerid_name);
1988 if (!ast_strlen_zero(p->callerid_num)) {
1990 while (*(p->callerid_num + i) != '\0') {
1991 if(!isdigit(*(p->callerid_num+i))) { break; }
1994 if(*(p->callerid_num+i) == '\0')
1995 ooCallSetCallingPartyNumber(call, p->callerid_num);
1997 if(ast_strlen_zero(p->callerid_name))
1998 ooCallSetCallerId(call, p->callerid_num);
2002 if (!ast_strlen_zero(p->caller_h323id))
2003 ooCallAddAliasH323ID(call, p->caller_h323id);
2005 if (!ast_strlen_zero(p->caller_dialedDigits)) {
2007 ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits);
2009 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
2010 } else if (!ast_strlen_zero(p->callerid_num)) {
2011 if (ooIsDailedDigit(p->callerid_num)) {
2013 ast_verbose("setting callid number %s\n", p->callerid_num);
2015 ooCallAddAliasDialedDigits(call, p->callerid_num);
2016 } else if (ast_strlen_zero(p->caller_h323id)) {
2017 ooCallAddAliasH323ID(call, p->callerid_num);
2022 if (!ast_strlen_zero(p->exten)) {
2023 if (ooIsDailedDigit(p->exten)) {
2024 ooCallSetCalledPartyNumber(call, p->exten);
2025 ooCallAddRemoteAliasDialedDigits(call, p->exten);
2027 ooCallAddRemoteAliasH323ID(call, p->exten);
2033 ast_codec_pref_string(&p->prefs, prefsBuf, sizeof(prefsBuf));
2034 ast_verbose(" Outgoing call %s(%s) - Codec prefs - %s\n",
2035 p->username?p->username:"NULL", call->callToken, prefsBuf);
2038 ooh323c_set_capability_for_call(call, &p->prefs, p->cap,
2039 p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
2041 /* configure_local_rtp(p, call); */
2042 ast_mutex_unlock(&p->lock);
2045 ast_mutex_unlock(&call->Lock);
2047 ast_verbose("+++ onNewCallCreated %s\n", call->callToken);
2051 int onCallEstablished(ooCallData *call)
2053 struct ooh323_pvt *p = NULL;
2056 ast_verbose("--- onCallEstablished %s\n", call->callToken);
2059 if (!(p = find_call(call))) {
2060 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2064 if(ast_test_flag(p, H323_OUTGOING)) {
2065 ast_mutex_lock(&p->lock);
2067 ast_mutex_unlock(&p->lock);
2068 ast_log(LOG_ERROR, "Channel has no owner\n");
2072 while (p->owner && ast_channel_trylock(p->owner)) {
2073 ast_debug(1, "Failed to grab lock, trying again\n");
2074 DEADLOCK_AVOIDANCE(&p->lock);
2077 struct ast_channel* c = p->owner;
2079 if (call->remoteDisplayName) {
2080 struct ast_party_connected_line connected;
2081 struct ast_set_party_connected_line update_connected;
2083 memset(&update_connected, 0, sizeof(update_connected));
2084 update_connected.id.name = 1;
2085 ast_party_connected_line_init(&connected);
2086 connected.id.name.valid = 1;
2087 connected.id.name.str = (char *) call->remoteDisplayName;
2088 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
2089 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
2092 ast_queue_control(c, AST_CONTROL_ANSWER);
2093 ast_channel_unlock(p->owner);
2094 manager_event(EVENT_FLAG_SYSTEM,"ChannelUpdate","Channel: %s\r\nChanneltype: %s\r\n"
2095 "CallRef: %d\r\n", c->name, "OOH323", p->call_reference);
2097 ast_mutex_unlock(&p->lock);
2102 ast_verbose("+++ onCallEstablished %s\n", call->callToken);
2107 int onCallCleared(ooCallData *call)
2109 struct ooh323_pvt *p = NULL;
2113 ast_verbose("--- onCallCleared %s \n", call->callToken);
2116 if ((p = find_call(call))) {
2117 ast_mutex_lock(&p->lock);
2120 if (ast_channel_trylock(p->owner)) {
2121 ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
2122 ast_debug(1, "Failed to grab lock, trying again\n");
2123 DEADLOCK_AVOIDANCE(&p->lock);
2125 ownerLock = 1; break;
2130 if (!ast_test_flag(p, H323_ALREADYGONE)) {
2132 ast_set_flag(p, H323_ALREADYGONE);
2133 p->owner->hangupcause = call->q931cause;
2134 p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
2135 ast_queue_hangup_with_cause(p->owner,call->q931cause);
2140 p->owner->tech_pvt = NULL;
2141 ast_channel_unlock(p->owner);
2143 ast_module_unref(myself);
2146 ast_set_flag(p, H323_NEEDDESTROY);
2148 ooh323c_stop_call_thread(call);
2150 ast_mutex_unlock(&p->lock);
2151 ast_mutex_lock(&usecnt_lock);
2153 ast_mutex_unlock(&usecnt_lock);
2158 ast_verbose("+++ onCallCleared\n");
2163 /* static void ooh323_delete_user(struct ooh323_user *user)
2165 struct ooh323_user *prev = NULL, *cur = NULL;
2168 ast_verbose("--- ooh323_delete_user\n");
2172 ast_mutex_lock(&userl.lock);
2174 if (cur == user) break;
2181 prev->next = cur->next;
2183 userl.users = cur->next;
2185 ast_mutex_unlock(&userl.lock);
2191 ast_verbose("+++ ooh323_delete_user\n");
2195 void ooh323_delete_peer(struct ooh323_peer *peer)
2197 struct ooh323_peer *prev = NULL, *cur = NULL;
2200 ast_verbose("--- ooh323_delete_peer\n");
2204 ast_mutex_lock(&peerl.lock);
2206 if(cur==peer) break;
2213 prev->next = cur->next;
2215 peerl.peers = cur->next;
2217 ast_mutex_unlock(&peerl.lock);
2219 if(peer->h323id) free(peer->h323id);
2220 if(peer->email) free(peer->email);
2221 if(peer->url) free(peer->url);
2222 if(peer->e164) free(peer->e164);
2224 peer->cap = ast_format_cap_destroy(peer->cap);
2229 ast_verbose("+++ ooh323_delete_peer\n");
2235 static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
2237 struct ooh323_user *user = NULL;
2240 ast_verbose("--- build_user\n");
2242 user = ast_calloc(1,sizeof(struct ooh323_user));
2244 memset(user, 0, sizeof(struct ooh323_user));
2245 if (!(user->cap = ast_format_cap_alloc())) {
2249 ast_mutex_init(&user->lock);
2250 ast_copy_string(user->name, name, sizeof(user->name));
2251 ast_format_cap_copy(user->cap, gCap);
2252 memcpy(&user->prefs, &gPrefs, sizeof(user->prefs));
2253 user->rtptimeout = gRTPTimeout;
2254 user->dtmfmode = gDTMFMode;
2255 user->dtmfcodec = gDTMFCodec;
2256 user->faxdetect = gFAXdetect;
2257 user->t38support = gT38Support;
2258 user->faststart = gFastStart;
2259 user->h245tunneling = gTunneling;
2260 user->g729onlyA = g729onlyA;
2261 /* set default context */
2262 ast_copy_string(user->context, gContext, sizeof(user->context));
2263 ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
2264 user->amaflags = gAMAFLAGS;
2267 if (!strcasecmp(v->name, "context")) {
2268 ast_copy_string(user->context, v->value, sizeof(user->context));
2269 } else if (!strcasecmp(v->name, "incominglimit")) {
2270 user->incominglimit = atoi(v->value);
2271 if (user->incominglimit < 0)
2272 user->incominglimit = 0;
2273 } else if (!strcasecmp(v->name, "accountcode")) {
2274 strncpy(user->accountcode, v->value,
2275 sizeof(user->accountcode)-1);
2276 } else if (!strcasecmp(v->name, "roundtrip")) {
2277 sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
2278 } else if (!strcasecmp(v->name, "faststart")) {
2279 user->faststart = ast_true(v->value);
2280 } else if (!strcasecmp(v->name, "h245tunneling")) {
2281 user->h245tunneling = ast_true(v->value);
2282 } else if (!strcasecmp(v->name, "g729onlyA")) {
2283 user->g729onlyA = ast_true(v->value);
2284 } else if (!strcasecmp(v->name, "rtptimeout")) {
2285 user->rtptimeout = atoi(v->value);
2286 if (user->rtptimeout < 0)
2287 user->rtptimeout = gRTPTimeout;
2288 } else if (!strcasecmp(v->name, "rtpmask")) {
2289 if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2290 (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED)
2292 ast_mutex_init(&user->rtpmask->lock);
2293 user->rtpmask->inuse = 1;
2294 ast_copy_string(user->rtpmaskstr, v->value,
2295 sizeof(user->rtpmaskstr));
2296 } else user->rtpmask = NULL;
2297 } else if (!strcasecmp(v->name, "disallow")) {
2298 ast_parse_allow_disallow(&user->prefs,
2299 user->cap, v->value, 0);
2300 } else if (!strcasecmp(v->name, "allow")) {
2301 const char* tcodecs = v->value;
2302 if (!strcasecmp(v->value, "all")) {
2303 tcodecs = "ulaw,alaw,g729,g723,gsm";
2305 ast_parse_allow_disallow(&user->prefs,
2306 user->cap, tcodecs, 1);
2307 } else if (!strcasecmp(v->name, "amaflags")) {
2308 user->amaflags = ast_cdr_amaflags2int(v->value);
2309 } else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
2310 struct ast_sockaddr p;
2311 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2312 ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
2314 ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
2317 } else if (!strcasecmp(v->name, "dtmfmode")) {
2318 if (!strcasecmp(v->value, "rfc2833"))
2319 user->dtmfmode = H323_DTMF_RFC2833;
2320 if (!strcasecmp(v->value, "cisco"))
2321 user->dtmfmode = H323_DTMF_CISCO;
2322 else if (!strcasecmp(v->value, "q931keypad"))
2323 user->dtmfmode = H323_DTMF_Q931;
2324 else if (!strcasecmp(v->value, "h245alphanumeric"))
2325 user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2326 else if (!strcasecmp(v->value, "h245signal"))
2327 user->dtmfmode = H323_DTMF_H245SIGNAL;
2328 else if (!strcasecmp(v->value, "inband"))
2329 user->dtmfmode = H323_DTMF_INBAND;
2330 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2331 user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2332 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2333 user->dtmfcodec = atoi(v->value);
2334 } else if (!strcasecmp(v->name, "faxdetect")) {
2335 if (ast_true(v->value)) {
2336 user->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2337 } else if (ast_false(v->value)) {
2338 user->faxdetect = 0;
2340 char *buf = ast_strdupa(v->value);
2341 char *word, *next = buf;
2342 user->faxdetect = 0;
2343 while ((word = strsep(&next, ","))) {
2344 if (!strcasecmp(word, "cng")) {
2345 user->faxdetect |= FAXDETECT_CNG;
2346 } else if (!strcasecmp(word, "t38")) {
2347 user->faxdetect |= FAXDETECT_T38;
2349 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2354 } else if (!strcasecmp(v->name, "t38support")) {
2355 if (!strcasecmp(v->value, "disabled"))
2356 user->t38support = T38_DISABLED;
2357 if (!strcasecmp(v->value, "no"))
2358 user->t38support = T38_DISABLED;
2359 else if (!strcasecmp(v->value, "faxgw"))
2360 user->t38support = T38_FAXGW;
2361 else if (!strcasecmp(v->value, "yes"))
2362 user->t38support = T38_ENABLED;
2369 ast_verbose("+++ build_user\n");
2374 static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
2376 struct ooh323_peer *peer = NULL;
2379 ast_verbose("--- build_peer\n");
2381 peer = ast_calloc(1, sizeof(*peer));
2383 memset(peer, 0, sizeof(struct ooh323_peer));
2384 if (!(peer->cap = ast_format_cap_alloc())) {
2388 ast_mutex_init(&peer->lock);
2389 ast_copy_string(peer->name, name, sizeof(peer->name));
2390 ast_format_cap_copy(peer->cap, gCap);
2391 memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs));
2392 peer->rtptimeout = gRTPTimeout;
2393 ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
2394 peer->amaflags = gAMAFLAGS;
2395 peer->dtmfmode = gDTMFMode;
2396 peer->dtmfcodec = gDTMFCodec;
2397 peer->faxdetect = gFAXdetect;
2398 peer->t38support = gT38Support;
2399 peer->faststart = gFastStart;
2400 peer->h245tunneling = gTunneling;
2401 peer->g729onlyA = g729onlyA;
2403 if (0 == friend_type) {
2408 if (!strcasecmp(v->name, "h323id")) {
2409 if (!(peer->h323id = ast_strdup(v->value))) {
2410 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2412 ooh323_delete_peer(peer);
2415 } else if (!strcasecmp(v->name, "e164")) {
2416 if (!(peer->e164 = ast_strdup(v->value))) {
2417 ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
2419 ooh323_delete_peer(peer);
2422 } else if (!strcasecmp(v->name, "email")) {
2423 if (!(peer->email = ast_strdup(v->value))) {
2424 ast_log(LOG_ERROR, "Could not allocate memory for email of "
2426 ooh323_delete_peer(peer);
2429 } else if (!strcasecmp(v->name, "url")) {
2430 if (!(peer->url = ast_strdup(v->value))) {
2431 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2433 ooh323_delete_peer(peer);
2436 } else if (!strcasecmp(v->name, "port")) {
2437 peer->port = atoi(v->value);
2438 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
2439 struct ast_sockaddr p;
2440 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2441 ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
2443 ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2446 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2447 peer->outgoinglimit = atoi(v->value);
2448 if (peer->outgoinglimit < 0)
2449 peer->outgoinglimit = 0;
2450 } else if (!strcasecmp(v->name, "accountcode")) {
2451 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
2452 } else if (!strcasecmp(v->name, "faststart")) {
2453 peer->faststart = ast_true(v->value);
2454 } else if (!strcasecmp(v->name, "h245tunneling")) {
2455 peer->h245tunneling = ast_true(v->value);
2456 } else if (!strcasecmp(v->name, "g729onlyA")) {
2457 peer->g729onlyA = ast_true(v->value);
2458 } else if (!strcasecmp(v->name, "rtptimeout")) {
2459 peer->rtptimeout = atoi(v->value);
2460 if(peer->rtptimeout < 0)
2461 peer->rtptimeout = gRTPTimeout;
2462 } else if (!strcasecmp(v->name, "rtpmask")) {
2463 if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2464 (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED)
2466 ast_mutex_init(&peer->rtpmask->lock);
2467 peer->rtpmask->inuse = 1;
2468 ast_copy_string(peer->rtpmaskstr, v->value,
2469 sizeof(peer->rtpmaskstr));
2470 } else peer->rtpmask = NULL;
2471 } else if (!strcasecmp(v->name, "disallow")) {
2472 ast_parse_allow_disallow(&peer->prefs, peer->cap,
2474 } else if (!strcasecmp(v->name, "allow")) {
2475 const char* tcodecs = v->value;
2476 if (!strcasecmp(v->value, "all")) {
2477 tcodecs = "ulaw,alaw,g729,g723,gsm";
2479 ast_parse_allow_disallow(&peer->prefs, peer->cap,
2481 } else if (!strcasecmp(v->name, "amaflags")) {
2482 peer->amaflags = ast_cdr_amaflags2int(v->value);
2483 } else if (!strcasecmp(v->name, "roundtrip")) {
2484 sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
2485 } else if (!strcasecmp(v->name, "dtmfmode")) {
2486 if (!strcasecmp(v->value, "rfc2833"))
2487 peer->dtmfmode = H323_DTMF_RFC2833;
2488 if (!strcasecmp(v->value, "cisco"))
2489 peer->dtmfmode = H323_DTMF_CISCO;
2490 else if (!strcasecmp(v->value, "q931keypad"))
2491 peer->dtmfmode = H323_DTMF_Q931;
2492 else if (!strcasecmp(v->value, "h245alphanumeric"))
2493 peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2494 else if (!strcasecmp(v->value, "h245signal"))
2495 peer->dtmfmode = H323_DTMF_H245SIGNAL;
2496 else if (!strcasecmp(v->value, "inband"))
2497 peer->dtmfmode = H323_DTMF_INBAND;
2498 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2499 peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2500 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2501 peer->dtmfcodec = atoi(v->value);
2502 } else if (!strcasecmp(v->name, "faxdetect")) {
2503 if (ast_true(v->value)) {
2504 peer->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2505 } else if (ast_false(v->value)) {
2506 peer->faxdetect = 0;
2508 char *buf = ast_strdupa(v->value);
2509 char *word, *next = buf;
2510 peer->faxdetect = 0;
2511 while ((word = strsep(&next, ","))) {
2512 if (!strcasecmp(word, "cng")) {
2513 peer->faxdetect |= FAXDETECT_CNG;
2514 } else if (!strcasecmp(word, "t38")) {
2515 peer->faxdetect |= FAXDETECT_T38;
2517 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2522 } else if (!strcasecmp(v->name, "t38support")) {
2523 if (!strcasecmp(v->value, "disabled"))
2524 peer->t38support = T38_DISABLED;
2525 if (!strcasecmp(v->value, "no"))
2526 peer->t38support = T38_DISABLED;
2527 else if (!strcasecmp(v->value, "faxgw"))
2528 peer->t38support = T38_FAXGW;
2529 else if (!strcasecmp(v->value, "yes"))
2530 peer->t38support = T38_ENABLED;
2537 ast_verbose("+++ build_peer\n");
2542 static int ooh323_do_reload(void)
2545 ast_verbose("--- ooh323_do_reload\n");
2551 ast_verbose("+++ ooh323_do_reload\n");
2557 /*--- h323_reload: Force reload of module from cli ---*/
2559 char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2564 e->command = "ooh323 reload";
2566 "Usage: ooh323 reload\n"
2567 " Reload OOH323 config.\n";
2574 return CLI_SHOWUSAGE;
2577 ast_verbose("--- ooh323_reload\n");
2579 ast_mutex_lock(&h323_reload_lock);
2580 if (h323_reloading) {
2581 ast_verbose("Previous OOH323 reload not yet done\n");
2585 ast_mutex_unlock(&h323_reload_lock);
2589 ast_verbose("+++ ooh323_reload\n");
2594 int reload_config(int reload)
2597 struct ooAliases *pNewAlias = NULL, *cur, *prev;
2598 struct ast_config *cfg;
2599 struct ast_variable *v;
2600 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2601 struct ooh323_user *user = NULL;
2602 struct ooh323_peer *peer = NULL;
2605 struct ast_format tmpfmt;
2608 ast_verbose("--- reload_config\n");
2610 cfg = ast_config_load((char*)config, config_flags);
2612 /* We *must* have a config file otherwise stop immediately */
2614 ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
2616 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
2617 return RESULT_SUCCESS;
2623 ast_verbose(" reload_config - Freeing up alias list\n");
2635 /* Inintialize everything to default */
2636 strcpy(gLogFile, DEFAULT_LOGFILE);
2639 strcpy(gCallerID, DEFAULT_H323ID);
2640 ast_format_cap_set(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
2641 memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
2642 gDTMFMode = H323_DTMF_RFC2833;
2644 gFAXdetect = FAXDETECT_CNG;
2645 gT38Support = T38_FAXGW;
2646 gTRCLVL = OOTRCLVLERR;
2647 gRasGkMode = RasNoGatekeeper;
2648 gGatekeeper[0] = '\0';
2652 strcpy(gAccountcode, DEFAULT_H323ACCNT);
2656 strcpy(gContext, DEFAULT_CONTEXT);
2658 gMediaWaitForConnect = 0;
2659 ooconfig.mTCPPortStart = 12030;
2660 ooconfig.mTCPPortEnd = 12230;
2661 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2663 v = ast_variable_browse(cfg, "general");
2666 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
2671 if (!strcasecmp(v->name, "port")) {
2672 gPort = (int)strtol(v->value, NULL, 10);
2673 } else if (!strcasecmp(v->name, "bindaddr")) {
2674 ast_copy_string(gIP, v->value, sizeof(gIP));
2675 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
2676 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
2679 if (ast_sockaddr_is_ipv6(&bindaddr)) {
2682 } else if (!strcasecmp(v->name, "h225portrange")) {
2685 ast_copy_string(temp, v->value, sizeof(temp));
2686 endlimit = strchr(temp, ',');
2690 ooconfig.mTCPPortStart = atoi(temp);
2691 ooconfig.mTCPPortEnd = atoi(endlimit);
2694 ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
2696 } else if (!strcasecmp(v->name, "gateway")) {
2697 gIsGateway = ast_true(v->value);
2698 } else if (!strcasecmp(v->name, "faststart")) {
2699 gFastStart = ast_true(v->value);
2701 ooH323EpEnableFastStart();
2703 ooH323EpDisableFastStart();
2704 } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
2705 gMediaWaitForConnect = ast_true(v->value);
2706 if (gMediaWaitForConnect)
2707 ooH323EpEnableMediaWaitForConnect();
2709 ooH323EpDisableMediaWaitForConnect();
2710 } else if (!strcasecmp(v->name, "h245tunneling")) {
2711 gTunneling = ast_true(v->value);
2713 ooH323EpEnableH245Tunneling();
2715 ooH323EpDisableH245Tunneling();
2716 } else if (!strcasecmp(v->name, "g729onlyA")) {
2717 g729onlyA = ast_true(v->value);
2718 } else if (!strcasecmp(v->name, "roundtrip")) {
2719 sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
2720 } else if (!strcasecmp(v->name, "trybemaster")) {
2721 gBeMaster = ast_true(v->value);
2723 ooH323EpTryBeMaster(1);
2725 ooH323EpTryBeMaster(0);
2726 } else if (!strcasecmp(v->name, "h323id")) {
2727 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2729 ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
2732 if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
2733 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2735 pNewAlias->type = T_H225AliasAddress_h323_ID;
2736 pNewAlias->value = strdup(v->value);
2737 pNewAlias->next = gAliasList;
2738 gAliasList = pNewAlias;
2740 } else if (!strcasecmp(v->name, "e164")) {
2741 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2743 ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
2746 pNewAlias->type = T_H225AliasAddress_dialedDigits;
2747 pNewAlias->value = strdup(v->value);
2748 pNewAlias->next = gAliasList;
2749 gAliasList = pNewAlias;
2751 } else if (!strcasecmp(v->name, "email")) {
2752 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2754 ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
2757 pNewAlias->type = T_H225AliasAddress_email_ID;
2758 pNewAlias->value = strdup(v->value);
2759 pNewAlias->next = gAliasList;
2760 gAliasList = pNewAlias;
2762 } else if (!strcasecmp(v->name, "t35country")) {
2763 t35countrycode = atoi(v->value);
2764 } else if (!strcasecmp(v->name, "t35extensions")) {
2765 t35extensions = atoi(v->value);
2766 } else if (!strcasecmp(v->name, "manufacturer")) {
2767 manufacturer = atoi(v->value);
2768 } else if (!strcasecmp(v->name, "vendorid")) {
2769 ast_copy_string(vendor, v->value, sizeof(vendor));
2770 } else if (!strcasecmp(v->name, "versionid")) {
2771 ast_copy_string(version, v->value, sizeof(version));
2772 } else if (!strcasecmp(v->name, "callerid")) {
2773 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2774 } else if (!strcasecmp(v->name, "incominglimit")) {
2775 gIncomingLimit = atoi(v->value);
2776 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2777 gOutgoingLimit = atoi(v->value);
2778 } else if (!strcasecmp(v->name, "gatekeeper")) {
2779 if (!strcasecmp(v->value, "DISABLE")) {
2780 gRasGkMode = RasNoGatekeeper;
2781 } else if (!strcasecmp(v->value, "DISCOVER")) {
2782 gRasGkMode = RasDiscoverGatekeeper;
2784 gRasGkMode = RasUseSpecificGatekeeper;
2785 strncpy(gGatekeeper, v->value, sizeof(gGatekeeper)-1);
2787 } else if (!strcasecmp(v->name, "logfile")) {
2788 strncpy(gLogFile, v->value, sizeof(gLogFile)-1);
2789 } else if (!strcasecmp(v->name, "context")) {
2790 strncpy(gContext, v->value, sizeof(gContext)-1);
2791 ast_verbose(VERBOSE_PREFIX_3 " == Setting default context to %s\n",
2793 } else if (!strcasecmp(v->name, "rtptimeout")) {
2794 gRTPTimeout = atoi(v->value);
2795 if (gRTPTimeout <= 0)
2797 } else if (!strcasecmp(v->name, "tos")) {
2798 if (sscanf(v->value, "%30i", &format) == 1)
2799 gTOS = format & 0xff;
2800 else if (!strcasecmp(v->value, "lowdelay"))
2801 gTOS = IPTOS_LOWDELAY;
2802 else if (!strcasecmp(v->value, "throughput"))
2803 gTOS = IPTOS_THROUGHPUT;
2804 else if (!strcasecmp(v->value, "reliability"))
2805 gTOS = IPTOS_RELIABILITY;
2806 else if (!strcasecmp(v->value, "mincost"))
2807 gTOS = IPTOS_MINCOST;
2808 else if (!strcasecmp(v->value, "none"))
2811 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be "
2812 "'lowdelay', 'throughput', 'reliability', "
2813 "'mincost', or 'none'\n", v->lineno);
2814 } else if (!strcasecmp(v->name, "amaflags")) {
2815 gAMAFLAGS = ast_cdr_amaflags2int(v->value);
2816 } else if (!strcasecmp(v->name, "accountcode")) {
2817 ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode));
2818 } else if (!strcasecmp(v->name, "disallow")) {
2819 ast_parse_allow_disallow(&gPrefs, gCap, v->value, 0);
2820 } else if (!strcasecmp(v->name, "allow")) {
2821 const char* tcodecs = v->value;
2822 if (!strcasecmp(v->value, "all")) {
2823 tcodecs = "ulaw,alaw,g729,g723,gsm";
2825 ast_parse_allow_disallow(&gPrefs, gCap, tcodecs, 1);
2826 } else if (!strcasecmp(v->name, "dtmfmode")) {
2827 if (!strcasecmp(v->value, "inband"))
2828 gDTMFMode = H323_DTMF_INBAND;
2829 else if (!strcasecmp(v->value, "rfc2833"))
2830 gDTMFMode = H323_DTMF_RFC2833;
2831 else if (!strcasecmp(v->value, "cisco"))
2832 gDTMFMode = H323_DTMF_CISCO;
2833 else if (!strcasecmp(v->value, "q931keypad"))
2834 gDTMFMode = H323_DTMF_Q931;
2835 else if (!strcasecmp(v->value, "h245alphanumeric"))
2836 gDTMFMode = H323_DTMF_H245ALPHANUMERIC;
2837 else if (!strcasecmp(v->value, "h245signal"))
2838 gDTMFMode = H323_DTMF_H245SIGNAL;
2840 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n",
2842 gDTMFMode = H323_DTMF_RFC2833;
2844 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2845 gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2846 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2847 gDTMFCodec = atoi(v->value);
2848 } else if (!strcasecmp(v->name, "faxdetect")) {
2849 if (ast_true(v->value)) {
2850 gFAXdetect = FAXDETECT_CNG | FAXDETECT_T38;
2851 } else if (ast_false(v->value)) {
2854 char *buf = ast_strdupa(v->value);
2855 char *word, *next = buf;
2857 while ((word = strsep(&next, ","))) {
2858 if (!strcasecmp(word, "cng")) {
2859 gFAXdetect |= FAXDETECT_CNG;
2860 } else if (!strcasecmp(word, "t38")) {
2861 gFAXdetect |= FAXDETECT_T38;
2863 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2868 } else if (!strcasecmp(v->name, "t38support")) {
2869 if (!strcasecmp(v->value, "disabled"))
2870 gT38Support = T38_DISABLED;
2871 if (!strcasecmp(v->value, "no"))
2872 gT38Support = T38_DISABLED;
2873 else if (!strcasecmp(v->value, "faxgw"))
2874 gT38Support = T38_FAXGW;
2875 else if (!strcasecmp(v->value, "yes"))
2876 gT38Support = T38_ENABLED;
2877 } else if (!strcasecmp(v->name, "tracelevel")) {
2878 gTRCLVL = atoi(v->value);
2879 ooH323EpSetTraceLevel(gTRCLVL);
2884 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
2885 if (strcasecmp(cat, "general")) {
2886 int friend_type = 0;
2887 utype = ast_variable_retrieve(cfg, cat, "type");
2889 friend_type = strcasecmp(utype, "friend");
2890 if (!strcmp(utype, "user") || 0 == friend_type) {
2891 user = build_user(cat, ast_variable_browse(cfg, cat));
2893 ast_mutex_lock(&userl.lock);
2894 user->next = userl.users;
2896 ast_mutex_unlock(&userl.lock);
2898 ast_log(LOG_WARNING, "Failed to build user %s\n", cat);
2901 if (!strcasecmp(utype, "peer") || 0 == friend_type) {
2902 peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type);
2904 ast_mutex_lock(&peerl.lock);
2905 peer->next = peerl.peers;
2907 ast_mutex_unlock(&peerl.lock);
2909 ast_log(LOG_WARNING, "Failed to build peer %s\n", cat);
2915 ast_config_destroy(cfg);
2918 /* Determine ip address if neccessary */
2919 if (ast_strlen_zero(gIP)) {
2920 ooGetLocalIPAddress(gIP);
2921 if (!strcmp(gIP, "127.0.0.1") || !strcmp(gIP, "::1")) {
2922 ast_log(LOG_NOTICE, "Failed to determine local ip address. Please "
2923 "specify it in ooh323.conf. OOH323 Disabled\n");
2929 ast_verbose("+++ reload_config\n");
2936 static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2939 struct ooh323_peer *prev = NULL, *peer = NULL;
2943 e->command = "ooh323 show peer";
2945 "Usage: ooh323 show peer <name>\n"
2946 " List details of specific OOH323 peer.\n";
2953 return CLI_SHOWUSAGE;
2955 ast_mutex_lock(&peerl.lock);
2958 ast_mutex_lock(&peer->lock);
2959 if (!strcmp(peer->name, a->argv[3])) {
2964 ast_mutex_unlock(&prev->lock);
2969 sprintf(ip_port, "%s:%d", peer->ip, peer->port);
2970 ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
2971 ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
2972 peer->h245tunneling?"yes":"no");