Asterisk - The Open Source Telephony Project GIT-master-0034c23
chan_ooh323.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2005 by Objective Systems, Inc.
3 *
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:
9 *
10 * http://www.obj-sys.com/open/license.html
11 *
12 * Any redistributions of this file including modified versions must
13 * maintain this copyright notice.
14 *
15 *****************************************************************************/
16
17/* Reworked version I, Nov-2009, by Alexandr Anikin, may@telecom-service.ru */
18
19
20/*** MODULEINFO
21 <defaultenabled>no</defaultenabled>
22 <support_level>extended</support_level>
23 ***/
24
25/*** DOCUMENTATION
26<info name="CHANNEL" language="en_US" tech="OOH323">
27 <enumlist>
28 <enum name="faxdetect">
29 <para>R/W Fax Detect</para>
30 <para>Returns 0 or 1</para>
31 <para>Write yes or no</para>
32 </enum>
33 <enum name="t38support">
34 <para>R/W t38support</para>
35 <para>Returns 0 or 1</para>
36 <para>Write yes or no</para>
37 </enum>
38 <enum name="h323id_url">
39 <para>R/O Returns caller URL</para>
40 </enum>
41 <enum name="caller_h323id">
42 <para>R/O Returns caller h323id</para>
43 </enum>
44 <enum name="caller_dialeddigits">
45 <para>R/O Returns caller dialed digits</para>
46 </enum>
47 <enum name="caller_email">
48 <para>R/O Returns caller email</para>
49 </enum>
50 <enum name="callee_email">
51 <para>R/O Returns callee email</para>
52 </enum>
53 <enum name="callee_dialeddigits">
54 <para>R/O Returns callee dialed digits</para>
55 </enum>
56 <enum name="caller_url">
57 <para>R/O Returns caller URL</para>
58 </enum>
59 <enum name="max_forwards">
60 <para>R/W Get or set the maximum number of call forwards for this channel.
61
62 This number describes the number of times a call may be forwarded by this channel
63 before the call fails. "Forwards" in this case refers to redirects by phones as well
64 as calls to local channels.
65
66 Note that this has no relation to the SIP Max-Forwards header.
67 </para>
68 </enum>
69 </enumlist>
70</info>
71 ***/
72
73#include "chan_ooh323.h"
74#include <math.h>
75
76#ifndef IPTOS_MINCOST
77#define IPTOS_MINCOST 0x02
78#endif
79
80#define FORMAT_STRING_SIZE 512
81
82/* Defaults */
83#define DEFAULT_CONTEXT "default"
84#define DEFAULT_H323ID "Asterisk PBX"
85#define DEFAULT_LOGFILE "h323_log"
86#define DEFAULT_H323ACCNT "ast_h323"
87
88/* Flags */
89#define H323_SILENCESUPPRESSION (1<<0)
90#define H323_GKROUTED (1<<1)
91#define H323_TUNNELING (1<<2)
92#define H323_FASTSTART (1<<3)
93#define H323_OUTGOING (1<<4)
94#define H323_ALREADYGONE (1<<5)
95#define H323_NEEDDESTROY (1<<6)
96#define H323_DISABLEGK (1<<7)
97#define H323_NEEDSTART (1<<8)
98
99#define MAXT30 240
100#define T38TOAUDIOTIMEOUT 30
101#define T38_DISABLED 0
102#define T38_ENABLED 1
103#define T38_FAXGW 1
104
105#define FAXDETECT_CNG 1
106#define FAXDETECT_T38 2
107
108/* Channel description */
109static const char type[] = "OOH323";
110static const char tdesc[] = "Objective Systems H323 Channel Driver";
111static const char config[] = "ooh323.conf";
112
114
116{
117 .flags = 0,
118 .max_size = -1,
119 .resync_threshold = -1,
120 .impl = ""
121};
123
124/* Channel Definition */
125static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
126 const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
127static int ooh323_digit_begin(struct ast_channel *ast, char digit);
128static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
129static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout);
130static int ooh323_hangup(struct ast_channel *ast);
131static int ooh323_answer(struct ast_channel *ast);
132static struct ast_frame *ooh323_read(struct ast_channel *ast);
133static int ooh323_write(struct ast_channel *ast, struct ast_frame *f);
134static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
135static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
136static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
137static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
138static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
139
140static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
141static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
142static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
143 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active);
144static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result);
145void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort);
146
147struct ooh323_peer *find_friend(const char *name, int port);
148
149
151 .type = type,
152 .description = tdesc,
154 .requester = ooh323_request,
155 .send_digit_begin = ooh323_digit_begin,
156 .send_digit_end = ooh323_digit_end,
157 .call = ooh323_call,
158 .hangup = ooh323_hangup,
159 .answer = ooh323_answer,
160 .read = ooh323_read,
161 .write = ooh323_write,
162 .exception = ooh323_read,
163 .indicate = ooh323_indicate,
164 .fixup = ooh323_fixup,
165 .send_html = 0,
166 .queryoption = ooh323_queryoption,
167 .early_bridge = ast_rtp_instance_early_bridge,
168 .func_channel_read = function_ooh323_read,
169 .func_channel_write = function_ooh323_write,
170};
171
172static struct ast_rtp_glue ooh323_rtp = {
173 .type = type,
174 .get_rtp_info = ooh323_get_rtp_peer,
175 .get_vrtp_info = ooh323_get_vrtp_peer,
176 .update_peer = ooh323_set_rtp_peer,
177 .get_codec = ooh323_get_codec,
178};
179
180
181struct ooh323_user;
182
183/* H.323 channel private structure */
184static struct ooh323_pvt {
185 ast_mutex_t lock; /* Channel private lock */
186 ast_cond_t rtpcond; /* RTP condition */
188 struct ast_sockaddr redirip; /* redir ip */
189 struct ast_rtp_instance *vrtp; /* Placeholder for now */
190
191 int t38support; /* T.38 mode - disable, transparent, faxgw */
200 time_t lastTxT38;
202
203 struct ast_channel *owner; /* Master Channel */
204 union {
205 char *user; /* cooperating user/peer */
206 char *peer;
208 time_t lastrtptx;
209 time_t lastrtprx;
210 unsigned int flags;
211 unsigned int call_reference;
213 char *username;
214 char *host;
220 char caller_url[256];
225
226 int port;
227 struct ast_format *readformat; /* negotiated read format */
228 struct ast_format *writeformat; /* negotiated write format */
232 char exten[AST_MAX_EXTENSION]; /* Requested extension */
233 char context[AST_MAX_EXTENSION]; /* Context where to start */
234 char accountcode[256]; /* Account code */
235 int nat;
237 int progsent; /* progress is sent */
238 int alertsent; /* alerting is sent */
239 int directrtp; /* direct rtp */
240 int earlydirect; /* early direct rtp */
241 int g729onlyA; /* G.729 only A */
242 struct ast_dsp *vad;
243 struct OOH323Regex *rtpmask; /* rtp ip regexp */
244 char rtpmaskstr[120];
245 int rtdrcount, rtdrinterval; /* roundtripdelayreq */
246 int faststart, h245tunneling; /* faststart & h245 tunneling */
247 int aniasdni; /* use dialed number as answering identification */
248 struct ooh323_pvt *next; /* Next entity */
250
251/* Protect the channel/interface list (ooh323_pvt) */
253
254/* Profile of H.323 user registered with PBX*/
257 char name[256];
260 unsigned inUse;
261 char accountcode[20];
269 int mUseIP; /* Use IP address or H323-ID to search user */
270 char mIP[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
271 struct OOH323Regex *rtpmask;
272 char rtpmaskstr[120];
274 int nat;
281};
282
283/* Profile of valid asterisk peers */
286 char name[256];
288 unsigned outUse;
290 char accountcode[20];
296 int mFriend; /* indicates defined as friend */
297 char ip[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
298 int port;
299 char *h323id; /* H323-ID alias, which asterisk will register with gk to reach this peer*/
300 char *email; /* Email alias, which asterisk will register with gk to reach this peer*/
301 char *url; /* url alias, which asterisk will register with gk to reach this peer*/
302 char *e164; /* e164 alias, which asterisk will register with gk to reach this peer*/
304 struct OOH323Regex *rtpmask;
305 char rtpmaskstr[120];
307 int nat;
313};
314
315
316/* List of H.323 users known to PBX */
317static struct ast_user_list {
321
322static struct ast_peer_list {
326
327/* Mutex to protect H.323 reload process */
328static int h323_reloading = 0;
330
331/* Mutex to protect usage counter */
332static int usecnt = 0;
334
335static long callnumber = 0;
337
338/* stack callbacks */
339int onAlerting(ooCallData *call);
340int onProgress(ooCallData *call);
341int onNewCallCreated(ooCallData *call);
342int onOutgoingCall(ooCallData *call);
343int onCallEstablished(ooCallData *call);
344int onCallCleared(ooCallData *call);
345void onModeChanged(ooCallData *call, int t38mode);
346
347extern OOH323EndPoint gH323ep;
348
350static char gInitError[256] = "";
351static int gPort = 1720;
352static char gIP[2+8*4+7]; /* Max for IPv6 addr */
354int v6mode = 0;
355static char gCallerID[AST_MAX_EXTENSION] = "";
356static struct ooAliases *gAliasList;
357static struct ast_format_cap *gCap;
359static int gDTMFCodec = 101;
362static char gGatekeeper[100];
363static char gRASIP[2+8*4+7]; /* Max for IPv6 addr */
364static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
365
366static int gIsGateway = 0;
367static int gFastStart = 1;
368static int gTunneling = 1;
369static int gBeMaster = 0;
370static int gMediaWaitForConnect = 0;
371static int gDirectRTP = 0;
372static int gEarlyDirect = 0;
373static int gTOS = 0;
374static int gRTPTimeout = 60;
375static int g729onlyA = 0;
377static int gAMAFLAGS;
379static int gIncomingLimit = 1024;
380static int gOutgoingLimit = 1024;
382static int gTRCLVL = OOTRCLVLERR;
383static int gRTDRCount = 0, gRTDRInterval = 0;
384static int gNat = FALSE;
385static int gANIasDNI = 0;
386
387static int t35countrycode = 0;
388static int t35extensions = 0;
389static int manufacturer = 0;
390static char vendor[AST_MAX_EXTENSION] = "";
391static char version[AST_MAX_EXTENSION] = "";
392
393static struct ooh323_config
394{
398
399/** Asterisk RTP stuff*/
401static struct io_context *io;
402
403/* Protect the monitoring thread, so only one process can kill or start it,
404 and not when it's doing something critical. */
406
407
408/* This is the thread for the monitor which checks for input on the channels
409 which are not currently in use. */
411
412
413static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
414 const char *host, struct ast_format_cap *cap,
415 const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
416{
417 struct ast_format_cap *caps = NULL;
418 struct ast_channel *ch = NULL;
419 struct ast_format *tmpfmt = NULL;
420 int features = 0;
421
422 if (gH323Debug) {
423 ast_verb(0, "--- ooh323_new - %s\n", host);
424 }
425
427
428 /* Don't hold a h323 pvt lock while we allocate a channel */
432 i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags,
433 "OOH323/%s-%ld", host, callnumber);
434 callnumber++;
436
437 ast_mutex_lock(&i->lock);
438
439 if (ch && caps) {
441
442 if (cap) {
443 tmpfmt = ast_format_cap_get_format(cap, 0);
444 }
445 if (!tmpfmt) {
446 tmpfmt = ast_format_cap_get_format(i->cap, 0);
447 }
448
449 ast_format_cap_append(caps, tmpfmt, 0);
451 ao2_ref(caps, -1);
452
455 ast_set_write_format(ch, tmpfmt);
456 ast_set_read_format(ch, tmpfmt);
457 ao2_ref(tmpfmt, -1);
458
460
461 if (state == AST_STATE_RING)
463
466 i->owner = ch;
468
469 /* Allocate dsp for in-band DTMF support */
470 if ((i->dtmfmode & H323_DTMF_INBAND) || (i->faxdetect & FAXDETECT_CNG)) {
471 i->vad = ast_dsp_new();
472 }
473
474 /* inband DTMF*/
475 if (i->dtmfmode & H323_DTMF_INBAND) {
476 features |= DSP_FEATURE_DIGIT_DETECT;
479 }
480 }
481
482 /* fax detection*/
483 if (i->faxdetect & FAXDETECT_CNG) {
484 features |= DSP_FEATURE_FAX_DETECT;
487 }
488
489 if (features) {
490 ast_dsp_set_features(i->vad, features);
491 }
492
494 usecnt++;
496
497 /* Notify the module monitors that use count for resource has changed*/
499
502
504
506
508 pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
509
510 }
512 pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS",
514 }
515 if (!ast_strlen_zero(i->caller_email)) {
516 pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL",
517 i->caller_email);
518 }
519 if (!ast_strlen_zero(i->caller_url)) {
520 pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url);
521 }
522 }
523
525 ast_channel_accountcode_set(ch, i->accountcode);
526
527 if (i->amaflags)
529
530 ast_setstate(ch, state);
531 if (state != AST_STATE_DOWN) {
532 if (ast_pbx_start(ch)) {
533 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));
535 ast_hangup(ch);
536 ch = NULL;
537 }
538 }
539 } else {
540 ao2_cleanup(caps);
541 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
542 }
543
544
545 if(ch) ast_channel_unlock(ch);
546
547 if (gH323Debug) {
548 ast_verb(0, "+++ h323_new\n");
549 }
550
551 return ch;
552}
553
554
555
556static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
557{
558 struct ooh323_pvt *pvt = NULL;
559
560 if (gH323Debug) {
561 ast_verb(0, "--- ooh323_alloc\n");
562 }
563
564 if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
565 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
566 return NULL;
567 }
569 ast_free(pvt);
570 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
571 return NULL;
572 }
573
574 ast_mutex_init(&pvt->lock);
575 ast_mutex_lock(&pvt->lock);
576
577 pvt->faxmode = 0;
578 pvt->chmodepend = 0;
579 pvt->faxdetected = 0;
580 pvt->faxdetect = gFAXdetect;
581 pvt->t38support = gT38Support;
582 pvt->rtptimeout = gRTPTimeout;
583 pvt->nat = gNat;
585 pvt->rtdrcount = gRTDRCount;
586 pvt->g729onlyA = g729onlyA;
587
588 pvt->call_reference = callref;
589 if (callToken)
591
592 /* whether to use gk for this call */
593 if (gRasGkMode == RasNoGatekeeper)
594 OO_SETFLAG(pvt->flags, H323_DISABLEGK);
595
596 pvt->dtmfmode = gDTMFMode;
597 pvt->dtmfcodec = gDTMFCodec;
598 ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
600
601 pvt->amaflags = gAMAFLAGS;
603
604 pvt->aniasdni = gANIasDNI;
605
606 ast_mutex_unlock(&pvt->lock);
607 /* Add to interface list */
609 pvt->next = iflist;
610 iflist = pvt;
612
613 if (gH323Debug) {
614 ast_verb(0, "+++ ooh323_alloc\n");
615 }
616
617 return pvt;
618}
619
620
621/*
622 Possible data values - peername, exten/peername, exten@ip
623 */
624static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
625 const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
626
627{
629 struct ast_channel *chan = NULL;
630 struct ooh323_pvt *p = NULL;
631 struct ooh323_peer *peer = NULL;
632 char *dest = NULL;
633 char *ext = NULL;
634 char tmp[256];
635 int port = 0;
636
637 if (gH323Debug) {
638 ast_verb(0, "--- ooh323_request - data %s format %s\n", data, ast_format_cap_get_names(cap, &codec_buf));
639 }
640
642 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
643 return NULL;
644 }
645
646 p = ooh323_alloc(0,0); /* Initial callRef is zero */
647
648 if (!p) {
649 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", data);
650 return NULL;
651 }
652 ast_mutex_lock(&p->lock);
653
654 /* This is an outgoing call, since ooh323_request is called */
656
657
658 ast_copy_string(tmp, data, sizeof(tmp));
659
660 dest = strchr(tmp, '/');
661
662 if (dest) {
663 *dest = '\0';
664 dest++;
665 ext = dest;
666 dest = tmp;
667 } else if ((dest = strchr(tmp, '@'))) {
668 *dest = '\0';
669 dest++;
670 ext = tmp;
671 } else {
672 dest = tmp;
673 ext = NULL;
674 }
675
676#if 0
677 if ((sport = strchr(dest, ':'))) {
678 *sport = '\0';
679 sport++;
680 port = atoi(sport);
681 }
682#endif
683
684 if (dest) {
685 peer = find_peer(dest, port);
686 } else{
691 ast_log(LOG_ERROR, "Destination format is not supported\n");
693 return NULL;
694 }
695
696 if (peer) {
697 p->username = ast_strdup(peer->name);
698 p->host = ast_strdup(peer->ip);
699 p->port = peer->port;
700 /* Disable gk as we are going to call a known peer*/
701 /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
702
703 if (ext)
704 ast_copy_string(p->exten, ext, sizeof(p->exten));
705
707 p->g729onlyA = peer->g729onlyA;
708 p->dtmfmode |= peer->dtmfmode;
709 p->dtmfcodec = peer->dtmfcodec;
710 p->faxdetect = peer->faxdetect;
711 p->t38support = peer->t38support;
712 p->rtptimeout = peer->rtptimeout;
713 p->nat = peer->nat;
714 p->faststart = peer->faststart;
715 p->h245tunneling = peer->h245tunneling;
716 p->directrtp = peer->directrtp;
717 p->earlydirect = peer->earlydirect;
718 if (peer->rtpmask && peer->rtpmaskstr[0]) {
719 p->rtpmask = peer->rtpmask;
720 ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
721 }
722
723 if (peer->rtdrinterval) {
724 p->rtdrinterval = peer->rtdrinterval;
725 p->rtdrcount = peer->rtdrcount;
726 }
727
728 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
729 p->amaflags = peer->amaflags;
730 } else {
731 if (gRasGkMode == RasNoGatekeeper) {
732 /* no gk and no peer */
733 ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
738 return NULL;
739 } else if (!gH323ep.gkClient || (gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered)) {
740 ast_log(LOG_ERROR, "Gatekeeper client is configured but not registered\n");
742 return NULL;
743 }
744 p->g729onlyA = g729onlyA;
745 p->dtmfmode = gDTMFMode;
750 p->nat = gNat;
758
759 p->username = ast_strdup(dest);
760
761 p->host = ast_strdup(dest);
762 if (port > 0) {
763 p->port = port;
764 }
765 if (ext) {
766 ast_copy_string(p->exten, ext, sizeof(p->exten));
767 }
768 }
769
770
771 chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
772 assignedids, requestor);
773
775
776 if (!chan) {
780 } else {
781 ast_mutex_lock(&p->lock);
782 p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
783 if(!p->callToken) {
788 ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
789 return NULL;
790 }
791
793 ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
794 if (!p->rtp) {
795 ast_cond_wait(&p->rtpcond, &p->lock);
796 }
799 }
800
802 if (gH323Debug)
803 ast_verb(0, "+++ ooh323_request\n");
804
805 return chan;
806
807}
808
809
810static struct ooh323_pvt* find_call(ooCallData *call)
811{
812 struct ooh323_pvt *p;
813
814 if (gH323Debug)
815 ast_verb(0, "--- find_call\n");
816
818
819 for (p = iflist; p; p = p->next) {
820 if (p->callToken && !strcmp(p->callToken, call->callToken)) {
821 break;
822 }
823 }
825
826 if (gH323Debug)
827 ast_verb(0, "+++ find_call\n");
828
829 return p;
830}
831
832struct ooh323_user *find_user(const char * name, const char* ip)
833{
834 struct ooh323_user *user;
835
836 if (gH323Debug)
837 ast_verb(0, "--- find_user: %s, %s\n",name,ip);
838
840
841 for (user = userl.users; user; user = user->next) {
842 if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
843 break;
844 }
845 if (name && !strcmp(user->name, name)) {
846 break;
847 }
848 }
849
851
852 if (gH323Debug)
853 ast_verb(0, "+++ find_user\n");
854
855 return user;
856}
857
858struct ooh323_peer *find_friend(const char *name, int port)
859{
860 struct ooh323_peer *peer;
861
862 if (gH323Debug)
863 ast_verb(0, "--- find_friend \"%s\"\n", name);
864
865
867 for (peer = peerl.peers; peer; peer = peer->next) {
868 if (gH323Debug) {
869 ast_verb(0, " comparing with \"%s\"\n", peer->ip);
870 }
871 if (!strcmp(peer->ip, name)) {
872 if (port <= 0 || (port > 0 && peer->port == port)) {
873 break;
874 }
875 }
876 }
878
879 if (gH323Debug) {
880 if (peer) {
881 ast_verb(0, " found matching friend\n");
882 }
883 ast_verb(0, "+++ find_friend \"%s\"\n", name);
884 }
885
886 return peer;
887}
888
889
890struct ooh323_peer *find_peer(const char * name, int port)
891{
892 struct ooh323_peer *peer;
893
894 if (gH323Debug)
895 ast_verb(0, "--- find_peer \"%s\"\n", name);
896
897
899 for (peer = peerl.peers; peer; peer = peer->next) {
900 if (gH323Debug) {
901 ast_verb(0, " comparing with \"%s\"\n", peer->ip);
902 }
903 if (!strcasecmp(peer->name, name))
904 break;
905 if (peer->h323id && !strcasecmp(peer->h323id, name))
906 break;
907 if (peer->e164 && !strcasecmp(peer->e164, name))
908 break;
909 /*
910 if (!strcmp(peer->ip, name)) {
911 if (port > 0 && peer->port == port) { break; }
912 else if (port <= 0) { break; }
913 }
914 */
915 }
917
918 if (gH323Debug) {
919 if (peer) {
920 ast_verb(0, " found matching peer\n");
921 }
922 ast_verb(0, "+++ find_peer \"%s\"\n", name);
923 }
924
925 return peer;
926}
927
928static int ooh323_digit_begin(struct ast_channel *chan, char digit)
929{
930 char dtmf[2];
931 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
932 int res = 0;
933
934 if (gH323Debug)
935 ast_verb(0, "--- ooh323_digit_begin\n");
936
937 if (!p) {
938 ast_log(LOG_ERROR, "No private structure for call\n");
939 return -1;
940 }
941 ast_mutex_lock(&p->lock);
942
943 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
945 } else if (((p->dtmfmode & H323_DTMF_Q931) ||
948 dtmf[0] = digit;
949 dtmf[1] = '\0';
950 ooSendDTMFDigit(p->callToken, dtmf);
951 } else if (p->dtmfmode & H323_DTMF_INBAND) {
952 res = -1; // tell Asterisk to generate inband indications
953 }
955
956 if (gH323Debug) {
957 ast_verb(0, "+++ ooh323_digit_begin, res = %d\n", res);
958 }
959 return res;
960}
961
962static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
963{
964 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
965 int res = 0;
966
967 if (gH323Debug)
968 ast_verb(0, "--- ooh323_digit_end\n");
969
970 if (!p) {
971 ast_log(LOG_ERROR, "No private structure for call\n");
972 return -1;
973 }
974 ast_mutex_lock(&p->lock);
975 if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) {
977 } else if(p->dtmfmode & H323_DTMF_INBAND) {
978 res = -1; // tell Asterisk to stop inband indications
979 }
980
982
983 if (gH323Debug) {
984 ast_verb(0, "+++ ooh323_digit_end, res = %d\n", res);
985 }
986 return res;
987}
988
989
990static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout)
991{
992 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
993 char destination[256];
994 int res=0, i;
995 const char *val = NULL;
996 ooCallOptions opts = {
997 .fastStart = TRUE,
998 .tunneling = TRUE,
999 .disableGk = TRUE,
1000 .callMode = OO_CALLMODE_AUDIOCALL,
1001 .transfercap = 0
1002 };
1003
1004 if (gH323Debug)
1005 ast_verb(0, "--- ooh323_call- %s\n", dest);
1006
1007
1009 ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
1010 "reserved\n", ast_channel_name(ast));
1011 return -1;
1012 }
1013 ast_mutex_lock(&p->lock);
1015 if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
1018 }
1019
1020 if (ast_channel_connected(ast)->id.name.valid && ast_channel_connected(ast)->id.name.str) {
1023 } else if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
1026 } else {
1028 ast_free(ast_channel_connected(ast)->id.name.str);
1032 }
1033
1034 /* Retrieve vars */
1035
1036
1037 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
1039 }
1040
1041 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
1043 if(!p->callerid_num)
1045 }
1046
1047 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
1049 }
1050
1051 if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
1052 ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
1053 }
1054
1055 if (p->host && p->port != 0)
1056 snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
1057 else if (p->host)
1058 snprintf(destination, sizeof(destination), "%s", p->host);
1059 else
1060 ast_copy_string(destination, dest, sizeof(destination));
1061
1062 destination[sizeof(destination)-1]='\0';
1063
1064 opts.transfercap = ast_channel_transfercapability(ast);
1065 opts.fastStart = p->faststart;
1066 opts.tunneling = p->h245tunneling;
1067
1068 for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
1069
1070 if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
1071 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
1072 } else {
1073 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
1074 }
1075
1077 if (res != OO_OK) {
1078 ast_log(LOG_ERROR, "Failed to make call\n");
1079 return -1; /* ToDO: cleanup */
1080 }
1081 if (gH323Debug)
1082 ast_verb(0, "+++ ooh323_call\n");
1083
1084 return 0;
1085}
1086
1087static int ooh323_hangup(struct ast_channel *ast)
1088{
1089 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1090 int q931cause = AST_CAUSE_NORMAL_CLEARING;
1091
1092 if (gH323Debug)
1093 ast_verb(0, "--- ooh323_hangup\n");
1094
1095 if (p) {
1096 ast_mutex_lock(&p->lock);
1097
1098 if (ast_channel_hangupcause(ast)) {
1099 q931cause = ast_channel_hangupcause(ast);
1100 } else {
1101 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
1102 if (cause) {
1103 if (!strcmp(cause, "CONGESTION")) {
1105 } else if (!strcmp(cause, "BUSY")) {
1106 q931cause = AST_CAUSE_USER_BUSY;
1107 } else if (!strcmp(cause, "CHANISUNVAIL")) {
1109 } else if (!strcmp(cause, "NOANSWER")) {
1110 q931cause = AST_CAUSE_NO_ANSWER;
1111 } else if (!strcmp(cause, "CANCEL")) {
1112 q931cause = AST_CAUSE_CALL_REJECTED;
1113 }
1114 }
1115 }
1116
1117
1118
1119 if (gH323Debug)
1120 ast_verb(0, " hanging %s with cause: %d\n", p->username, q931cause);
1123 ooHangCall(p->callToken,
1124 ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
1126 /* ast_mutex_unlock(&p->lock); */
1127 } else
1129 /* detach channel here */
1130 if (p->owner) {
1132 p->owner = NULL;
1134 }
1135
1138 usecnt--;
1140
1141 /* Notify the module monitors that use count for resource has changed */
1143
1144 } else {
1145 ast_debug(1, "No call to hangup\n" );
1146 }
1147
1148 if (gH323Debug)
1149 ast_verb(0, "+++ ooh323_hangup\n");
1150
1151 return 0;
1152}
1153
1154static int ooh323_answer(struct ast_channel *ast)
1155{
1156 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1157 char *callToken = (char *)NULL;
1158
1159 if (gH323Debug)
1160 ast_verb(0, "--- ooh323_answer\n");
1161
1162 if (p) {
1163
1164 ast_mutex_lock(&p->lock);
1166 if (ast_channel_state(ast) != AST_STATE_UP) {
1167 ast_channel_lock(ast);
1168 if (!p->alertsent) {
1169 if (gH323Debug) {
1170 ast_debug(1, "Sending forced ringback for %s, res = %u\n",
1171 callToken, ooManualRingback(callToken));
1172 } else {
1173 ooManualRingback(callToken);
1174 }
1175 p->alertsent = 1;
1176 }
1178 ast_debug(1, "ooh323_answer(%s)\n", ast_channel_name(ast));
1179 ast_channel_unlock(ast);
1180 ooAnswerCall(p->callToken);
1181 }
1182 if (callToken) {
1184 }
1186 }
1187
1188 if (gH323Debug)
1189 ast_verb(0, "+++ ooh323_answer\n");
1190
1191 return 0;
1192}
1193
1194static struct ast_frame *ooh323_read(struct ast_channel *ast)
1195{
1196 struct ast_frame *fr;
1197 static struct ast_frame null_frame = { AST_FRAME_NULL, };
1198 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1199
1200 if (!p) return &null_frame;
1201
1202 ast_mutex_lock(&p->lock);
1203 if (p->rtp)
1204 fr = ooh323_rtp_read(ast, p);
1205 else
1206 fr = &null_frame;
1207 /* time(&p->lastrtprx); */
1209 return fr;
1210}
1211
1212static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
1213{
1214 struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1215 int res = 0;
1216
1217 if (p) {
1218 ast_mutex_lock(&p->lock);
1219
1220 p->lastrtptx = time(NULL);
1221
1222 if (f->frametype == AST_FRAME_MODEM) {
1223 ast_debug(1, "Send UDPTL %u/%d len %d for %s\n",
1225 if (p->udptl)
1226 res = ast_udptl_write(p->udptl, f);
1228 return res;
1229 }
1230
1231
1232 if (f->frametype == AST_FRAME_VOICE) {
1233/* sending progress for first */
1234 if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
1235 p->callToken) {
1236 ooManualProgress(p->callToken);
1237 p->progsent = 1;
1238 }
1239
1240
1243 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1245 "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1250
1252 } else {
1253 /* ast_set_write_format(ast, f->subclass);
1254 ast->nativeformats = f->subclass; */
1255 }
1257 return 0;
1258 }
1259
1260 if (p->rtp)
1261 res = ast_rtp_instance_write(p->rtp, f);
1262
1264
1265 } else if (f->frametype == AST_FRAME_IMAGE) {
1267 return 0;
1268 } else {
1269 ast_log(LOG_WARNING, "Can't send %u type frames with OOH323 write\n",
1270 f->frametype);
1272 return 0;
1273 }
1274
1275 }
1276
1277 return res;
1278}
1279
1280static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1281{
1282
1283 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
1284 char *callToken = (char *)NULL;
1285 int res = -1, rres;
1286
1287 if (!p) return -1;
1288
1289 ast_mutex_lock(&p->lock);
1292
1293 if (!callToken) {
1294 if (gH323Debug)
1295 ast_verb(0, " ooh323_indicate - No callToken\n");
1296 return -1;
1297 }
1298
1299 if (!ast_sockaddr_isnull(&p->redirip)) {
1300 res = 0;
1301 }
1302
1303 if (gH323Debug) {
1304 ast_verb(0, "----- ooh323_indicate %d on call %s\n", condition, callToken);
1305 }
1306
1307 ast_mutex_lock(&p->lock);
1308 switch (condition) {
1310 /* While h323 does support overlapped dialing, this channel driver does not
1311 * at this time. Treat a response of Incomplete as if it were congestion.
1312 */
1315 ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
1316 }
1317 break;
1318 case AST_CONTROL_BUSY:
1320 ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
1321 }
1322 break;
1323 case AST_CONTROL_HOLD:
1324 ast_moh_start(ast, data, NULL);
1325 break;
1326 case AST_CONTROL_UNHOLD:
1327 ast_moh_stop(ast);
1328 break;
1330 if (ast_channel_state(ast) != AST_STATE_UP) {
1331 if (!p->progsent) {
1332 rres = ooManualProgress(callToken);
1333 if (gH323Debug) {
1334 ast_debug(1, "Sending manual progress for %s, res = %u\n", callToken, rres);
1335 }
1336 p->progsent = 1;
1337 }
1338 }
1339 break;
1342 if (!p->alertsent) {
1343 rres = ooManualRingback(callToken);
1344 if (gH323Debug) {
1345 ast_debug(1, "Sending manual ringback for %s, res = %u\n", callToken, rres);
1346 }
1347 p->alertsent = 1;
1348 }
1349 p->alertsent = 1;
1350 }
1351 break;
1353 if (p->rtp) {
1355 }
1356 break;
1358 if (p->rtp) {
1360 }
1361 break;
1363 if (!ast_channel_connected(ast)->id.name.valid
1364 || ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
1365 break;
1366 }
1367 if (gH323Debug) {
1368 ast_debug(1, "Sending connected line info for %s (%s)\n",
1369 callToken, ast_channel_connected(ast)->id.name.str);
1370 }
1371 ooSetANI(callToken, ast_channel_connected(ast)->id.name.str);
1372 break;
1373
1375 if (p->t38support != T38_ENABLED) {
1376 struct ast_control_t38_parameters parameters = { .request_response = 0 };
1377 parameters.request_response = AST_T38_REFUSED;
1379 &parameters, sizeof(parameters));
1380 break;
1381 }
1382 if (datalen != sizeof(struct ast_control_t38_parameters)) {
1383 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
1384 "Expected %d, got %d\n",
1385 (int)sizeof(enum ast_control_t38), (int)datalen);
1386 } else {
1387 const struct ast_control_t38_parameters *parameters = data;
1388 struct ast_control_t38_parameters our_parameters;
1389 enum ast_control_t38 message = parameters->request_response;
1390 switch (message) {
1391
1392 case AST_T38_NEGOTIATED:
1393 if (p->faxmode) {
1394 res = 0;
1395 break;
1396 }
1398
1399 if (p->faxmode) {
1400 /* T.38 already negotiated */
1401 our_parameters.request_response = AST_T38_NEGOTIATED;
1402 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1403 our_parameters.rate = AST_T38_RATE_14400;
1404 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1405 } else if (!p->chmodepend) {
1406 p->chmodepend = 1;
1407 ooRequestChangeMode(p->callToken, 1);
1408 res = 0;
1409 }
1410 break;
1411
1413
1414 if (!p->faxmode) {
1415 /* T.38 already terminated */
1416 our_parameters.request_response = AST_T38_TERMINATED;
1417 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1418 } else if (!p->chmodepend) {
1419 p->chmodepend = 1;
1420 ooRequestChangeMode(p->callToken, 0);
1421 res = 0;
1422 }
1423 break;
1424
1426 our_parameters.request_response = AST_T38_REQUEST_PARMS;
1427 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1428 our_parameters.rate = AST_T38_RATE_14400;
1429 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1431 break;
1432
1433 default:
1434 ;
1435
1436 }
1437
1438 }
1439 break;
1443 case -1:
1444 break;
1445 default:
1446 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
1447 condition, callToken);
1448 }
1449
1451
1452 if (gH323Debug) {
1453 ast_verb(0, "++++ ooh323_indicate %d on %s is %d\n", condition, callToken, res);
1454 }
1455
1456 ast_free(callToken);
1457 return res;
1458}
1459
1460static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1461{
1462
1463 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
1464 int res = -1;
1466 char* cp;
1467
1468 if (!p) return -1;
1469
1470 ast_mutex_lock(&p->lock);
1471
1472 if (gH323Debug)
1473 ast_verb(0, "----- ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
1474
1475 switch (option) {
1476
1478
1479 if (*datalen != sizeof(enum ast_t38_state)) {
1480 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
1481 " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
1482 break;
1483 }
1484
1485 if (p->t38support != T38_DISABLED) {
1486 if (p->faxmode) {
1488 } else {
1490 }
1491 }
1492
1493 *((enum ast_t38_state *) data) = state;
1494 res = 0;
1495 break;
1496
1497
1499
1500 cp = (char *) data;
1501 *cp = p->vad ? 1 : 0;
1502 ast_debug(1, "Reporting digit detection %sabled on %s\n",
1503 *cp ? "en" : "dis", ast_channel_name(ast));
1504
1505 res = 0;
1506 break;
1507
1508 default: ;
1509
1510 }
1511
1512 if (gH323Debug)
1513 ast_verb(0, "+++++ ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
1514
1516
1517 return res;
1518}
1519
1520
1521
1522static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1523{
1524 struct ooh323_pvt *p = ast_channel_tech_pvt(newchan);
1525
1526 if (!p) return -1;
1527
1528 if (gH323Debug)
1529 ast_verb(0, "--- ooh323c ooh323_fixup\n");
1530
1531 ast_mutex_lock(&p->lock);
1532 if (p->owner != oldchan) {
1533 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
1535 return -1;
1536 }
1537
1538 if (p->owner == oldchan) {
1539 p->owner = newchan;
1540 } else {
1541 p->owner = oldchan;
1542 }
1543
1545
1546 if (gH323Debug)
1547 ast_verb(0, "+++ ooh323c ooh323_fixup \n");
1548
1549 return 0;
1550}
1551
1552
1553void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
1554{
1555 struct ooh323_pvt *p = NULL;
1556
1557 if (gH323Debug)
1558 ast_verb(0, "--- ooh323_update_writeformat %s/%d\n",
1559 ast_format_get_name(fmt), txframes);
1560
1561 p = find_call(call);
1562 if (!p) {
1563 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1564 return;
1565 }
1566
1567 ast_mutex_lock(&p->lock);
1568
1569 ao2_replace(p->writeformat, fmt);
1570
1571 if (p->owner) {
1572 struct ast_format_cap *caps;
1573
1575 if (!caps) {
1576 ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
1577 return;
1578 }
1579
1580 while (p->owner && ast_channel_trylock(p->owner)) {
1581 ast_debug(1,"Failed to grab lock, trying again\n");
1583 }
1584 if (!p->owner) {
1586 ast_log(LOG_ERROR, "Channel has no owner\n");
1587 ao2_ref(caps, -1);
1588 return;
1589 }
1590 if (gH323Debug) {
1591 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1592 ast_verb(0, "Writeformat before update %s/%s\n",
1595 }
1596
1597 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
1599 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
1600 }
1601 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
1603 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
1604 }
1605
1606 if (txframes) {
1607 ast_format_cap_set_framing(caps, txframes);
1608 }
1609 ast_format_cap_append(caps, fmt, 0);
1611 ao2_ref(caps, -1);
1615 } else
1616 ast_log(LOG_ERROR, "No owner found\n");
1617
1618
1620
1621 if (gH323Debug)
1622 ast_verb(0, "+++ ooh323_update_writeformat\n");
1623}
1624
1625void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
1626{
1627 struct ooh323_pvt *p = NULL;
1628
1629 if (gH323Debug)
1630 ast_verb(0, "--- ooh323_update_readformat %s\n",
1631 ast_format_get_name(fmt));
1632
1633 p = find_call(call);
1634 if (!p) {
1635 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1636 return;
1637 }
1638
1639 ast_mutex_lock(&p->lock);
1640
1641 ao2_replace(p->readformat, fmt);
1642
1643 if (p->owner) {
1644 struct ast_format_cap *caps;
1645
1647 if (!caps) {
1648 ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
1649 return;
1650 }
1651
1652 while (p->owner && ast_channel_trylock(p->owner)) {
1653 ast_debug(1,"Failed to grab lock, trying again\n");
1655 }
1656 if (!p->owner) {
1658 ast_log(LOG_ERROR, "Channel has no owner\n");
1659 ao2_ref(caps, -1);
1660 return;
1661 }
1662
1663 if (gH323Debug) {
1664 ast_verb(0, "Readformat before update %s\n",
1666 }
1667 ast_format_cap_append(caps, fmt, 0);
1669 ao2_ref(caps, -1);
1672 } else
1673 ast_log(LOG_ERROR, "No owner found\n");
1674
1676
1677 if (gH323Debug)
1678 ast_verb(0, "+++ ooh323_update_readformat\n");
1679}
1680
1681
1682int onAlerting(ooCallData *call)
1683{
1684 struct ooh323_pvt *p = NULL;
1685 struct ast_channel *c = NULL;
1686
1687 if (gH323Debug)
1688 ast_verb(0, "--- onAlerting %s\n", call->callToken);
1689
1690 p = find_call(call);
1691
1692 if(!p) {
1693 ast_log(LOG_ERROR, "No matching call found\n");
1694 return -1;
1695 }
1696 ast_mutex_lock(&p->lock);
1697 if (!p->owner) {
1699 ast_debug(1, "Channel has no owner\n");
1700 return 0;
1701 }
1702 while (p->owner && ast_channel_trylock(p->owner)) {
1703 ast_debug(1, "Failed to grab lock, trying again\n");
1705 }
1706 if (!p->owner) {
1708 ast_log(LOG_ERROR, "Channel has no owner\n");
1709 return 0;
1710 }
1711 c = p->owner;
1712
1713 if (call->remoteDisplayName) {
1715 struct ast_set_party_connected_line update_connected;
1716
1717 memset(&update_connected, 0, sizeof(update_connected));
1718 update_connected.id.name = 1;
1720 connected.id.name.valid = 1;
1721 connected.id.name.str = (char *) call->remoteDisplayName;
1724 }
1727
1731
1732 if (gH323Debug)
1733 ast_verb(0, "+++ onAlerting %s\n", call->callToken);
1734
1735 return OO_OK;
1736}
1737
1738int onProgress(ooCallData *call)
1739{
1740 struct ooh323_pvt *p = NULL;
1741 struct ast_channel *c = NULL;
1742
1743 if (gH323Debug)
1744 ast_verb(0, "--- onProgress %s\n", call->callToken);
1745
1746 p = find_call(call);
1747
1748 if(!p) {
1749 ast_log(LOG_ERROR, "No matching call found\n");
1750 return -1;
1751 }
1752 ast_mutex_lock(&p->lock);
1753 if (!p->owner) {
1755 ast_log(LOG_ERROR, "Channel has no owner\n");
1756 return 0;
1757 }
1758 while (p->owner && ast_channel_trylock(p->owner)) {
1759 ast_debug(1, "Failed to grab lock, trying again\n");
1761 }
1762 if (!p->owner) {
1764 ast_log(LOG_ERROR, "Channel has no owner\n");
1765 return 0;
1766 }
1767 c = p->owner;
1768
1769 if (call->remoteDisplayName) {
1771 struct ast_set_party_connected_line update_connected;
1772
1773 memset(&update_connected, 0, sizeof(update_connected));
1774 update_connected.id.name = 1;
1776 connected.id.name.valid = 1;
1777 connected.id.name.str = (char *) call->remoteDisplayName;
1780 }
1783
1787
1788 if (gH323Debug)
1789 ast_verb(0, "+++ onProgress %s\n", call->callToken);
1790
1791 return OO_OK;
1792}
1793
1794/**
1795 * Callback for sending digits from H.323 up to asterisk
1796 *
1797 */
1798int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
1799{
1800 struct ooh323_pvt *p = NULL;
1801 struct ast_frame f;
1802 int res;
1803
1804 ast_debug(1, "Received Digit: %c\n", digit[0]);
1805 p = find_call(call);
1806 if (!p) {
1807 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1808 return -1;
1809 }
1810 if (!p->owner) {
1811 ast_log(LOG_ERROR, "Channel has no owner\n");
1812 return -1;
1813 }
1814 ast_mutex_lock(&p->lock);
1815 memset(&f, 0, sizeof(f));
1817 f.subclass.integer = digit[0];
1818 f.datalen = 0;
1819 f.samples = 800;
1820 f.offset = 0;
1821 f.data.ptr = NULL;
1822 f.mallocd = 0;
1823 f.src = "SEND_DIGIT";
1824
1825 while (p->owner && ast_channel_trylock(p->owner)) {
1826 ast_debug(1, "Failed to grab lock, trying again\n");
1828 }
1829 if (!p->owner) {
1831 ast_log(LOG_ERROR, "Channel has no owner\n");
1832 return 0;
1833 }
1834 res = ast_queue_frame(p->owner, &f);
1837 return res;
1838}
1839
1840int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
1841{
1842 struct ooh323_pvt *p = NULL;
1843 struct ooh323_user *user = NULL;
1844 struct ast_channel *c = NULL;
1845 ooAliases *alias = NULL;
1846 char *at = NULL;
1847 char number [OO_MAX_NUMBER_LENGTH];
1848
1849 if (gH323Debug)
1850 ast_verb(0, "--- ooh323_onReceivedSetup %s\n", call->callToken);
1851
1852
1853 if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
1854 ast_log(LOG_ERROR, "Failed to create a new call.\n");
1855 return -1;
1856 }
1857 ast_mutex_lock(&p->lock);
1859
1860
1861 if (call->remoteDisplayName) {
1862 p->callerid_name = ast_strdup(call->remoteDisplayName);
1863 }
1864
1865 if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
1867 }
1868
1869 if (call->remoteAliases) {
1870 for (alias = call->remoteAliases; alias; alias = alias->next) {
1871 if (alias->type == T_H225AliasAddress_h323_ID) {
1872 if (!p->callerid_name) {
1873 p->callerid_name = ast_strdup(alias->value);
1874 }
1875 ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
1876 }
1877 else if(alias->type == T_H225AliasAddress_dialedDigits)
1878 {
1879 if(!p->callerid_num)
1880 p->callerid_num = ast_strdup(alias->value);
1881 ast_copy_string(p->caller_dialedDigits, alias->value,
1882 sizeof(p->caller_dialedDigits));
1883 }
1884 else if(alias->type == T_H225AliasAddress_email_ID)
1885 {
1886 ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
1887 }
1888 else if(alias->type == T_H225AliasAddress_url_ID)
1889 {
1890 ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
1891 }
1892 }
1893 }
1894
1895 number[0] = '\0';
1896 if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
1897 ast_copy_string(p->exten, number, sizeof(p->exten));
1898 } else {
1901 ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
1902 } else if(!ast_strlen_zero(p->callee_h323id)) {
1903 ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
1904 } else if(!ast_strlen_zero(p->callee_email)) {
1905 ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
1906 if ((at = strchr(p->exten, '@'))) {
1907 *at = '\0';
1908 }
1909 }
1910 }
1911
1912 /* if no extension found, set to default 's' */
1913 if (ast_strlen_zero(p->exten)) {
1914 p->exten[0]='s';
1915 p->exten[1]='\0';
1916 }
1917
1918 user = find_user(p->callerid_name, call->remoteIP);
1919 if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
1920 ast_mutex_lock(&user->lock);
1921 p->username = ast_strdup(user->name);
1922 p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
1923 ast_strdup(user->name);
1924 ast_copy_string(p->context, user->context, sizeof(p->context));
1925 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
1926 p->amaflags = user->amaflags;
1928 p->g729onlyA = user->g729onlyA;
1929 p->dtmfmode |= user->dtmfmode;
1930 p->dtmfcodec = user->dtmfcodec;
1931 p->faxdetect = user->faxdetect;
1932 p->t38support = user->t38support;
1933 p->rtptimeout = user->rtptimeout;
1934 p->nat = user->nat;
1935 p->h245tunneling = user->h245tunneling;
1936 p->faststart = user->faststart;
1937 p->directrtp = user->directrtp;
1938 p->earlydirect = user->earlydirect;
1939
1940 if (p->faststart)
1941 OO_SETFLAG(call->flags, OO_M_FASTSTART);
1942 else
1943 OO_CLRFLAG(call->flags, OO_M_FASTSTART);
1944 /* if we disable h245tun for this user then we clear flag */
1945 /* in any other case we don't must touch this */
1946 /* ie if we receive setup without h245tun but enabled
1947 we can't enable it per call */
1948 if (!p->h245tunneling)
1949 OO_CLRFLAG(call->flags, OO_M_TUNNELING);
1950
1951 if (user->rtpmask && user->rtpmaskstr[0]) {
1952 p->rtpmask = user->rtpmask;
1953 ast_copy_string(p->rtpmaskstr, user->rtpmaskstr,
1954 sizeof(p->rtpmaskstr));
1955 }
1956 if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
1957 p->rtdrcount = user->rtdrcount;
1958 p->rtdrinterval = user->rtdrinterval;
1959 }
1960
1961 p->aniasdni = user->aniasdni;
1962
1963 if (user->incominglimit) user->inUse++;
1964 ast_mutex_unlock(&user->lock);
1965 } else {
1966 if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
1967 p->username = ast_strdup(call->remoteIP);
1968 p->directrtp = gDirectRTP;
1970 } else {
1972 ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
1973 if (!user) {
1975 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1976 }
1977 else {
1979 call->callEndReason = OO_REASON_REMOTE_REJECTED;
1980 }
1982 return -1;
1983 }
1984 }
1985
1987 p->t38support, p->g729onlyA);
1988/* Incoming call */
1990 if(!c) {
1992 ast_log(LOG_ERROR, "Could not create ast_channel\n");
1993 return -1;
1994 }
1995
1996 if (p->aniasdni) {
1997 ooCallSetCallerId(call, p->exten);
1998 }
1999 if (!configure_local_rtp(p, call)) {
2001 ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
2002 return -1;
2003 }
2004
2006
2007 if (gH323Debug)
2008 ast_verb(0, "+++ ooh323_onReceivedSetup - Determined context %s, "
2009 "extension %s\n", p->context, p->exten);
2010
2011 return OO_OK;
2012}
2013
2014
2015
2016int onOutgoingCall(ooCallData *call)
2017{
2018 struct ooh323_pvt *p = NULL;
2019 int i = 0;
2020
2021 if (gH323Debug)
2022 ast_verb(0, "--- onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
2023
2024 if (!strcmp(call->callType, "outgoing")) {
2025 p = find_call(call);
2026 if (!p) {
2027 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2028 return -1;
2029 }
2030 ast_mutex_lock(&p->lock);
2031
2032 if (!ast_strlen_zero(p->callerid_name)) {
2033 ooCallSetCallerId(call, p->callerid_name);
2034 }
2035 if (!ast_strlen_zero(p->callerid_num)) {
2036 i = 0;
2037 while (*(p->callerid_num + i) != '\0') {
2038 if(!isdigit(*(p->callerid_num+i))) { break; }
2039 i++;
2040 }
2041 if(*(p->callerid_num+i) == '\0')
2042 ooCallSetCallingPartyNumber(call, p->callerid_num);
2043 else {
2044 if(!p->callerid_name)
2045 ooCallSetCallerId(call, p->callerid_num);
2046 }
2047 }
2048
2050 ooCallAddAliasH323ID(call, p->caller_h323id);
2051
2053 if (gH323Debug) {
2054 ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
2055 }
2056 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
2057 } else if (!ast_strlen_zero(p->callerid_num)) {
2058 if (ooIsDialedDigit(p->callerid_num)) {
2059 if (gH323Debug) {
2060 ast_verb(0, "setting callid number %s\n", p->callerid_num);
2061 }
2062 ooCallAddAliasDialedDigits(call, p->callerid_num);
2063 } else if (ast_strlen_zero(p->caller_h323id)) {
2064 ooCallAddAliasH323ID(call, p->callerid_num);
2065 }
2066 }
2067 if (p->rtpmask && p->rtpmaskstr[0]) {
2068 call->rtpMask = p->rtpmask;
2069 ast_mutex_lock(&call->rtpMask->lock);
2070 call->rtpMask->inuse++;
2071 ast_mutex_unlock(&call->rtpMask->lock);
2072 ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
2073 }
2074
2075 if (!p->rtp && !configure_local_rtp(p, call)) {
2077 return OO_FAILED;
2078 }
2079
2081 }
2082
2083 if (gH323Debug)
2084 ast_verb(0, "+++ onOutgoingCall %s\n", call->callToken);
2085 return OO_OK;
2086}
2087
2088
2089int onNewCallCreated(ooCallData *call)
2090{
2091 struct ooh323_pvt *p = NULL;
2092 int i = 0;
2093
2094 if (gH323Debug)
2095 ast_verb(0, "--- onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
2096
2097 ast_mutex_lock(&call->Lock);
2099 ast_log(LOG_ERROR,"Failed to create call thread.\n");
2100 ast_mutex_unlock(&call->Lock);
2101 return -1;
2102 }
2103
2104 if (!strcmp(call->callType, "outgoing")) {
2105 p = find_call(call);
2106 if (!p) {
2107 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2108 ast_mutex_unlock(&call->Lock);
2109 return -1;
2110 }
2111 ast_mutex_lock(&p->lock);
2112
2113 if (!ast_strlen_zero(p->callerid_name)) {
2114 ooCallSetCallerId(call, p->callerid_name);
2115 }
2116 if (!ast_strlen_zero(p->callerid_num)) {
2117 i = 0;
2118 while (*(p->callerid_num + i) != '\0') {
2119 if(!isdigit(*(p->callerid_num+i))) { break; }
2120 i++;
2121 }
2122 if(*(p->callerid_num+i) == '\0')
2123 ooCallSetCallingPartyNumber(call, p->callerid_num);
2124 else {
2126 ooCallSetCallerId(call, p->callerid_num);
2127 }
2128 }
2129
2131 ooCallAddAliasH323ID(call, p->caller_h323id);
2132
2134 if (gH323Debug) {
2135 ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
2136 }
2137 ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
2138 } else if (!ast_strlen_zero(p->callerid_num)) {
2139 if (ooIsDialedDigit(p->callerid_num)) {
2140 if (gH323Debug) {
2141 ast_verb(0, "setting callid number %s\n", p->callerid_num);
2142 }
2143 ooCallAddAliasDialedDigits(call, p->callerid_num);
2144 } else if (ast_strlen_zero(p->caller_h323id)) {
2145 ooCallAddAliasH323ID(call, p->callerid_num);
2146 }
2147 }
2148
2149
2150 if (!ast_strlen_zero(p->exten)) {
2151 if (ooIsDialedDigit(p->exten)) {
2152 ooCallSetCalledPartyNumber(call, p->exten);
2153 ooCallAddRemoteAliasDialedDigits(call, p->exten);
2154 } else {
2155 ooCallAddRemoteAliasH323ID(call, p->exten);
2156 }
2157 }
2158
2159 if (gH323Debug) {
2160 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
2161
2162 ast_verb(0, " Outgoing call %s(%s) - Codec prefs - %s\n",
2163 p->username?p->username:"NULL", call->callToken,
2164 ast_format_cap_get_names(p->cap, &codec_buf));
2165 }
2166
2168 p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
2169
2173 }
2174
2175 ast_mutex_unlock(&call->Lock);
2176 if (gH323Debug)
2177 ast_verb(0, "+++ onNewCallCreated %s\n", call->callToken);
2178 return OO_OK;
2179}
2180
2181int onCallEstablished(ooCallData *call)
2182{
2183 struct ooh323_pvt *p = NULL;
2184
2185 if (gH323Debug)
2186 ast_verb(0, "--- onCallEstablished %s\n", call->callToken);
2187
2188
2189 if (!(p = find_call(call))) {
2190 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2191 return -1;
2192 }
2193
2195 ast_mutex_lock(&p->lock);
2196 if (!p->owner) {
2198 ast_log(LOG_ERROR, "Channel has no owner\n");
2199 return -1;
2200 }
2201
2202 while (p->owner && ast_channel_trylock(p->owner)) {
2203 ast_debug(1, "Failed to grab lock, trying again\n");
2205 }
2206 if (p->owner) {
2207 struct ast_channel* c = p->owner;
2208
2209 if (call->remoteDisplayName) {
2211 struct ast_set_party_connected_line update_connected;
2212
2213 memset(&update_connected, 0, sizeof(update_connected));
2214 update_connected.id.name = 1;
2216 connected.id.name.valid = 1;
2217 connected.id.name.str = (char *) call->remoteDisplayName;
2220 }
2221
2225 }
2227
2228 }
2229
2230 if (gH323Debug)
2231 ast_verb(0, "+++ onCallEstablished %s\n", call->callToken);
2232
2233 return OO_OK;
2234}
2235
2236int onCallCleared(ooCallData *call)
2237{
2238 struct ooh323_pvt *p = NULL;
2239 int ownerLock = 0;
2240
2241 if (gH323Debug)
2242 ast_verb(0, "--- onCallCleared %s \n", call->callToken);
2243
2244
2245 if ((p = find_call(call))) {
2246 ast_mutex_lock(&p->lock);
2247
2248 while (p->owner) {
2249 if (ast_channel_trylock(p->owner)) {
2250 ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
2251 ast_debug(1, "Failed to grab lock, trying again\n");
2253 } else {
2254 ownerLock = 1; break;
2255 }
2256 }
2257
2258 if (ownerLock) {
2260
2262 ast_channel_hangupcause_set(p->owner, call->q931cause);
2264 ast_queue_hangup_with_cause(p->owner,call->q931cause);
2265 }
2266 }
2267
2268 if(p->owner) {
2271 p->owner = NULL;
2273 }
2274
2275 if (!p->rtp) {
2277 }
2278
2280
2282
2285 usecnt--;
2287
2288 }
2289
2290 if (gH323Debug)
2291 ast_verb(0, "+++ onCallCleared\n");
2292
2293 return OO_OK;
2294}
2295
2296/* static void ooh323_delete_user(struct ooh323_user *user)
2297{
2298 struct ooh323_user *prev = NULL, *cur = NULL;
2299
2300 if (gH323Debug)
2301 ast_verb(0, "--- ooh323_delete_user\n");
2302
2303 if (user) {
2304 cur = userl.users;
2305 ast_mutex_lock(&userl.lock);
2306 while (cur) {
2307 if (cur == user) break;
2308 prev = cur;
2309 cur = cur->next;
2310 }
2311
2312 if (cur) {
2313 if (prev)
2314 prev->next = cur->next;
2315 else
2316 userl.users = cur->next;
2317 }
2318 ast_mutex_unlock(&userl.lock);
2319
2320 ast_free(user);
2321 }
2322
2323 if (gH323Debug)
2324 ast_verb(0, "+++ ooh323_delete_user\n");
2325
2326} */
2327
2329{
2330 struct ooh323_peer *prev = NULL, *cur = NULL;
2331
2332 if (gH323Debug)
2333 ast_verb(0, "--- ooh323_delete_peer\n");
2334
2335 if (peer) {
2336 cur = peerl.peers;
2338 while(cur) {
2339 if(cur==peer) break;
2340 prev = cur;
2341 cur = cur->next;
2342 }
2343
2344 if (cur) {
2345 if(prev)
2346 prev->next = cur->next;
2347 else
2348 peerl.peers = cur->next;
2349 }
2351
2352 ast_free(peer->h323id);
2353 ast_free(peer->email);
2354 ast_free(peer->url);
2355 ast_free(peer->e164);
2356
2357 ao2_cleanup(peer->cap);
2358 ast_free(peer);
2359 }
2360
2361 if (gH323Debug)
2362 ast_verb(0, "+++ ooh323_delete_peer\n");
2363
2364}
2365
2366
2367
2368static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
2369{
2370 struct ooh323_user *user = NULL;
2371
2372 if (gH323Debug)
2373 ast_verb(0, "--- build_user\n");
2374
2375 user = ast_calloc(1,sizeof(struct ooh323_user));
2376 if (user) {
2377 memset(user, 0, sizeof(struct ooh323_user));
2378 if (!(user->cap = ast_format_cap_alloc(0))) {
2379 ast_free(user);
2380 return NULL;
2381 }
2382 ast_mutex_init(&user->lock);
2383 ast_copy_string(user->name, name, sizeof(user->name));
2385 user->rtptimeout = gRTPTimeout;
2386 user->nat = gNat;
2387 user->dtmfmode = gDTMFMode;
2388 user->dtmfcodec = gDTMFCodec;
2389 user->faxdetect = gFAXdetect;
2390 user->t38support = gT38Support;
2391 user->faststart = gFastStart;
2392 user->h245tunneling = gTunneling;
2393 user->directrtp = gDirectRTP;
2394 user->earlydirect = gEarlyDirect;
2395 user->g729onlyA = g729onlyA;
2396 /* set default context */
2397 ast_copy_string(user->context, gContext, sizeof(user->context));
2398 ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
2399 user->amaflags = gAMAFLAGS;
2400
2401 while (v) {
2402 if (!strcasecmp(v->name, "context")) {
2403 ast_copy_string(user->context, v->value, sizeof(user->context));
2404 } else if (!strcasecmp(v->name, "incominglimit")) {
2405 user->incominglimit = atoi(v->value);
2406 if (user->incominglimit < 0)
2407 user->incominglimit = 0;
2408 } else if (!strcasecmp(v->name, "accountcode")) {
2409 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
2410 } else if (!strcasecmp(v->name, "roundtrip")) {
2411 sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
2412 } else if (!strcasecmp(v->name, "faststart")) {
2413 user->faststart = ast_true(v->value);
2414 } else if (!strcasecmp(v->name, "h245tunneling")) {
2415 user->h245tunneling = ast_true(v->value);
2416 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2417 user->directrtp = ast_true(v->value);
2418 user->earlydirect = ast_true(v->value);
2419 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2420 user->earlydirect = ast_true(v->value);
2421 } else if (!strcasecmp(v->name, "g729onlyA")) {
2422 user->g729onlyA = ast_true(v->value);
2423 } else if (!strcasecmp(v->name, "nat")) {
2424 user->nat = ast_true(v->value);
2425 } else if (!strcasecmp(v->name, "rtptimeout")) {
2426 user->rtptimeout = atoi(v->value);
2427 if (user->rtptimeout < 0)
2428 user->rtptimeout = gRTPTimeout;
2429 } else if (!strcasecmp(v->name, "rtpmask")) {
2430 if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2431 (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED)
2432 == 0)) {
2433 ast_mutex_init(&user->rtpmask->lock);
2434 user->rtpmask->inuse = 1;
2435 ast_copy_string(user->rtpmaskstr, v->value,
2436 sizeof(user->rtpmaskstr));
2437 } else user->rtpmask = NULL;
2438 } else if (!strcasecmp(v->name, "disallow")) {
2440 } else if (!strcasecmp(v->name, "allow")) {
2441 const char* tcodecs = v->value;
2442 if (!strcasecmp(v->value, "all")) {
2443 tcodecs = "ulaw,alaw,g729,g723,gsm";
2444 }
2446 } else if (!strcasecmp(v->name, "amaflags")) {
2447 user->amaflags = ast_channel_string2amaflag(v->value);
2448 } else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
2449 struct ast_sockaddr p;
2450 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2451 ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
2452 } else {
2453 ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
2454 }
2455 user->mUseIP = 1;
2456 } else if (!strcasecmp(v->name, "dtmfmode")) {
2457 if (!strcasecmp(v->value, "rfc2833"))
2458 user->dtmfmode = H323_DTMF_RFC2833;
2459 if (!strcasecmp(v->value, "cisco"))
2460 user->dtmfmode = H323_DTMF_CISCO;
2461 else if (!strcasecmp(v->value, "q931keypad"))
2462 user->dtmfmode = H323_DTMF_Q931;
2463 else if (!strcasecmp(v->value, "h245alphanumeric"))
2464 user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2465 else if (!strcasecmp(v->value, "h245signal"))
2466 user->dtmfmode = H323_DTMF_H245SIGNAL;
2467 else if (!strcasecmp(v->value, "inband"))
2468 user->dtmfmode = H323_DTMF_INBAND;
2469 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2470 user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2471 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2472 user->dtmfcodec = atoi(v->value);
2473 } else if (!strcasecmp(v->name, "faxdetect")) {
2474 if (ast_true(v->value)) {
2475 user->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2476 } else if (ast_false(v->value)) {
2477 user->faxdetect = 0;
2478 } else {
2479 char *buf = ast_strdupa(v->value);
2480 char *word, *next = buf;
2481 user->faxdetect = 0;
2482 while ((word = strsep(&next, ","))) {
2483 if (!strcasecmp(word, "cng")) {
2484 user->faxdetect |= FAXDETECT_CNG;
2485 } else if (!strcasecmp(word, "t38")) {
2486 user->faxdetect |= FAXDETECT_T38;
2487 } else {
2488 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2489 }
2490 }
2491
2492 }
2493 } else if (!strcasecmp(v->name, "t38support")) {
2494 if (!strcasecmp(v->value, "disabled"))
2495 user->t38support = T38_DISABLED;
2496 if (!strcasecmp(v->value, "no"))
2497 user->t38support = T38_DISABLED;
2498 else if (!strcasecmp(v->value, "faxgw"))
2499 user->t38support = T38_FAXGW;
2500 else if (!strcasecmp(v->value, "yes"))
2501 user->t38support = T38_ENABLED;
2502 } else if (!strcasecmp(v->name, "aniasdni")) {
2503 user->aniasdni = ast_true(v->value);
2504 }
2505 v = v->next;
2506 }
2507 }
2508
2509 if (gH323Debug)
2510 ast_verb(0, "+++ build_user\n");
2511
2512 return user;
2513}
2514
2515static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
2516{
2517 struct ooh323_peer *peer = NULL;
2518
2519 if (gH323Debug)
2520 ast_verb(0, "--- build_peer\n");
2521
2522 peer = ast_calloc(1, sizeof(*peer));
2523 if (peer) {
2524 memset(peer, 0, sizeof(struct ooh323_peer));
2525 if (!(peer->cap = ast_format_cap_alloc(0))) {
2526 ast_free(peer);
2527 return NULL;
2528 }
2529 ast_mutex_init(&peer->lock);
2530 ast_copy_string(peer->name, name, sizeof(peer->name));
2532 peer->rtptimeout = gRTPTimeout;
2533 peer->nat = gNat;
2534 ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
2535 peer->amaflags = gAMAFLAGS;
2536 peer->dtmfmode = gDTMFMode;
2537 peer->dtmfcodec = gDTMFCodec;
2538 peer->faxdetect = gFAXdetect;
2539 peer->t38support = gT38Support;
2540 peer->faststart = gFastStart;
2541 peer->h245tunneling = gTunneling;
2542 peer->directrtp = gDirectRTP;
2543 peer->earlydirect = gEarlyDirect;
2544 peer->g729onlyA = g729onlyA;
2545 peer->port = 1720;
2546 if (0 == friend_type) {
2547 peer->mFriend = 1;
2548 }
2549
2550 while (v) {
2551 if (!strcasecmp(v->name, "h323id")) {
2552 if (!(peer->h323id = ast_strdup(v->value))) {
2553 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2554 "peer %s\n", name);
2555 ooh323_delete_peer(peer);
2556 return NULL;
2557 }
2558 } else if (!strcasecmp(v->name, "e164")) {
2559 int valid = 1;
2560 const char *tmp;
2561 for(tmp = v->value; *tmp; tmp++) {
2562 if (!isdigit(*tmp)) {
2563 valid = 0;
2564 break;
2565 }
2566 }
2567 if (valid) {
2568 if (!(peer->e164 = ast_strdup(v->value))) {
2569 ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
2570 "peer %s\n", name);
2571 ooh323_delete_peer(peer);
2572 return NULL;
2573 }
2574 } else {
2575 ast_log(LOG_ERROR, "Invalid e164: %s for peer %s\n", v->value, name);
2576 }
2577 } else if (!strcasecmp(v->name, "email")) {
2578 if (!(peer->email = ast_strdup(v->value))) {
2579 ast_log(LOG_ERROR, "Could not allocate memory for email of "
2580 "peer %s\n", name);
2581 ooh323_delete_peer(peer);
2582 return NULL;
2583 }
2584 } else if (!strcasecmp(v->name, "url")) {
2585 if (!(peer->url = ast_strdup(v->value))) {
2586 ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2587 "peer %s\n", name);
2588 ooh323_delete_peer(peer);
2589 return NULL;
2590 }
2591 } else if (!strcasecmp(v->name, "port")) {
2592 peer->port = atoi(v->value);
2593 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
2594 struct ast_sockaddr p;
2595 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2596 ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
2597 } else {
2598 ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2599 }
2600
2601 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2602 int val = atoi(v->value);
2603 if (val < 0) {
2604 peer->outgoinglimit = 0;
2605 } else {
2606 peer->outgoinglimit = val;
2607 }
2608 } else if (!strcasecmp(v->name, "accountcode")) {
2609 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
2610 } else if (!strcasecmp(v->name, "faststart")) {
2611 peer->faststart = ast_true(v->value);
2612 } else if (!strcasecmp(v->name, "h245tunneling")) {
2613 peer->h245tunneling = ast_true(v->value);
2614 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2615 peer->directrtp = ast_true(v->value);
2616 peer->earlydirect = ast_true(v->value);
2617 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2618 peer->earlydirect = ast_true(v->value);
2619 } else if (!strcasecmp(v->name, "g729onlyA")) {
2620 peer->g729onlyA = ast_true(v->value);
2621 } else if (!strcasecmp(v->name, "nat")) {
2622 peer->nat = ast_true(v->value);
2623 } else if (!strcasecmp(v->name, "rtptimeout")) {
2624 peer->rtptimeout = atoi(v->value);
2625 if(peer->rtptimeout < 0)
2626 peer->rtptimeout = gRTPTimeout;
2627 } else if (!strcasecmp(v->name, "rtpmask")) {
2628 if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2629 (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED)
2630 == 0)) {
2631 ast_mutex_init(&peer->rtpmask->lock);
2632 peer->rtpmask->inuse = 1;
2634 sizeof(peer->rtpmaskstr));
2635 } else peer->rtpmask = NULL;
2636 } else if (!strcasecmp(v->name, "disallow")) {
2638 } else if (!strcasecmp(v->name, "allow")) {
2639 const char* tcodecs = v->value;
2640 if (!strcasecmp(v->value, "all")) {
2641 tcodecs = "ulaw,alaw,g729,g723,gsm";
2642 }
2644 } else if (!strcasecmp(v->name, "amaflags")) {
2646 } else if (!strcasecmp(v->name, "roundtrip")) {
2647 sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
2648 } else if (!strcasecmp(v->name, "dtmfmode")) {
2649 if (!strcasecmp(v->value, "rfc2833"))
2651 if (!strcasecmp(v->value, "cisco"))
2652 peer->dtmfmode = H323_DTMF_CISCO;
2653 else if (!strcasecmp(v->value, "q931keypad"))
2654 peer->dtmfmode = H323_DTMF_Q931;
2655 else if (!strcasecmp(v->value, "h245alphanumeric"))
2657 else if (!strcasecmp(v->value, "h245signal"))
2659 else if (!strcasecmp(v->value, "inband"))
2660 peer->dtmfmode = H323_DTMF_INBAND;
2661 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2662 peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2663 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2664 peer->dtmfcodec = atoi(v->value);
2665 } else if (!strcasecmp(v->name, "faxdetect")) {
2666 if (ast_true(v->value)) {
2668 } else if (ast_false(v->value)) {
2669 peer->faxdetect = 0;
2670 } else {
2671 char *buf = ast_strdupa(v->value);
2672 char *word, *next = buf;
2673 peer->faxdetect = 0;
2674 while ((word = strsep(&next, ","))) {
2675 if (!strcasecmp(word, "cng")) {
2676 peer->faxdetect |= FAXDETECT_CNG;
2677 } else if (!strcasecmp(word, "t38")) {
2678 peer->faxdetect |= FAXDETECT_T38;
2679 } else {
2680 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2681 }
2682 }
2683
2684 }
2685 } else if (!strcasecmp(v->name, "t38support")) {
2686 if (!strcasecmp(v->value, "disabled"))
2687 peer->t38support = T38_DISABLED;
2688 if (!strcasecmp(v->value, "no"))
2689 peer->t38support = T38_DISABLED;
2690 else if (!strcasecmp(v->value, "faxgw"))
2691 peer->t38support = T38_FAXGW;
2692 else if (!strcasecmp(v->value, "yes"))
2693 peer->t38support = T38_ENABLED;
2694 }
2695 v = v->next;
2696 }
2697 }
2698
2699 if (gH323Debug)
2700 ast_verb(0, "+++ build_peer\n");
2701
2702 return peer;
2703}
2704
2705static int ooh323_do_reload(void)
2706{
2707 struct ooAliases * pNewAlias = NULL;
2708 struct ooh323_peer *peer = NULL;
2709
2710 if (gH323Debug) {
2711 ast_verb(0, "--- ooh323_do_reload\n");
2712 }
2713
2714 /* Gatekeeper */
2715 if (gH323ep.gkClient) {
2716 ooGkClientDestroy();
2717 }
2718
2719 reload_config(1);
2720
2721 /* Gatekeeper */
2722 if (gRasGkMode == RasUseSpecificGatekeeper ||
2723 gRasGkMode == RasDiscoverGatekeeper) {
2724 ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ?
2725 gGatekeeper : 0, gRASIP, 0);
2726 ooGkClientStart(gH323ep.gkClient);
2727 }
2728
2729 /* Set aliases if any */
2730 if (gH323Debug) {
2731 ast_verb(0, "updating local aliases\n");
2732 }
2733
2734 for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
2735 switch (pNewAlias->type) {
2736 case T_H225AliasAddress_h323_ID:
2737 ooH323EpAddAliasH323ID(pNewAlias->value);
2738 break;
2739 case T_H225AliasAddress_dialedDigits:
2740 ooH323EpAddAliasDialedDigits(pNewAlias->value);
2741 break;
2742 case T_H225AliasAddress_email_ID:
2743 ooH323EpAddAliasEmailID(pNewAlias->value);
2744 break;
2745 default:
2746 ;
2747 }
2748 }
2749
2751 peer = peerl.peers;
2752 while (peer) {
2753 if(peer->h323id) {
2754 ooH323EpAddAliasH323ID(peer->h323id);
2755 }
2756 if(peer->email) {
2757 ooH323EpAddAliasEmailID(peer->email);
2758 }
2759 if(peer->e164) {
2760 ooH323EpAddAliasDialedDigits(peer->e164);
2761 }
2762 if(peer->url) {
2763 ooH323EpAddAliasURLID(peer->url);
2764 }
2765 peer = peer->next;
2766 }
2768
2769 if (gH323Debug) {
2770 ast_verb(0, "+++ ooh323_do_reload\n");
2771 }
2772
2773 return 0;
2774}
2775
2776/*--- h323_reload: Force reload of module from cli ---*/
2777
2778char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2779{
2780
2781 switch (cmd) {
2782 case CLI_INIT:
2783 e->command = "ooh323 reload";
2784 e->usage =
2785 "Usage: ooh323 reload\n"
2786 " Reload OOH323 config.\n";
2787 return NULL;
2788 case CLI_GENERATE:
2789 return NULL;
2790 }
2791
2792 if (a->argc != 2)
2793 return CLI_SHOWUSAGE;
2794
2795 if (gH323Debug)
2796 ast_verb(0, "--- ooh323_reload\n");
2797
2799 if (h323_reloading) {
2800 ast_verb(0, "Previous OOH323 reload not yet done\n");
2801 } else {
2802 h323_reloading = 1;
2803 }
2806
2807 if (gH323Debug)
2808 ast_verb(0, "+++ ooh323_reload\n");
2809
2810 return 0;
2811}
2812
2814{
2815 int format;
2816 struct ooAliases *pNewAlias = NULL, *cur, *prev;
2817 struct ast_config *cfg;
2818 struct ast_variable *v;
2819 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2820 struct ooh323_user *user = NULL;
2821 struct ooh323_peer *peer = NULL;
2822 char *cat;
2823 const char *utype;
2824
2825 if (gH323Debug)
2826 ast_verb(0, "--- reload_config\n");
2827
2828 cfg = ast_config_load((char*)config, config_flags);
2829
2830 /* We *must* have a config file otherwise stop immediately */
2831 if (!cfg) {
2832 ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
2833 return 1;
2834 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
2835 return RESULT_SUCCESS;
2836
2837 if (reload) {
2838 delete_users();
2839 delete_peers();
2840 if (gH323Debug) {
2841 ast_verb(0, " reload_config - Freeing up alias list\n");
2842 }
2843 cur = gAliasList;
2844 while (cur) {
2845 prev = cur;
2846 cur = cur->next;
2847 ast_free(prev->value);
2848 ast_free(prev);
2849 }
2850 gAliasList = NULL;
2851 ooH323EpClearAllAliases();
2852 }
2853
2854 /* Inintialize everything to default */
2855 snprintf(gLogFile, sizeof(gLogFile), "%s/%s", ast_config_AST_LOG_DIR, DEFAULT_LOGFILE);
2856 gPort = 1720;
2857 gIP[0] = '\0';
2858 strcpy(gCallerID, DEFAULT_H323ID);
2862 gDTMFCodec = 101;
2865 gTRCLVL = OOTRCLVLERR;
2866 gRasGkMode = RasNoGatekeeper;
2867 gGatekeeper[0] = '\0';
2868 gRASIP[0] = '\0';
2869 gRTPTimeout = 60;
2870 gNat = FALSE;
2871 gRTDRInterval = 0;
2872 gRTDRCount = 0;
2874 gFastStart = 1;
2875 gTunneling = 1;
2876 gTOS = 0;
2877 strcpy(gContext, DEFAULT_CONTEXT);
2878 gAliasList = NULL;
2880 ooconfig.mTCPPortStart = 12030;
2881 ooconfig.mTCPPortEnd = 12230;
2882 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2883
2884 v = ast_variable_browse(cfg, "general");
2885 while (v) {
2886
2887 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
2888 v = v->next;
2889 continue;
2890 }
2891
2892 if (!strcasecmp(v->name, "port")) {
2893 gPort = (int)strtol(v->value, NULL, 10);
2894 } else if (!strcasecmp(v->name, "bindaddr")) {
2895 ast_copy_string(gIP, v->value, sizeof(gIP));
2897 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
2898 ast_config_destroy(cfg);
2899 return 1;
2900 }
2902 v6mode = 1;
2903 }
2904 } else if (!strcasecmp(v->name, "h225portrange")) {
2905 char* endlimit = 0;
2906 char temp[512];
2907 ast_copy_string(temp, v->value, sizeof(temp));
2908 endlimit = strchr(temp, ',');
2909 if (endlimit) {
2910 *endlimit = '\0';
2911 endlimit++;
2912 ooconfig.mTCPPortStart = atoi(temp);
2913 ooconfig.mTCPPortEnd = atoi(endlimit);
2914
2915 } else {
2916 ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
2917 }
2918 } else if (!strcasecmp(v->name, "gateway")) {
2920 } else if (!strcasecmp(v->name, "faststart")) {
2922 if (gFastStart)
2923 ooH323EpEnableFastStart();
2924 else
2925 ooH323EpDisableFastStart();
2926 } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
2929 ooH323EpEnableMediaWaitForConnect();
2930 else
2931 ooH323EpDisableMediaWaitForConnect();
2932 } else if (!strcasecmp(v->name, "h245tunneling")) {
2934 if (gTunneling)
2935 ooH323EpEnableH245Tunneling();
2936 else
2937 ooH323EpDisableH245Tunneling();
2938 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2941 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2943 } else if (!strcasecmp(v->name, "g729onlyA")) {
2944 g729onlyA = ast_true(v->value);
2945 } else if (!strcasecmp(v->name, "roundtrip")) {
2946 sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
2947 } else if (!strcasecmp(v->name, "trybemaster")) {
2948 gBeMaster = ast_true(v->value);
2949 if (gBeMaster)
2950 ooH323EpTryBeMaster(1);
2951 else
2952 ooH323EpTryBeMaster(0);
2953 } else if (!strcasecmp(v->name, "h323id")) {
2954 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2955 if (!pNewAlias) {
2956 ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
2957 ast_config_destroy(cfg);
2958 return 1;
2959 }
2960 if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
2962 }
2963 pNewAlias->type = T_H225AliasAddress_h323_ID;
2964 pNewAlias->value = ast_strdup(v->value);
2965 pNewAlias->next = gAliasList;
2966 gAliasList = pNewAlias;
2967 pNewAlias = NULL;
2968 } else if (!strcasecmp(v->name, "e164")) {
2969 int valid = 1;
2970 const char *tmp;
2971 for(tmp = v->value; *tmp; tmp++) {
2972 if (!isdigit(*tmp)) {
2973 valid = 0;
2974 break;
2975 }
2976 }
2977 if (valid) {
2978 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2979 if (!pNewAlias) {
2980 ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
2981 ast_config_destroy(cfg);
2982 return 1;
2983 }
2984 pNewAlias->type = T_H225AliasAddress_dialedDigits;
2985 pNewAlias->value = ast_strdup(v->value);
2986 pNewAlias->next = gAliasList;
2987 gAliasList = pNewAlias;
2988 pNewAlias = NULL;
2989 } else {
2990 ast_log(LOG_ERROR, "Invalid e164: %s\n", v->value);
2991 }
2992 } else if (!strcasecmp(v->name, "email")) {
2993 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2994 if (!pNewAlias) {
2995 ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
2996 ast_config_destroy(cfg);
2997 return 1;
2998 }
2999 pNewAlias->type = T_H225AliasAddress_email_ID;
3000 pNewAlias->value = ast_strdup(v->value);
3001 pNewAlias->next = gAliasList;
3002 gAliasList = pNewAlias;
3003 pNewAlias = NULL;
3004 } else if (!strcasecmp(v->name, "t35country")) {
3005 t35countrycode = atoi(v->value);
3006 } else if (!strcasecmp(v->name, "t35extensions")) {
3007 t35extensions = atoi(v->value);
3008 } else if (!strcasecmp(v->name, "manufacturer")) {
3009 manufacturer = atoi(v->value);
3010 } else if (!strcasecmp(v->name, "vendorid")) {
3011 ast_copy_string(vendor, v->value, sizeof(vendor));
3012 } else if (!strcasecmp(v->name, "versionid")) {
3013 ast_copy_string(version, v->value, sizeof(version));
3014 } else if (!strcasecmp(v->name, "callerid")) {
3016 } else if (!strcasecmp(v->name, "incominglimit")) {
3017 gIncomingLimit = atoi(v->value);
3018 } else if (!strcasecmp(v->name, "outgoinglimit")) {
3019 gOutgoingLimit = atoi(v->value);
3020 } else if (!strcasecmp(v->name, "gatekeeper")) {
3021 if (!strcasecmp(v->value, "DISABLE")) {
3022 gRasGkMode = RasNoGatekeeper;
3023 } else if (!strcasecmp(v->value, "DISCOVER")) {
3024 gRasGkMode = RasDiscoverGatekeeper;
3025 } else {
3026 gRasGkMode = RasUseSpecificGatekeeper;
3028 }
3029 } else if (!strcasecmp(v->name, "localras")) {
3030 ast_copy_string(gRASIP, v->value, sizeof(gRASIP));
3031 ast_verb(3, " == Setting RAS IP to %s\n", gRASIP);
3032 } else if (!strcasecmp(v->name, "logfile")) {
3033 if (v->value[0] == '/') {
3034 ast_copy_string(gLogFile, v->value, sizeof(gLogFile));
3035 } else {
3036 snprintf(gLogFile, sizeof(gLogFile), "%s/%s", ast_config_AST_LOG_DIR, v->value);
3037 }
3038 } else if (!strcasecmp(v->name, "context")) {
3039 ast_copy_string(gContext, v->value, sizeof(gContext));
3040 ast_verb(3, " == Setting default context to %s\n", gContext);
3041 } else if (!strcasecmp(v->name, "nat")) {
3042 gNat = ast_true(v->value);
3043 } else if (!strcasecmp(v->name, "rtptimeout")) {
3044 gRTPTimeout = atoi(v->value);
3045 if (gRTPTimeout < 0)
3046 gRTPTimeout = 60;
3047 } else if (!strcasecmp(v->name, "tos")) {
3048 if (sscanf(v->value, "%30i", &format) == 1)
3049 gTOS = format & 0xff;
3050 else if (!strcasecmp(v->value, "lowdelay"))
3051 gTOS = IPTOS_LOWDELAY;
3052 else if (!strcasecmp(v->value, "throughput"))
3053 gTOS = IPTOS_THROUGHPUT;
3054 else if (!strcasecmp(v->value, "reliability"))
3055 gTOS = IPTOS_RELIABILITY;
3056 else if (!strcasecmp(v->value, "mincost"))
3058 else if (!strcasecmp(v->value, "none"))
3059 gTOS = 0;
3060 else
3061 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be "
3062 "'lowdelay', 'throughput', 'reliability', "
3063 "'mincost', or 'none'\n", v->lineno);
3064 } else if (!strcasecmp(v->name, "amaflags")) {
3066 } else if (!strcasecmp(v->name, "accountcode")) {
3068 } else if (!strcasecmp(v->name, "disallow")) {
3070 } else if (!strcasecmp(v->name, "allow")) {
3071 const char* tcodecs = v->value;
3072 if (!strcasecmp(v->value, "all")) {
3073 tcodecs = "ulaw,alaw,g729,g723,gsm";
3074 }
3076 } else if (!strcasecmp(v->name, "dtmfmode")) {
3077 if (!strcasecmp(v->value, "inband"))
3079 else if (!strcasecmp(v->value, "rfc2833"))
3081 else if (!strcasecmp(v->value, "cisco"))
3083 else if (!strcasecmp(v->value, "q931keypad"))
3085 else if (!strcasecmp(v->value, "h245alphanumeric"))
3087 else if (!strcasecmp(v->value, "h245signal"))
3089 else {
3090 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n",
3091 v->value);
3093 }
3094 } else if (!strcasecmp(v->name, "relaxdtmf")) {
3096 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
3097 gDTMFCodec = atoi(v->value);
3098 } else if (!strcasecmp(v->name, "faxdetect")) {
3099 if (ast_true(v->value)) {
3101 } else if (ast_false(v->value)) {
3102 gFAXdetect = 0;
3103 } else {
3104 char *buf = ast_strdupa(v->value);
3105 char *word, *next = buf;
3106 gFAXdetect = 0;
3107 while ((word = strsep(&next, ","))) {
3108 if (!strcasecmp(word, "cng")) {
3110 } else if (!strcasecmp(word, "t38")) {
3112 } else {
3113 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
3114 }
3115 }
3116
3117 }
3118 } else if (!strcasecmp(v->name, "t38support")) {
3119 if (!strcasecmp(v->value, "disabled"))
3121 if (!strcasecmp(v->value, "no"))
3123 else if (!strcasecmp(v->value, "faxgw"))
3125 else if (!strcasecmp(v->value, "yes"))
3127 } else if (!strcasecmp(v->name, "tracelevel")) {
3128 gTRCLVL = atoi(v->value);
3129 ooH323EpSetTraceLevel(gTRCLVL);
3130 } else if (!strcasecmp(v->name, "aniasdni")) {
3131 gANIasDNI = ast_true(v->value);
3132 }
3133 v = v->next;
3134 }
3135
3136 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
3137 if (strcasecmp(cat, "general")) {
3138 int friend_type = 0;
3139 utype = ast_variable_retrieve(cfg, cat, "type");
3140 if (utype) {
3141 friend_type = strcasecmp(utype, "friend");
3142 if (!strcmp(utype, "user") || 0 == friend_type) {
3143 user = build_user(cat, ast_variable_browse(cfg, cat));
3144 if (user) {
3146 user->next = userl.users;
3147 userl.users = user;
3149 } else {
3150 ast_log(LOG_WARNING, "Failed to build user %s\n", cat);
3151 }
3152 }
3153 if (!strcasecmp(utype, "peer") || 0 == friend_type) {
3154 peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type);
3155 if (peer) {
3157 peer->next = peerl.peers;
3158 peerl.peers = peer;
3160 } else {
3161 ast_log(LOG_WARNING, "Failed to build peer %s\n", cat);
3162 }
3163 }
3164 }
3165 }
3166 }
3167 ast_config_destroy(cfg);
3168
3169
3170 /* Determine ip address if neccessary */
3171 if (ast_strlen_zero(gIP)) {
3172 ooGetLocalIPAddress(gIP);
3173 if (!strcmp(gIP, "127.0.0.1") || !strcmp(gIP, "::1")) {
3174 ast_log(LOG_NOTICE, "Failed to determine local ip address. Please "
3175 "specify it in ooh323.conf. OOH323 Disabled\n");
3176 return 1;
3177 }
3178 }
3179
3180 if (gH323Debug)
3181 ast_verb(0, "+++ reload_config\n");
3182
3183 return 0;
3184
3185}
3186
3187
3188static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3189{
3190 char ip_port[64];
3191 struct ooh323_peer *prev = NULL, *peer = NULL;
3192
3193 switch (cmd) {
3194 case CLI_INIT:
3195 e->command = "ooh323 show peer";
3196 e->usage =
3197 "Usage: ooh323 show peer <name>\n"
3198 " List details of specific OOH323 peer.\n";
3199 return NULL;
3200 case CLI_GENERATE:
3201 return NULL;
3202 }
3203
3204 if (a->argc != 4)
3205 return CLI_SHOWUSAGE;
3206
3208 peer = peerl.peers;
3209 while (peer) {
3210 ast_mutex_lock(&peer->lock);
3211 if (!strcmp(peer->name, a->argv[3])) {
3212 break;
3213 } else {
3214 prev = peer;
3215 peer = peer->next;
3216 ast_mutex_unlock(&prev->lock);
3217 }
3218 }
3219
3220 if (peer) {
3221 sprintf(ip_port, "%s:%d", peer->ip, peer->port);
3222 ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
3223 ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
3224 peer->h245tunneling?"yes":"no");
3225 ast_cli(a->fd, "%-15s%s\n", "DirectRTP", peer->directrtp ? "yes" : "no");
3226 ast_cli(a->fd, "%-15s%s\n", "EarlyDirectRTP", peer->earlydirect ? "yes" : "no");
3227 ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
3228 if (peer->dtmfmode & H323_DTMF_CISCO) {
3229 ast_cli(a->fd, "%s\n", "cisco");
3230 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
3231 } else if (peer->dtmfmode & H323_DTMF_RFC2833) {
3232 ast_cli(a->fd, "%s\n", "rfc2833");
3233 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
3234 } else if (peer->dtmfmode & H323_DTMF_Q931) {
3235 ast_cli(a->fd, "%s\n", "q931keypad");
3236 } else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC) {
3237 ast_cli(a->fd, "%s\n", "h245alphanumeric");
3238 } else if (peer->dtmfmode & H323_DTMF_H245SIGNAL) {
3239 ast_cli(a->fd, "%s\n", "h245signal");
3240 } else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX) {
3241 ast_cli(a->fd, "%s\n", "inband-relaxed");
3242 } else if (peer->dtmfmode & H323_DTMF_INBAND) {
3243 ast_cli(a->fd, "%s\n", "inband");
3244 } else {
3245 ast_cli(a->fd, "%s\n", "unknown");
3246 }
3247 ast_cli(a->fd,"%-15s", "T.38 Mode: ");
3248 if (peer->t38support == T38_DISABLED) {
3249 ast_cli(a->fd, "%s\n", "disabled");
3250 } else if (peer->t38support == T38_FAXGW) {
3251 ast_cli(a->fd, "%s\n", "faxgw compatible");
3252 }
3253 if (peer->faxdetect == (FAXDETECT_CNG | FAXDETECT_T38)) {
3254 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Yes");
3255 } else if (peer->faxdetect & FAXDETECT_CNG) {
3256 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Cng");
3257 } else if (peer->faxdetect & FAXDETECT_T38) {
3258 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "T.38");
3259 } else {
3260 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "No");
3261 }
3262
3263 ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode);
3264 ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_channel_amaflags2string(peer->amaflags));
3265 ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port);
3266 ast_cli(a->fd, "%-15.15s%u\n", "OutgoingLimit: ", peer->outgoinglimit);
3267 ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout);
3268 ast_cli(a->fd, "%-15.15s%s\n", "nat: ", peer->nat?"yes":"no");
3269 if (peer->rtpmaskstr[0]) {
3270 ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr);
3271 }
3272 if (peer->rtdrcount && peer->rtdrinterval) {
3273 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval);
3274 }
3275 ast_mutex_unlock(&peer->lock);
3276 } else {
3277 ast_cli(a->fd, "Peer %s not found\n", a->argv[3]);
3278 ast_cli(a->fd, "\n");
3279 }
3281
3282 return CLI_SUCCESS;
3283}
3284
3285static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3286{
3287 struct ooh323_peer *prev = NULL, *peer = NULL;
3288 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3289 char ip_port[64];
3290#define FORMAT "%-15.15s %-15.15s %-23.23s %-s\n"
3291
3292 switch (cmd) {
3293 case CLI_INIT:
3294 e->command = "ooh323 show peers";
3295 e->usage =
3296 "Usage: ooh323 show peers\n"
3297 " Lists all known OOH323 peers.\n";
3298 return NULL;
3299 case CLI_GENERATE:
3300 return NULL;
3301 }
3302
3303 if (a->argc != 3)
3304 return CLI_SHOWUSAGE;
3305
3306 ast_cli(a->fd, FORMAT, "Name", "Accountcode", "ip:port", "Formats");
3307
3309 peer = peerl.peers;
3310 while (peer) {
3311 ast_mutex_lock(&peer->lock);
3312 snprintf(ip_port, sizeof(ip_port), "%s:%d", peer->ip, peer->port);
3313 ast_cli(a->fd, FORMAT, peer->name,
3314 peer->accountcode,
3315 ip_port,
3316 ast_format_cap_get_names(peer->cap, &codec_buf));
3317 prev = peer;
3318 peer = peer->next;
3319 ast_mutex_unlock(&prev->lock);
3320
3321 }
3323#undef FORMAT
3324 return CLI_SUCCESS;
3325}
3326
3327static char *handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3328{
3329 struct ooh323_user *prev = NULL, *user = NULL;
3330
3331 switch (cmd) {
3332 case CLI_INIT:
3333 e->command = "ooh323 show user";
3334 e->usage =
3335 "Usage: ooh323 show user <name>\n"
3336 " List details of specific OOH323 user.\n";
3337 return NULL;
3338 case CLI_GENERATE:
3339 return NULL;
3340 }
3341
3342 if (a->argc != 4)
3343 return CLI_SHOWUSAGE;
3344
3345
3347 user = userl.users;
3348 while (user) {
3349 ast_mutex_lock(&user->lock);
3350 if (!strcmp(user->name, a->argv[3])) {
3351 break;
3352 } else {
3353 prev = user;
3354 user = user->next;
3355 ast_mutex_unlock(&prev->lock);
3356 }
3357 }
3358
3359 if (user) {
3360 ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
3361 ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no",
3362 user->h245tunneling?"yes":"no");
3363 ast_cli(a->fd, "%-15s%s\n", "DirectRTP", user->directrtp ? "yes" : "no");
3364 ast_cli(a->fd, "%-15s%s\n", "EarlyDirectRTP", user->earlydirect ? "yes" : "no");
3365 ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
3366 if (user->dtmfmode & H323_DTMF_CISCO) {
3367 ast_cli(a->fd, "%s\n", "cisco");
3368 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
3369 } else if (user->dtmfmode & H323_DTMF_RFC2833) {
3370 ast_cli(a->fd, "%s\n", "rfc2833");
3371 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
3372 } else if (user->dtmfmode & H323_DTMF_Q931) {
3373 ast_cli(a->fd, "%s\n", "q931keypad");
3374 } else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC) {
3375 ast_cli(a->fd, "%s\n", "h245alphanumeric");
3376 } else if (user->dtmfmode & H323_DTMF_H245SIGNAL) {
3377 ast_cli(a->fd, "%s\n", "h245signal");
3378 } else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX) {
3379 ast_cli(a->fd, "%s\n", "inband-relaxed");
3380 } else if (user->dtmfmode & H323_DTMF_INBAND) {
3381 ast_cli(a->fd, "%s\n", "inband");
3382 } else {
3383 ast_cli(a->fd, "%s\n", "unknown");
3384 }
3385 ast_cli(a->fd,"%-15s", "T.38 Mode: ");
3386 if (user->t38support == T38_DISABLED) {
3387 ast_cli(a->fd, "%s\n", "disabled");
3388 } else if (user->t38support == T38_FAXGW) {
3389 ast_cli(a->fd, "%s\n", "faxgw compatible");
3390 }
3391 if (user->faxdetect == (FAXDETECT_CNG | FAXDETECT_T38)) {
3392 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Yes");
3393 } else if (user->faxdetect & FAXDETECT_CNG) {
3394 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Cng");
3395 } else if (user->faxdetect & FAXDETECT_T38) {
3396 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "T.38");
3397 } else {
3398 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "No");
3399 }
3400
3401 ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode);
3402 ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_channel_amaflags2string(user->amaflags));
3403 ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context);
3404 ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit);
3405 ast_cli(a->fd, "%-15.15s%u\n", "InUse: ", user->inUse);
3406 ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout);
3407 ast_cli(a->fd, "%-15.15s%s\n", "nat: ", user->nat?"yes":"no");
3408 if (user->rtpmaskstr[0]) {
3409 ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr);
3410 }
3411 ast_mutex_unlock(&user->lock);
3412 if (user->rtdrcount && user->rtdrinterval) {
3413 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval);
3414 }
3415 } else {
3416 ast_cli(a->fd, "User %s not found\n", a->argv[3]);
3417 ast_cli(a->fd, "\n");
3418 }
3420
3421 return CLI_SUCCESS;
3422}
3423
3424static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3425{
3426 struct ooh323_user *prev = NULL, *user = NULL;
3427 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3428#define FORMAT1 "%-15.15s %-15.15s %-15.15s %-s\n"
3429
3430 switch (cmd) {
3431 case CLI_INIT:
3432 e->command = "ooh323 show users";
3433 e->usage =
3434 "Usage: ooh323 show users \n"
3435 " Lists all known OOH323 users.\n";
3436 return NULL;
3437 case CLI_GENERATE:
3438 return NULL;
3439 }
3440
3441 if (a->argc != 3)
3442 return CLI_SHOWUSAGE;
3443
3444
3445 ast_cli(a->fd, FORMAT1, "Username", "Accountcode", "Context", "Formats");
3446
3448 user = userl.users;
3449 while(user)
3450 {
3451 ast_mutex_lock(&user->lock);
3452 ast_cli(a->fd, FORMAT1, user->name,
3453 user->accountcode, user->context,
3454 ast_format_cap_get_names(user->cap, &codec_buf));
3455 prev = user;
3456 user = user->next;
3457 ast_mutex_unlock(&prev->lock);
3458
3459 }
3461#undef FORMAT1
3462 return RESULT_SUCCESS;
3463
3464}
3465
3466static char *handle_cli_ooh323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3467{
3468 switch (cmd) {
3469 case CLI_INIT:
3470 e->command = "ooh323 set debug [off]";
3471 e->usage =
3472 "Usage: ooh323 set debug [off]\n"
3473 " Enables/Disables debugging of OOH323 channel driver\n";
3474 return NULL;
3475 case CLI_GENERATE:
3476 return NULL;
3477 }
3478
3479 if (a->argc < 3 || a->argc > 4)
3480 return CLI_SHOWUSAGE;
3481 if (a->argc == 4 && strcasecmp(a->argv[3], "off"))
3482 return CLI_SHOWUSAGE;
3483
3484 gH323Debug = (a->argc == 4) ? FALSE : TRUE;
3485 ast_cli(a->fd, "OOH323 Debugging %s\n", gH323Debug ? "Enabled" : "Disabled");
3486
3487 return CLI_SUCCESS;
3488}
3489
3490#if 0
3491static int ooh323_show_channels(int fd, int argc, char *argv[])
3492{
3493 return RESULT_SUCCESS;
3494}
3495#endif
3496
3497static char *handle_cli_ooh323_show_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3498{
3500
3501 switch (cmd) {
3502 case CLI_INIT:
3503 e->command = "ooh323 show gk";
3504 e->usage =
3505 "Usage: ooh323 show gk\n"
3506 " Shows Gatekeeper connection state\n";
3507 return NULL;
3508 case CLI_GENERATE:
3509 return NULL;
3510 }
3511
3512 if (a->argc != 3)
3513 return CLI_SHOWUSAGE;
3514
3515 ast_cli(a->fd, "\nGateKeeper connection state:\n");
3516 if (!gH323ep.gkClient) {
3517 ast_cli(a->fd, "No Gatekeeper is configured\n");
3518 return CLI_SUCCESS;
3519 }
3520
3521 if (gRasGkMode == RasNoGatekeeper) {
3522 snprintf(value, sizeof(value), "%s", "No Gatekeeper");
3523 } else if (gRasGkMode == RasDiscoverGatekeeper) {
3524 snprintf(value, sizeof(value), "%s", "Discover");
3525 } else {
3526 snprintf(value, sizeof(value), "%s", gGatekeeper);
3527 }
3528 ast_cli(a->fd, "%-20s%s\n", "Gatekeeper:", value);
3529 switch(gH323ep.gkClient->state) {
3530 case GkClientIdle:
3531 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Idle");
3532 break;
3533 case GkClientDiscovered:
3534 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Discovered");
3535 break;
3536 case GkClientRegistered:
3537 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Registered");
3538 break;
3539 case GkClientUnregistered:
3540 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Unregistered");
3541 break;
3542 case GkClientGkErr:
3543 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Error");
3544 break;
3545 case GkClientFailed:
3546 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Failed");
3547 break;
3548 case GkClientStopped:
3549 ast_cli(a->fd, "%-20s%s\n", "GK state:", "Shutdown");
3550 break;
3551 default:
3552 break;
3553 }
3554
3555 return CLI_SUCCESS;
3556}
3557
3558static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3559{
3561 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3562 ooAliases *pAlias = NULL, *pAliasNext = NULL;;
3563
3564 switch (cmd) {
3565 case CLI_INIT:
3566 e->command = "ooh323 show config";
3567 e->usage =
3568 "Usage: ooh323 show config\n"
3569 " Shows global configuration of H.323 channel driver\n";
3570 return NULL;
3571 case CLI_GENERATE:
3572 return NULL;
3573 }
3574
3575 if (a->argc != 3)
3576 return CLI_SHOWUSAGE;
3577
3578 ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n");
3579 snprintf(value, sizeof(value), "%s:%d", gIP, gPort);
3580 ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value);
3581 ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ", ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd);
3582 ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no");
3583 ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
3584 ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
3585 ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect", gMediaWaitForConnect?"yes":"no");
3586 ast_cli(a->fd, "%-20s%s\n", "DirectRTP", gDirectRTP ? "yes" : "no");
3587 ast_cli(a->fd, "%-20s%s\n", "EarlyDirectRTP", gEarlyDirect ? "yes" : "no");
3588
3589#if (0)
3590 extern OOH323EndPoint gH323ep;
3591 ast_cli(a->fd, "%-20s%s\n", "FASTSTART",
3592 (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no");
3593 ast_cli(a->fd, "%-20s%s\n", "TUNNELING",
3594 (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no");
3595 ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN",
3596 (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no");
3597#endif
3598
3599 if (gRasGkMode == RasNoGatekeeper) {
3600 snprintf(value, sizeof(value), "%s", "No Gatekeeper");
3601 } else if (gRasGkMode == RasDiscoverGatekeeper) {
3602 snprintf(value, sizeof(value), "%s", "Discover");
3603 } else {
3604 snprintf(value, sizeof(value), "%s", gGatekeeper);
3605 }
3606 ast_cli(a->fd, "%-20s%s\n", "Gatekeeper:", value);
3607 ast_cli(a->fd, "%-20s%s\n", "H.323 LogFile:", gLogFile);
3608 ast_cli(a->fd, "%-20s%s\n", "Context:", gContext);
3609 ast_cli(a->fd, "%-20s%s\n", "Capability:",
3610 ast_format_cap_get_names(gCap, &codec_buf));
3611 ast_cli(a->fd, "%-20s", "DTMF Mode: ");
3612 if (gDTMFMode & H323_DTMF_CISCO) {
3613 ast_cli(a->fd, "%s\n", "cisco");
3614 ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec);
3615 } else if (gDTMFMode & H323_DTMF_RFC2833) {
3616 ast_cli(a->fd, "%s\n", "rfc2833");
3617 ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec);
3618 } else if (gDTMFMode & H323_DTMF_Q931) {
3619 ast_cli(a->fd, "%s\n", "q931keypad");
3621 ast_cli(a->fd, "%s\n", "h245alphanumeric");
3622 } else if (gDTMFMode & H323_DTMF_H245SIGNAL) {
3623 ast_cli(a->fd, "%s\n", "h245signal");
3625 ast_cli(a->fd, "%s\n", "inband-relaxed");
3626 } else if (gDTMFMode & H323_DTMF_INBAND) {
3627 ast_cli(a->fd, "%s\n", "inband");
3628 } else {
3629 ast_cli(a->fd, "%s\n", "unknown");
3630 }
3631
3632 ast_cli(a->fd,"%-20s", "T.38 Mode: ");
3633 if (gT38Support == T38_DISABLED) {
3634 ast_cli(a->fd, "%s\n", "disabled");
3635 } else if (gT38Support == T38_FAXGW) {
3636 ast_cli(a->fd, "%s\n", "faxgw compatible");
3637 }
3639 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Yes");
3640 } else if (gFAXdetect & FAXDETECT_CNG) {
3641 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Cng");
3642 } else if (gFAXdetect & FAXDETECT_T38) {
3643 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "T.38");
3644 } else {
3645 ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "No");
3646 }
3647
3648 if (gRTDRCount && gRTDRInterval) {
3649 ast_cli(a->fd, "%-20.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval);
3650 }
3651
3652 ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber);
3653 ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode);
3654 ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_channel_amaflags2string(gAMAFLAGS));
3655
3656 pAlias = gAliasList;
3657 if(pAlias) {
3658 ast_cli(a->fd, "%-20s\n", "Aliases: ");
3659 }
3660 while (pAlias) {
3661 pAliasNext = pAlias->next;
3662 if (pAliasNext) {
3663 ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value);
3664 pAlias = pAliasNext->next;
3665 } else {
3666 ast_cli(a->fd,"\t%-30s\n",pAlias->value);
3667 pAlias = pAlias->next;
3668 }
3669 }
3670 return CLI_SUCCESS;
3671}
3672
3673static struct ast_cli_entry cli_ooh323[] = {
3674 AST_CLI_DEFINE(handle_cli_ooh323_set_debug, "Enable/Disable OOH323 debugging"),
3675 AST_CLI_DEFINE(handle_cli_ooh323_show_config, "Show details on global configuration of H.323 channel driver"),
3676 AST_CLI_DEFINE(handle_cli_ooh323_show_gk, "Show OOH323 Gatekeeper connection status"),
3677 AST_CLI_DEFINE(handle_cli_ooh323_show_peer, "Show details on specific OOH323 peer"),
3678 AST_CLI_DEFINE(handle_cli_ooh323_show_peers, "Show defined OOH323 peers"),
3679 AST_CLI_DEFINE(handle_cli_ooh323_show_user, "Show details on specific OOH323 user"),
3680 AST_CLI_DEFINE(handle_cli_ooh323_show_users, "Show defined OOH323 users"),
3681 AST_CLI_DEFINE(handle_cli_ooh323_reload, "reload ooh323 config")
3682};
3683
3684/*! \brief OOH323 Dialplan function - reads ooh323 settings */
3685static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
3686{
3687 struct ooh323_pvt *p = ast_channel_tech_pvt(chan);
3688
3689 ast_channel_lock(chan);
3690 if (!p) {
3691 ast_channel_unlock(chan);
3692 return -1;
3693 }
3694
3695 if (strcmp(ast_channel_tech(chan)->type, "OOH323")) {
3696 ast_log(LOG_ERROR, "This function is only supported on OOH323 channels, Channel is %s\n", ast_channel_tech(chan)->type);
3697 ast_channel_unlock(chan);
3698 return -1;
3699 }
3700
3701 ast_mutex_lock(&p->lock);
3702 if (!strcasecmp(data, "faxdetect")) {
3703 ast_copy_string(buf, p->faxdetect ? "1" : "0", len);
3704 } else if (!strcasecmp(data, "t38support")) {
3705 ast_copy_string(buf, p->t38support ? "1" : "0", len);
3706 } else if (!strcasecmp(data, "caller_h323id")) {
3708 } else if (!strcasecmp(data, "caller_dialeddigits")) {
3710 } else if (!strcasecmp(data, "caller_email")) {
3712 } else if (!strcasecmp(data, "h323id_url")) {
3714 } else if (!strcasecmp(data, "callee_h323id")) {
3716 } else if (!strcasecmp(data, "callee_dialeddigits")) {
3718 } else if (!strcasecmp(data, "callee_email")) {
3720 } else if (!strcasecmp(data, "callee_url")) {
3722 }
3724
3725 ast_channel_unlock(chan);
3726 return 0;
3727}
3728
3729/*! \brief OOH323 Dialplan function - writes ooh323 settings */
3730static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
3731{
3732 struct ooh323_pvt *p = ast_channel_tech_pvt(chan);
3733 int res = -1;
3734
3735 ast_channel_lock(chan);
3736 if (!p) {
3737 ast_channel_unlock(chan);
3738 return -1;
3739 }
3740
3741 if (strcmp(ast_channel_tech(chan)->type, "OOH323")) {
3742 ast_log(LOG_ERROR, "This function is only supported on OOH323 channels, Channel is %s\n", ast_channel_tech(chan)->type);
3743 ast_channel_unlock(chan);
3744 return -1;
3745 }
3746
3747 ast_mutex_lock(&p->lock);
3748 if (!strcasecmp(data, "faxdetect")) {
3749 if (ast_true(value)) {
3750 p->faxdetect = 1;
3751 res = 0;
3752 } else if (ast_false(value)) {
3753 p->faxdetect = 0;
3754 res = 0;
3755 } else {
3756 char *buf = ast_strdupa(value);
3757 char *word, *next = buf;
3758 p->faxdetect = 0;
3759 res = 0;
3760 while ((word = strsep(&next, ","))) {
3761 if (!strcasecmp(word, "cng")) {
3763 } else if (!strcasecmp(word, "t38")) {
3765 } else {
3766 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s'.\n", word);
3767 res = -1;
3768 }
3769 }
3770
3771 }
3772 } else if (!strcasecmp(data, "t38support")) {
3773 if (ast_true(value)) {
3774 p->t38support = 1;
3775 res = 0;
3776 } else {
3777 p->t38support = 0;
3778 res = 0;
3779 }
3780 }
3782 ast_channel_unlock(chan);
3783
3784 return res;
3785}
3786
3787static int load_module(void)
3788{
3789 struct ooAliases * pNewAlias = NULL;
3790 struct ooh323_peer *peer = NULL;
3791 OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0};
3792
3793 OOH323CALLBACKS h323Callbacks = {
3794 .onNewCallCreated = onNewCallCreated,
3795 .onAlerting = onAlerting,
3796 .onProgress = onProgress,
3797 .onIncomingCall = NULL,
3798 .onOutgoingCall = onOutgoingCall,
3799 .onCallEstablished = onCallEstablished,
3800 .onCallCleared = onCallCleared,
3801 .openLogicalChannels = NULL,
3802 .onReceivedDTMF = ooh323_onReceivedDigit,
3803 .onModeChanged = onModeChanged,
3804 .onMediaChanged = (cb_OnMediaChanged) setup_rtp_remote,
3805 };
3808 }
3810 ao2_ref(gCap, -1);
3811 gCap = NULL;
3813 }
3816
3818
3819 h225Callbacks.onReceivedSetup = &ooh323_onReceivedSetup;
3820
3821 userl.users = NULL;
3823 peerl.peers = NULL;
3825
3826#if 0
3827 ast_register_atexit(&ast_ooh323c_exit);
3828#endif
3829
3830 if (!(sched = ast_sched_context_create())) {
3831 ast_log(LOG_WARNING, "Unable to create schedule context\n");
3832 }
3833 if (!(io = io_context_create())) {
3834 ast_log(LOG_WARNING, "Unable to create I/O context\n");
3835 }
3836
3837
3838 if (!reload_config(0)) {
3839
3840 /* fire up the H.323 Endpoint */
3841 if (OO_OK != ooH323EpInitialize(OO_CALLMODE_AUDIOCALL, gLogFile, gInitError, sizeof(gInitError))) {
3842 ast_log(LOG_ERROR, "Failed to initialize OOH323 endpoint: %s"
3843 "OOH323 Disabled\n", gInitError);
3844 ao2_ref(gCap, -1);
3845 gCap = NULL;
3847