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>
24 #include "chan_ooh323.h"
27 #define FORMAT_STRING_SIZE 512
30 #define DEFAULT_CONTEXT "default"
31 #define DEFAULT_H323ID "Asterisk PBX"
32 #define DEFAULT_LOGFILE "/var/log/asterisk/h323_log"
33 #define DEFAULT_H323ACCNT "ast_h323"
36 #define H323_SILENCESUPPRESSION (1<<0)
37 #define H323_GKROUTED (1<<1)
38 #define H323_TUNNELING (1<<2)
39 #define H323_FASTSTART (1<<3)
40 #define H323_OUTGOING (1<<4)
41 #define H323_ALREADYGONE (1<<5)
42 #define H323_NEEDDESTROY (1<<6)
43 #define H323_DISABLEGK (1<<7)
44 #define H323_NEEDSTART (1<<8)
47 #define T38TOAUDIOTIMEOUT 30
48 #define T38_DISABLED 0
52 /* Channel description */
53 static const char type[] = "OOH323";
54 static const char tdesc[] = "Objective Systems H323 Channel Driver";
55 static const char config[] = "ooh323.conf";
57 struct ast_module *myself;
59 static struct ast_jb_conf default_jbconf =
63 .resync_threshold = -1,
66 static struct ast_jb_conf global_jbconf;
68 /* Channel Definition */
69 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
70 const struct ast_channel *requestor, void *data, int *cause);
71 static int ooh323_digit_begin(struct ast_channel *ast, char digit);
72 static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
73 static int ooh323_call(struct ast_channel *ast, char *dest, int timeout);
74 static int ooh323_hangup(struct ast_channel *ast);
75 static int ooh323_answer(struct ast_channel *ast);
76 static struct ast_frame *ooh323_read(struct ast_channel *ast);
77 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f);
78 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
79 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
80 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
82 static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
83 static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
84 static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
85 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active);
87 static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan);
88 static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
90 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
92 struct ooh323_peer *find_friend(const char *name, int port);
95 static struct ast_channel_tech ooh323_tech = {
98 .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
99 .requester = ooh323_request,
100 .send_digit_begin = ooh323_digit_begin,
101 .send_digit_end = ooh323_digit_end,
103 .hangup = ooh323_hangup,
104 .answer = ooh323_answer,
106 .write = ooh323_write,
107 .exception = ooh323_read,
108 .indicate = ooh323_indicate,
109 .fixup = ooh323_fixup,
111 .queryoption = ooh323_queryoption,
112 .bridge = ast_rtp_instance_bridge, /* XXX chan unlocked ? */
113 .early_bridge = ast_rtp_instance_early_bridge,
117 static struct ast_rtp_glue ooh323_rtp = {
119 .get_rtp_info = ooh323_get_rtp_peer,
120 .get_vrtp_info = ooh323_get_vrtp_peer,
121 .update_peer = ooh323_set_rtp_peer,
124 static struct ast_udptl_protocol ooh323_udptl = {
126 get_udptl_info: ooh323_get_udptl_peer,
127 set_udptl_peer: ooh323_set_udptl_peer,
134 /* H.323 channel private structure */
135 static struct ooh323_pvt {
136 ast_mutex_t lock; /* Channel private lock */
137 struct ast_rtp_instance *rtp;
138 struct ast_rtp_instance *vrtp; /* Placeholder for now */
140 int t38support; /* T.38 mode - disable, transparent, faxgw */
142 struct ast_udptl *udptl;
146 struct ast_sockaddr udptlredirip;
150 struct ast_channel *owner; /* Master Channel */
152 char *user; /* cooperating user/peer */
158 unsigned int call_reference;
164 char caller_h323id[AST_MAX_EXTENSION];
165 char caller_dialedDigits[AST_MAX_EXTENSION];
166 char caller_email[AST_MAX_EXTENSION];
167 char caller_url[256];
168 char callee_h323id[AST_MAX_EXTENSION];
169 char callee_dialedDigits[AST_MAX_EXTENSION];
170 char callee_email[AST_MAX_EXTENSION];
171 char callee_url[AST_MAX_EXTENSION];
174 struct ast_format readformat; /* negotiated read format */
175 struct ast_format writeformat; /* negotiated write format */
176 struct ast_format_cap *cap;
177 struct ast_codec_pref prefs;
180 char exten[AST_MAX_EXTENSION]; /* Requested extension */
181 char context[AST_MAX_EXTENSION]; /* Context where to start */
182 char accountcode[256]; /* Account code */
185 int progsent; /* progress is sent */
186 int alertsent; /* alerting is sent */
187 int g729onlyA; /* G.729 only A */
189 struct OOH323Regex *rtpmask; /* rtp ip regexp */
190 char rtpmaskstr[120];
191 int rtdrcount, rtdrinterval; /* roundtripdelayreq */
192 int faststart, h245tunneling; /* faststart & h245 tunneling */
193 struct ooh323_pvt *next; /* Next entity */
196 /* Protect the channel/interface list (ooh323_pvt) */
197 AST_MUTEX_DEFINE_STATIC(iflock);
199 /* Profile of H.323 user registered with PBX*/
203 char context[AST_MAX_EXTENSION];
206 char accountcode[20];
208 struct ast_format_cap *cap;
209 struct ast_codec_pref prefs;
214 int mUseIP; /* Use IP address or H323-ID to search user */
215 char mIP[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
216 struct OOH323Regex *rtpmask;
217 char rtpmaskstr[120];
218 int rtdrcount, rtdrinterval;
219 int faststart, h245tunneling;
221 struct ooh323_user *next;
224 /* Profile of valid asterisk peers */
228 unsigned outgoinglimit;
230 struct ast_format_cap *cap;
231 struct ast_codec_pref prefs;
232 char accountcode[20];
237 int mFriend; /* indicates defined as friend */
238 char ip[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
240 char *h323id; /* H323-ID alias, which asterisk will register with gk to reach this peer*/
241 char *email; /* Email alias, which asterisk will register with gk to reach this peer*/
242 char *url; /* url alias, which asterisk will register with gk to reach this peer*/
243 char *e164; /* e164 alias, which asterisk will register with gk to reach this peer*/
245 struct OOH323Regex *rtpmask;
246 char rtpmaskstr[120];
247 int rtdrcount,rtdrinterval;
248 int faststart, h245tunneling;
250 struct ooh323_peer *next;
254 /* List of H.323 users known to PBX */
255 static struct ast_user_list {
256 struct ooh323_user *users;
260 static struct ast_peer_list {
261 struct ooh323_peer *peers;
265 /* Mutex to protect H.323 reload process */
266 static int h323_reloading = 0;
267 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
269 /* Mutex to protect usage counter */
270 static int usecnt = 0;
271 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
273 AST_MUTEX_DEFINE_STATIC(ooh323c_cmd_lock);
275 static long callnumber = 0;
276 AST_MUTEX_DEFINE_STATIC(ooh323c_cn_lock);
278 /* stack callbacks */
279 int onAlerting(ooCallData *call);
280 int onProgress(ooCallData *call);
281 int onNewCallCreated(ooCallData *call);
282 int onOutgoingCall(ooCallData *call);
283 int onCallEstablished(ooCallData *call);
284 int onCallCleared(ooCallData *call);
285 void onModeChanged(ooCallData *call, int t38mode);
287 static char gLogFile[256] = DEFAULT_LOGFILE;
288 static int gPort = 1720;
289 static char gIP[2+8*4+7]; /* Max for IPv6 addr */
290 struct ast_sockaddr bindaddr;
292 static char gCallerID[AST_MAX_EXTENSION] = "";
293 static struct ooAliases *gAliasList;
294 static struct ast_format_cap *gCap;
295 static struct ast_codec_pref gPrefs;
296 static int gDTMFMode = H323_DTMF_RFC2833;
297 static int gDTMFCodec = 101;
298 static int gT38Support = T38_FAXGW;
299 static char gGatekeeper[100];
300 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
302 static int gIsGateway = 0;
303 static int gFastStart = 1;
304 static int gTunneling = 1;
305 static int gBeMaster = 0;
306 static int gMediaWaitForConnect = 0;
308 static int gRTPTimeout = 60;
309 static int g729onlyA = 0;
310 static char gAccountcode[80] = DEFAULT_H323ACCNT;
311 static int gAMAFLAGS;
312 static char gContext[AST_MAX_EXTENSION] = DEFAULT_CONTEXT;
313 static int gIncomingLimit = 1024;
314 static int gOutgoingLimit = 1024;
315 OOBOOL gH323Debug = FALSE;
316 static int gTRCLVL = OOTRCLVLERR;
317 static int gRTDRCount = 0, gRTDRInterval = 0;
319 static int t35countrycode = 0;
320 static int t35extensions = 0;
321 static int manufacturer = 0;
322 static char vendor[AST_MAX_EXTENSION] = "";
323 static char version[AST_MAX_EXTENSION] = "";
325 static struct ooh323_config
331 /** Asterisk RTP stuff*/
332 static struct ast_sched_context *sched;
333 static struct io_context *io;
335 /* Protect the monitoring thread, so only one process can kill or start it,
336 and not when it's doing something critical. */
337 AST_MUTEX_DEFINE_STATIC(monlock);
340 /* This is the thread for the monitor which checks for input on the channels
341 which are not currently in use. */
342 static pthread_t monitor_thread = AST_PTHREADT_NULL;
345 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
346 const char *host, struct ast_format_cap *cap, const char *linkedid)
348 struct ast_channel *ch = NULL;
349 struct ast_format tmpfmt;
351 ast_verbose("--- ooh323_new - %s\n", host);
353 ast_format_clear(&tmpfmt);
354 /* Don't hold a h323 pvt lock while we allocate a channel */
355 ast_mutex_unlock(&i->lock);
356 ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,
357 i->accountcode, i->exten, i->context, linkedid, i->amaflags,
358 "OOH323/%s-%ld", host, callnumber);
359 ast_mutex_lock(&ooh323c_cn_lock);
361 ast_mutex_unlock(&ooh323c_cn_lock);
363 ast_mutex_lock(&i->lock);
366 ast_channel_lock(ch);
367 ch->tech = &ooh323_tech;
370 ast_best_codec(cap, &tmpfmt);
372 ast_codec_pref_index(&i->prefs, 0, &tmpfmt);
374 ast_format_cap_add(ch->nativeformats, &tmpfmt);
375 ast_format_copy(&ch->rawwriteformat, &tmpfmt);
376 ast_format_copy(&ch->rawreadformat, &tmpfmt);
378 ast_jb_configure(ch, &global_jbconf);
380 if (state == AST_STATE_RING)
383 ch->adsicpe = AST_ADSI_UNAVAILABLE;
384 ast_set_write_format(ch, &tmpfmt);
385 ast_set_read_format(ch, &tmpfmt);
388 ast_module_ref(myself);
390 /* Allocate dsp for in-band DTMF support */
391 if (i->dtmfmode & H323_DTMF_INBAND) {
392 i->vad = ast_dsp_new();
393 ast_dsp_set_features(i->vad, DSP_FEATURE_DIGIT_DETECT);
394 ast_dsp_set_features(i->vad,
395 DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT);
396 ast_dsp_set_faxmode(i->vad,
397 DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
399 if (i->dtmfmode & H323_DTMF_INBANDRELAX)
400 ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
403 ast_mutex_lock(&usecnt_lock);
405 ast_mutex_unlock(&usecnt_lock);
407 /* Notify the module monitors that use count for resource has changed*/
408 ast_update_use_count();
410 ast_copy_string(ch->context, i->context, sizeof(ch->context));
411 ast_copy_string(ch->exten, i->exten, sizeof(ch->exten));
415 if(!ast_test_flag(i, H323_OUTGOING)) {
417 if (!ast_strlen_zero(i->caller_h323id)) {
418 pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
421 if (!ast_strlen_zero(i->caller_dialedDigits)) {
422 pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS",
423 i->caller_dialedDigits);
425 if (!ast_strlen_zero(i->caller_email)) {
426 pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL",
429 if (!ast_strlen_zero(i->caller_url)) {
430 pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url);
434 if (!ast_strlen_zero(i->accountcode))
435 ast_string_field_set(ch, accountcode, i->accountcode);
438 ch->amaflags = i->amaflags;
440 ast_setstate(ch, state);
441 if (state != AST_STATE_DOWN) {
442 if (ast_pbx_start(ch)) {
443 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
444 ast_channel_unlock(ch);
450 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", "Channel: %s\r\nChanneltype: %s\r\n"
451 "CallRef: %d\r\n", ch->name, "OOH323", i->call_reference);
453 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
456 if(ch) ast_channel_unlock(ch);
459 ast_verbose("+++ h323_new\n");
466 static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
468 struct ooh323_pvt *pvt = NULL;
471 ast_verbose("--- ooh323_alloc\n");
473 if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
474 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
477 if (!(pvt->cap = ast_format_cap_alloc_nolock())) {
479 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
483 ast_mutex_init(&pvt->lock);
484 ast_mutex_lock(&pvt->lock);
487 pvt->t38support = gT38Support;
488 pvt->rtptimeout = gRTPTimeout;
489 pvt->rtdrinterval = gRTDRInterval;
490 pvt->rtdrcount = gRTDRCount;
491 pvt->g729onlyA = g729onlyA;
493 pvt->call_reference = callref;
495 pvt->callToken = strdup(callToken);
497 /* whether to use gk for this call */
498 if (gRasGkMode == RasNoGatekeeper)
499 OO_SETFLAG(pvt->flags, H323_DISABLEGK);
501 pvt->dtmfmode = gDTMFMode;
502 pvt->dtmfcodec = gDTMFCodec;
503 ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
504 ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
506 pvt->amaflags = gAMAFLAGS;
507 ast_format_cap_copy(pvt->cap, gCap);
508 memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
510 ast_mutex_unlock(&pvt->lock);
511 /* Add to interface list */
512 ast_mutex_lock(&iflock);
515 ast_mutex_unlock(&iflock);
518 ast_verbose("+++ ooh323_alloc\n");
525 Possible data values - peername, exten/peername, exten@ip
527 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
528 const struct ast_channel *requestor, void *data, int *cause)
531 struct ast_channel *chan = NULL;
532 struct ooh323_pvt *p = NULL;
533 struct ooh323_peer *peer = NULL;
537 char formats[FORMAT_STRING_SIZE];
541 ast_verbose("--- ooh323_request - data %s format %s\n", (char*)data,
542 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
544 if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
545 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
549 p = ooh323_alloc(0,0); /* Initial callRef is zero */
552 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char*)data);
555 ast_mutex_lock(&p->lock);
557 /* This is an outgoing call, since ooh323_request is called */
558 ast_set_flag(p, H323_OUTGOING);
561 ast_copy_string(tmp, data, sizeof(tmp));
563 dest = strchr(tmp, '/');
570 } else if ((dest = strchr(tmp, '@'))) {
580 if ((sport = strchr(dest, ':'))) {
588 peer = find_peer(dest, port);
590 ast_mutex_lock(&iflock);
591 ast_mutex_unlock(&p->lock);
593 ast_mutex_unlock(&iflock);
594 ast_log(LOG_ERROR, "Destination format is not supported\n");
599 p->username = strdup(peer->name);
600 p->host = strdup(peer->ip);
601 p->port = peer->port;
602 /* Disable gk as we are going to call a known peer*/
603 /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
606 ast_copy_string(p->exten, ext, sizeof(p->exten));
608 ast_format_cap_copy(p->cap, peer->cap);
609 memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
610 p->g729onlyA = peer->g729onlyA;
611 p->dtmfmode |= peer->dtmfmode;
612 p->dtmfcodec = peer->dtmfcodec;
613 p->t38support = peer->t38support;
614 p->rtptimeout = peer->rtptimeout;
615 p->faststart = peer->faststart;
616 p->h245tunneling = peer->h245tunneling;
617 if (peer->rtpmask && peer->rtpmaskstr[0]) {
618 p->rtpmask = peer->rtpmask;
619 ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
622 if (peer->rtdrinterval) {
623 p->rtdrinterval = peer->rtdrinterval;
624 p->rtdrcount = peer->rtdrcount;
627 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
628 p->amaflags = peer->amaflags;
630 if (gRasGkMode == RasNoGatekeeper) {
631 /* no gk and no peer */
632 ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
633 ast_mutex_lock(&iflock);
634 ast_mutex_unlock(&p->lock);
636 ast_mutex_unlock(&iflock);
639 p->g729onlyA = g729onlyA;
640 p->dtmfmode = gDTMFMode;
641 p->dtmfcodec = gDTMFCodec;
642 p->t38support = gT38Support;
643 p->rtptimeout = gRTPTimeout;
644 ast_format_cap_copy(p->cap, gCap);
645 p->rtdrinterval = gRTDRInterval;
646 p->rtdrcount = gRTDRCount;
647 p->faststart = gFastStart;
648 p->h245tunneling = gTunneling;
650 memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));
651 p->username = strdup(dest);
653 p->host = strdup(dest);
658 ast_copy_string(p->exten, ext, sizeof(p->exten));
663 chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
664 requestor ? requestor->linkedid : NULL);
666 ast_mutex_unlock(&p->lock);
669 ast_mutex_lock(&iflock);
671 ast_mutex_unlock(&iflock);
673 ast_mutex_lock(&p->lock);
674 p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
676 ast_mutex_unlock(&p->lock);
677 ast_mutex_lock(&iflock);
679 ast_mutex_unlock(&iflock);
680 ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
684 ast_mutex_unlock(&p->lock);
685 ast_mutex_lock(&ooh323c_cmd_lock);
686 ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
687 ast_mutex_unlock(&ooh323c_cmd_lock);
692 ast_verbose("+++ ooh323_request\n");
699 static struct ooh323_pvt* find_call(ooCallData *call)
701 struct ooh323_pvt *p;
704 ast_verbose("--- find_call\n");
706 ast_mutex_lock(&iflock);
708 for (p = iflist; p; p = p->next) {
709 if (p->callToken && !strcmp(p->callToken, call->callToken)) {
713 ast_mutex_unlock(&iflock);
716 ast_verbose("+++ find_call\n");
721 struct ooh323_user *find_user(const char * name, const char* ip)
723 struct ooh323_user *user;
726 ast_verbose("--- find_user: %s, %s\n",name,ip);
728 ast_mutex_lock(&userl.lock);
730 for (user = userl.users; user; user = user->next) {
731 if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
734 if (name && !strcmp(user->name, name)) {
739 ast_mutex_unlock(&userl.lock);
742 ast_verbose("+++ find_user\n");
747 struct ooh323_peer *find_friend(const char *name, int port)
749 struct ooh323_peer *peer;
752 ast_verbose("--- find_friend \"%s\"\n", name);
755 ast_mutex_lock(&peerl.lock);
756 for (peer = peerl.peers; peer; peer = peer->next) {
758 ast_verbose(" comparing with \"%s\"\n", peer->ip);
760 if (!strcmp(peer->ip, name)) {
761 if (port <= 0 || (port > 0 && peer->port == port)) {
766 ast_mutex_unlock(&peerl.lock);
770 ast_verbose(" found matching friend\n");
772 ast_verbose("+++ find_friend \"%s\"\n", name);
779 struct ooh323_peer *find_peer(const char * name, int port)
781 struct ooh323_peer *peer;
784 ast_verbose("--- find_peer \"%s\"\n", name);
787 ast_mutex_lock(&peerl.lock);
788 for (peer = peerl.peers; peer; peer = peer->next) {
790 ast_verbose(" comparing with \"%s\"\n", peer->ip);
792 if (!strcasecmp(peer->name, name))
794 if (peer->h323id && !strcasecmp(peer->h323id, name))
796 if (peer->e164 && !strcasecmp(peer->e164, name))
799 if (!strcmp(peer->ip, name)) {
800 if (port > 0 && peer->port == port) { break; }
801 else if (port <= 0) { break; }
805 ast_mutex_unlock(&peerl.lock);
809 ast_verbose(" found matching peer\n");
811 ast_verbose("+++ find_peer \"%s\"\n", name);
817 static int ooh323_digit_begin(struct ast_channel *chan, char digit)
820 struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
823 ast_verbose("--- ooh323_digit_begin\n");
826 ast_log(LOG_ERROR, "No private structure for call\n");
829 ast_mutex_lock(&p->lock);
832 if (digit == 'e' && !p->faxmode && p->t38support != T38_DISABLED) {
833 if (!p->chmodepend) {
835 ast_verbose("request to change %s to t.38 because fax cng\n",
838 ooRequestChangeMode(p->callToken, 1);
841 } else if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
842 ast_rtp_instance_dtmf_begin(p->rtp, digit);
843 } else if (((p->dtmfmode & H323_DTMF_Q931) ||
844 (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
845 (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
848 ooSendDTMFDigit(p->callToken, dtmf);
850 ast_mutex_unlock(&p->lock);
852 ast_verbose("+++ ooh323_digit_begin\n");
857 static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
859 struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
862 ast_verbose("--- ooh323_digit_end\n");
865 ast_log(LOG_ERROR, "No private structure for call\n");
868 ast_mutex_lock(&p->lock);
869 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) )
870 ast_rtp_instance_dtmf_end(p->rtp, digit);
872 ast_mutex_unlock(&p->lock);
874 ast_verbose("+++ ooh323_digit_end\n");
880 static int ooh323_call(struct ast_channel *ast, char *dest, int timeout)
882 struct ooh323_pvt *p = ast->tech_pvt;
883 char destination[256];
885 const char *val = NULL;
886 ooCallOptions opts = {
890 .callMode = OO_CALLMODE_AUDIOCALL,
895 ast_verbose("--- ooh323_call- %s\n", dest);
898 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
899 ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
900 "reserved\n", ast->name);
903 ast_mutex_lock(&p->lock);
904 ast_set_flag(p, H323_OUTGOING);
905 if (ast->connected.id.number.valid && ast->connected.id.number.str) {
906 free(p->callerid_num);
907 p->callerid_num = strdup(ast->connected.id.number.str);
910 if (ast->connected.id.name.valid && ast->connected.id.name.str) {
911 free(p->callerid_name);
912 p->callerid_name = strdup(ast->connected.id.name.str);
913 } else if (ast->connected.id.number.valid && ast->connected.id.number.str) {
914 free(p->callerid_name);
915 p->callerid_name = strdup(ast->connected.id.number.str);
917 ast->connected.id.name.valid = 1;
918 free(ast->connected.id.name.str);
919 ast->connected.id.name.str = strdup(gCallerID);
920 free(p->callerid_name);
921 p->callerid_name = strdup(ast->connected.id.name.str);
927 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
928 ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
931 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
932 ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
934 p->callerid_num = strdup(val);
937 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
938 ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
941 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
942 ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
945 if (p->host && p->port != 0)
946 snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
948 snprintf(destination, sizeof(destination), "%s", p->host);
950 ast_copy_string(destination, dest, sizeof(destination));
952 destination[sizeof(destination)-1]='\0';
954 opts.transfercap = ast->transfercapability;
955 opts.fastStart = p->faststart;
956 opts.tunneling = p->h245tunneling;
958 for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
960 if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
961 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
963 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
966 ast_mutex_unlock(&p->lock);
968 ast_log(LOG_ERROR, "Failed to make call\n");
969 return -1; /* ToDO: cleanup */
972 ast_verbose("+++ ooh323_call\n");
977 static int ooh323_hangup(struct ast_channel *ast)
979 struct ooh323_pvt *p = ast->tech_pvt;
980 int q931cause = AST_CAUSE_NORMAL_CLEARING;
983 ast_verbose("--- ooh323_hangup\n");
986 ast_mutex_lock(&p->lock);
988 if (ast->hangupcause) {
989 q931cause = ast->hangupcause;
991 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
993 if (!strcmp(cause, "CONGESTION")) {
994 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
995 } else if (!strcmp(cause, "BUSY")) {
996 q931cause = AST_CAUSE_USER_BUSY;
997 } else if (!strcmp(cause, "CHANISUNVAIL")) {
998 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
999 } else if (!strcmp(cause, "NOANSWER")) {
1000 q931cause = AST_CAUSE_NO_ANSWER;
1001 } else if (!strcmp(cause, "CANCEL")) {
1002 q931cause = AST_CAUSE_CALL_REJECTED;
1010 ast_verbose(" hanging %s with cause: %d\n", p->username, q931cause);
1011 ast->tech_pvt = NULL;
1012 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1013 ooHangCall(p->callToken,
1014 ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
1015 ast_set_flag(p, H323_ALREADYGONE);
1016 /* ast_mutex_unlock(&p->lock); */
1018 ast_set_flag(p, H323_NEEDDESTROY);
1019 /* detach channel here */
1021 p->owner->tech_pvt = NULL;
1023 ast_module_unref(myself);
1026 ast_mutex_unlock(&p->lock);
1027 ast_mutex_lock(&usecnt_lock);
1029 ast_mutex_unlock(&usecnt_lock);
1031 /* Notify the module monitors that use count for resource has changed */
1032 ast_update_use_count();
1035 ast_debug(1, "No call to hangup\n" );
1039 ast_verbose("+++ ooh323_hangup\n");
1044 static int ooh323_answer(struct ast_channel *ast)
1046 struct ooh323_pvt *p = ast->tech_pvt;
1049 ast_verbose("--- ooh323_answer\n");
1053 ast_mutex_lock(&p->lock);
1054 if (ast->_state != AST_STATE_UP) {
1055 ast_channel_lock(ast);
1056 ast_setstate(ast, AST_STATE_UP);
1058 ast_debug(1, "ooh323_answer(%s)\n", ast->name);
1059 ast_channel_unlock(ast);
1060 ooAnswerCall(p->callToken);
1062 ast_mutex_unlock(&p->lock);
1066 ast_verbose("+++ ooh323_answer\n");
1071 static struct ast_frame *ooh323_read(struct ast_channel *ast)
1073 struct ast_frame *fr;
1074 static struct ast_frame null_frame = { AST_FRAME_NULL, };
1075 struct ooh323_pvt *p = ast->tech_pvt;
1077 if (!p) return &null_frame;
1079 ast_mutex_lock(&p->lock);
1081 fr = ooh323_rtp_read(ast, p);
1084 /* time(&p->lastrtprx); */
1085 ast_mutex_unlock(&p->lock);
1089 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
1091 struct ooh323_pvt *p = ast->tech_pvt;
1096 ast_mutex_lock(&p->lock);
1098 if (f->frametype == AST_FRAME_MODEM) {
1099 ast_debug(1, "Send UDPTL %d/%d len %d for %s\n",
1100 f->frametype, f->subclass.integer, f->datalen, ast->name);
1102 res = ast_udptl_write(p->udptl, f);
1103 ast_mutex_unlock(&p->lock);
1108 if (f->frametype == AST_FRAME_VOICE) {
1109 /* sending progress for first */
1110 if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
1112 ooManualProgress(p->callToken);
1117 if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
1118 if (!(ast_format_cap_is_empty(ast->nativeformats))) {
1119 ast_log(LOG_WARNING,
1120 "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1121 ast_getformatname(&f->subclass.format),
1122 ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
1123 ast_getformatname(&ast->readformat),
1124 ast_getformatname(&ast->writeformat));
1126 ast_set_write_format(ast, &f->subclass.format);
1128 /* ast_set_write_format(ast, f->subclass);
1129 ast->nativeformats = f->subclass; */
1131 ast_mutex_unlock(&p->lock);
1136 res = ast_rtp_instance_write(p->rtp, f);
1138 ast_mutex_unlock(&p->lock);
1140 } else if (f->frametype == AST_FRAME_IMAGE) {
1141 ast_mutex_unlock(&p->lock);
1144 ast_log(LOG_WARNING, "Can't send %d type frames with OOH323 write\n",
1146 ast_mutex_unlock(&p->lock);
1155 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1158 struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
1159 char *callToken = (char *)NULL;
1164 ast_mutex_lock(&p->lock);
1165 callToken = (p->callToken ? strdup(p->callToken) : NULL);
1166 ast_mutex_unlock(&p->lock);
1170 ast_verbose(" ooh323_indicate - No callToken\n");
1175 ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken);
1177 ast_mutex_lock(&p->lock);
1178 switch (condition) {
1179 case AST_CONTROL_CONGESTION:
1180 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1181 ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED,
1182 AST_CAUSE_SWITCH_CONGESTION);
1183 ast_set_flag(p, H323_ALREADYGONE);
1186 case AST_CONTROL_BUSY:
1187 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1188 ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
1189 ast_set_flag(p, H323_ALREADYGONE);
1192 case AST_CONTROL_HOLD:
1193 ast_moh_start(ast, data, NULL);
1195 case AST_CONTROL_UNHOLD:
1198 case AST_CONTROL_PROGRESS:
1199 if (ast->_state != AST_STATE_UP) {
1202 ast_debug(1, "Sending manual progress for %s, res = %d\n", callToken,
1203 ooManualProgress(callToken));
1205 ooManualProgress(callToken);
1211 case AST_CONTROL_RINGING:
1212 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) {
1213 if (!p->alertsent) {
1215 ast_debug(1, "Sending manual ringback for %s, res = %d\n",
1217 ooManualRingback(callToken));
1219 ooManualRingback(callToken);
1225 case AST_CONTROL_SRCUPDATE:
1227 ast_rtp_instance_update_source(p->rtp);
1230 case AST_CONTROL_SRCCHANGE:
1232 ast_rtp_instance_change_source(p->rtp);
1235 case AST_CONTROL_CONNECTED_LINE:
1236 if (!ast->connected.id.name.valid
1237 || ast_strlen_zero(ast->connected.id.name.str)) {
1241 ast_debug(1, "Sending connected line info for %s (%s)\n",
1242 callToken, ast->connected.id.name.str);
1244 ooSetANI(callToken, ast->connected.id.name.str);
1247 case AST_CONTROL_T38_PARAMETERS:
1248 if (p->t38support != T38_ENABLED) {
1249 struct ast_control_t38_parameters parameters = { .request_response = 0 };
1250 parameters.request_response = AST_T38_REFUSED;
1251 ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
1252 ¶meters, sizeof(parameters));
1255 if (datalen != sizeof(struct ast_control_t38_parameters)) {
1256 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
1257 "Expected %d, got %d\n",
1258 (int)sizeof(enum ast_control_t38), (int)datalen);
1260 const struct ast_control_t38_parameters *parameters = data;
1261 enum ast_control_t38 message = parameters->request_response;
1264 case AST_T38_REQUEST_NEGOTIATE:
1266 if (!p->chmodepend && !p->faxmode) {
1267 ooRequestChangeMode(p->callToken, 1);
1273 case AST_T38_REQUEST_TERMINATE:
1275 if (!p->chmodepend && p->faxmode) {
1276 ooRequestChangeMode(p->callToken, 0);
1290 case AST_CONTROL_PROCEEDING:
1294 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
1295 condition, callToken);
1298 ast_mutex_unlock(&p->lock);
1301 ast_verbose("++++ ooh323_indicate %d on %s\n", condition, callToken);
1307 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1310 struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
1312 enum ast_t38_state state = T38_STATE_UNAVAILABLE;
1317 ast_mutex_lock(&p->lock);
1320 ast_verbose("----- ooh323_queryoption %d on channel %s\n", option, ast->name);
1324 case AST_OPTION_T38_STATE:
1326 if (*datalen != sizeof(enum ast_t38_state)) {
1327 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
1328 " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
1331 if (p->t38support != T38_DISABLED)
1332 state = T38_STATE_UNKNOWN;
1334 state = (p->chmodepend) ? T38_STATE_UNKNOWN : T38_STATE_NEGOTIATED;
1335 else if (p->chmodepend)
1336 state = T38_STATE_NEGOTIATING;
1339 *((enum ast_t38_state *) data) = state;
1344 case AST_OPTION_DIGIT_DETECT:
1347 *cp = p->vad ? 1 : 0;
1348 ast_debug(1, "Reporting digit detection %sabled on %s\n",
1349 *cp ? "en" : "dis", ast->name);
1359 ast_verbose("+++++ ooh323_queryoption %d on channel %s\n", option, ast->name);
1361 ast_mutex_unlock(&p->lock);
1368 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1370 struct ooh323_pvt *p = newchan->tech_pvt;
1375 ast_verbose("--- ooh323c ooh323_fixup\n");
1377 ast_mutex_lock(&p->lock);
1378 if (p->owner != oldchan) {
1379 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
1380 ast_mutex_unlock(&p->lock);
1384 if (p->owner == oldchan) {
1390 ast_mutex_unlock(&p->lock);
1393 ast_verbose("+++ ooh323c ooh323_fixup \n");
1399 void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
1401 struct ooh323_pvt *p = NULL;
1402 char formats[FORMAT_STRING_SIZE];
1405 ast_verbose("--- ooh323_update_writeformat %s/%d\n",
1406 ast_getformatname(fmt), txframes);
1408 p = find_call(call);
1410 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1414 ast_mutex_lock(&p->lock);
1416 ast_format_copy(&(p->writeformat), fmt);
1419 while (p->owner && ast_channel_trylock(p->owner)) {
1420 ast_debug(1,"Failed to grab lock, trying again\n");
1421 DEADLOCK_AVOIDANCE(&p->lock);
1424 ast_mutex_unlock(&p->lock);
1425 ast_log(LOG_ERROR, "Channel has no owner\n");
1429 ast_verbose("Writeformat before update %s/%s\n",
1430 ast_getformatname(&p->owner->writeformat),
1431 ast_getformatname_multiple(formats, sizeof(formats), p->owner->nativeformats));
1433 ast_codec_pref_setsize(&p->prefs, fmt, txframes);
1434 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
1435 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
1436 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1437 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
1439 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
1440 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1441 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
1444 ast_format_cap_set(p->owner->nativeformats, fmt);
1445 ast_set_write_format(p->owner, &p->owner->writeformat);
1446 ast_set_read_format(p->owner, &p->owner->readformat);
1447 ast_channel_unlock(p->owner);
1449 ast_log(LOG_ERROR, "No owner found\n");
1452 ast_mutex_unlock(&p->lock);
1455 ast_verbose("+++ ooh323_update_writeformat\n");
1458 void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
1460 struct ooh323_pvt *p = NULL;
1463 ast_verbose("--- ooh323_update_readformat %s\n",
1464 ast_getformatname(fmt));
1466 p = find_call(call);
1468 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1472 ast_mutex_lock(&p->lock);
1474 ast_format_copy(&(p->readformat), fmt);
1477 while (p->owner && ast_channel_trylock(p->owner)) {
1478 ast_debug(1,"Failed to grab lock, trying again\n");
1479 DEADLOCK_AVOIDANCE(&p->lock);
1482 ast_mutex_unlock(&p->lock);
1483 ast_log(LOG_ERROR, "Channel has no owner\n");
1488 ast_verbose("Readformat before update %s\n",
1489 ast_getformatname(&p->owner->readformat));
1490 ast_format_cap_set(p->owner->nativeformats, fmt);
1491 ast_set_read_format(p->owner, &p->owner->readformat);
1492 ast_channel_unlock(p->owner);
1494 ast_log(LOG_ERROR, "No owner found\n");
1496 ast_mutex_unlock(&p->lock);
1499 ast_verbose("+++ ooh323_update_readformat\n");
1503 int onAlerting(ooCallData *call)
1505 struct ooh323_pvt *p = NULL;
1506 struct ast_channel *c = NULL;
1509 ast_verbose("--- onAlerting %s\n", call->callToken);
1511 p = find_call(call);
1514 ast_log(LOG_ERROR, "No matching call found\n");
1517 ast_mutex_lock(&p->lock);
1519 ast_mutex_unlock(&p->lock);
1520 ast_log(LOG_ERROR, "Channel has no owner\n");
1523 while (p->owner && ast_channel_trylock(p->owner)) {
1524 ast_debug(1, "Failed to grab lock, trying again\n");
1525 DEADLOCK_AVOIDANCE(&p->lock);
1528 ast_mutex_unlock(&p->lock);
1529 ast_log(LOG_ERROR, "Channel has no owner\n");
1534 if (call->remoteDisplayName) {
1535 struct ast_party_connected_line connected;
1536 struct ast_set_party_connected_line update_connected;
1538 memset(&update_connected, 0, sizeof(update_connected));
1539 update_connected.id.name = 1;
1540 ast_party_connected_line_init(&connected);
1541 connected.id.name.valid = 1;
1542 connected.id.name.str = (char *) call->remoteDisplayName;
1543 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1544 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1546 if (c->_state != AST_STATE_UP)
1547 ast_setstate(c, AST_STATE_RINGING);
1549 ast_queue_control(c, AST_CONTROL_RINGING);
1550 ast_channel_unlock(c);
1551 ast_mutex_unlock(&p->lock);
1554 ast_verbose("+++ onAlerting %s\n", call->callToken);
1559 int onProgress(ooCallData *call)
1561 struct ooh323_pvt *p = NULL;
1562 struct ast_channel *c = NULL;
1565 ast_verbose("--- onProgress %s\n", call->callToken);
1567 p = find_call(call);
1570 ast_log(LOG_ERROR, "No matching call found\n");
1573 ast_mutex_lock(&p->lock);
1575 ast_mutex_unlock(&p->lock);
1576 ast_log(LOG_ERROR, "Channel has no owner\n");
1579 while (p->owner && ast_channel_trylock(p->owner)) {
1580 ast_debug(1, "Failed to grab lock, trying again\n");
1581 DEADLOCK_AVOIDANCE(&p->lock);
1584 ast_mutex_unlock(&p->lock);
1585 ast_log(LOG_ERROR, "Channel has no owner\n");
1590 if (call->remoteDisplayName) {
1591 struct ast_party_connected_line connected;
1592 struct ast_set_party_connected_line update_connected;
1594 memset(&update_connected, 0, sizeof(update_connected));
1595 update_connected.id.name = 1;
1596 ast_party_connected_line_init(&connected);
1597 connected.id.name.valid = 1;
1598 connected.id.name.str = (char *) call->remoteDisplayName;
1599 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1600 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1602 if (c->_state != AST_STATE_UP)
1603 ast_setstate(c, AST_STATE_RINGING);
1605 ast_queue_control(c, AST_CONTROL_PROGRESS);
1606 ast_channel_unlock(c);
1607 ast_mutex_unlock(&p->lock);
1610 ast_verbose("+++ onProgress %s\n", call->callToken);
1616 * Callback for sending digits from H.323 up to asterisk
1619 int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
1621 struct ooh323_pvt *p = NULL;
1625 ast_debug(1, "Received Digit: %c\n", digit[0]);
1626 p = find_call(call);
1628 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1632 ast_log(LOG_ERROR, "Channel has no owner\n");
1635 ast_mutex_lock(&p->lock);
1636 memset(&f, 0, sizeof(f));
1637 f.frametype = AST_FRAME_DTMF;
1638 f.subclass.integer = digit[0];
1644 f.src = "SEND_DIGIT";
1646 while (p->owner && ast_channel_trylock(p->owner)) {
1647 ast_debug(1, "Failed to grab lock, trying again\n");
1648 DEADLOCK_AVOIDANCE(&p->lock);
1651 ast_mutex_unlock(&p->lock);
1652 ast_log(LOG_ERROR, "Channel has no owner\n");
1655 res = ast_queue_frame(p->owner, &f);
1656 ast_channel_unlock(p->owner);
1657 ast_mutex_unlock(&p->lock);
1661 int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
1663 struct ooh323_pvt *p = NULL;
1664 struct ooh323_user *user = NULL;
1665 struct ast_channel *c = NULL;
1666 ooAliases *alias = NULL;
1668 char number [OO_MAX_NUMBER_LENGTH];
1671 ast_verbose("--- ooh323_onReceivedSetup %s\n", call->callToken);
1674 if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
1675 ast_log(LOG_ERROR, "Failed to create a new call.\n");
1678 ast_mutex_lock(&p->lock);
1679 ast_clear_flag(p, H323_OUTGOING);
1682 if (call->remoteDisplayName) {
1683 p->callerid_name = strdup(call->remoteDisplayName);
1686 if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
1687 p->callerid_num = strdup(number);
1690 if (call->remoteAliases) {
1691 for (alias = call->remoteAliases; alias; alias = alias->next) {
1692 if (alias->type == T_H225AliasAddress_h323_ID) {
1693 if (!p->callerid_name) {
1694 p->callerid_name = strdup(alias->value);
1696 ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
1698 else if(alias->type == T_H225AliasAddress_dialedDigits)
1700 if(!p->callerid_num)
1701 p->callerid_num = strdup(alias->value);
1702 ast_copy_string(p->caller_dialedDigits, alias->value,
1703 sizeof(p->caller_dialedDigits));
1705 else if(alias->type == T_H225AliasAddress_email_ID)
1707 ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
1709 else if(alias->type == T_H225AliasAddress_url_ID)
1711 ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
1717 if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
1718 strncpy(p->exten, number, sizeof(p->exten)-1);
1720 update_our_aliases(call, p);
1721 if (!ast_strlen_zero(p->callee_dialedDigits)) {
1722 ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
1723 } else if(!ast_strlen_zero(p->callee_h323id)) {
1724 ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
1725 } else if(!ast_strlen_zero(p->callee_email)) {
1726 ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
1727 if ((at = strchr(p->exten, '@'))) {
1733 /* if no extension found, set to default 's' */
1734 if (ast_strlen_zero(p->exten)) {
1739 user = find_user(p->callerid_name, call->remoteIP);
1740 if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
1741 ast_mutex_lock(&user->lock);
1742 p->username = strdup(user->name);
1743 p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
1744 ast_strdup(user->name);
1745 ast_copy_string(p->context, user->context, sizeof(p->context));
1746 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
1747 p->amaflags = user->amaflags;
1748 ast_format_cap_copy(p->cap, user->cap);
1749 p->g729onlyA = user->g729onlyA;
1750 memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
1751 p->dtmfmode |= user->dtmfmode;
1752 p->dtmfcodec = user->dtmfcodec;
1753 p->t38support = user->t38support;
1754 p->rtptimeout = user->rtptimeout;
1755 p->h245tunneling = user->h245tunneling;
1756 p->faststart = user->faststart;
1759 OO_SETFLAG(call->flags, OO_M_FASTSTART);
1761 OO_CLRFLAG(call->flags, OO_M_FASTSTART);
1762 /* if we disable h245tun for this user then we clear flag */
1763 /* in any other case we don't must touch this */
1764 /* ie if we receive setup without h245tun but enabled
1765 we can't enable it per call */
1766 if (!p->h245tunneling)
1767 OO_CLRFLAG(call->flags, OO_M_TUNNELING);
1769 if (user->rtpmask && user->rtpmaskstr[0]) {
1770 p->rtpmask = user->rtpmask;
1771 ast_copy_string(p->rtpmaskstr, user->rtpmaskstr,
1772 sizeof(p->rtpmaskstr));
1774 if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
1775 p->rtdrcount = user->rtdrcount;
1776 p->rtdrinterval = user->rtdrinterval;
1778 if (user->incominglimit) user->inUse++;
1779 ast_mutex_unlock(&user->lock);
1781 if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
1782 p->username = strdup(call->remoteIP);
1784 ast_mutex_unlock(&p->lock);
1785 ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
1787 ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
1788 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1791 ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
1792 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1794 ast_set_flag(p, H323_NEEDDESTROY);
1799 ooh323c_set_capability_for_call(call, &p->prefs, p->cap, p->dtmfmode, p->dtmfcodec,
1800 p->t38support, p->g729onlyA);
1802 c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL);
1804 ast_mutex_unlock(&p->lock);
1805 ast_log(LOG_ERROR, "Could not create ast_channel\n");
1808 if (!configure_local_rtp(p, call)) {
1809 ast_mutex_unlock(&p->lock);
1810 ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
1814 ast_mutex_unlock(&p->lock);
1817 ast_verbose("+++ ooh323_onReceivedSetup - Determined context %s, "
1818 "extension %s\n", p->context, p->exten);
1825 int onOutgoingCall(ooCallData *call)
1827 struct ooh323_pvt *p = NULL;
1831 ast_verbose("--- onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
1833 if (!strcmp(call->callType, "outgoing")) {
1834 p = find_call(call);
1836 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1839 ast_mutex_lock(&p->lock);
1841 if (!ast_strlen_zero(p->callerid_name)) {
1842 ooCallSetCallerId(call, p->callerid_name);
1844 if (!ast_strlen_zero(p->callerid_num)) {
1846 while (*(p->callerid_num + i) != '\0') {
1847 if(!isdigit(*(p->callerid_num+i))) { break; }
1850 if(*(p->callerid_num+i) == '\0')
1851 ooCallSetCallingPartyNumber(call, p->callerid_num);
1853 if(!p->callerid_name)
1854 ooCallSetCallerId(call, p->callerid_num);
1858 if (!ast_strlen_zero(p->caller_h323id))
1859 ooCallAddAliasH323ID(call, p->caller_h323id);
1861 if (!ast_strlen_zero(p->caller_dialedDigits)) {
1863 ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits);
1865 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
1866 } else if (!ast_strlen_zero(p->callerid_num)) {
1867 if (ooIsDailedDigit(p->callerid_num)) {
1869 ast_verbose("setting callid number %s\n", p->callerid_num);
1871 ooCallAddAliasDialedDigits(call, p->callerid_num);
1872 } else if (ast_strlen_zero(p->caller_h323id)) {
1873 ooCallAddAliasH323ID(call, p->callerid_num);
1876 if (p->rtpmask && p->rtpmaskstr[0]) {
1877 call->rtpMask = p->rtpmask;
1878 ast_mutex_lock(&call->rtpMask->lock);
1879 call->rtpMask->inuse++;
1880 ast_mutex_unlock(&call->rtpMask->lock);
1881 ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
1884 if (!configure_local_rtp(p, call)) {
1885 ast_mutex_unlock(&p->lock);
1889 ast_mutex_unlock(&p->lock);
1893 ast_verbose("+++ onOutgoingCall %s\n", call->callToken);
1898 int onNewCallCreated(ooCallData *call)
1900 struct ooh323_pvt *p = NULL;
1904 ast_verbose("--- onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
1906 ast_mutex_lock(&call->Lock);
1907 if (ooh323c_start_call_thread(call)) {
1908 ast_log(LOG_ERROR,"Failed to create call thread.\n");
1909 ast_mutex_unlock(&call->Lock);
1913 if (!strcmp(call->callType, "outgoing")) {
1914 p = find_call(call);
1916 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1917 ast_mutex_unlock(&call->Lock);
1920 ast_mutex_lock(&p->lock);
1922 if (!ast_strlen_zero(p->callerid_name)) {
1923 ooCallSetCallerId(call, p->callerid_name);
1925 if (!ast_strlen_zero(p->callerid_num)) {
1927 while (*(p->callerid_num + i) != '\0') {
1928 if(!isdigit(*(p->callerid_num+i))) { break; }
1931 if(*(p->callerid_num+i) == '\0')
1932 ooCallSetCallingPartyNumber(call, p->callerid_num);
1934 if(ast_strlen_zero(p->callerid_name))
1935 ooCallSetCallerId(call, p->callerid_num);
1939 if (!ast_strlen_zero(p->caller_h323id))
1940 ooCallAddAliasH323ID(call, p->caller_h323id);
1942 if (!ast_strlen_zero(p->caller_dialedDigits)) {
1944 ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits);
1946 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
1947 } else if (!ast_strlen_zero(p->callerid_num)) {
1948 if (ooIsDailedDigit(p->callerid_num)) {
1950 ast_verbose("setting callid number %s\n", p->callerid_num);
1952 ooCallAddAliasDialedDigits(call, p->callerid_num);
1953 } else if (ast_strlen_zero(p->caller_h323id)) {
1954 ooCallAddAliasH323ID(call, p->callerid_num);
1959 if (!ast_strlen_zero(p->exten)) {
1960 if (ooIsDailedDigit(p->exten)) {
1961 ooCallSetCalledPartyNumber(call, p->exten);
1962 ooCallAddRemoteAliasDialedDigits(call, p->exten);
1964 ooCallAddRemoteAliasH323ID(call, p->exten);
1970 ast_codec_pref_string(&p->prefs, prefsBuf, sizeof(prefsBuf));
1971 ast_verbose(" Outgoing call %s(%s) - Codec prefs - %s\n",
1972 p->username?p->username:"NULL", call->callToken, prefsBuf);
1975 ooh323c_set_capability_for_call(call, &p->prefs, p->cap,
1976 p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
1978 /* configure_local_rtp(p, call); */
1979 ast_mutex_unlock(&p->lock);
1982 ast_mutex_unlock(&call->Lock);
1984 ast_verbose("+++ onNewCallCreated %s\n", call->callToken);
1988 int onCallEstablished(ooCallData *call)
1990 struct ooh323_pvt *p = NULL;
1993 ast_verbose("--- onCallEstablished %s\n", call->callToken);
1996 if (!(p = find_call(call))) {
1997 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2001 if(ast_test_flag(p, H323_OUTGOING)) {
2002 ast_mutex_lock(&p->lock);
2004 ast_mutex_unlock(&p->lock);
2005 ast_log(LOG_ERROR, "Channel has no owner\n");
2009 while (p->owner && ast_channel_trylock(p->owner)) {
2010 ast_debug(1, "Failed to grab lock, trying again\n");
2011 DEADLOCK_AVOIDANCE(&p->lock);
2014 struct ast_channel* c = p->owner;
2016 if (call->remoteDisplayName) {
2017 struct ast_party_connected_line connected;
2018 struct ast_set_party_connected_line update_connected;
2020 memset(&update_connected, 0, sizeof(update_connected));
2021 update_connected.id.name = 1;
2022 ast_party_connected_line_init(&connected);
2023 connected.id.name.valid = 1;
2024 connected.id.name.str = (char *) call->remoteDisplayName;
2025 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
2026 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
2029 ast_queue_control(c, AST_CONTROL_ANSWER);
2030 ast_channel_unlock(p->owner);
2031 manager_event(EVENT_FLAG_SYSTEM,"ChannelUpdate","Channel: %s\r\nChanneltype: %s\r\n"
2032 "CallRef: %d\r\n", c->name, "OOH323", p->call_reference);
2034 ast_mutex_unlock(&p->lock);
2039 ast_verbose("+++ onCallEstablished %s\n", call->callToken);
2044 int onCallCleared(ooCallData *call)
2046 struct ooh323_pvt *p = NULL;
2050 ast_verbose("--- onCallCleared %s \n", call->callToken);
2053 if ((p = find_call(call))) {
2054 ast_mutex_lock(&p->lock);
2057 if (ast_channel_trylock(p->owner)) {
2058 ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
2059 ast_debug(1, "Failed to grab lock, trying again\n");
2060 DEADLOCK_AVOIDANCE(&p->lock);
2062 ownerLock = 1; break;
2067 if (!ast_test_flag(p, H323_ALREADYGONE)) {
2069 ast_set_flag(p, H323_ALREADYGONE);
2070 p->owner->hangupcause = call->q931cause;
2071 p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
2072 ast_queue_hangup_with_cause(p->owner,call->q931cause);
2077 p->owner->tech_pvt = NULL;
2078 ast_channel_unlock(p->owner);
2080 ast_module_unref(myself);
2083 ast_set_flag(p, H323_NEEDDESTROY);
2085 ooh323c_stop_call_thread(call);
2087 ast_mutex_unlock(&p->lock);
2088 ast_mutex_lock(&usecnt_lock);
2090 ast_mutex_unlock(&usecnt_lock);
2095 ast_verbose("+++ onCallCleared\n");
2100 /* static void ooh323_delete_user(struct ooh323_user *user)
2102 struct ooh323_user *prev = NULL, *cur = NULL;
2105 ast_verbose("--- ooh323_delete_user\n");
2109 ast_mutex_lock(&userl.lock);
2111 if (cur == user) break;
2118 prev->next = cur->next;
2120 userl.users = cur->next;
2122 ast_mutex_unlock(&userl.lock);
2128 ast_verbose("+++ ooh323_delete_user\n");
2132 void ooh323_delete_peer(struct ooh323_peer *peer)
2134 struct ooh323_peer *prev = NULL, *cur = NULL;
2137 ast_verbose("--- ooh323_delete_peer\n");
2141 ast_mutex_lock(&peerl.lock);
2143 if(cur==peer) break;
2150 prev->next = cur->next;
2152 peerl.peers = cur->next;
2154 ast_mutex_unlock(&peerl.lock);
2156 if(peer->h323id) free(peer->h323id);
2157 if(peer->email) free(peer->email);
2158 if(peer->url) free(peer->url);
2159 if(peer->e164) free(peer->e164);
2161 peer->cap = ast_format_cap_destroy(peer->cap);
2166 ast_verbose("+++ ooh323_delete_peer\n");
2172 static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
2174 struct ooh323_user *user = NULL;
2177 ast_verbose("--- build_user\n");
2179 user = ast_calloc(1,sizeof(struct ooh323_user));
2181 memset(user, 0, sizeof(struct ooh323_user));
2182 if (!(user->cap = ast_format_cap_alloc())) {
2186 ast_mutex_init(&user->lock);
2187 ast_copy_string(user->name, name, sizeof(user->name));
2188 ast_format_cap_copy(user->cap, gCap);
2189 memcpy(&user->prefs, &gPrefs, sizeof(user->prefs));
2190 user->rtptimeout = gRTPTimeout;
2191 user->dtmfmode = gDTMFMode;
2192 user->dtmfcodec = gDTMFCodec;
2193 user->t38support = gT38Support;
2194 user->faststart = gFastStart;
2195 user->h245tunneling = gTunneling;
2196 user->g729onlyA = g729onlyA;
2197 /* set default context */
2198 ast_copy_string(user->context, gContext, sizeof(user->context));
2199 ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
2200 user->amaflags = gAMAFLAGS;
2203 if (!strcasecmp(v->name, "context")) {
2204 ast_copy_string(user->context, v->value, sizeof(user->context));
2205 } else if (!strcasecmp(v->name, "incominglimit")) {
2206 user->incominglimit = atoi(v->value);
2207 if (user->incominglimit < 0)
2208 user->incominglimit = 0;
2209 } else if (!strcasecmp(v->name, "accountcode")) {
2210 strncpy(user->accountcode, v->value,
2211 sizeof(user->accountcode)-1);
2212 } else if (!strcasecmp(v->name, "roundtrip")) {
2213 sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
2214 } else if (!strcasecmp(v->name, "faststart")) {
2215 user->faststart = ast_true(v->value);
2216 } else if (!strcasecmp(v->name, "h245tunneling")) {
2217 user->h245tunneling = ast_true(v->value);
2218 } else if (!strcasecmp(v->name, "g729onlyA")) {
2219 user->g729onlyA = ast_true(v->value);
2220 } else if (!strcasecmp(v->name, "rtptimeout")) {
2221 user->rtptimeout = atoi(v->value);
2222 if (user->rtptimeout < 0)
2223 user->rtptimeout = gRTPTimeout;
2224 } else if (!strcasecmp(v->name, "rtpmask")) {
2225 if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2226 (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED)
2228 ast_mutex_init(&user->rtpmask->lock);
2229 user->rtpmask->inuse = 1;
2230 ast_copy_string(user->rtpmaskstr, v->value,
2231 sizeof(user->rtpmaskstr));
2232 } else user->rtpmask = NULL;
2233 } else if (!strcasecmp(v->name, "disallow")) {
2234 ast_parse_allow_disallow(&user->prefs,
2235 user->cap, v->value, 0);
2236 } else if (!strcasecmp(v->name, "allow")) {
2237 const char* tcodecs = v->value;
2238 if (!strcasecmp(v->value, "all")) {
2239 tcodecs = "ulaw,alaw,g729,g723,gsm";
2241 ast_parse_allow_disallow(&user->prefs,
2242 user->cap, tcodecs, 1);
2243 } else if (!strcasecmp(v->name, "amaflags")) {
2244 user->amaflags = ast_cdr_amaflags2int(v->value);
2245 } else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
2246 struct ast_sockaddr p;
2247 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2248 ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
2250 ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
2253 } else if (!strcasecmp(v->name, "dtmfmode")) {
2254 if (!strcasecmp(v->value, "rfc2833"))
2255 user->dtmfmode = H323_DTMF_RFC2833;
2256 if (!strcasecmp(v->value, "cisco"))
2257 user->dtmfmode = H323_DTMF_CISCO;
2258 else if (!strcasecmp(v->value, "q931keypad"))
2259 user->dtmfmode = H323_DTMF_Q931;
2260 else if (!strcasecmp(v->value, "h245alphanumeric"))
2261 user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2262 else if (!strcasecmp(v->value, "h245signal"))
2263 user->dtmfmode = H323_DTMF_H245SIGNAL;
2264 else if (!strcasecmp(v->value, "inband"))
2265 user->dtmfmode = H323_DTMF_INBAND;
2266 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2267 user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2268 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2269 user->dtmfcodec = atoi(v->value);
2270 } else if (!strcasecmp(v->name, "t38support")) {
2271 if (!strcasecmp(v->value, "disabled"))
2272 user->t38support = T38_DISABLED;
2273 if (!strcasecmp(v->value, "no"))
2274 user->t38support = T38_DISABLED;
2275 else if (!strcasecmp(v->value, "faxgw"))
2276 user->t38support = T38_FAXGW;
2277 else if (!strcasecmp(v->value, "yes"))
2278 user->t38support = T38_ENABLED;
2285 ast_verbose("+++ build_user\n");
2290 static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
2292 struct ooh323_peer *peer = NULL;
2295 ast_verbose("--- build_peer\n");
2297 peer = ast_calloc(1, sizeof(*peer));
2299 memset(peer, 0, sizeof(struct ooh323_peer));
2300 if (!(peer->cap = ast_format_cap_alloc())) {
2304 ast_mutex_init(&peer->lock);
2305 ast_copy_string(peer->name, name, sizeof(peer->name));
2306 ast_format_cap_copy(peer->cap, gCap);
2307 memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs));
2308 peer->rtptimeout = gRTPTimeout;
2309 ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
2310 peer->amaflags = gAMAFLAGS;
2311 peer->dtmfmode = gDTMFMode;
2312 peer->dtmfcodec = gDTMFCodec;
2313 peer->t38support = gT38Support;
2314 peer->faststart = gFastStart;
2315 peer->h245tunneling = gTunneling;
2316 peer->g729onlyA = g729onlyA;
2318 if (0 == friend_type) {
2323 if (!strcasecmp(v->name, "h323id")) {
2324 if (!(peer->h323id = ast_strdup(v->value))) {
2325 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2327 ooh323_delete_peer(peer);
2330 } else if (!strcasecmp(v->name, "e164")) {
2331 if (!(peer->e164 = ast_strdup(v->value))) {
2332 ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
2334 ooh323_delete_peer(peer);
2337 } else if (!strcasecmp(v->name, "email")) {
2338 if (!(peer->email = ast_strdup(v->value))) {
2339 ast_log(LOG_ERROR, "Could not allocate memory for email of "
2341 ooh323_delete_peer(peer);
2344 } else if (!strcasecmp(v->name, "url")) {
2345 if (!(peer->url = ast_strdup(v->value))) {
2346 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2348 ooh323_delete_peer(peer);
2351 } else if (!strcasecmp(v->name, "port")) {
2352 peer->port = atoi(v->value);
2353 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
2354 struct ast_sockaddr p;
2355 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2356 ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
2358 ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2361 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2362 peer->outgoinglimit = atoi(v->value);
2363 if (peer->outgoinglimit < 0)
2364 peer->outgoinglimit = 0;
2365 } else if (!strcasecmp(v->name, "accountcode")) {
2366 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
2367 } else if (!strcasecmp(v->name, "faststart")) {
2368 peer->faststart = ast_true(v->value);
2369 } else if (!strcasecmp(v->name, "h245tunneling")) {
2370 peer->h245tunneling = ast_true(v->value);
2371 } else if (!strcasecmp(v->name, "g729onlyA")) {
2372 peer->g729onlyA = ast_true(v->value);
2373 } else if (!strcasecmp(v->name, "rtptimeout")) {
2374 peer->rtptimeout = atoi(v->value);
2375 if(peer->rtptimeout < 0)
2376 peer->rtptimeout = gRTPTimeout;
2377 } else if (!strcasecmp(v->name, "rtpmask")) {
2378 if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2379 (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED)
2381 ast_mutex_init(&peer->rtpmask->lock);
2382 peer->rtpmask->inuse = 1;
2383 ast_copy_string(peer->rtpmaskstr, v->value,
2384 sizeof(peer->rtpmaskstr));
2385 } else peer->rtpmask = NULL;
2386 } else if (!strcasecmp(v->name, "disallow")) {
2387 ast_parse_allow_disallow(&peer->prefs, peer->cap,
2389 } else if (!strcasecmp(v->name, "allow")) {
2390 const char* tcodecs = v->value;
2391 if (!strcasecmp(v->value, "all")) {
2392 tcodecs = "ulaw,alaw,g729,g723,gsm";
2394 ast_parse_allow_disallow(&peer->prefs, peer->cap,
2396 } else if (!strcasecmp(v->name, "amaflags")) {
2397 peer->amaflags = ast_cdr_amaflags2int(v->value);
2398 } else if (!strcasecmp(v->name, "roundtrip")) {
2399 sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
2400 } else if (!strcasecmp(v->name, "dtmfmode")) {
2401 if (!strcasecmp(v->value, "rfc2833"))
2402 peer->dtmfmode = H323_DTMF_RFC2833;
2403 if (!strcasecmp(v->value, "cisco"))
2404 peer->dtmfmode = H323_DTMF_CISCO;
2405 else if (!strcasecmp(v->value, "q931keypad"))
2406 peer->dtmfmode = H323_DTMF_Q931;
2407 else if (!strcasecmp(v->value, "h245alphanumeric"))
2408 peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2409 else if (!strcasecmp(v->value, "h245signal"))
2410 peer->dtmfmode = H323_DTMF_H245SIGNAL;
2411 else if (!strcasecmp(v->value, "inband"))
2412 peer->dtmfmode = H323_DTMF_INBAND;
2413 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2414 peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2415 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2416 peer->dtmfcodec = atoi(v->value);
2417 } else if (!strcasecmp(v->name, "t38support")) {
2418 if (!strcasecmp(v->value, "disabled"))
2419 peer->t38support = T38_DISABLED;
2420 if (!strcasecmp(v->value, "no"))
2421 peer->t38support = T38_DISABLED;
2422 else if (!strcasecmp(v->value, "faxgw"))
2423 peer->t38support = T38_FAXGW;
2424 else if (!strcasecmp(v->value, "yes"))
2425 peer->t38support = T38_ENABLED;
2432 ast_verbose("+++ build_peer\n");
2437 static int ooh323_do_reload(void)
2440 ast_verbose("--- ooh323_do_reload\n");
2446 ast_verbose("+++ ooh323_do_reload\n");
2452 /*--- h323_reload: Force reload of module from cli ---*/
2454 char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2459 e->command = "ooh323 reload";
2461 "Usage: ooh323 reload\n"
2462 " Reload OOH323 config.\n";
2469 return CLI_SHOWUSAGE;
2472 ast_verbose("--- ooh323_reload\n");
2474 ast_mutex_lock(&h323_reload_lock);
2475 if (h323_reloading) {
2476 ast_verbose("Previous OOH323 reload not yet done\n");
2480 ast_mutex_unlock(&h323_reload_lock);
2484 ast_verbose("+++ ooh323_reload\n");
2489 int reload_config(int reload)
2492 struct ooAliases *pNewAlias = NULL, *cur, *prev;
2493 struct ast_config *cfg;
2494 struct ast_variable *v;
2495 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2496 struct ooh323_user *user = NULL;
2497 struct ooh323_peer *peer = NULL;
2500 struct ast_format tmpfmt;
2503 ast_verbose("--- reload_config\n");
2505 cfg = ast_config_load((char*)config, config_flags);
2507 /* We *must* have a config file otherwise stop immediately */
2509 ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
2511 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
2512 return RESULT_SUCCESS;
2518 ast_verbose(" reload_config - Freeing up alias list\n");
2530 /* Inintialize everything to default */
2531 strcpy(gLogFile, DEFAULT_LOGFILE);
2534 strcpy(gCallerID, DEFAULT_H323ID);
2535 ast_format_cap_set(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
2536 memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
2537 gDTMFMode = H323_DTMF_RFC2833;
2539 gT38Support = T38_FAXGW;
2540 gTRCLVL = OOTRCLVLERR;
2541 gRasGkMode = RasNoGatekeeper;
2542 gGatekeeper[0] = '\0';
2546 strcpy(gAccountcode, DEFAULT_H323ACCNT);
2550 strcpy(gContext, DEFAULT_CONTEXT);
2552 gMediaWaitForConnect = 0;
2553 ooconfig.mTCPPortStart = 12030;
2554 ooconfig.mTCPPortEnd = 12230;
2555 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2557 v = ast_variable_browse(cfg, "general");
2560 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
2565 if (!strcasecmp(v->name, "port")) {
2566 gPort = (int)strtol(v->value, NULL, 10);
2567 } else if (!strcasecmp(v->name, "bindaddr")) {
2568 ast_copy_string(gIP, v->value, sizeof(gIP));
2569 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
2570 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
2573 if (ast_sockaddr_is_ipv6(&bindaddr)) {
2576 } else if (!strcasecmp(v->name, "h225portrange")) {
2579 ast_copy_string(temp, v->value, sizeof(temp));
2580 endlimit = strchr(temp, ',');
2584 ooconfig.mTCPPortStart = atoi(temp);
2585 ooconfig.mTCPPortEnd = atoi(endlimit);
2588 ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
2590 } else if (!strcasecmp(v->name, "gateway")) {
2591 gIsGateway = ast_true(v->value);
2592 } else if (!strcasecmp(v->name, "faststart")) {
2593 gFastStart = ast_true(v->value);
2595 ooH323EpEnableFastStart();
2597 ooH323EpDisableFastStart();
2598 } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
2599 gMediaWaitForConnect = ast_true(v->value);
2600 if (gMediaWaitForConnect)
2601 ooH323EpEnableMediaWaitForConnect();
2603 ooH323EpDisableMediaWaitForConnect();
2604 } else if (!strcasecmp(v->name, "h245tunneling")) {
2605 gTunneling = ast_true(v->value);
2607 ooH323EpEnableH245Tunneling();
2609 ooH323EpDisableH245Tunneling();
2610 } else if (!strcasecmp(v->name, "g729onlyA")) {
2611 g729onlyA = ast_true(v->value);
2612 } else if (!strcasecmp(v->name, "roundtrip")) {
2613 sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
2614 } else if (!strcasecmp(v->name, "trybemaster")) {
2615 gBeMaster = ast_true(v->value);
2617 ooH323EpTryBeMaster(1);
2619 ooH323EpTryBeMaster(0);
2620 } else if (!strcasecmp(v->name, "h323id")) {
2621 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2623 ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
2626 if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
2627 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2629 pNewAlias->type = T_H225AliasAddress_h323_ID;
2630 pNewAlias->value = strdup(v->value);
2631 pNewAlias->next = gAliasList;
2632 gAliasList = pNewAlias;
2634 } else if (!strcasecmp(v->name, "e164")) {
2635 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2637 ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
2640 pNewAlias->type = T_H225AliasAddress_dialedDigits;
2641 pNewAlias->value = strdup(v->value);
2642 pNewAlias->next = gAliasList;
2643 gAliasList = pNewAlias;
2645 } else if (!strcasecmp(v->name, "email")) {
2646 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2648 ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
2651 pNewAlias->type = T_H225AliasAddress_email_ID;
2652 pNewAlias->value = strdup(v->value);
2653 pNewAlias->next = gAliasList;
2654 gAliasList = pNewAlias;
2656 } else if (!strcasecmp(v->name, "t35country")) {
2657 t35countrycode = atoi(v->value);
2658 } else if (!strcasecmp(v->name, "t35extensions")) {
2659 t35extensions = atoi(v->value);
2660 } else if (!strcasecmp(v->name, "manufacturer")) {
2661 manufacturer = atoi(v->value);
2662 } else if (!strcasecmp(v->name, "vendorid")) {
2663 ast_copy_string(vendor, v->value, sizeof(vendor));
2664 } else if (!strcasecmp(v->name, "versionid")) {
2665 ast_copy_string(version, v->value, sizeof(version));
2666 } else if (!strcasecmp(v->name, "callerid")) {
2667 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2668 } else if (!strcasecmp(v->name, "incominglimit")) {
2669 gIncomingLimit = atoi(v->value);
2670 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2671 gOutgoingLimit = atoi(v->value);
2672 } else if (!strcasecmp(v->name, "gatekeeper")) {
2673 if (!strcasecmp(v->value, "DISABLE")) {
2674 gRasGkMode = RasNoGatekeeper;
2675 } else if (!strcasecmp(v->value, "DISCOVER")) {
2676 gRasGkMode = RasDiscoverGatekeeper;
2678 gRasGkMode = RasUseSpecificGatekeeper;
2679 strncpy(gGatekeeper, v->value, sizeof(gGatekeeper)-1);
2681 } else if (!strcasecmp(v->name, "logfile")) {
2682 strncpy(gLogFile, v->value, sizeof(gLogFile)-1);
2683 } else if (!strcasecmp(v->name, "context")) {
2684 strncpy(gContext, v->value, sizeof(gContext)-1);
2685 ast_verbose(VERBOSE_PREFIX_3 " == Setting default context to %s\n",
2687 } else if (!strcasecmp(v->name, "rtptimeout")) {
2688 gRTPTimeout = atoi(v->value);
2689 if (gRTPTimeout <= 0)
2691 } else if (!strcasecmp(v->name, "tos")) {
2692 if (sscanf(v->value, "%30i", &format) == 1)
2693 gTOS = format & 0xff;
2694 else if (!strcasecmp(v->value, "lowdelay"))
2695 gTOS = IPTOS_LOWDELAY;
2696 else if (!strcasecmp(v->value, "throughput"))
2697 gTOS = IPTOS_THROUGHPUT;
2698 else if (!strcasecmp(v->value, "reliability"))
2699 gTOS = IPTOS_RELIABILITY;
2700 else if (!strcasecmp(v->value, "mincost"))
2701 gTOS = IPTOS_MINCOST;
2702 else if (!strcasecmp(v->value, "none"))
2705 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be "
2706 "'lowdelay', 'throughput', 'reliability', "
2707 "'mincost', or 'none'\n", v->lineno);
2708 } else if (!strcasecmp(v->name, "amaflags")) {
2709 gAMAFLAGS = ast_cdr_amaflags2int(v->value);
2710 } else if (!strcasecmp(v->name, "accountcode")) {
2711 ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode));
2712 } else if (!strcasecmp(v->name, "disallow")) {
2713 ast_parse_allow_disallow(&gPrefs, gCap, v->value, 0);
2714 } else if (!strcasecmp(v->name, "allow")) {
2715 const char* tcodecs = v->value;
2716 if (!strcasecmp(v->value, "all")) {
2717 tcodecs = "ulaw,alaw,g729,g723,gsm";
2719 ast_parse_allow_disallow(&gPrefs, gCap, tcodecs, 1);
2720 } else if (!strcasecmp(v->name, "dtmfmode")) {
2721 if (!strcasecmp(v->value, "inband"))
2722 gDTMFMode = H323_DTMF_INBAND;
2723 else if (!strcasecmp(v->value, "rfc2833"))
2724 gDTMFMode = H323_DTMF_RFC2833;
2725 else if (!strcasecmp(v->value, "cisco"))
2726 gDTMFMode = H323_DTMF_CISCO;
2727 else if (!strcasecmp(v->value, "q931keypad"))
2728 gDTMFMode = H323_DTMF_Q931;
2729 else if (!strcasecmp(v->value, "h245alphanumeric"))
2730 gDTMFMode = H323_DTMF_H245ALPHANUMERIC;
2731 else if (!strcasecmp(v->value, "h245signal"))
2732 gDTMFMode = H323_DTMF_H245SIGNAL;
2734 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n",
2736 gDTMFMode = H323_DTMF_RFC2833;
2738 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2739 gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2740 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2741 gDTMFCodec = atoi(v->value);
2742 } else if (!strcasecmp(v->name, "t38support")) {
2743 if (!strcasecmp(v->value, "disabled"))
2744 gT38Support = T38_DISABLED;
2745 if (!strcasecmp(v->value, "no"))
2746 gT38Support = T38_DISABLED;
2747 else if (!strcasecmp(v->value, "faxgw"))
2748 gT38Support = T38_FAXGW;
2749 else if (!strcasecmp(v->value, "yes"))
2750 gT38Support = T38_ENABLED;
2751 } else if (!strcasecmp(v->name, "tracelevel")) {
2752 gTRCLVL = atoi(v->value);
2753 ooH323EpSetTraceLevel(gTRCLVL);
2758 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
2759 if (strcasecmp(cat, "general")) {
2760 int friend_type = 0;
2761 utype = ast_variable_retrieve(cfg, cat, "type");
2763 friend_type = strcasecmp(utype, "friend");
2764 if (!strcmp(utype, "user") || 0 == friend_type) {
2765 user = build_user(cat, ast_variable_browse(cfg, cat));
2767 ast_mutex_lock(&userl.lock);
2768 user->next = userl.users;
2770 ast_mutex_unlock(&userl.lock);
2772 ast_log(LOG_WARNING, "Failed to build user %s\n", cat);
2775 if (!strcasecmp(utype, "peer") || 0 == friend_type) {
2776 peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type);
2778 ast_mutex_lock(&peerl.lock);
2779 peer->next = peerl.peers;
2781 ast_mutex_unlock(&peerl.lock);
2783 ast_log(LOG_WARNING, "Failed to build peer %s\n", cat);
2789 ast_config_destroy(cfg);
2792 /* Determine ip address if neccessary */
2793 if (ast_strlen_zero(gIP)) {
2794 ooGetLocalIPAddress(gIP);
2795 if (!strcmp(gIP, "127.0.0.1") || !strcmp(gIP, "::1")) {
2796 ast_log(LOG_NOTICE, "Failed to determine local ip address. Please "
2797 "specify it in ooh323.conf. OOH323 Disabled\n");
2803 ast_verbose("+++ reload_config\n");
2810 static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2813 struct ooh323_peer *prev = NULL, *peer = NULL;
2817 e->command = "ooh323 show peer";
2819 "Usage: ooh323 show peer <name>\n"
2820 " List details of specific OOH323 peer.\n";
2827 return CLI_SHOWUSAGE;
2830 ast_mutex_lock(&peerl.lock);
2833 ast_mutex_lock(&peer->lock);
2834 if(!strcmp(peer->name, a->argv[3]))
2839 ast_mutex_unlock(&prev->lock);
2844 sprintf(ip_port, "%s:%d", peer->ip, peer->port);
2845 ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
2846 ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
2847 peer->h245tunneling?"yes":"no");
2848 ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
2849 print_codec_to_cli(a->fd, &peer->prefs);
2850 ast_cli(a->fd, ")\n");
2851 ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
2852 if (peer->dtmfmode & H323_DTMF_CISCO) {
2853 ast_cli(a->fd, "%s\n", "cisco");
2854 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
2855 } else if (peer->dtmfmode & H323_DTMF_RFC2833) {
2856 ast_cli(a->fd, "%s\n", "rfc2833");
2857 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
2858 } else if (peer->dtmfmode & H323_DTMF_Q931)
2859 ast_cli(a->fd, "%s\n", "q931keypad");
2860 else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC)
2861 ast_cli(a->fd, "%s\n", "h245alphanumeric");
2862 else if (peer->dtmfmode & H323_DTMF_H245SIGNAL)
2863 ast_cli(a->fd, "%s\n", "h245signal");
2864 else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX)
2865 ast_cli(a->fd, "%s\n", "inband-relaxed");
2866 else if (peer->dtmfmode & H323_DTMF_INBAND)
2867 ast_cli(a->fd, "%s\n", "inband");
2869 ast_cli(a->fd, "%s\n", "unknown");
2871 ast_cli(a->fd,"%-15s", "T.38 Mode: ");
2872 if (peer->t38support == T38_DISABLED)
2873 ast_cli(a->fd, "%s\n", "disabled");
2874 else if (peer->t38support == T38_FAXGW)
2875 ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
2877 ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode);
2878 ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ",
2879 ast_cdr_flags2str(peer->amaflags));
2880 ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port);
2881 ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit);
2882 ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout);
2883 if (peer->rtpmaskstr[0])
2884 ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr);
2885 if (peer->rtdrcount && peer->rtdrinterval)
2886 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval);
2887 ast_mutex_unlock(&peer->lock);
2889 ast_cli(a->fd, "Peer %s not found\n", a->argv[3]);
2890 ast_cli(a->fd, "\n");
2892 ast_mutex_unlock(&peerl.lock);
2897 static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2899 struct ooh323_peer *prev = NULL, *peer = NULL;
2900 char formats[FORMAT_STRING_SIZE];
2902 #define FORMAT "%-15.15s %-15.15s %-23.23s %-s\n"
2906 e->command = "ooh323 show peers";
2908 "Usage: ooh323 show peers\n"
2909 " Lists all known OOH323 peers.\n";
2916 return CLI_SHOWUSAGE;
2918 ast_cli(a->fd, FORMAT, "Name", "Accountcode", "ip:port", "Formats");
2920 ast_mutex_lock(&peerl.lock);
2923 ast_mutex_lock(&peer->lock);
2924 snprintf(ip_port, sizeof(ip_port), "%s:%d", peer->ip, peer->port);
2925 ast_cli(a->fd, FORMAT, peer->name,
2928 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->cap));
2931 ast_mutex_unlock(&prev->lock);
2934 ast_mutex_unlock(&peerl.lock);
2939 /*! \brief Print codec list from preference to CLI/manager */
2940 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
2943 struct ast_format tmpfmt;
2944 for (x = 0; x < 32; x++) {
2945 ast_codec_pref_index(pref, x, &tmpfmt);
2948 ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
2949 ast_cli(fd, ":%d", pref->framing[x]);
2950 if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
2954 ast_cli(fd, "none");
2957 static char *handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2959 struct ooh323_user *prev = NULL, *user = NULL;
2963 e->command = "ooh323 show user";
2965 "Usage: ooh323 show user <name>\n"
2966 " List details of specific OOH323 user.\n";
2973 return CLI_SHOWUSAGE;
2976 ast_mutex_lock(&userl.lock);
2979 ast_mutex_lock(&user->lock);
2980 if(!strcmp(user->name, a->argv[3])) {
2985 ast_mutex_unlock(&prev->lock);
2990 ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
2991 ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no",
2992 user->h245tunneling?"yes":"no");
2993 ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
2994 print_codec_to_cli(a->fd, &user->prefs);
2995 ast_cli(a->fd, ")\n");
2996 ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
2997 if (user->dtmfmode & H323_DTMF_CISCO) {
2998 ast_cli(a->fd, "%s\n", "cisco");
2999 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
3000 } else if (user->dtmfmode & H323_DTMF_RFC2833) {
3001 ast_cli(a->fd, "%s\n", "rfc2833");
3002 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
3003 } else if (user->dtmfmode & H323_DTMF_Q931)
3004 ast_cli(a->fd, "%s\n", "q931keypad");
3005 else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC)
3006 ast_cli(a->fd, "%s\n", "h245alphanumeric");
3007 else if (user->dtmfmode & H323_DTMF_H245SIGNAL)
3008 ast_cli(a->fd, "%s\n", "h245signal");
3009 else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX)
3010 ast_cli(a->fd, "%s\n", "inband-relaxed");
3011 else if (user->dtmfmode & H323_DTMF_INBAND)
3012 ast_cli(a->fd, "%s\n", "inband");
3014 ast_cli(a->fd, "%s\n", "unknown");
3016 ast_cli(a->fd,"%-15s", "T.38 Mode: ");
3017 if (user->t38support == T38_DISABLED)
3018 ast_cli(a->fd, "%s\n", "disabled");
3019 else if (user->t38support == T38_FAXGW)
3020 ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
3022 ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode);
3023 ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ",
3024 ast_cdr_flags2str(user->amaflags));
3025 ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context);
3026 ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit);
3027 ast_cli(a->fd, "%-15.15s%d\n", "InUse: ", user->inUse);
3028 ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout);
3029 if (user->rtpmaskstr[0])
3030 ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr);
3031 ast_mutex_unlock(&user->lock);
3032 if (user->rtdrcount && user->rtdrinterval)
3033 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval);
3035 ast_cli(a->fd, "User %s not found\n", a->argv[3]);
3036 ast_cli(a->fd, "\n");
3038 ast_mutex_unlock(&userl.lock);
3043 static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3045 struct ooh323_user *prev = NULL, *user = NULL;
3046 char formats[FORMAT_STRING_SIZE];
3047 #define FORMAT1 "%-15.15s %-15.15s %-15.15s %-s\n"
3051 e->command = "ooh323 show users";
3053 "Usage: ooh323 show users \n"
3054 " Lists all known OOH323 users.\n";
3061 return CLI_SHOWUSAGE;
3064 ast_cli(a->fd, FORMAT1, "Username", "Accountcode", "Context", "Formats");
3066 ast_mutex_lock(&userl.lock);
3070 ast_mutex_lock(&user->lock);
3071 ast_cli(a->fd, FORMAT1, user->name,
3072 user->accountcode, user->context,
3073 ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->cap));
3076 ast_mutex_unlock(&prev->lock);
3079 ast_mutex_unlock(&userl.lock);
3081 return RESULT_SUCCESS;
3085 static char *handle_cli_ooh323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3089 e->command = "ooh323 set debug [off]";
3091 "Usage: ooh323 set debug [off]\n"
3092 " Enables/Disables debugging of OOH323 channel driver\n";
3098 if (a->argc < 3 || a->argc > 4)
3099 return CLI_SHOWUSAGE;
3100 if (a->argc == 4 && strcasecmp(a->argv[3], "off"))
3101 return CLI_SHOWUSAGE;
3103 gH323Debug = (a->argc == 4) ? FALSE : TRUE;
3104 ast_cli(a->fd, "OOH323 Debugging %s\n", gH323Debug ? "Enabled" : "Disabled");
3110 static int ooh323_show_channels(int fd, int argc, char *argv[])
3112 return RESULT_SUCCESS;
3116 static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3118 char value[FORMAT_STRING_SIZE];
3119 ooAliases *pAlias = NULL, *pAliasNext = NULL;;
3123 e->command = "ooh323 show config";
3125 "Usage: ooh323 show config\n"
3126 " Shows global configuration of H.323 channel driver\n";
3133 return CLI_SHOWUSAGE;
3137 ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n");
3138 snprintf(value, sizeof(value), "%s:%d", gIP, gPort);
3139 ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value);
3140 ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ",
3141 ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd);
3142 ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no");
3143 ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
3144 ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
3145 ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect",
3146 gMediaWaitForConnect?"yes":"no");
3149 extern OOH323EndPoint gH323ep;
3150 ast_cli(a->fd, "%-20s%s\n", "FASTSTART",
3151 (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no");
3152 ast_cli(a->fd, "%-20s%s\n", "TUNNELING",
3153 (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no");
3154 ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN",
3155 (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no");
3158 if (gRasGkMode == RasNoGatekeeper)
3159 snprintf(value, sizeof(value), "%s", "No Gatekeeper");
3160 else if (gRasGkMode == RasDiscoverGatekeeper)
3161 snprintf(value, sizeof(value), "%s", "Discover");
3163 snprintf(value, sizeof(value), "%s", gGatekeeper);
3165 ast_cli(a->fd, "%-20s%s\n", "Gatekeeper:", value);
3167 ast_cli(a->fd, "%-20s%s\n", "H.323 LogFile:", gLogFile);
3169 ast_cli(a->fd, "%-20s%s\n", "Context:", gContext);
3171 ast_cli(a->fd, "%-20s%s\n", "Capability:",
3172 ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCap));
3174 ast_cli(a->fd, "%-20s", "DTMF Mode: ");
3175 if (gDTMFMode & H323_DTMF_CISCO) {
3176 ast_cli(a->fd, "%s\n", "cisco");
3177 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec);
3178 } else if (gDTMFMode & H323_DTMF_RFC2833) {
3179 ast_cli(a->fd, "%s\n", "rfc2833");
3180 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec);
3181 } else if (gDTMFMode & H323_DTMF_Q931)
3182 ast_cli(a->fd, "%s\n", "q931keypad");
3183 else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC)
3184 ast_cli(a->fd, "%s\n", "h245alphanumeric");
3185 else if (gDTMFMode & H323_DTMF_H245SIGNAL)
3186 ast_cli(a->fd, "%s\n", "h245signal");
3187 else if (gDTMFMode & H323_DTMF_INBAND && gDTMFMode & H323_DTMF_INBANDRELAX)
3188 ast_cli(a->fd, "%s\n", "inband-relaxed");
3189 else if (gDTMFMode & H323_DTMF_INBAND)
3190 ast_cli(a->fd, "%s\n", "inband");
3192 ast_cli(a->fd, "%s\n", "unknown");
3194 ast_cli(a->fd,"%-20s", "T.38 Mode: ");
3195 if (gT38Support == T38_DISABLED)
3196 ast_cli(a->fd, "%s\n", "disabled");
3197 else if (gT38Support == T38_FAXGW)
3198 ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
3200 if (gRTDRCount && gRTDRInterval)
3201 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval);
3203 ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber);
3204 ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode);
3206 ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_cdr_flags2str(gAMAFLAGS));
3208 pAlias = gAliasList;
3210 ast_cli(a->fd, "%-20s\n", "Aliases: ");
3213 pAliasNext = pAlias->next;
3215 ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value);
3216 pAlias = pAliasNext->next;
3219 ast_cli(a->fd,"\t%-30s\n",pAlias->value);
3220 pAlias = pAlias->next;
3226 static struct ast_cli_entry cli_ooh323[] = {
3227 AST_CLI_DEFINE(handle_cli_ooh323_set_debug, "Enable/Disable OOH323 debugging"),
3228 AST_CLI_DEFINE(handle_cli_ooh323_show_config, "Show details on global configuration of H.323 channel driver"),
3229 AST_CLI_DEFINE(handle_cli_ooh323_show_peer, "Show details on specific OOH323 peer"),
3230 AST_CLI_DEFINE(handle_cli_ooh323_show_peers, "Show defined OOH323 peers"),
3231 AST_CLI_DEFINE(handle_cli_ooh323_show_user, "Show details on specific OOH323 user"),
3232 AST_CLI_DEFINE(handle_cli_ooh323_show_users, "Show defined OOH323 users"),
3233 AST_CLI_DEFINE(handle_cli_ooh323_reload, "reload ooh323 config")
3237 static int load_module(void)
3240 struct ooAliases * pNewAlias = NULL;
3241 struct ooh323_peer *peer = NULL;
3242 struct ast_format tmpfmt;
3243 OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0};
3245 OOH323CALLBACKS h323Callbacks = {
3246 .onNewCallCreated = onNewCallCreated,
3247 .onAlerting = onAlerting,
3248 .onProgress = onProgress,
3249 .onIncomingCall = NULL,
3250 .onOutgoingCall = onOutgoingCall,
3251 .onCallEstablished = onCallEstablished,
3252 .onCallCleared = onCallCleared,
3253 .openLogicalChannels = NULL,
3254 .onReceivedDTMF = ooh323_onReceivedDigit,
3255 .onModeChanged = onModeChanged
3257 if (!(gCap = ast_format_cap_alloc())) {
3260 if (!(ooh323_tech.capabilities = ast_format_cap_alloc())) {
3263 ast_format_cap_add(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
3264 ast_format_cap_add_all(ooh323_tech.capabilities);
3266 myself = ast_module_info->self;
3268 h225Callbacks.onReceivedSetup = &ooh323_onReceivedSetup;
3271 ast_mutex_init(&userl.lock);
3273 ast_mutex_init(&peerl.lock);
3276 ast_register_atexit(&ast_ooh323c_exit);
3279 if (!(sched = ast_sched_context_create())) {
3280 ast_log(LOG_WARNING, "Unable to create schedule context\n");
3282 if (!(io = io_context_create())) {
3283 ast_log(LOG_WARNING, "Unable to create I/O context\n");
3287 if (!(res = reload_config(0))) {
3288 /* Make sure we can register our OOH323 channel type */
3289 if (ast_channel_register(&ooh323_tech)) {
3290 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
3293 ast_rtp_glue_register(&ooh323_rtp);
3294 ast_udptl_proto_register(&ooh323_udptl);
3295 ast_cli_register_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
3297 /* fire up the H.323 Endpoint */
3298 if (OO_OK != ooH323EpInitialize(OO_CALLMODE_AUDIOCALL, gLogFile)) {
3299 ast_log(LOG_ERROR, "Failed to initialize OOH323 endpoint-"
3300 "OOH323 Disabled\n");
3305 ooH323EpSetAsGateway();
3307 ooH323EpSetVersionInfo(t35countrycode, t35extensions, manufacturer,
3309 ooH323EpDisableAutoAnswer();
3310 ooH323EpSetH225MsgCallbacks(h225Callbacks);
3311 ooH323EpSetTraceLevel(gTRCLVL);
3312 ooH323EpSetLocalAddress(gIP, gPort);
3314 ast_debug(1, "OOH323 channel is in IP6 mode\n");
3316 ooH323EpSetCallerID(gCallerID);
3318 if(ooH323EpSetTCPPortRange(ooconfig.mTCPPortStart,
3319 ooconfig.mTCPPortEnd) == OO_FAILED) {
3320 ast_log(LOG_ERROR, "h225portrange: Failed to set range\n");
3323 /* Set aliases if any */
3324 for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
3325 switch (pNewAlias->type) {
3326 case T_H225AliasAddress_h323_ID:
3327 ooH323EpAddAliasH323ID(pNewAlias->value);
3329 case T_H225AliasAddress_dialedDigits:
3330 ooH323EpAddAliasDialedDigits(pNewAlias->value);
3332 case T_H225AliasAddress_email_ID:
3333 ooH323EpAddAliasEmailID(pNewAlias->value);
3340 ast_mutex_lock(&peerl.lock);
3343 if(peer->h323id) ooH323EpAddAliasH323ID(peer->h323id);
3344 if(peer->email) ooH323EpAddAliasEmailID(peer->email);
3345 if(peer->e164) ooH323EpAddAliasDialedDigits(peer->e164);
3346 if(peer->url) ooH323EpAddAliasURLID(peer->url);
3349 ast_mutex_unlock(&peerl.lock);
3352 if (gMediaWaitForConnect)
3353 ooH323EpEnableMediaWaitForConnect();
3355 ooH323EpDisableMediaWaitForConnect();
3357 /* Fast start and tunneling options */
3359 ooH323EpEnableFastStart();
3361 ooH323EpDisableFastStart();
3364 ooH323EpDisableH245Tunneling();
3367 ooH323EpTryBeMaster(1);
3369 ooH323EpEnableManualRingback();
3372 if (gRasGkMode == RasUseSpecificGatekeeper)
3373 ooGkClientInit(gRasGkMode, gGatekeeper, 0);
3374 else if (gRasGkMode == RasDiscoverGatekeeper)
3375 ooGkClientInit(gRasGkMode, 0, 0);
3377 /* Register callbacks */
3378 ooH323EpSetH323Callbacks(h323Callbacks);
3380 /* Add endpoint capabilities */
3381 if (ooh323c_set_capability(&gPrefs, gCap, gDTMFMode, gDTMFCodec) < 0) {
3382 ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
3386 /* Create H.323 listener */
3387 if (ooCreateH323Listener() != OO_OK) {
3388 ast_log(LOG_ERROR, "OOH323 Listener Creation failure. "
3389 "OOH323 DISABLED\n");
3395 if (ooh323c_start_stack_thread() < 0) {
3396 ast_log(LOG_ERROR, "Failed to start OOH323 stack thread. "
3397 "OOH323 DISABLED\n");
3401 /* And start the monitor for the first time */
3409 static void *do_monitor(void *data)
3413 struct ooh323_pvt *h323 = NULL;
3417 struct ooh323_pvt *h323_next;
3418 /* Check for a reload request */
3419 ast_mutex_lock(&h323_reload_lock);
3420 reloading = h323_reloading;
3422 ast_mutex_unlock(&h323_reload_lock);
3424 ast_verb(1, "Reloading H.323\n");
3428 /* Check for interfaces needing to be killed */
3429 ast_mutex_lock(&iflock);
3433 h323_next = h323->next;
3435 /* TODO: Need to add rtptimeout keepalive support */
3436 if (ast_test_flag(h323, H323_NEEDDESTROY)) {
3437 ooh323_destroy (h323);
3438 } /* else if (ast_test_flag(h323, H323_NEEDSTART) && h323->owner) {
3439 ast_channel_lock(h323->owner);
3440 if (ast_pbx_start(h323->owner)) {
3441 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", h323->owner->name);
3442 ast_channel_unlock(h323->owner);
3443 ast_hangup(h323->owner);
3445 ast_channel_unlock(h323->owner);
3446 ast_clear_flag(h323, H323_NEEDSTART);
3450 ast_mutex_unlock(&iflock);
3451 pthread_testcancel();
3453 /* Wait for sched or io */
3454 res = ast_sched_wait(sched);
3455 if ((res < 0) || (res > 1000)) {
3458 res = ast_io_wait(io, res);
3459 pthread_testcancel();
3460 ast_mutex_lock(&monlock);
3462 ast_sched_runq(sched);