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, const char *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, const 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);
92 static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result);
93 void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort);
95 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
97 struct ooh323_peer *find_friend(const char *name, int port);
100 static struct ast_channel_tech ooh323_tech = {
102 .description = tdesc,
103 .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
104 .requester = ooh323_request,
105 .send_digit_begin = ooh323_digit_begin,
106 .send_digit_end = ooh323_digit_end,
108 .hangup = ooh323_hangup,
109 .answer = ooh323_answer,
111 .write = ooh323_write,
112 .exception = ooh323_read,
113 .indicate = ooh323_indicate,
114 .fixup = ooh323_fixup,
116 .queryoption = ooh323_queryoption,
117 .early_bridge = ast_rtp_instance_early_bridge,
118 .func_channel_read = function_ooh323_read,
119 .func_channel_write = function_ooh323_write,
122 static struct ast_rtp_glue ooh323_rtp = {
124 .get_rtp_info = ooh323_get_rtp_peer,
125 .get_vrtp_info = ooh323_get_vrtp_peer,
126 .update_peer = ooh323_set_rtp_peer,
127 .get_codec = ooh323_get_codec,
133 /* H.323 channel private structure */
134 static struct ooh323_pvt {
135 ast_mutex_t lock; /* Channel private lock */
136 ast_cond_t rtpcond; /* RTP condition */
137 struct ast_rtp_instance *rtp;
138 struct ast_sockaddr redirip; /* redir ip */
139 struct ast_rtp_instance *vrtp; /* Placeholder for now */
141 int t38support; /* T.38 mode - disable, transparent, faxgw */
145 struct ast_udptl *udptl;
149 struct ast_sockaddr udptlredirip;
153 struct ast_channel *owner; /* Master Channel */
155 char *user; /* cooperating user/peer */
161 unsigned int call_reference;
167 char caller_h323id[AST_MAX_EXTENSION];
168 char caller_dialedDigits[AST_MAX_EXTENSION];
169 char caller_email[AST_MAX_EXTENSION];
170 char caller_url[256];
171 char callee_h323id[AST_MAX_EXTENSION];
172 char callee_dialedDigits[AST_MAX_EXTENSION];
173 char callee_email[AST_MAX_EXTENSION];
174 char callee_url[AST_MAX_EXTENSION];
177 struct ast_format readformat; /* negotiated read format */
178 struct ast_format writeformat; /* negotiated write format */
179 struct ast_format_cap *cap;
180 struct ast_codec_pref prefs;
183 char exten[AST_MAX_EXTENSION]; /* Requested extension */
184 char context[AST_MAX_EXTENSION]; /* Context where to start */
185 char accountcode[256]; /* Account code */
188 int progsent; /* progress is sent */
189 int alertsent; /* alerting is sent */
190 int directrtp; /* direct rtp */
191 int earlydirect; /* early direct rtp */
192 int g729onlyA; /* G.729 only A */
194 struct OOH323Regex *rtpmask; /* rtp ip regexp */
195 char rtpmaskstr[120];
196 int rtdrcount, rtdrinterval; /* roundtripdelayreq */
197 int faststart, h245tunneling; /* faststart & h245 tunneling */
198 int aniasdni; /* use dialed number as answering identification */
199 struct ooh323_pvt *next; /* Next entity */
202 /* Protect the channel/interface list (ooh323_pvt) */
203 AST_MUTEX_DEFINE_STATIC(iflock);
205 /* Profile of H.323 user registered with PBX*/
209 char context[AST_MAX_EXTENSION];
212 char accountcode[20];
214 struct ast_format_cap *cap;
215 struct ast_codec_pref prefs;
221 int mUseIP; /* Use IP address or H323-ID to search user */
222 char mIP[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
223 struct OOH323Regex *rtpmask;
224 char rtpmaskstr[120];
225 int rtdrcount, rtdrinterval;
227 int faststart, h245tunneling;
232 struct ooh323_user *next;
235 /* Profile of valid asterisk peers */
239 unsigned outgoinglimit;
241 struct ast_format_cap *cap;
242 struct ast_codec_pref prefs;
243 char accountcode[20];
249 int mFriend; /* indicates defined as friend */
250 char ip[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
252 char *h323id; /* H323-ID alias, which asterisk will register with gk to reach this peer*/
253 char *email; /* Email alias, which asterisk will register with gk to reach this peer*/
254 char *url; /* url alias, which asterisk will register with gk to reach this peer*/
255 char *e164; /* e164 alias, which asterisk will register with gk to reach this peer*/
257 struct OOH323Regex *rtpmask;
258 char rtpmaskstr[120];
259 int rtdrcount,rtdrinterval;
261 int faststart, h245tunneling;
265 struct ooh323_peer *next;
269 /* List of H.323 users known to PBX */
270 static struct ast_user_list {
271 struct ooh323_user *users;
275 static struct ast_peer_list {
276 struct ooh323_peer *peers;
280 /* Mutex to protect H.323 reload process */
281 static int h323_reloading = 0;
282 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
284 /* Mutex to protect usage counter */
285 static int usecnt = 0;
286 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
288 static long callnumber = 0;
289 AST_MUTEX_DEFINE_STATIC(ooh323c_cn_lock);
291 /* stack callbacks */
292 int onAlerting(ooCallData *call);
293 int onProgress(ooCallData *call);
294 int onNewCallCreated(ooCallData *call);
295 int onOutgoingCall(ooCallData *call);
296 int onCallEstablished(ooCallData *call);
297 int onCallCleared(ooCallData *call);
298 void onModeChanged(ooCallData *call, int t38mode);
300 extern OOH323EndPoint gH323ep;
302 static char gLogFile[256] = DEFAULT_LOGFILE;
303 static int gPort = 1720;
304 static char gIP[2+8*4+7]; /* Max for IPv6 addr */
305 struct ast_sockaddr bindaddr;
307 static char gCallerID[AST_MAX_EXTENSION] = "";
308 static struct ooAliases *gAliasList;
309 static struct ast_format_cap *gCap;
310 static struct ast_codec_pref gPrefs;
311 static int gDTMFMode = H323_DTMF_RFC2833;
312 static int gDTMFCodec = 101;
313 static int gFAXdetect = FAXDETECT_CNG;
314 static int gT38Support = T38_FAXGW;
315 static char gGatekeeper[100];
316 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
318 static int gIsGateway = 0;
319 static int gFastStart = 1;
320 static int gTunneling = 1;
321 static int gBeMaster = 0;
322 static int gMediaWaitForConnect = 0;
323 static int gDirectRTP = 0;
324 static int gEarlyDirect = 0;
326 static int gRTPTimeout = 60;
327 static int g729onlyA = 0;
328 static char gAccountcode[80] = DEFAULT_H323ACCNT;
329 static int gAMAFLAGS;
330 static char gContext[AST_MAX_EXTENSION] = DEFAULT_CONTEXT;
331 static int gIncomingLimit = 1024;
332 static int gOutgoingLimit = 1024;
333 OOBOOL gH323Debug = FALSE;
334 static int gTRCLVL = OOTRCLVLERR;
335 static int gRTDRCount = 0, gRTDRInterval = 0;
336 static int gNat = FALSE;
337 static int gANIasDNI = 0;
339 static int t35countrycode = 0;
340 static int t35extensions = 0;
341 static int manufacturer = 0;
342 static char vendor[AST_MAX_EXTENSION] = "";
343 static char version[AST_MAX_EXTENSION] = "";
345 static struct ooh323_config
351 /** Asterisk RTP stuff*/
352 static struct ast_sched_context *sched;
353 static struct io_context *io;
355 /* Protect the monitoring thread, so only one process can kill or start it,
356 and not when it's doing something critical. */
357 AST_MUTEX_DEFINE_STATIC(monlock);
360 /* This is the thread for the monitor which checks for input on the channels
361 which are not currently in use. */
362 static pthread_t monitor_thread = AST_PTHREADT_NULL;
365 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
366 const char *host, struct ast_format_cap *cap, const char *linkedid)
368 struct ast_channel *ch = NULL;
369 struct ast_format tmpfmt;
373 ast_verb(0, "--- ooh323_new - %s\n", host);
376 ast_format_clear(&tmpfmt);
377 /* Don't hold a h323 pvt lock while we allocate a channel */
378 ast_mutex_unlock(&i->lock);
379 ast_mutex_lock(&ooh323c_cn_lock);
380 ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,
381 i->accountcode, i->exten, i->context, linkedid, i->amaflags,
382 "OOH323/%s-%ld", host, callnumber);
384 ast_mutex_unlock(&ooh323c_cn_lock);
386 ast_mutex_lock(&i->lock);
389 ast_channel_tech_set(ch, &ooh323_tech);
392 ast_best_codec(cap, &tmpfmt);
394 ast_codec_pref_index(&i->prefs, 0, &tmpfmt);
396 ast_format_cap_add(ast_channel_nativeformats(ch), &tmpfmt);
397 ast_format_copy(ast_channel_rawwriteformat(ch), &tmpfmt);
398 ast_format_copy(ast_channel_rawreadformat(ch), &tmpfmt);
400 ast_jb_configure(ch, &global_jbconf);
402 if (state == AST_STATE_RING)
403 ast_channel_rings_set(ch, 1);
405 ast_channel_adsicpe_set(ch, AST_ADSI_UNAVAILABLE);
406 ast_set_write_format(ch, &tmpfmt);
407 ast_set_read_format(ch, &tmpfmt);
408 ast_channel_tech_pvt_set(ch, i);
410 ast_module_ref(myself);
412 /* Allocate dsp for in-band DTMF support */
413 if ((i->dtmfmode & H323_DTMF_INBAND) || (i->faxdetect & FAXDETECT_CNG)) {
414 i->vad = ast_dsp_new();
418 if (i->dtmfmode & H323_DTMF_INBAND) {
419 features |= DSP_FEATURE_DIGIT_DETECT;
420 if (i->dtmfmode & H323_DTMF_INBANDRELAX) {
421 ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
426 if (i->faxdetect & FAXDETECT_CNG) {
427 features |= DSP_FEATURE_FAX_DETECT;
428 ast_dsp_set_faxmode(i->vad,
429 DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
433 ast_dsp_set_features(i->vad, features);
436 ast_mutex_lock(&usecnt_lock);
438 ast_mutex_unlock(&usecnt_lock);
440 /* Notify the module monitors that use count for resource has changed*/
441 ast_update_use_count();
443 ast_channel_context_set(ch, i->context);
444 ast_channel_exten_set(ch, i->exten);
446 ast_channel_priority_set(ch, 1);
448 if(!ast_test_flag(i, H323_OUTGOING)) {
450 if (!ast_strlen_zero(i->caller_h323id)) {
451 pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
454 if (!ast_strlen_zero(i->caller_dialedDigits)) {
455 pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS",
456 i->caller_dialedDigits);
458 if (!ast_strlen_zero(i->caller_email)) {
459 pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL",
462 if (!ast_strlen_zero(i->caller_url)) {
463 pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url);
467 if (!ast_strlen_zero(i->accountcode))
468 ast_channel_accountcode_set(ch, i->accountcode);
471 ast_channel_amaflags_set(ch, i->amaflags);
473 ast_setstate(ch, state);
474 if (state != AST_STATE_DOWN) {
475 if (ast_pbx_start(ch)) {
476 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));
477 ast_channel_unlock(ch);
484 ast_publish_channel_state(ch);
488 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
491 if(ch) ast_channel_unlock(ch);
494 ast_verb(0, "+++ h323_new\n");
502 static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
504 struct ooh323_pvt *pvt = NULL;
507 ast_verb(0, "--- ooh323_alloc\n");
510 if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
511 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
514 if (!(pvt->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
516 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
520 ast_mutex_init(&pvt->lock);
521 ast_mutex_lock(&pvt->lock);
525 pvt->faxdetected = 0;
526 pvt->faxdetect = gFAXdetect;
527 pvt->t38support = gT38Support;
528 pvt->rtptimeout = gRTPTimeout;
530 pvt->rtdrinterval = gRTDRInterval;
531 pvt->rtdrcount = gRTDRCount;
532 pvt->g729onlyA = g729onlyA;
534 pvt->call_reference = callref;
536 pvt->callToken = strdup(callToken);
538 /* whether to use gk for this call */
539 if (gRasGkMode == RasNoGatekeeper)
540 OO_SETFLAG(pvt->flags, H323_DISABLEGK);
542 pvt->dtmfmode = gDTMFMode;
543 pvt->dtmfcodec = gDTMFCodec;
544 ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
545 ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
547 pvt->amaflags = gAMAFLAGS;
548 ast_format_cap_copy(pvt->cap, gCap);
549 memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
551 pvt->aniasdni = gANIasDNI;
553 ast_mutex_unlock(&pvt->lock);
554 /* Add to interface list */
555 ast_mutex_lock(&iflock);
558 ast_mutex_unlock(&iflock);
561 ast_verb(0, "+++ ooh323_alloc\n");
569 Possible data values - peername, exten/peername, exten@ip
571 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
572 const struct ast_channel *requestor, const char *data, int *cause)
575 struct ast_channel *chan = NULL;
576 struct ooh323_pvt *p = NULL;
577 struct ooh323_peer *peer = NULL;
581 char formats[FORMAT_STRING_SIZE];
585 ast_verb(0, "--- ooh323_request - data %s format %s\n", data,
586 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
588 if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
589 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
593 p = ooh323_alloc(0,0); /* Initial callRef is zero */
596 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", data);
599 ast_mutex_lock(&p->lock);
601 /* This is an outgoing call, since ooh323_request is called */
602 ast_set_flag(p, H323_OUTGOING);
605 ast_copy_string(tmp, data, sizeof(tmp));
607 dest = strchr(tmp, '/');
614 } else if ((dest = strchr(tmp, '@'))) {
624 if ((sport = strchr(dest, ':'))) {
632 peer = find_peer(dest, port);
634 ast_mutex_lock(&iflock);
635 ast_mutex_unlock(&p->lock);
637 ast_mutex_unlock(&iflock);
638 ast_log(LOG_ERROR, "Destination format is not supported\n");
639 *cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
644 p->username = strdup(peer->name);
645 p->host = strdup(peer->ip);
646 p->port = peer->port;
647 /* Disable gk as we are going to call a known peer*/
648 /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
651 ast_copy_string(p->exten, ext, sizeof(p->exten));
653 ast_format_cap_copy(p->cap, peer->cap);
654 memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
655 p->g729onlyA = peer->g729onlyA;
656 p->dtmfmode |= peer->dtmfmode;
657 p->dtmfcodec = peer->dtmfcodec;
658 p->faxdetect = peer->faxdetect;
659 p->t38support = peer->t38support;
660 p->rtptimeout = peer->rtptimeout;
662 p->faststart = peer->faststart;
663 p->h245tunneling = peer->h245tunneling;
664 p->directrtp = peer->directrtp;
665 p->earlydirect = peer->earlydirect;
666 if (peer->rtpmask && peer->rtpmaskstr[0]) {
667 p->rtpmask = peer->rtpmask;
668 ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
671 if (peer->rtdrinterval) {
672 p->rtdrinterval = peer->rtdrinterval;
673 p->rtdrcount = peer->rtdrcount;
676 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
677 p->amaflags = peer->amaflags;
679 if (gRasGkMode == RasNoGatekeeper) {
680 /* no gk and no peer */
681 ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
682 ast_mutex_lock(&iflock);
683 ast_mutex_unlock(&p->lock);
685 ast_mutex_unlock(&iflock);
687 } else if (!gH323ep.gkClient || (gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered)) {
688 ast_log(LOG_ERROR, "Gatekeeper client is configured but not registered\n");
689 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
692 p->g729onlyA = g729onlyA;
693 p->dtmfmode = gDTMFMode;
694 p->dtmfcodec = gDTMFCodec;
695 p->faxdetect = gFAXdetect;
696 p->t38support = gT38Support;
697 p->rtptimeout = gRTPTimeout;
699 ast_format_cap_copy(p->cap, gCap);
700 p->rtdrinterval = gRTDRInterval;
701 p->rtdrcount = gRTDRCount;
702 p->faststart = gFastStart;
703 p->h245tunneling = gTunneling;
704 p->directrtp = gDirectRTP;
705 p->earlydirect = gEarlyDirect;
707 memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));
708 p->username = strdup(dest);
710 p->host = strdup(dest);
715 ast_copy_string(p->exten, ext, sizeof(p->exten));
720 chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
721 requestor ? ast_channel_linkedid(requestor) : NULL);
723 ast_mutex_unlock(&p->lock);
726 ast_mutex_lock(&iflock);
728 ast_mutex_unlock(&iflock);
730 ast_mutex_lock(&p->lock);
731 p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
733 ast_mutex_unlock(&p->lock);
734 ast_mutex_lock(&iflock);
736 ast_mutex_unlock(&iflock);
737 ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
741 ast_mutex_unlock(&p->lock);
742 ast_cond_init(&p->rtpcond, NULL);
743 ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
744 ast_mutex_lock(&p->lock);
746 ast_cond_wait(&p->rtpcond, &p->lock);
748 ast_mutex_unlock(&p->lock);
749 ast_cond_destroy(&p->rtpcond);
754 ast_verb(0, "+++ ooh323_request\n");
761 static struct ooh323_pvt* find_call(ooCallData *call)
763 struct ooh323_pvt *p;
766 ast_verb(0, "--- find_call\n");
768 ast_mutex_lock(&iflock);
770 for (p = iflist; p; p = p->next) {
771 if (p->callToken && !strcmp(p->callToken, call->callToken)) {
775 ast_mutex_unlock(&iflock);
778 ast_verb(0, "+++ find_call\n");
783 struct ooh323_user *find_user(const char * name, const char* ip)
785 struct ooh323_user *user;
788 ast_verb(0, "--- find_user: %s, %s\n",name,ip);
790 ast_mutex_lock(&userl.lock);
792 for (user = userl.users; user; user = user->next) {
793 if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
796 if (name && !strcmp(user->name, name)) {
801 ast_mutex_unlock(&userl.lock);
804 ast_verb(0, "+++ find_user\n");
809 struct ooh323_peer *find_friend(const char *name, int port)
811 struct ooh323_peer *peer;
814 ast_verb(0, "--- find_friend \"%s\"\n", name);
817 ast_mutex_lock(&peerl.lock);
818 for (peer = peerl.peers; peer; peer = peer->next) {
820 ast_verb(0, " comparing with \"%s\"\n", peer->ip);
822 if (!strcmp(peer->ip, name)) {
823 if (port <= 0 || (port > 0 && peer->port == port)) {
828 ast_mutex_unlock(&peerl.lock);
832 ast_verb(0, " found matching friend\n");
834 ast_verb(0, "+++ find_friend \"%s\"\n", name);
841 struct ooh323_peer *find_peer(const char * name, int port)
843 struct ooh323_peer *peer;
846 ast_verb(0, "--- find_peer \"%s\"\n", name);
849 ast_mutex_lock(&peerl.lock);
850 for (peer = peerl.peers; peer; peer = peer->next) {
852 ast_verb(0, " comparing with \"%s\"\n", peer->ip);
854 if (!strcasecmp(peer->name, name))
856 if (peer->h323id && !strcasecmp(peer->h323id, name))
858 if (peer->e164 && !strcasecmp(peer->e164, name))
861 if (!strcmp(peer->ip, name)) {
862 if (port > 0 && peer->port == port) { break; }
863 else if (port <= 0) { break; }
867 ast_mutex_unlock(&peerl.lock);
871 ast_verb(0, " found matching peer\n");
873 ast_verb(0, "+++ find_peer \"%s\"\n", name);
879 static int ooh323_digit_begin(struct ast_channel *chan, char digit)
882 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
886 ast_verb(0, "--- ooh323_digit_begin\n");
889 ast_log(LOG_ERROR, "No private structure for call\n");
892 ast_mutex_lock(&p->lock);
894 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
895 ast_rtp_instance_dtmf_begin(p->rtp, digit);
896 } else if (((p->dtmfmode & H323_DTMF_Q931) ||
897 (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
898 (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
901 ooSendDTMFDigit(p->callToken, dtmf);
902 } else if (p->dtmfmode & H323_DTMF_INBAND) {
903 res = -1; // tell Asterisk to generate inband indications
905 ast_mutex_unlock(&p->lock);
908 ast_verb(0, "+++ ooh323_digit_begin, res = %d\n", res);
913 static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
915 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
919 ast_verb(0, "--- ooh323_digit_end\n");
922 ast_log(LOG_ERROR, "No private structure for call\n");
925 ast_mutex_lock(&p->lock);
926 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) {
927 ast_rtp_instance_dtmf_end(p->rtp, digit);
928 } else if(p->dtmfmode & H323_DTMF_INBAND) {
929 res = -1; // tell Asterisk to stop inband indications
932 ast_mutex_unlock(&p->lock);
935 ast_verb(0, "+++ ooh323_digit_end, res = %d\n", res);
941 static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout)
943 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
944 char destination[256];
946 const char *val = NULL;
947 ooCallOptions opts = {
951 .callMode = OO_CALLMODE_AUDIOCALL,
956 ast_verb(0, "--- ooh323_call- %s\n", dest);
959 if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
960 ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
961 "reserved\n", ast_channel_name(ast));
964 ast_mutex_lock(&p->lock);
965 ast_set_flag(p, H323_OUTGOING);
966 if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
967 free(p->callerid_num);
968 p->callerid_num = strdup(ast_channel_connected(ast)->id.number.str);
971 if (ast_channel_connected(ast)->id.name.valid && ast_channel_connected(ast)->id.name.str) {
972 free(p->callerid_name);
973 p->callerid_name = strdup(ast_channel_connected(ast)->id.name.str);
974 } else if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
975 free(p->callerid_name);
976 p->callerid_name = strdup(ast_channel_connected(ast)->id.number.str);
978 ast_channel_connected(ast)->id.name.valid = 1;
979 free(ast_channel_connected(ast)->id.name.str);
980 ast_channel_connected(ast)->id.name.str = strdup(gCallerID);
981 free(p->callerid_name);
982 p->callerid_name = strdup(ast_channel_connected(ast)->id.name.str);
988 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
989 ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
992 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
993 ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
995 p->callerid_num = strdup(val);
998 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
999 ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
1002 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
1003 ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
1006 if (p->host && p->port != 0)
1007 snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
1009 snprintf(destination, sizeof(destination), "%s", p->host);
1011 ast_copy_string(destination, dest, sizeof(destination));
1013 destination[sizeof(destination)-1]='\0';
1015 opts.transfercap = ast_channel_transfercapability(ast);
1016 opts.fastStart = p->faststart;
1017 opts.tunneling = p->h245tunneling;
1019 for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
1021 if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
1022 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
1024 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
1027 ast_mutex_unlock(&p->lock);
1029 ast_log(LOG_ERROR, "Failed to make call\n");
1030 return -1; /* ToDO: cleanup */
1033 ast_verb(0, "+++ ooh323_call\n");
1038 static int ooh323_hangup(struct ast_channel *ast)
1040 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1041 int q931cause = AST_CAUSE_NORMAL_CLEARING;
1044 ast_verb(0, "--- ooh323_hangup\n");
1047 ast_mutex_lock(&p->lock);
1049 if (ast_channel_hangupcause(ast)) {
1050 q931cause = ast_channel_hangupcause(ast);
1052 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
1054 if (!strcmp(cause, "CONGESTION")) {
1055 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1056 } else if (!strcmp(cause, "BUSY")) {
1057 q931cause = AST_CAUSE_USER_BUSY;
1058 } else if (!strcmp(cause, "CHANISUNVAIL")) {
1059 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1060 } else if (!strcmp(cause, "NOANSWER")) {
1061 q931cause = AST_CAUSE_NO_ANSWER;
1062 } else if (!strcmp(cause, "CANCEL")) {
1063 q931cause = AST_CAUSE_CALL_REJECTED;
1071 ast_verb(0, " hanging %s with cause: %d\n", p->username, q931cause);
1072 ast_channel_tech_pvt_set(ast, NULL);
1073 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1074 ooHangCall(p->callToken,
1075 ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
1076 ast_set_flag(p, H323_ALREADYGONE);
1077 /* ast_mutex_unlock(&p->lock); */
1079 ast_set_flag(p, H323_NEEDDESTROY);
1080 /* detach channel here */
1082 ast_channel_tech_pvt_set(p->owner, NULL);
1084 ast_module_unref(myself);
1087 ast_mutex_unlock(&p->lock);
1088 ast_mutex_lock(&usecnt_lock);
1090 ast_mutex_unlock(&usecnt_lock);
1092 /* Notify the module monitors that use count for resource has changed */
1093 ast_update_use_count();
1096 ast_debug(1, "No call to hangup\n" );
1100 ast_verb(0, "+++ ooh323_hangup\n");
1105 static int ooh323_answer(struct ast_channel *ast)
1107 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1108 char *callToken = (char *)NULL;
1111 ast_verb(0, "--- ooh323_answer\n");
1115 ast_mutex_lock(&p->lock);
1116 callToken = (p->callToken ? strdup(p->callToken) : NULL);
1117 if (ast_channel_state(ast) != AST_STATE_UP) {
1118 ast_channel_lock(ast);
1119 if (!p->alertsent) {
1121 ast_debug(1, "Sending forced ringback for %s, res = %d\n",
1122 callToken, ooManualRingback(callToken));
1124 ooManualRingback(callToken);
1128 ast_setstate(ast, AST_STATE_UP);
1130 ast_debug(1, "ooh323_answer(%s)\n", ast_channel_name(ast));
1131 ast_channel_unlock(ast);
1132 ooAnswerCall(p->callToken);
1137 ast_mutex_unlock(&p->lock);
1141 ast_verb(0, "+++ ooh323_answer\n");
1146 static struct ast_frame *ooh323_read(struct ast_channel *ast)
1148 struct ast_frame *fr;
1149 static struct ast_frame null_frame = { AST_FRAME_NULL, };
1150 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1152 if (!p) return &null_frame;
1154 ast_mutex_lock(&p->lock);
1156 fr = ooh323_rtp_read(ast, p);
1159 /* time(&p->lastrtprx); */
1160 ast_mutex_unlock(&p->lock);
1164 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
1166 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1171 ast_mutex_lock(&p->lock);
1173 p->lastrtptx = time(NULL);
1175 if (f->frametype == AST_FRAME_MODEM) {
1176 ast_debug(1, "Send UDPTL %d/%d len %d for %s\n",
1177 f->frametype, f->subclass.integer, f->datalen, ast_channel_name(ast));
1179 res = ast_udptl_write(p->udptl, f);
1180 ast_mutex_unlock(&p->lock);
1185 if (f->frametype == AST_FRAME_VOICE) {
1186 /* sending progress for first */
1187 if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
1189 ooManualProgress(p->callToken);
1194 if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
1195 if (!(ast_format_cap_is_empty(ast_channel_nativeformats(ast)))) {
1196 ast_log(LOG_WARNING,
1197 "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1198 ast_getformatname(&f->subclass.format),
1199 ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
1200 ast_getformatname(ast_channel_readformat(ast)),
1201 ast_getformatname(ast_channel_writeformat(ast)));
1203 ast_set_write_format(ast, &f->subclass.format);
1205 /* ast_set_write_format(ast, f->subclass);
1206 ast->nativeformats = f->subclass; */
1208 ast_mutex_unlock(&p->lock);
1213 res = ast_rtp_instance_write(p->rtp, f);
1215 ast_mutex_unlock(&p->lock);
1217 } else if (f->frametype == AST_FRAME_IMAGE) {
1218 ast_mutex_unlock(&p->lock);
1221 ast_log(LOG_WARNING, "Can't send %d type frames with OOH323 write\n",
1223 ast_mutex_unlock(&p->lock);
1232 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1235 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
1236 char *callToken = (char *)NULL;
1241 ast_mutex_lock(&p->lock);
1242 callToken = (p->callToken ? strdup(p->callToken) : NULL);
1243 ast_mutex_unlock(&p->lock);
1247 ast_verb(0, " ooh323_indicate - No callToken\n");
1251 if (!ast_sockaddr_isnull(&p->redirip)) {
1256 ast_verb(0, "----- ooh323_indicate %d on call %s\n", condition, callToken);
1259 ast_mutex_lock(&p->lock);
1260 switch (condition) {
1261 case AST_CONTROL_INCOMPLETE:
1262 /* While h323 does support overlapped dialing, this channel driver does not
1263 * at this time. Treat a response of Incomplete as if it were congestion.
1265 case AST_CONTROL_CONGESTION:
1266 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1267 ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
1270 case AST_CONTROL_BUSY:
1271 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1272 ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
1275 case AST_CONTROL_HOLD:
1276 ast_moh_start(ast, data, NULL);
1278 case AST_CONTROL_UNHOLD:
1281 case AST_CONTROL_PROGRESS:
1282 if (ast_channel_state(ast) != AST_STATE_UP) {
1285 ast_debug(1, "Sending manual progress for %s, res = %d\n", callToken,
1286 ooManualProgress(callToken));
1288 ooManualProgress(callToken);
1294 case AST_CONTROL_RINGING:
1295 if (ast_channel_state(ast) == AST_STATE_RING || ast_channel_state(ast) == AST_STATE_RINGING) {
1296 if (!p->alertsent) {
1298 ast_debug(1, "Sending manual ringback for %s, res = %d\n",
1300 ooManualRingback(callToken));
1302 ooManualRingback(callToken);
1309 case AST_CONTROL_SRCUPDATE:
1311 ast_rtp_instance_update_source(p->rtp);
1314 case AST_CONTROL_SRCCHANGE:
1316 ast_rtp_instance_change_source(p->rtp);
1319 case AST_CONTROL_CONNECTED_LINE:
1320 if (!ast_channel_connected(ast)->id.name.valid
1321 || ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
1325 ast_debug(1, "Sending connected line info for %s (%s)\n",
1326 callToken, ast_channel_connected(ast)->id.name.str);
1328 ooSetANI(callToken, ast_channel_connected(ast)->id.name.str);
1331 case AST_CONTROL_T38_PARAMETERS:
1332 if (p->t38support != T38_ENABLED) {
1333 struct ast_control_t38_parameters parameters = { .request_response = 0 };
1334 parameters.request_response = AST_T38_REFUSED;
1335 ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
1336 ¶meters, sizeof(parameters));
1339 if (datalen != sizeof(struct ast_control_t38_parameters)) {
1340 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
1341 "Expected %d, got %d\n",
1342 (int)sizeof(enum ast_control_t38), (int)datalen);
1344 const struct ast_control_t38_parameters *parameters = data;
1345 struct ast_control_t38_parameters our_parameters;
1346 enum ast_control_t38 message = parameters->request_response;
1349 case AST_T38_NEGOTIATED:
1354 case AST_T38_REQUEST_NEGOTIATE:
1357 /* T.38 already negotiated */
1358 our_parameters.request_response = AST_T38_NEGOTIATED;
1359 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1360 our_parameters.rate = AST_T38_RATE_14400;
1361 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1362 } else if (!p->chmodepend) {
1364 ooRequestChangeMode(p->callToken, 1);
1369 case AST_T38_REQUEST_TERMINATE:
1372 /* T.38 already terminated */
1373 our_parameters.request_response = AST_T38_TERMINATED;
1374 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1375 } else if (!p->chmodepend) {
1377 ooRequestChangeMode(p->callToken, 0);
1382 case AST_T38_REQUEST_PARMS:
1383 our_parameters.request_response = AST_T38_REQUEST_PARMS;
1384 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1385 our_parameters.rate = AST_T38_RATE_14400;
1386 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1387 res = AST_T38_REQUEST_PARMS;
1397 case AST_CONTROL_PROCEEDING:
1401 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
1402 condition, callToken);
1405 ast_mutex_unlock(&p->lock);
1408 ast_verb(0, "++++ ooh323_indicate %d on %s is %d\n", condition, callToken, res);
1415 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1418 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
1420 enum ast_t38_state state = T38_STATE_UNAVAILABLE;
1425 ast_mutex_lock(&p->lock);
1428 ast_verb(0, "----- ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
1432 case AST_OPTION_T38_STATE:
1434 if (*datalen != sizeof(enum ast_t38_state)) {
1435 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
1436 " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
1440 if (p->t38support != T38_DISABLED) {
1442 state = (p->chmodepend) ? T38_STATE_NEGOTIATING : T38_STATE_NEGOTIATED;
1444 state = T38_STATE_UNKNOWN;
1448 *((enum ast_t38_state *) data) = state;
1453 case AST_OPTION_DIGIT_DETECT:
1456 *cp = p->vad ? 1 : 0;
1457 ast_debug(1, "Reporting digit detection %sabled on %s\n",
1458 *cp ? "en" : "dis", ast_channel_name(ast));
1468 ast_verb(0, "+++++ ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
1470 ast_mutex_unlock(&p->lock);
1477 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1479 struct ooh323_pvt *p = ast_channel_tech_pvt(newchan);
1484 ast_verb(0, "--- ooh323c ooh323_fixup\n");
1486 ast_mutex_lock(&p->lock);
1487 if (p->owner != oldchan) {
1488 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
1489 ast_mutex_unlock(&p->lock);
1493 if (p->owner == oldchan) {
1499 ast_mutex_unlock(&p->lock);
1502 ast_verb(0, "+++ ooh323c ooh323_fixup \n");
1508 void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
1510 struct ooh323_pvt *p = NULL;
1511 char formats[FORMAT_STRING_SIZE];
1514 ast_verb(0, "--- ooh323_update_writeformat %s/%d\n",
1515 ast_getformatname(fmt), txframes);
1517 p = find_call(call);
1519 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1523 ast_mutex_lock(&p->lock);
1525 ast_format_copy(&(p->writeformat), fmt);
1528 while (p->owner && ast_channel_trylock(p->owner)) {
1529 ast_debug(1,"Failed to grab lock, trying again\n");
1530 DEADLOCK_AVOIDANCE(&p->lock);
1533 ast_mutex_unlock(&p->lock);
1534 ast_log(LOG_ERROR, "Channel has no owner\n");
1538 ast_verb(0, "Writeformat before update %s/%s\n",
1539 ast_getformatname(ast_channel_writeformat(p->owner)),
1540 ast_getformatname_multiple(formats, sizeof(formats), ast_channel_nativeformats(p->owner)));
1542 ast_codec_pref_setsize(&p->prefs, fmt, txframes);
1543 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
1544 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
1545 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1546 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
1548 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
1549 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1550 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
1553 ast_format_cap_set(ast_channel_nativeformats(p->owner), fmt);
1554 ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
1555 ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
1556 ast_channel_unlock(p->owner);
1558 ast_log(LOG_ERROR, "No owner found\n");
1561 ast_mutex_unlock(&p->lock);
1564 ast_verb(0, "+++ ooh323_update_writeformat\n");
1567 void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
1569 struct ooh323_pvt *p = NULL;
1572 ast_verb(0, "--- ooh323_update_readformat %s\n",
1573 ast_getformatname(fmt));
1575 p = find_call(call);
1577 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1581 ast_mutex_lock(&p->lock);
1583 ast_format_copy(&(p->readformat), fmt);
1586 while (p->owner && ast_channel_trylock(p->owner)) {
1587 ast_debug(1,"Failed to grab lock, trying again\n");
1588 DEADLOCK_AVOIDANCE(&p->lock);
1591 ast_mutex_unlock(&p->lock);
1592 ast_log(LOG_ERROR, "Channel has no owner\n");
1597 ast_verb(0, "Readformat before update %s\n",
1598 ast_getformatname(ast_channel_readformat(p->owner)));
1599 ast_format_cap_set(ast_channel_nativeformats(p->owner), fmt);
1600 ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
1601 ast_channel_unlock(p->owner);
1603 ast_log(LOG_ERROR, "No owner found\n");
1605 ast_mutex_unlock(&p->lock);
1608 ast_verb(0, "+++ ooh323_update_readformat\n");
1612 int onAlerting(ooCallData *call)
1614 struct ooh323_pvt *p = NULL;
1615 struct ast_channel *c = NULL;
1618 ast_verb(0, "--- onAlerting %s\n", call->callToken);
1620 p = find_call(call);
1623 ast_log(LOG_ERROR, "No matching call found\n");
1626 ast_mutex_lock(&p->lock);
1628 ast_mutex_unlock(&p->lock);
1629 ast_debug(1, "Channel has no owner\n");
1632 while (p->owner && ast_channel_trylock(p->owner)) {
1633 ast_debug(1, "Failed to grab lock, trying again\n");
1634 DEADLOCK_AVOIDANCE(&p->lock);
1637 ast_mutex_unlock(&p->lock);
1638 ast_log(LOG_ERROR, "Channel has no owner\n");
1643 if (call->remoteDisplayName) {
1644 struct ast_party_connected_line connected;
1645 struct ast_set_party_connected_line update_connected;
1647 memset(&update_connected, 0, sizeof(update_connected));
1648 update_connected.id.name = 1;
1649 ast_party_connected_line_init(&connected);
1650 connected.id.name.valid = 1;
1651 connected.id.name.str = (char *) call->remoteDisplayName;
1652 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1653 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1655 if (ast_channel_state(c) != AST_STATE_UP)
1656 ast_setstate(c, AST_STATE_RINGING);
1658 ast_queue_control(c, AST_CONTROL_RINGING);
1659 ast_channel_unlock(c);
1660 ast_mutex_unlock(&p->lock);
1663 ast_verb(0, "+++ onAlerting %s\n", call->callToken);
1668 int onProgress(ooCallData *call)
1670 struct ooh323_pvt *p = NULL;
1671 struct ast_channel *c = NULL;
1674 ast_verb(0, "--- onProgress %s\n", call->callToken);
1676 p = find_call(call);
1679 ast_log(LOG_ERROR, "No matching call found\n");
1682 ast_mutex_lock(&p->lock);
1684 ast_mutex_unlock(&p->lock);
1685 ast_log(LOG_ERROR, "Channel has no owner\n");
1688 while (p->owner && ast_channel_trylock(p->owner)) {
1689 ast_debug(1, "Failed to grab lock, trying again\n");
1690 DEADLOCK_AVOIDANCE(&p->lock);
1693 ast_mutex_unlock(&p->lock);
1694 ast_log(LOG_ERROR, "Channel has no owner\n");
1699 if (call->remoteDisplayName) {
1700 struct ast_party_connected_line connected;
1701 struct ast_set_party_connected_line update_connected;
1703 memset(&update_connected, 0, sizeof(update_connected));
1704 update_connected.id.name = 1;
1705 ast_party_connected_line_init(&connected);
1706 connected.id.name.valid = 1;
1707 connected.id.name.str = (char *) call->remoteDisplayName;
1708 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1709 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1711 if (ast_channel_state(c) != AST_STATE_UP)
1712 ast_setstate(c, AST_STATE_RINGING);
1714 ast_queue_control(c, AST_CONTROL_PROGRESS);
1715 ast_channel_unlock(c);
1716 ast_mutex_unlock(&p->lock);
1719 ast_verb(0, "+++ onProgress %s\n", call->callToken);
1725 * Callback for sending digits from H.323 up to asterisk
1728 int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
1730 struct ooh323_pvt *p = NULL;
1734 ast_debug(1, "Received Digit: %c\n", digit[0]);
1735 p = find_call(call);
1737 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1741 ast_log(LOG_ERROR, "Channel has no owner\n");
1744 ast_mutex_lock(&p->lock);
1745 memset(&f, 0, sizeof(f));
1746 f.frametype = AST_FRAME_DTMF;
1747 f.subclass.integer = digit[0];
1753 f.src = "SEND_DIGIT";
1755 while (p->owner && ast_channel_trylock(p->owner)) {
1756 ast_debug(1, "Failed to grab lock, trying again\n");
1757 DEADLOCK_AVOIDANCE(&p->lock);
1760 ast_mutex_unlock(&p->lock);
1761 ast_log(LOG_ERROR, "Channel has no owner\n");
1764 res = ast_queue_frame(p->owner, &f);
1765 ast_channel_unlock(p->owner);
1766 ast_mutex_unlock(&p->lock);
1770 int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
1772 struct ooh323_pvt *p = NULL;
1773 struct ooh323_user *user = NULL;
1774 struct ast_channel *c = NULL;
1775 ooAliases *alias = NULL;
1777 char number [OO_MAX_NUMBER_LENGTH];
1780 ast_verb(0, "--- ooh323_onReceivedSetup %s\n", call->callToken);
1783 if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
1784 ast_log(LOG_ERROR, "Failed to create a new call.\n");
1787 ast_mutex_lock(&p->lock);
1788 ast_clear_flag(p, H323_OUTGOING);
1791 if (call->remoteDisplayName) {
1792 p->callerid_name = strdup(call->remoteDisplayName);
1795 if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
1796 p->callerid_num = strdup(number);
1799 if (call->remoteAliases) {
1800 for (alias = call->remoteAliases; alias; alias = alias->next) {
1801 if (alias->type == T_H225AliasAddress_h323_ID) {
1802 if (!p->callerid_name) {
1803 p->callerid_name = strdup(alias->value);
1805 ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
1807 else if(alias->type == T_H225AliasAddress_dialedDigits)
1809 if(!p->callerid_num)
1810 p->callerid_num = strdup(alias->value);
1811 ast_copy_string(p->caller_dialedDigits, alias->value,
1812 sizeof(p->caller_dialedDigits));
1814 else if(alias->type == T_H225AliasAddress_email_ID)
1816 ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
1818 else if(alias->type == T_H225AliasAddress_url_ID)
1820 ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
1826 if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
1827 ast_copy_string(p->exten, number, sizeof(p->exten));
1829 update_our_aliases(call, p);
1830 if (!ast_strlen_zero(p->callee_dialedDigits)) {
1831 ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
1832 } else if(!ast_strlen_zero(p->callee_h323id)) {
1833 ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
1834 } else if(!ast_strlen_zero(p->callee_email)) {
1835 ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
1836 if ((at = strchr(p->exten, '@'))) {
1842 /* if no extension found, set to default 's' */
1843 if (ast_strlen_zero(p->exten)) {
1848 user = find_user(p->callerid_name, call->remoteIP);
1849 if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
1850 ast_mutex_lock(&user->lock);
1851 p->username = strdup(user->name);
1852 p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
1853 ast_strdup(user->name);
1854 ast_copy_string(p->context, user->context, sizeof(p->context));
1855 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
1856 p->amaflags = user->amaflags;
1857 ast_format_cap_copy(p->cap, user->cap);
1858 p->g729onlyA = user->g729onlyA;
1859 memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
1860 p->dtmfmode |= user->dtmfmode;
1861 p->dtmfcodec = user->dtmfcodec;
1862 p->faxdetect = user->faxdetect;
1863 p->t38support = user->t38support;
1864 p->rtptimeout = user->rtptimeout;
1866 p->h245tunneling = user->h245tunneling;
1867 p->faststart = user->faststart;
1868 p->directrtp = user->directrtp;
1869 p->earlydirect = user->earlydirect;
1872 OO_SETFLAG(call->flags, OO_M_FASTSTART);
1874 OO_CLRFLAG(call->flags, OO_M_FASTSTART);
1875 /* if we disable h245tun for this user then we clear flag */
1876 /* in any other case we don't must touch this */
1877 /* ie if we receive setup without h245tun but enabled
1878 we can't enable it per call */
1879 if (!p->h245tunneling)
1880 OO_CLRFLAG(call->flags, OO_M_TUNNELING);
1882 if (user->rtpmask && user->rtpmaskstr[0]) {
1883 p->rtpmask = user->rtpmask;
1884 ast_copy_string(p->rtpmaskstr, user->rtpmaskstr,
1885 sizeof(p->rtpmaskstr));
1887 if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
1888 p->rtdrcount = user->rtdrcount;
1889 p->rtdrinterval = user->rtdrinterval;
1892 p->aniasdni = user->aniasdni;
1894 if (user->incominglimit) user->inUse++;
1895 ast_mutex_unlock(&user->lock);
1897 if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
1898 p->username = strdup(call->remoteIP);
1899 p->directrtp = gDirectRTP;
1900 p->earlydirect = gEarlyDirect;
1902 ast_mutex_unlock(&p->lock);
1903 ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
1905 ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
1906 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1909 ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
1910 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1912 ast_set_flag(p, H323_NEEDDESTROY);
1917 ooh323c_set_capability_for_call(call, &p->prefs, p->cap, p->dtmfmode, p->dtmfcodec,
1918 p->t38support, p->g729onlyA);
1920 c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL);
1922 ast_mutex_unlock(&p->lock);
1923 ast_log(LOG_ERROR, "Could not create ast_channel\n");
1928 ooCallSetCallerId(call, p->exten);
1930 if (!configure_local_rtp(p, call)) {
1931 ast_mutex_unlock(&p->lock);
1932 ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
1936 ast_mutex_unlock(&p->lock);
1939 ast_verb(0, "+++ ooh323_onReceivedSetup - Determined context %s, "
1940 "extension %s\n", p->context, p->exten);
1947 int onOutgoingCall(ooCallData *call)
1949 struct ooh323_pvt *p = NULL;
1953 ast_verb(0, "--- onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
1955 if (!strcmp(call->callType, "outgoing")) {
1956 p = find_call(call);
1958 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1961 ast_mutex_lock(&p->lock);
1963 if (!ast_strlen_zero(p->callerid_name)) {
1964 ooCallSetCallerId(call, p->callerid_name);
1966 if (!ast_strlen_zero(p->callerid_num)) {
1968 while (*(p->callerid_num + i) != '\0') {
1969 if(!isdigit(*(p->callerid_num+i))) { break; }
1972 if(*(p->callerid_num+i) == '\0')
1973 ooCallSetCallingPartyNumber(call, p->callerid_num);
1975 if(!p->callerid_name)
1976 ooCallSetCallerId(call, p->callerid_num);
1980 if (!ast_strlen_zero(p->caller_h323id))
1981 ooCallAddAliasH323ID(call, p->caller_h323id);
1983 if (!ast_strlen_zero(p->caller_dialedDigits)) {
1985 ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
1987 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
1988 } else if (!ast_strlen_zero(p->callerid_num)) {
1989 if (ooIsDailedDigit(p->callerid_num)) {
1991 ast_verb(0, "setting callid number %s\n", p->callerid_num);
1993 ooCallAddAliasDialedDigits(call, p->callerid_num);
1994 } else if (ast_strlen_zero(p->caller_h323id)) {
1995 ooCallAddAliasH323ID(call, p->callerid_num);
1998 if (p->rtpmask && p->rtpmaskstr[0]) {
1999 call->rtpMask = p->rtpmask;
2000 ast_mutex_lock(&call->rtpMask->lock);
2001 call->rtpMask->inuse++;
2002 ast_mutex_unlock(&call->rtpMask->lock);
2003 ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
2006 if (!p->rtp && !configure_local_rtp(p, call)) {
2007 ast_mutex_unlock(&p->lock);
2011 ast_mutex_unlock(&p->lock);
2015 ast_verb(0, "+++ onOutgoingCall %s\n", call->callToken);
2020 int onNewCallCreated(ooCallData *call)
2022 struct ooh323_pvt *p = NULL;
2026 ast_verb(0, "--- onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
2028 ast_mutex_lock(&call->Lock);
2029 if (ooh323c_start_call_thread(call)) {
2030 ast_log(LOG_ERROR,"Failed to create call thread.\n");
2031 ast_mutex_unlock(&call->Lock);
2035 if (!strcmp(call->callType, "outgoing")) {
2036 p = find_call(call);
2038 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2039 ast_mutex_unlock(&call->Lock);
2042 ast_mutex_lock(&p->lock);
2044 if (!ast_strlen_zero(p->callerid_name)) {
2045 ooCallSetCallerId(call, p->callerid_name);
2047 if (!ast_strlen_zero(p->callerid_num)) {
2049 while (*(p->callerid_num + i) != '\0') {
2050 if(!isdigit(*(p->callerid_num+i))) { break; }
2053 if(*(p->callerid_num+i) == '\0')
2054 ooCallSetCallingPartyNumber(call, p->callerid_num);
2056 if(ast_strlen_zero(p->callerid_name))
2057 ooCallSetCallerId(call, p->callerid_num);
2061 if (!ast_strlen_zero(p->caller_h323id))
2062 ooCallAddAliasH323ID(call, p->caller_h323id);
2064 if (!ast_strlen_zero(p->caller_dialedDigits)) {
2066 ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
2068 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
2069 } else if (!ast_strlen_zero(p->callerid_num)) {
2070 if (ooIsDailedDigit(p->callerid_num)) {
2072 ast_verb(0, "setting callid number %s\n", p->callerid_num);
2074 ooCallAddAliasDialedDigits(call, p->callerid_num);
2075 } else if (ast_strlen_zero(p->caller_h323id)) {
2076 ooCallAddAliasH323ID(call, p->callerid_num);
2081 if (!ast_strlen_zero(p->exten)) {
2082 if (ooIsDailedDigit(p->exten)) {
2083 ooCallSetCalledPartyNumber(call, p->exten);
2084 ooCallAddRemoteAliasDialedDigits(call, p->exten);
2086 ooCallAddRemoteAliasH323ID(call, p->exten);
2092 ast_codec_pref_string(&p->prefs, prefsBuf, sizeof(prefsBuf));
2093 ast_verb(0, " Outgoing call %s(%s) - Codec prefs - %s\n",
2094 p->username?p->username:"NULL", call->callToken, prefsBuf);
2097 ooh323c_set_capability_for_call(call, &p->prefs, p->cap,
2098 p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
2100 configure_local_rtp(p, call);
2101 ast_cond_signal(&p->rtpcond);
2102 ast_mutex_unlock(&p->lock);
2105 ast_mutex_unlock(&call->Lock);
2107 ast_verb(0, "+++ onNewCallCreated %s\n", call->callToken);
2111 int onCallEstablished(ooCallData *call)
2113 struct ooh323_pvt *p = NULL;
2116 ast_verb(0, "--- onCallEstablished %s\n", call->callToken);
2119 if (!(p = find_call(call))) {
2120 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2124 if(ast_test_flag(p, H323_OUTGOING)) {
2125 ast_mutex_lock(&p->lock);
2127 ast_mutex_unlock(&p->lock);
2128 ast_log(LOG_ERROR, "Channel has no owner\n");
2132 while (p->owner && ast_channel_trylock(p->owner)) {
2133 ast_debug(1, "Failed to grab lock, trying again\n");
2134 DEADLOCK_AVOIDANCE(&p->lock);
2137 struct ast_channel* c = p->owner;
2139 if (call->remoteDisplayName) {
2140 struct ast_party_connected_line connected;
2141 struct ast_set_party_connected_line update_connected;
2143 memset(&update_connected, 0, sizeof(update_connected));
2144 update_connected.id.name = 1;
2145 ast_party_connected_line_init(&connected);
2146 connected.id.name.valid = 1;
2147 connected.id.name.str = (char *) call->remoteDisplayName;
2148 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
2149 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
2152 ast_queue_control(c, AST_CONTROL_ANSWER);
2153 ast_publish_channel_state(c);
2154 ast_channel_unlock(p->owner);
2156 ast_mutex_unlock(&p->lock);
2161 ast_verb(0, "+++ onCallEstablished %s\n", call->callToken);
2166 int onCallCleared(ooCallData *call)
2168 struct ooh323_pvt *p = NULL;
2172 ast_verb(0, "--- onCallCleared %s \n", call->callToken);
2175 if ((p = find_call(call))) {
2176 ast_mutex_lock(&p->lock);
2179 if (ast_channel_trylock(p->owner)) {
2180 ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
2181 ast_debug(1, "Failed to grab lock, trying again\n");
2182 DEADLOCK_AVOIDANCE(&p->lock);
2184 ownerLock = 1; break;
2189 if (!ast_test_flag(p, H323_ALREADYGONE)) {
2191 ast_set_flag(p, H323_ALREADYGONE);
2192 ast_channel_hangupcause_set(p->owner, call->q931cause);
2193 ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
2194 ast_queue_hangup_with_cause(p->owner,call->q931cause);
2199 ast_channel_tech_pvt_set(p->owner, NULL);
2200 ast_channel_unlock(p->owner);
2202 ast_module_unref(myself);
2205 ast_set_flag(p, H323_NEEDDESTROY);
2207 ooh323c_stop_call_thread(call);
2209 ast_mutex_unlock(&p->lock);
2210 ast_mutex_lock(&usecnt_lock);
2212 ast_mutex_unlock(&usecnt_lock);
2217 ast_verb(0, "+++ onCallCleared\n");
2222 /* static void ooh323_delete_user(struct ooh323_user *user)
2224 struct ooh323_user *prev = NULL, *cur = NULL;
2227 ast_verb(0, "--- ooh323_delete_user\n");
2231 ast_mutex_lock(&userl.lock);
2233 if (cur == user) break;
2240 prev->next = cur->next;
2242 userl.users = cur->next;
2244 ast_mutex_unlock(&userl.lock);
2250 ast_verb(0, "+++ ooh323_delete_user\n");
2254 void ooh323_delete_peer(struct ooh323_peer *peer)
2256 struct ooh323_peer *prev = NULL, *cur = NULL;
2259 ast_verb(0, "--- ooh323_delete_peer\n");
2263 ast_mutex_lock(&peerl.lock);
2265 if(cur==peer) break;
2272 prev->next = cur->next;
2274 peerl.peers = cur->next;
2276 ast_mutex_unlock(&peerl.lock);
2278 if(peer->h323id) free(peer->h323id);
2279 if(peer->email) free(peer->email);
2280 if(peer->url) free(peer->url);
2281 if(peer->e164) free(peer->e164);
2283 peer->cap = ast_format_cap_destroy(peer->cap);
2288 ast_verb(0, "+++ ooh323_delete_peer\n");
2294 static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
2296 struct ooh323_user *user = NULL;
2299 ast_verb(0, "--- build_user\n");
2301 user = ast_calloc(1,sizeof(struct ooh323_user));
2303 memset(user, 0, sizeof(struct ooh323_user));
2304 if (!(user->cap = ast_format_cap_alloc(0))) {
2308 ast_mutex_init(&user->lock);
2309 ast_copy_string(user->name, name, sizeof(user->name));
2310 ast_format_cap_copy(user->cap, gCap);
2311 memcpy(&user->prefs, &gPrefs, sizeof(user->prefs));
2312 user->rtptimeout = gRTPTimeout;
2314 user->dtmfmode = gDTMFMode;
2315 user->dtmfcodec = gDTMFCodec;
2316 user->faxdetect = gFAXdetect;
2317 user->t38support = gT38Support;
2318 user->faststart = gFastStart;
2319 user->h245tunneling = gTunneling;
2320 user->directrtp = gDirectRTP;
2321 user->earlydirect = gEarlyDirect;
2322 user->g729onlyA = g729onlyA;
2323 /* set default context */
2324 ast_copy_string(user->context, gContext, sizeof(user->context));
2325 ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
2326 user->amaflags = gAMAFLAGS;
2329 if (!strcasecmp(v->name, "context")) {
2330 ast_copy_string(user->context, v->value, sizeof(user->context));
2331 } else if (!strcasecmp(v->name, "incominglimit")) {
2332 user->incominglimit = atoi(v->value);
2333 if (user->incominglimit < 0)
2334 user->incominglimit = 0;
2335 } else if (!strcasecmp(v->name, "accountcode")) {
2336 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
2337 } else if (!strcasecmp(v->name, "roundtrip")) {
2338 sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
2339 } else if (!strcasecmp(v->name, "faststart")) {
2340 user->faststart = ast_true(v->value);
2341 } else if (!strcasecmp(v->name, "h245tunneling")) {
2342 user->h245tunneling = ast_true(v->value);
2343 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2344 user->directrtp = ast_true(v->value);
2345 user->earlydirect = ast_true(v->value);
2346 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2347 user->earlydirect = ast_true(v->value);
2348 } else if (!strcasecmp(v->name, "g729onlyA")) {
2349 user->g729onlyA = ast_true(v->value);
2350 } else if (!strcasecmp(v->name, "nat")) {
2351 user->nat = ast_true(v->value);
2352 } else if (!strcasecmp(v->name, "rtptimeout")) {
2353 user->rtptimeout = atoi(v->value);
2354 if (user->rtptimeout < 0)
2355 user->rtptimeout = gRTPTimeout;
2356 } else if (!strcasecmp(v->name, "rtpmask")) {
2357 if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2358 (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED)
2360 ast_mutex_init(&user->rtpmask->lock);
2361 user->rtpmask->inuse = 1;
2362 ast_copy_string(user->rtpmaskstr, v->value,
2363 sizeof(user->rtpmaskstr));
2364 } else user->rtpmask = NULL;
2365 } else if (!strcasecmp(v->name, "disallow")) {
2366 ast_parse_allow_disallow(&user->prefs,
2367 user->cap, v->value, 0);
2368 } else if (!strcasecmp(v->name, "allow")) {
2369 const char* tcodecs = v->value;
2370 if (!strcasecmp(v->value, "all")) {
2371 tcodecs = "ulaw,alaw,g729,g723,gsm";
2373 ast_parse_allow_disallow(&user->prefs,
2374 user->cap, tcodecs, 1);
2375 } else if (!strcasecmp(v->name, "amaflags")) {
2376 user->amaflags = ast_channel_string2amaflag(v->value);
2377 } else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
2378 struct ast_sockaddr p;
2379 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2380 ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
2382 ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
2385 } else if (!strcasecmp(v->name, "dtmfmode")) {
2386 if (!strcasecmp(v->value, "rfc2833"))
2387 user->dtmfmode = H323_DTMF_RFC2833;
2388 if (!strcasecmp(v->value, "cisco"))
2389 user->dtmfmode = H323_DTMF_CISCO;
2390 else if (!strcasecmp(v->value, "q931keypad"))
2391 user->dtmfmode = H323_DTMF_Q931;
2392 else if (!strcasecmp(v->value, "h245alphanumeric"))
2393 user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2394 else if (!strcasecmp(v->value, "h245signal"))
2395 user->dtmfmode = H323_DTMF_H245SIGNAL;
2396 else if (!strcasecmp(v->value, "inband"))
2397 user->dtmfmode = H323_DTMF_INBAND;
2398 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2399 user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2400 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2401 user->dtmfcodec = atoi(v->value);
2402 } else if (!strcasecmp(v->name, "faxdetect")) {
2403 if (ast_true(v->value)) {
2404 user->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2405 } else if (ast_false(v->value)) {
2406 user->faxdetect = 0;
2408 char *buf = ast_strdupa(v->value);
2409 char *word, *next = buf;
2410 user->faxdetect = 0;
2411 while ((word = strsep(&next, ","))) {
2412 if (!strcasecmp(word, "cng")) {
2413 user->faxdetect |= FAXDETECT_CNG;
2414 } else if (!strcasecmp(word, "t38")) {
2415 user->faxdetect |= FAXDETECT_T38;
2417 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2422 } else if (!strcasecmp(v->name, "t38support")) {
2423 if (!strcasecmp(v->value, "disabled"))
2424 user->t38support = T38_DISABLED;
2425 if (!strcasecmp(v->value, "no"))
2426 user->t38support = T38_DISABLED;
2427 else if (!strcasecmp(v->value, "faxgw"))
2428 user->t38support = T38_FAXGW;
2429 else if (!strcasecmp(v->value, "yes"))
2430 user->t38support = T38_ENABLED;
2431 } else if (!strcasecmp(v->name, "aniasdni")) {
2432 user->aniasdni = ast_true(v->value);
2439 ast_verb(0, "+++ build_user\n");
2444 static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
2446 struct ooh323_peer *peer = NULL;
2449 ast_verb(0, "--- build_peer\n");
2451 peer = ast_calloc(1, sizeof(*peer));
2453 memset(peer, 0, sizeof(struct ooh323_peer));
2454 if (!(peer->cap = ast_format_cap_alloc(0))) {
2458 ast_mutex_init(&peer->lock);
2459 ast_copy_string(peer->name, name, sizeof(peer->name));
2460 ast_format_cap_copy(peer->cap, gCap);
2461 memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs));
2462 peer->rtptimeout = gRTPTimeout;
2464 ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
2465 peer->amaflags = gAMAFLAGS;
2466 peer->dtmfmode = gDTMFMode;
2467 peer->dtmfcodec = gDTMFCodec;
2468 peer->faxdetect = gFAXdetect;
2469 peer->t38support = gT38Support;
2470 peer->faststart = gFastStart;
2471 peer->h245tunneling = gTunneling;
2472 peer->directrtp = gDirectRTP;
2473 peer->earlydirect = gEarlyDirect;
2474 peer->g729onlyA = g729onlyA;
2476 if (0 == friend_type) {
2481 if (!strcasecmp(v->name, "h323id")) {
2482 if (!(peer->h323id = ast_strdup(v->value))) {
2483 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2485 ooh323_delete_peer(peer);
2488 } else if (!strcasecmp(v->name, "e164")) {
2491 for(tmp = v->value; *tmp; tmp++) {
2492 if (!isdigit(*tmp)) {
2498 if (!(peer->e164 = ast_strdup(v->value))) {
2499 ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
2501 ooh323_delete_peer(peer);
2505 ast_log(LOG_ERROR, "Invalid e164: %s for peer %s\n", v->value, name);
2507 } else if (!strcasecmp(v->name, "email")) {
2508 if (!(peer->email = ast_strdup(v->value))) {
2509 ast_log(LOG_ERROR, "Could not allocate memory for email of "
2511 ooh323_delete_peer(peer);
2514 } else if (!strcasecmp(v->name, "url")) {
2515 if (!(peer->url = ast_strdup(v->value))) {
2516 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2518 ooh323_delete_peer(peer);
2521 } else if (!strcasecmp(v->name, "port")) {
2522 peer->port = atoi(v->value);
2523 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
2524 struct ast_sockaddr p;
2525 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2526 ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
2528 ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2531 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2532 peer->outgoinglimit = atoi(v->value);
2533 if (peer->outgoinglimit < 0)
2534 peer->outgoinglimit = 0;
2535 } else if (!strcasecmp(v->name, "accountcode")) {
2536 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
2537 } else if (!strcasecmp(v->name, "faststart")) {
2538 peer->faststart = ast_true(v->value);
2539 } else if (!strcasecmp(v->name, "h245tunneling")) {
2540 peer->h245tunneling = ast_true(v->value);
2541 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2542 peer->directrtp = ast_true(v->value);
2543 peer->earlydirect = ast_true(v->value);
2544 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2545 peer->earlydirect = ast_true(v->value);
2546 } else if (!strcasecmp(v->name, "g729onlyA")) {
2547 peer->g729onlyA = ast_true(v->value);
2548 } else if (!strcasecmp(v->name, "nat")) {
2549 peer->nat = ast_true(v->value);
2550 } else if (!strcasecmp(v->name, "rtptimeout")) {
2551 peer->rtptimeout = atoi(v->value);
2552 if(peer->rtptimeout < 0)
2553 peer->rtptimeout = gRTPTimeout;
2554 } else if (!strcasecmp(v->name, "rtpmask")) {
2555 if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2556 (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED)
2558 ast_mutex_init(&peer->rtpmask->lock);
2559 peer->rtpmask->inuse = 1;
2560 ast_copy_string(peer->rtpmaskstr, v->value,
2561 sizeof(peer->rtpmaskstr));
2562 } else peer->rtpmask = NULL;
2563 } else if (!strcasecmp(v->name, "disallow")) {
2564 ast_parse_allow_disallow(&peer->prefs, peer->cap,
2566 } else if (!strcasecmp(v->name, "allow")) {
2567 const char* tcodecs = v->value;
2568 if (!strcasecmp(v->value, "all")) {
2569 tcodecs = "ulaw,alaw,g729,g723,gsm";
2571 ast_parse_allow_disallow(&peer->prefs, peer->cap,
2573 } else if (!strcasecmp(v->name, "amaflags")) {
2574 peer->amaflags = ast_channel_string2amaflag(v->value);
2575 } else if (!strcasecmp(v->name, "roundtrip")) {
2576 sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
2577 } else if (!strcasecmp(v->name, "dtmfmode")) {
2578 if (!strcasecmp(v->value, "rfc2833"))
2579 peer->dtmfmode = H323_DTMF_RFC2833;
2580 if (!strcasecmp(v->value, "cisco"))
2581 peer->dtmfmode = H323_DTMF_CISCO;
2582 else if (!strcasecmp(v->value, "q931keypad"))
2583 peer->dtmfmode = H323_DTMF_Q931;
2584 else if (!strcasecmp(v->value, "h245alphanumeric"))
2585 peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2586 else if (!strcasecmp(v->value, "h245signal"))
2587 peer->dtmfmode = H323_DTMF_H245SIGNAL;
2588 else if (!strcasecmp(v->value, "inband"))
2589 peer->dtmfmode = H323_DTMF_INBAND;
2590 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2591 peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2592 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2593 peer->dtmfcodec = atoi(v->value);
2594 } else if (!strcasecmp(v->name, "faxdetect")) {
2595 if (ast_true(v->value)) {
2596 peer->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2597 } else if (ast_false(v->value)) {
2598 peer->faxdetect = 0;
2600 char *buf = ast_strdupa(v->value);
2601 char *word, *next = buf;
2602 peer->faxdetect = 0;
2603 while ((word = strsep(&next, ","))) {
2604 if (!strcasecmp(word, "cng")) {
2605 peer->faxdetect |= FAXDETECT_CNG;
2606 } else if (!strcasecmp(word, "t38")) {
2607 peer->faxdetect |= FAXDETECT_T38;
2609 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2614 } else if (!strcasecmp(v->name, "t38support")) {
2615 if (!strcasecmp(v->value, "disabled"))
2616 peer->t38support = T38_DISABLED;
2617 if (!strcasecmp(v->value, "no"))
2618 peer->t38support = T38_DISABLED;
2619 else if (!strcasecmp(v->value, "faxgw"))
2620 peer->t38support = T38_FAXGW;
2621 else if (!strcasecmp(v->value, "yes"))
2622 peer->t38support = T38_ENABLED;
2629 ast_verb(0, "+++ build_peer\n");
2634 static int ooh323_do_reload(void)
2636 struct ooAliases * pNewAlias = NULL;
2637 struct ooh323_peer *peer = NULL;
2640 ast_verb(0, "--- ooh323_do_reload\n");
2644 if (gH323ep.gkClient) {
2645 ooGkClientDestroy();
2651 if (gRasGkMode == RasUseSpecificGatekeeper ||
2652 gRasGkMode == RasDiscoverGatekeeper) {
2653 ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ?
2654 gGatekeeper : 0, 0);
2655 ooGkClientStart(gH323ep.gkClient);
2658 /* Set aliases if any */
2660 ast_verb(0, "updating local aliases\n");
2663 for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
2664 switch (pNewAlias->type) {
2665 case T_H225AliasAddress_h323_ID:
2666 ooH323EpAddAliasH323ID(pNewAlias->value);
2668 case T_H225AliasAddress_dialedDigits:
2669 ooH323EpAddAliasDialedDigits(pNewAlias->value);
2671 case T_H225AliasAddress_email_ID:
2672 ooH323EpAddAliasEmailID(pNewAlias->value);
2679 ast_mutex_lock(&peerl.lock);
2683 ooH323EpAddAliasH323ID(peer->h323id);
2686 ooH323EpAddAliasEmailID(peer->email);
2689 ooH323EpAddAliasDialedDigits(peer->e164);
2692 ooH323EpAddAliasURLID(peer->url);
2696 ast_mutex_unlock(&peerl.lock);
2699 ast_verb(0, "+++ ooh323_do_reload\n");
2705 /*--- h323_reload: Force reload of module from cli ---*/
2707 char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2712 e->command = "ooh323 reload";
2714 "Usage: ooh323 reload\n"
2715 " Reload OOH323 config.\n";
2722 return CLI_SHOWUSAGE;
2725 ast_verb(0, "--- ooh323_reload\n");
2727 ast_mutex_lock(&h323_reload_lock);
2728 if (h323_reloading) {
2729 ast_verb(0, "Previous OOH323 reload not yet done\n");
2733 ast_mutex_unlock(&h323_reload_lock);
2737 ast_verb(0, "+++ ooh323_reload\n");
2742 int reload_config(int reload)
2745 struct ooAliases *pNewAlias = NULL, *cur, *prev;
2746 struct ast_config *cfg;
2747 struct ast_variable *v;
2748 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2749 struct ooh323_user *user = NULL;
2750 struct ooh323_peer *peer = NULL;
2753 struct ast_format tmpfmt;
2756 ast_verb(0, "--- reload_config\n");
2758 cfg = ast_config_load((char*)config, config_flags);
2760 /* We *must* have a config file otherwise stop immediately */
2762 ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
2764 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
2765 return RESULT_SUCCESS;
2771 ast_verb(0, " reload_config - Freeing up alias list\n");
2781 ooH323EpClearAllAliases();
2784 /* Inintialize everything to default */
2785 strcpy(gLogFile, DEFAULT_LOGFILE);
2788 strcpy(gCallerID, DEFAULT_H323ID);
2789 ast_format_cap_set(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
2790 memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
2791 gDTMFMode = H323_DTMF_RFC2833;
2793 gFAXdetect = FAXDETECT_CNG;
2794 gT38Support = T38_FAXGW;
2795 gTRCLVL = OOTRCLVLERR;
2796 gRasGkMode = RasNoGatekeeper;
2797 gGatekeeper[0] = '\0';
2802 strcpy(gAccountcode, DEFAULT_H323ACCNT);
2806 strcpy(gContext, DEFAULT_CONTEXT);
2808 gMediaWaitForConnect = 0;
2809 ooconfig.mTCPPortStart = 12030;
2810 ooconfig.mTCPPortEnd = 12230;
2811 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2813 v = ast_variable_browse(cfg, "general");
2816 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
2821 if (!strcasecmp(v->name, "port")) {
2822 gPort = (int)strtol(v->value, NULL, 10);
2823 } else if (!strcasecmp(v->name, "bindaddr")) {
2824 ast_copy_string(gIP, v->value, sizeof(gIP));
2825 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
2826 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
2827 ast_config_destroy(cfg);
2830 if (ast_sockaddr_is_ipv6(&bindaddr)) {
2833 } else if (!strcasecmp(v->name, "h225portrange")) {
2836 ast_copy_string(temp, v->value, sizeof(temp));
2837 endlimit = strchr(temp, ',');
2841 ooconfig.mTCPPortStart = atoi(temp);
2842 ooconfig.mTCPPortEnd = atoi(endlimit);
2845 ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
2847 } else if (!strcasecmp(v->name, "gateway")) {
2848 gIsGateway = ast_true(v->value);
2849 } else if (!strcasecmp(v->name, "faststart")) {
2850 gFastStart = ast_true(v->value);
2852 ooH323EpEnableFastStart();
2854 ooH323EpDisableFastStart();
2855 } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
2856 gMediaWaitForConnect = ast_true(v->value);
2857 if (gMediaWaitForConnect)
2858 ooH323EpEnableMediaWaitForConnect();
2860 ooH323EpDisableMediaWaitForConnect();
2861 } else if (!strcasecmp(v->name, "h245tunneling")) {
2862 gTunneling = ast_true(v->value);
2864 ooH323EpEnableH245Tunneling();
2866 ooH323EpDisableH245Tunneling();
2867 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2868 gDirectRTP = ast_true(v->value);
2869 gEarlyDirect = ast_true(v->value);
2870 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2871 gEarlyDirect = ast_true(v->value);
2872 } else if (!strcasecmp(v->name, "g729onlyA")) {
2873 g729onlyA = ast_true(v->value);
2874 } else if (!strcasecmp(v->name, "roundtrip")) {
2875 sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
2876 } else if (!strcasecmp(v->name, "trybemaster")) {
2877 gBeMaster = ast_true(v->value);
2879 ooH323EpTryBeMaster(1);
2881 ooH323EpTryBeMaster(0);
2882 } else if (!strcasecmp(v->name, "h323id")) {
2883 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2885 ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
2886 ast_config_destroy(cfg);
2889 if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
2890 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2892 pNewAlias->type = T_H225AliasAddress_h323_ID;
2893 pNewAlias->value = strdup(v->value);
2894 pNewAlias->next = gAliasList;
2895 gAliasList = pNewAlias;
2897 } else if (!strcasecmp(v->name, "e164")) {
2900 for(tmp = v->value; *tmp; tmp++) {
2901 if (!isdigit(*tmp)) {
2907 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2909 ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
2910 ast_config_destroy(cfg);
2913 pNewAlias->type = T_H225AliasAddress_dialedDigits;
2914 pNewAlias->value = strdup(v->value);
2915 pNewAlias->next = gAliasList;
2916 gAliasList = pNewAlias;
2919 ast_log(LOG_ERROR, "Invalid e164: %s\n", v->value);
2921 } else if (!strcasecmp(v->name, "email")) {
2922 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2924 ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
2925 ast_config_destroy(cfg);
2928 pNewAlias->type = T_H225AliasAddress_email_ID;
2929 pNewAlias->value = strdup(v->value);
2930 pNewAlias->next = gAliasList;
2931 gAliasList = pNewAlias;
2933 } else if (!strcasecmp(v->name, "t35country")) {
2934 t35countrycode = atoi(v->value);
2935 } else if (!strcasecmp(v->name, "t35extensions")) {
2936 t35extensions = atoi(v->value);
2937 } else if (!strcasecmp(v->name, "manufacturer")) {
2938 manufacturer = atoi(v->value);
2939 } else if (!strcasecmp(v->name, "vendorid")) {
2940 ast_copy_string(vendor, v->value, sizeof(vendor));
2941 } else if (!strcasecmp(v->name, "versionid")) {
2942 ast_copy_string(version, v->value, sizeof(version));
2943 } else if (!strcasecmp(v->name, "callerid")) {
2944 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2945 } else if (!strcasecmp(v->name, "incominglimit")) {
2946 gIncomingLimit = atoi(v->value);
2947 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2948 gOutgoingLimit = atoi(v->value);
2949 } else if (!strcasecmp(v->name, "gatekeeper")) {
2950 if (!strcasecmp(v->value, "DISABLE")) {
2951 gRasGkMode = RasNoGatekeeper;
2952 } else if (!strcasecmp(v->value, "DISCOVER")) {
2953 gRasGkMode = RasDiscoverGatekeeper;
2955 gRasGkMode = RasUseSpecificGatekeeper;
2956 ast_copy_string(gGatekeeper, v->value, sizeof(gGatekeeper));
2958 } else if (!strcasecmp(v->name, "logfile")) {
2959 ast_copy_string(gLogFile, v->value, sizeof(gLogFile));
2960 } else if (!strcasecmp(v->name, "context")) {
2961 ast_copy_string(gContext, v->value, sizeof(gContext));
2962 ast_verb(3, " == Setting default context to %s\n", gContext);
2963 } else if (!strcasecmp(v->name, "nat")) {
2964 gNat = ast_true(v->value);
2965 } else if (!strcasecmp(v->name, "rtptimeout")) {
2966 gRTPTimeout = atoi(v->value);
2967 if (gRTPTimeout <= 0)
2969 } else if (!strcasecmp(v->name, "tos")) {
2970 if (sscanf(v->value, "%30i", &format) == 1)
2971 gTOS = format & 0xff;
2972 else if (!strcasecmp(v->value, "lowdelay"))
2973 gTOS = IPTOS_LOWDELAY;
2974 else if (!strcasecmp(v->value, "throughput"))
2975 gTOS = IPTOS_THROUGHPUT;
2976 else if (!strcasecmp(v->value, "reliability"))
2977 gTOS = IPTOS_RELIABILITY;
2978 else if (!strcasecmp(v->value, "mincost"))
2979 gTOS = IPTOS_MINCOST;
2980 else if (!strcasecmp(v->value, "none"))
2983 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be "
2984 "'lowdelay', 'throughput', 'reliability', "