Asterisk - The Open Source Telephony Project GIT-master-67613d1
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/0 Returns caller URL</para>
40 </enum>
41 <enum name="caller_h323id">
42 <para>R/0 Returns caller h323id</para>
43 </enum>
44 <enum name="caller_dialeddigits">
45 <para>R/0 Returns caller dialed digits</para>
46 </enum>
47 <enum name="caller_email">
48 <para>R/0 Returns caller email</para>
49 </enum>
50 <enum name="callee_email">
51 <para>R/0 Returns callee email</para>
52 </enum>
53 <enum name="callee_dialeddigits">
54 <para>R/0 Returns callee dialed digits</para>
55 </enum>
56 <enum name="caller_url">
57 <para>R/0 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;
3849 }
3850
3851 /* Make sure we can register our OOH323 channel type */
3853 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
3854 ao2_ref(gCap, -1);
3855 gCap = NULL;
3859 }
3862
3863 if (gIsGateway)
3864 ooH323EpSetAsGateway();
3865
3866 ooH323EpSetVersionInfo(t35countrycode, t35extensions, manufacturer,
3867 vendor, version);
3868 ooH323EpDisableAutoAnswer();
3869 ooH323EpSetH225MsgCallbacks(h225Callbacks);
3870 ooH323EpSetTraceLevel(gTRCLVL);
3871 ooH323EpSetLocalAddress(gIP, gPort);
3872 if (v6mode) {
3873 ast_debug(1, "OOH323 channel is in IP6 mode\n");
3874 }
3875 ooH323EpSetCallerID(gCallerID);
3876
3877 if(ooH323EpSetTCPPortRange(ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd) == OO_FAILED) {
3878 ast_log(LOG_ERROR, "h225portrange: Failed to set range\n");
3879 }
3880
3881 /* Set aliases if any */
3882 for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
3883 switch (pNewAlias->type) {
3884 case T_H225AliasAddress_h323_ID:
3885 ooH323EpAddAliasH323ID(pNewAlias->value);
3886 break;
3887 case T_H225AliasAddress_dialedDigits:
3888 ooH323EpAddAliasDialedDigits(pNewAlias->value);
3889 break;
3890 case T_H225AliasAddress_email_ID:
3891 ooH323EpAddAliasEmailID(pNewAlias->value);
3892 break;
3893 default:
3894 ;
3895 }
3896 }
3897
3899 peer = peerl.peers;
3900 while (peer) {
3901 if(peer->h323id) ooH323EpAddAliasH323ID(peer->h323id);
3902 if(peer->email) ooH323EpAddAliasEmailID(peer->email);
3903 if(peer->e164) ooH323EpAddAliasDialedDigits(peer->e164);
3904 if(peer->url) ooH323EpAddAliasURLID(peer->url);
3905 peer = peer->next;
3906 }
3908
3909
3911 ooH323EpEnableMediaWaitForConnect();
3912 else
3913 ooH323EpDisableMediaWaitForConnect();
3914
3915 /* Fast start and tunneling options */
3916 if (gFastStart)
3917 ooH323EpEnableFastStart();
3918 else
3919 ooH323EpDisableFastStart();
3920
3921 if (!gTunneling)
3922 ooH323EpDisableH245Tunneling();
3923
3924 if (gBeMaster)
3925 ooH323EpTryBeMaster(1);
3926
3927 ooH323EpEnableManualRingback();
3928
3929 /* Gatekeeper */
3930 if (gRasGkMode == RasUseSpecificGatekeeper)
3931 ooGkClientInit(gRasGkMode, gGatekeeper, gRASIP, 0);
3932 else if (gRasGkMode == RasDiscoverGatekeeper)
3933 ooGkClientInit(gRasGkMode, 0, gRASIP, 0);
3934
3935 /* Register callbacks */
3936 ooH323EpSetH323Callbacks(h323Callbacks);
3937
3938 /* Add endpoint capabilities */
3940 ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
3941 ao2_ref(gCap, -1);
3942 gCap = NULL;
3945 return 1;
3946 }
3947
3948 /* Create H.323 listener */
3949 if (ooCreateH323Listener() != OO_OK) {
3950 ast_log(LOG_ERROR, "OOH323 Listener Creation failure. "
3951 "OOH323 DISABLED\n");
3952
3953 ooH323EpDestroy();
3954 ao2_ref(gCap, -1);
3955 gCap = NULL;
3958 return 1;
3959 }
3960
3961 if (ooh323c_start_stack_thread() < 0) {
3962 ast_log(LOG_ERROR, "Failed to start OOH323 stack thread. "
3963 "OOH323 DISABLED\n");
3964 ooH323EpDestroy();
3965 ao2_ref(gCap, -1);
3966 gCap = NULL;
3969 return 1;
3970 }
3971 /* And start the monitor for the first time */
3973 } else {
3974 ast_log(LOG_ERROR, "Can't load ooh323 config file, OOH323 Disabled\n");
3976 }
3977
3978 return 0;
3979}
3980
3981static int reload_module(void)
3982{
3984 if (h323_reloading) {
3985 ast_verb(0, "Previous OOH323 reload not yet done\n");
3986 } else {
3987 h323_reloading = 1;
3988 }
3991
3992 if (gH323Debug)
3993 ast_verb(0, "+++ ooh323_reload\n");
3994
3995 return 0;
3996}
3997
3998static void *do_monitor(void *data)
3999{
4000 int res;
4001 int reloading;
4002 struct ooh323_pvt *h323 = NULL;
4003 time_t t;
4004
4005 for (;;) {
4006 struct ooh323_pvt *h323_next;
4007 /* Check for a reload request */
4009 reloading = h323_reloading;
4010 h323_reloading = 0;
4012 if (reloading) {
4013 ast_verb(1, "Reloading H.323\n");
4015 }
4016 if (gH323ep.gkClient && gH323ep.gkClient->state == GkClientStopped) {
4017 ooGkClientDestroy();
4018 ast_verb(0, "Restart stopped gatekeeper client\n");
4019 ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ?
4020 gGatekeeper : 0, gRASIP, 0);
4021 ooGkClientStart(gH323ep.gkClient);
4022 }
4023
4024 /* Check for interfaces needing to be killed */
4026 time(&t);
4027 h323 = iflist;
4028 while (h323) {
4029 h323_next = h323->next;
4030
4031 if (h323->rtp && h323->rtptimeout && h323->lastrtptx &&
4032 h323->lastrtptx + h323->rtptimeout < t) {
4033 ast_rtp_instance_sendcng(h323->rtp, 0);
4034 h323->lastrtptx = time(NULL);
4035 }
4036
4037 if (h323->rtp && h323->owner && h323->rtptimeout &&
4038 h323->lastrtprx && ast_sockaddr_isnull(&h323->redirip) &&
4039 h323->lastrtprx + h323->rtptimeout < t) {
4040 if (!ast_channel_trylock(h323->owner)) {
4042 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", ast_channel_name(h323->owner), (long) (t - h323->lastrtprx));
4044 }
4045
4046 }
4047
4048 if (ast_test_flag(h323, H323_NEEDDESTROY)) {
4049 ooh323_destroy (h323);
4050 } /* else if (ast_test_flag(h323, H323_NEEDSTART) && h323->owner) {
4051 ast_channel_lock(h323->owner);
4052 if (ast_pbx_start(h323->owner)) {
4053 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", h323->owner->name);
4054 ast_channel_unlock(h323->owner);
4055 ast_hangup(h323->owner);
4056 }
4057 ast_channel_unlock(h323->owner);
4058 ast_clear_flag(h323, H323_NEEDSTART);
4059 } */
4060 h323 = h323_next;
4061 }
4063 pthread_testcancel();
4064
4065 /* Wait for sched or io */
4066 res = ast_sched_wait(sched);
4067 if ((res < 0) || (res > 1000)) {
4068 res = 1000;
4069 }
4070 res = ast_io_wait(io, res);
4071 pthread_testcancel();
4073 if (res >= 0) {
4075 }
4077 }
4078 /* Never reached */
4079 return NULL;
4080}
4081
4083{
4084 pthread_attr_t attr;
4085
4086 /* If we're supposed to be stopped -- stay stopped */
4088 return 0;
4089 if (ast_mutex_lock(&monlock)) {
4090 ast_log(LOG_WARNING, "Unable to lock monitor\n");
4091 return -1;
4092 }
4093 if (monitor_thread == pthread_self()) {
4095 ast_log(LOG_WARNING, "Cannot kill myself\n");
4096 return -1;
4097 }
4099 /* Wake up the thread */
4100 pthread_kill(monitor_thread, SIGURG);
4101 } else {
4102 pthread_attr_init(&attr);
4103 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4104 /* Start a new monitor */
4105 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
4107 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
4108 return -1;
4109 }
4110 }
4112 return 0;
4113}
4114
4115
4116
4118{
4119 /* NOTE: Assumes iflock already acquired */
4120 struct ooh323_pvt *prev = NULL, *cur = NULL;
4121 struct ooh323_user *user = NULL;
4122
4123 if (gH323Debug) {
4124 ast_verb(0, "--- ooh323_destroy \n");
4125
4126 if (p)
4127 ast_verb(0, " Destroying %s\n", p->username);
4128 }
4129
4130 cur = iflist;
4131 while (cur) {
4132 if (cur == p) { break; }
4133 prev = cur;
4134 cur = cur->next;
4135 }
4136
4137 if (cur) {
4138 ast_mutex_lock(&cur->lock);
4139 if (prev)
4140 prev->next = cur->next;
4141 else
4142 iflist = cur->next;
4143
4144 if (cur->callToken) {
4145 if (gH323Debug)
4146 ast_verb(0, " Destroying %s\n", cur->callToken);
4147 ast_free(cur->callToken);
4148 cur->callToken = 0;
4149 }
4150
4151 if (cur->username) {
4152 ast_free(cur->username);
4153 cur->username = 0;
4154 }
4155
4156 if (cur->host) {
4157 ast_free(cur->host);
4158 cur->host = 0;
4159 }
4160
4161 if (cur->callerid_name) {
4162 ast_free(cur->callerid_name);
4163 cur->callerid_name = 0;
4164 }
4165
4166 if (cur->callerid_num) {
4167 ast_free(cur->callerid_num);
4168 cur->callerid_num = 0;
4169 }
4170
4171 if (cur->rtp) {
4172 ast_rtp_instance_stop(cur->rtp);
4173 ast_rtp_instance_destroy(cur->rtp);
4174 cur->rtp = NULL;
4175 }
4176
4177 if (cur->udptl) {
4178 ast_udptl_destroy(cur->udptl);
4179 cur->udptl = NULL;
4180 }
4181
4182 /* Unlink us from the owner if we have one */
4183 if (cur->owner) {
4184 while(ast_channel_trylock(cur->owner)) {
4185 ast_debug(1, "Failed to grab lock, trying again\n");
4186 DEADLOCK_AVOIDANCE(&cur->lock);
4187 }
4188 ast_debug(1, "Detaching from %s\n", ast_channel_name(cur->owner));
4189 ast_channel_tech_pvt_set(cur->owner, NULL);
4190 ast_channel_unlock(cur->owner);
4191 cur->owner = NULL;
4193 }
4194
4195 if (cur->vad) {
4196 ast_dsp_free(cur->vad);
4197 cur->vad = NULL;
4198 }
4199
4200/* decrement user/peer count */
4201
4202 if(!ast_test_flag(cur, H323_OUTGOING)) {
4203 if (cur->neighbor.user) {
4204 user = find_user(p->callerid_name, cur->neighbor.user);
4205 if(user && user->inUse > 0) {
4206 ast_mutex_lock(&user->lock);
4207 user->inUse--;
4208 ast_mutex_unlock(&user->lock);
4209 }
4210 ast_free(cur->neighbor.user);
4211 }
4212 } else {
4213/* outgoing limit decrement here !!! */
4214 }
4215
4216 ast_mutex_unlock(&cur->lock);
4217 ast_mutex_destroy(&cur->lock);
4218 ao2_cleanup(cur->writeformat);
4219 ao2_cleanup(cur->readformat);
4220 ao2_cleanup(cur->cap);
4221 ast_free(cur);
4222 }
4223
4224 if (gH323Debug)
4225 ast_verb(0, "+++ ooh323_destroy\n");
4226
4227 return 0;
4228}
4229
4231{
4232 struct ooh323_peer *cur = NULL, *prev = NULL;
4234 cur = peerl.peers;
4235 while (cur) {
4236 prev = cur;
4237 cur = cur->next;
4238
4239 ast_mutex_destroy(&prev->lock);
4240 ast_free(prev->h323id);
4241 ast_free(prev->email);
4242 ast_free(prev->url);
4243 ast_free(prev->e164);
4244 if(prev->rtpmask) {
4245 ast_mutex_lock(&prev->rtpmask->lock);
4246 prev->rtpmask->inuse--;
4247 ast_mutex_unlock(&prev->rtpmask->lock);
4248 if (prev->rtpmask->inuse == 0) {
4249 regfree(&prev->rtpmask->regex);
4250 ast_mutex_destroy(&prev->rtpmask->lock);
4251 ast_free(prev->rtpmask);
4252 }
4253 }
4254 ast_free(prev);
4255
4256 if (cur == peerl.peers) {
4257 break;
4258 }
4259 }
4260 peerl.peers = NULL;
4262 return 0;
4263}
4264
4266{
4267 struct ooh323_user *cur = NULL, *prev = NULL;
4269 cur = userl.users;
4270 while (cur) {
4271 prev = cur;
4272 cur = cur->next;
4273 ast_mutex_destroy(&prev->lock);
4274
4275 if(prev->rtpmask) {
4276 ast_mutex_lock(&prev->rtpmask->lock);
4277 prev->rtpmask->inuse--;
4278 ast_mutex_unlock(&prev->rtpmask->lock);
4279 if (prev->rtpmask->inuse == 0) {
4280 regfree(&prev->rtpmask->regex);
4281 ast_mutex_destroy(&prev->rtpmask->lock);
4282 ast_free(prev->rtpmask);
4283 }
4284 }
4285 ao2_cleanup(prev->cap);
4286 ast_free(prev);
4287 if (cur == userl.users) {
4288 break;
4289 }
4290 }
4291 userl.users = NULL;
4293 return 0;
4294}
4295
4296static int unload_module(void)
4297{
4298 struct ooh323_pvt *p;
4299 struct ooAliases *cur = NULL, *prev = NULL;
4300
4301 if (gH323Debug) {
4302 ast_verb(0, "--- ooh323 unload_module \n");
4303 }
4304 /* First, take us out of the channel loop */
4308#if 0
4309 ast_unregister_atexit(&ast_ooh323c_exit);
4310#endif
4311
4312 if (gH323Debug) {
4313 ast_verb(0, " unload_module - hanging up all interfaces\n");
4314 }
4315 if (!ast_mutex_lock(&iflock)) {
4316 /* Hangup all interfaces if they have an owner */
4317 p = iflist;
4318 while (p) {
4319 if (p->owner) {
4321 }
4322 p = p->next;
4323 }
4324 iflist = NULL;
4326 } else {
4327 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
4328 return -1;
4329 }
4330
4331
4332 if (gH323Debug) {
4333 ast_verb(0, " unload_module - stopping monitor thread\n");
4334 }
4336 if (!ast_mutex_lock(&monlock)) {
4338 pthread_cancel(monitor_thread);
4339 pthread_kill(monitor_thread, SIGURG);
4340 pthread_join(monitor_thread, NULL);
4341 }
4344 } else {
4345 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
4346 return -1;
4347 }
4348 }
4349
4350
4351 if (gH323Debug) {
4352 ast_verb(0, " unload_module - stopping stack thread\n");
4353 }
4355
4356
4357 if (gH323Debug) {
4358 ast_verb(0, " unload_module - freeing up memory used by interfaces\n");
4359 }
4360 if (!ast_mutex_lock(&iflock)) {
4361 struct ooh323_pvt *pl;
4362
4363 /* Destroy all the interfaces and free their memory */
4364 p = iflist;
4365 while (p) {
4366 pl = p;
4367 p = p->next;
4368 /* Free associated memory */
4369 ooh323_destroy(pl);
4370 }
4371 iflist = NULL;
4373 } else {
4374 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
4375 return -1;
4376 }
4377
4378
4379 if (gH323Debug) {
4380 ast_verb(0, " unload_module - deleting users\n");
4381 }
4382 delete_users();
4383
4384
4385 if (gH323Debug) {
4386 ast_verb(0, " unload_module - deleting peers\n");
4387 }
4388 delete_peers();
4389
4390
4391 if (gH323Debug) {
4392 ast_verb(0, " unload_module - Freeing up alias list\n");
4393 }
4394 cur = gAliasList;
4395 while (cur) {
4396 prev = cur;
4397 cur = cur->next;
4398 ast_free(prev->value);
4399 ast_free(prev);
4400 }
4401 gAliasList = NULL;
4402
4403
4404 if (gH323Debug) {
4405 ast_verb(0, " unload_module- destroying OOH323 endpoint \n");
4406 }
4407 ooH323EpDestroy();
4408
4409 if (gH323Debug) {
4410 ast_verb(0, "+++ ooh323 unload_module \n");
4411 }
4412
4413 ao2_ref(gCap, -1);
4414 gCap = NULL;
4417 return 0;
4418}
4419
4420static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
4421{
4422 struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
4423 if (gH323Debug) {
4424 ast_verb(0, "+++ ooh323 get_codec, %s\n", ast_channel_name(chan));
4425 }
4426
4427 if (p) {
4430 } else if (ast_format_cap_count(p->cap)) {
4432 }
4433 }
4434
4435 if (gH323Debug) {
4436 ast_verb(0, "--- ooh323 get_codec, %s\n", ast_channel_name(chan));
4437 }
4438}
4439
4440
4441
4443{
4444 struct ooh323_pvt *p = NULL;
4446 struct ast_sockaddr tmp;
4447
4448 if (gH323Debug) {
4449 ast_verb(0, "+++ ooh323 get_rtp_peer \n");
4450 }
4451
4452 if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
4454
4455 if (!(p->rtp)) {
4457 }
4458
4459 *rtp = p->rtp ? ao2_ref(p->rtp, +1), p->rtp : NULL;
4460
4461 /* there must be checking of directmedia setting */
4462
4463 if ((ast_channel_state(chan) != AST_STATE_UP && !p->earlydirect) || !p->directrtp) {
4465 } else {
4467 }
4468
4471 }
4472
4474 if (gH323Debug) {
4475 ast_verb(0, "ooh323_get_rtp_peer %s -> %s:%d, %u\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&tmp),
4476 ast_sockaddr_port(&tmp), res);
4477 }
4478 if (gH323Debug) {
4479 ast_verb(0, "--- ooh323 get_rtp_peer, res = %d\n", (int) res);
4480 }
4481
4482 return res;
4483}
4484
4486{
4487 struct ooh323_pvt *p = NULL;
4489
4490 if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
4492
4493 if (!(p->rtp)) {
4495 }
4496
4497 *rtp = p->vrtp ? ao2_ref(p->vrtp, +1), p->vrtp : NULL;
4498
4499 /* there must check of supporting video per call */
4500
4502
4503 return res;
4504}
4505
4507{
4509 return OO_G711ULAW64K;
4510 } else if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
4511 return OO_G711ALAW64K;
4512 } else if (ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) {
4513 return OO_GSMFULLRATE;
4514 } else if (ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) {
4515 return OO_SPEEX;
4516 } else if (ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
4517 return OO_G729A;
4518 } else if (ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) {
4519 return OO_G726;
4521 return OO_G726AAL2;
4522 } else if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
4523 return OO_G7231;
4524 } else if (ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) {
4525 return OO_H263VIDEO;
4526 } else {
4527 ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_format_get_name(format));
4528 return -1;
4529 }
4530}
4531
4532static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
4533 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
4534{
4535 /* XXX Deal with Video */
4536 struct ooh323_pvt *p;
4537 int changed = 0;
4538 char *callToken = NULL;
4539
4540 if (gH323Debug) {
4541 ast_verb(0, "--- ooh323_set_peer - %s\n", ast_channel_name(chan));
4542 }
4543
4545 ast_log(LOG_WARNING, "Unknown format.\n");
4546 return -1;
4547 }
4548 p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
4549 if (!p) {
4550 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
4551 return -1;
4552 }
4553
4554 ast_mutex_lock(&p->lock);
4555
4556 if (rtp) {
4558 } else if (!ast_sockaddr_isnull(&p->redirip)) {
4559 changed = 1;
4560 memset(&p->redirip, 0, sizeof(p->redirip));
4561 }
4562
4564
4565 if (!callToken) {
4566 if (gH323Debug) {
4567 ast_verb(0, " set_rtp_peer - No callToken\n");
4568 }
4570 return -1;
4571 }
4572
4573
4574 if (changed) {
4575 if (!ast_sockaddr_isnull(&p->redirip)) {
4576 if (gH323Debug) {
4577 ast_verb(0, "ooh323_set_rtp_peer %s -> %s:%d\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&p->redirip),
4579 }
4580 ooUpdateLogChannels(callToken, ast_sockaddr_stringify_addr(&p->redirip),
4582 } else {
4583 if (gH323Debug) {
4584 ast_verb(0, "ooh323_set_rtp_peer return back to local\n");
4585 }
4586 ooUpdateLogChannels(callToken, "0.0.0.0" , 0);
4587 }
4588 }
4589
4592 return 0;
4593
4594}
4595
4596
4597
4598
4599int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
4600{
4601 char lhost[INET6_ADDRSTRLEN];
4602 unsigned lport = 0;
4603 struct ast_sockaddr tmp;
4604 ooMediaInfo mediaInfo;
4605 int x;
4606
4607 if (gH323Debug)
4608 ast_verb(0, "--- configure_local_rtp\n");
4609
4610 memset(&mediaInfo, 0, sizeof(mediaInfo));
4611 if (ast_parse_arg(call->localIP, PARSE_ADDR, &tmp)) {
4613 }
4614 if (!(p->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
4615 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n",
4616 strerror(errno));
4617 return 0;
4618 }
4619
4620 ast_rtp_instance_set_qos(p->rtp, gTOS, 0, "ooh323-rtp");
4621
4622 if (!(p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &tmp))) {
4623 ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
4624 strerror(errno));
4625 return 0;
4626 }
4628
4629 if (p->owner) {
4630 while (p->owner && ast_channel_trylock(p->owner)) {
4631 ast_debug(1,"Failed to grab lock, trying again\n");
4633 }
4634 if (!p->owner) {
4636 ast_log(LOG_ERROR, "Channel has no owner\n");
4637 return 0;
4638 }
4639 } else {
4640 ast_log(LOG_ERROR, "Channel has no owner\n");
4641 return 0;
4642 }
4643
4647
4649
4650 if (p->rtp) {
4651 if (p->cap) {
4654 }
4655 if (p->nat) {
4657 }
4658 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
4661 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
4662 }
4663 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
4666 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
4667 }
4668 /* figure out our local RTP port and tell the H.323 stack about it*/
4670 ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
4671 lport = ast_sockaddr_port(&tmp);
4672
4673 if (p->rtptimeout) {
4675 }
4677
4678 }
4679
4680 if (p->rtdrcount) {
4681 if (gH323Debug)
4682 ast_verb(0, "Setup RTDR info: %d, %d\n", p->rtdrinterval, p->rtdrcount);
4683 call->rtdrInterval = p->rtdrinterval;
4684 call->rtdrCount = p->rtdrcount;
4685 }
4686
4687
4688 ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
4689 mediaInfo.lMediaPort = lport;
4690 mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort + 1;
4691 for (x = 0; x < ast_format_cap_count(p->cap); x++) {
4692 struct ast_format *format = ast_format_cap_get_format(p->cap, x);
4693
4694 strcpy(mediaInfo.dir, "transmit");
4695 mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format);
4696 ooAddMediaInfo(call, mediaInfo);
4697 strcpy(mediaInfo.dir, "receive");
4698 ooAddMediaInfo(call, mediaInfo);
4699 if (mediaInfo.cap == OO_G729A) {
4700 strcpy(mediaInfo.dir, "transmit");
4701 mediaInfo.cap = OO_G729;
4702 ooAddMediaInfo(call, mediaInfo);
4703 strcpy(mediaInfo.dir, "receive");
4704 ooAddMediaInfo(call, mediaInfo);
4705
4706 strcpy(mediaInfo.dir, "transmit");
4707 mediaInfo.cap = OO_G729B;
4708 ooAddMediaInfo(call, mediaInfo);
4709 strcpy(mediaInfo.dir, "receive");
4710 ooAddMediaInfo(call, mediaInfo);
4711 }
4712
4713 ao2_ref(format, -1);
4714 }
4715
4716 if (p->udptl) {
4718 ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
4719 lport = ast_sockaddr_port(&tmp);
4720 ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
4721 mediaInfo.lMediaPort = lport;
4722 mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
4723 mediaInfo.cap = OO_T38;
4724 strcpy(mediaInfo.dir, "transmit");
4725 ooAddMediaInfo(call, mediaInfo);
4726 strcpy(mediaInfo.dir, "receive");
4727 ooAddMediaInfo(call, mediaInfo);
4728 }
4729
4730 if (gH323Debug)
4731 ast_verb(0, "+++ configure_local_rtp\n");
4732
4733 return 1;
4734}
4735
4736void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort)
4737{
4738 struct ooh323_pvt *p = NULL;
4739 struct ast_sockaddr tmp;
4740
4741 if (gH323Debug) {
4742 ast_verb(0, "--- setup_rtp_remote %s:%d\n", remoteIp, remotePort);
4743 }
4744 if (!remoteIp || !remoteIp[0] || !remotePort) {
4745 if (gH323Debug) {
4746 ast_verb(0, "+++ setup_rtp_remote no data\n");
4747 }
4748 return;
4749 }
4750
4751 /* Find the call or allocate a private structure if call not found */
4752 p = find_call(call);
4753
4754 if (!p || !p->rtp) {
4755 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
4756 return;
4757 }
4758
4759 ast_mutex_lock(&p->lock);
4760
4761 ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
4762 ast_sockaddr_set_port(&tmp, remotePort);
4764
4766
4767 if (gH323Debug) {
4768 ast_verb(0, "+++ setup_rtp_remote\n");
4769 }
4770
4771 return;
4772}
4773
4774
4775void setup_rtp_connection(ooCallData *call, const char *remoteIp, int remotePort)
4776{
4777 struct ooh323_pvt *p = NULL;
4778 struct ast_sockaddr tmp;
4779
4780 if (gH323Debug)
4781 ast_verb(0, "--- setup_rtp_connection %s:%d\n", remoteIp, remotePort);
4782
4783 /* Find the call or allocate a private structure if call not found */
4784 p = find_call(call);
4785
4786 if (!p || !p->rtp) {
4787 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
4788 return;
4789 }
4790
4791 ast_mutex_lock(&p->lock);
4792
4793 ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
4794 ast_sockaddr_set_port(&tmp, remotePort);
4796
4799 "audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
4800 }
4801
4803
4804 if(gH323Debug)
4805 ast_verb(0, "+++ setup_rtp_connection\n");
4806
4807 return;
4808}
4809
4811{
4812 struct ooh323_pvt *p = NULL;
4813
4814 if(gH323Debug)
4815 ast_verb(0, "--- close_rtp_connection\n");
4816
4817 p = find_call(call);
4818 if (!p) {
4819 ast_log(LOG_ERROR, "Couldn't find matching call to close rtp "
4820 "connection\n");
4821 return;
4822 }
4823 ast_mutex_lock(&p->lock);
4824 if (p->rtp) {
4826 }
4828
4829 if(gH323Debug)
4830 ast_verb(0, "+++ close_rtp_connection\n");
4831
4832 return;
4833}
4834
4835/*
4836 udptl handling functions
4837 */
4838
4839void setup_udptl_connection(ooCallData *call, const char *remoteIp,
4840 int remotePort)
4841{
4842 struct ooh323_pvt *p = NULL;
4843 struct ast_sockaddr them;
4844
4845 if (gH323Debug)
4846 ast_verb(0, "--- setup_udptl_connection\n");
4847
4848 /* Find the call or allocate a private structure if call not found */
4849 p = find_call(call);
4850
4851 if (!p) {
4852 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
4853 return;
4854 }
4855
4856 ast_mutex_lock(&p->lock);
4857 if (p->owner) {
4858 while (p->owner && ast_channel_trylock(p->owner)) {
4859 ast_debug(1, "Failed to grab lock, trying again\n");
4861 }
4862 if (!p->owner) {
4864 ast_log(LOG_ERROR, "Channel has no owner\n");
4865 return;
4866 }
4867 } else {
4869 ast_log(LOG_ERROR, "Channel has no owner\n");
4870 return;
4871 }
4872
4873 ast_parse_arg(remoteIp, PARSE_ADDR, &them);
4874 ast_sockaddr_set_port(&them, remotePort);
4875
4876 ast_udptl_set_peer(p->udptl, &them);
4878 p->t38_tx_enable = 1;
4879 p->lastTxT38 = time(NULL);
4880 if (p->t38support == T38_ENABLED) {
4881 struct ast_control_t38_parameters parameters = { .request_response = 0 };
4883 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
4884 parameters.rate = AST_T38_RATE_14400;
4885 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
4886 }
4887 if (gH323Debug) {
4888 ast_debug(1, "Receiving UDPTL %s:%d\n", ast_sockaddr_stringify_host(&them),
4889 ast_sockaddr_port(&them));
4890 }
4891
4894
4895 if(gH323Debug)
4896 ast_verb(0, "+++ setup_udptl_connection\n");
4897
4898 return;
4899}
4900
4902{
4903 struct ooh323_pvt *p = NULL;
4904
4905 if(gH323Debug)
4906 ast_verb(0, "--- close_udptl_connection\n");
4907
4908 p = find_call(call);
4909 if (!p) {
4910 ast_log(LOG_ERROR, "Couldn't find matching call to close udptl "
4911 "connection\n");
4912 return;
4913 }
4914 ast_mutex_lock(&p->lock);
4915 if (p->owner) {
4916 while (p->owner && ast_channel_trylock(p->owner)) {
4917 ast_debug(1, "Failed to grab lock, trying again\n");
4919 }
4920 if (!p->owner) {
4922 ast_log(LOG_ERROR, "Channel has no owner\n");
4923 return;
4924 }
4925 } else {
4927 ast_log(LOG_ERROR, "Channel has no owner\n");
4928 return;
4929 }
4930
4931 p->t38_tx_enable = 0;
4932 if (p->t38support == T38_ENABLED) {
4933 struct ast_control_t38_parameters parameters = { .request_response = 0 };
4935 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
4936 }
4937
4940
4941 if(gH323Debug)
4942 ast_verb(0, "+++ close_udptl_connection\n");
4943
4944 return;
4945}
4946
4947/* end of udptl handling */
4948
4949int update_our_aliases(ooCallData *call, struct ooh323_pvt *p)
4950{
4951 int updated = -1;
4952 ooAliases *psAlias = NULL;
4953
4954 if (!call->ourAliases)
4955 return updated;
4956 for (psAlias = call->ourAliases; psAlias; psAlias = psAlias->next) {
4957 if (psAlias->type == T_H225AliasAddress_h323_ID) {
4958 ast_copy_string(p->callee_h323id, psAlias->value, sizeof(p->callee_h323id));
4959 updated = 1;
4960 }
4961 if (psAlias->type == T_H225AliasAddress_dialedDigits) {
4962 ast_copy_string(p->callee_dialedDigits, psAlias->value,
4963 sizeof(p->callee_dialedDigits));
4964 updated = 1;
4965 }
4966 if (psAlias->type == T_H225AliasAddress_url_ID) {
4967 ast_copy_string(p->callee_url, psAlias->value, sizeof(p->callee_url));
4968 updated = 1;
4969 }
4970 if (psAlias->type == T_H225AliasAddress_email_ID) {
4971 ast_copy_string(p->callee_email, psAlias->value, sizeof(p->callee_email));
4972 updated = 1;
4973 }
4974 }
4975 return updated;
4976}
4977
4978struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
4979{
4980 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */
4981 struct ast_frame *f;
4982 struct ast_frame *dfr = NULL;
4983 static struct ast_frame null_frame = { AST_FRAME_NULL, };
4984 switch (ast_channel_fdno(ast)) {
4985 case 0:
4986 f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */
4987 p->lastrtprx = time(NULL);
4988 break;
4989 case 1:
4990 f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */
4991 break;
4992 case 2:
4993 f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
4994 p->lastrtprx = time(NULL);
4995 break;
4996 case 3:
4997 f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
4998 break;
4999 case 5:
5000 f = ast_udptl_read(p->udptl); /* UDPTL t.38 data */
5001 if (gH323Debug) {
5002 ast_debug(1, "Got UDPTL %u/%d len %d for %s\n",
5004 }
5005 p->lastrtprx = time(NULL);
5006 break;
5007
5008 default:
5009 f = &null_frame;
5010 }
5011
5012 if (f && p->owner && !p->faxmode && (f->frametype == AST_FRAME_VOICE)) {
5013 /* We already hold the channel lock */
5015 struct ast_format_cap *caps;
5016
5017 ast_debug(1, "Oooh, voice format changed to %s\n", ast_format_get_name(f->subclass.format));
5018
5020 if (caps) {
5023 ao2_ref(caps, -1);
5024 }
5027 }
5028 if (((p->dtmfmode & H323_DTMF_INBAND) || (p->faxdetect & FAXDETECT_CNG)) && p->vad &&
5032 dfr = ast_frdup(f);
5033 dfr = ast_dsp_process(p->owner, p->vad, dfr);
5034 }
5035 } else {
5036 return f;
5037 }
5038
5039 /* process INBAND DTMF*/
5040 if (dfr && (dfr->frametype == AST_FRAME_DTMF) && ((dfr->subclass.integer == 'f') || (dfr->subclass.integer == 'e'))) {
5041 ast_debug(1, "* Detected FAX Tone %s\n", (dfr->subclass.integer == 'e') ? "CED" : "CNG");
5042 /* Switch to T.38 ON CED*/
5043 if (!p->faxmode && !p->chmodepend && (dfr->subclass.integer == 'e') && (p->t38support != T38_DISABLED)) {
5044 if (gH323Debug)
5045 ast_verb(0, "request to change %s to t.38 because fax ced\n", p->callToken);
5046 p->chmodepend = 1;
5047 p->faxdetected = 1;
5048 ooRequestChangeMode(p->callToken, 1);
5049 } else if ((dfr->subclass.integer == 'f') && !p->faxdetected) {
5050 const char *target_context = ast_channel_context(p->owner);
5051 if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
5052 (ast_exists_extension(p->owner, target_context, "fax", 1,
5054 ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", ast_channel_name(p->owner));
5056 if (ast_async_goto(p->owner, target_context, "fax", 1)) {
5057 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context);
5058 }
5059 p->faxdetected = 1;
5060 ast_frfree(dfr);
5061 return &ast_null_frame;
5062 }
5063 }
5064 } else if (dfr && dfr->frametype == AST_FRAME_DTMF) {
5065 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
5066 ast_frfree(f);
5067 return dfr;
5068 }
5069
5070 if (dfr) {
5071 ast_frfree(dfr);
5072 }
5073 return f;
5074}
5075
5076void onModeChanged(ooCallData *call, int t38mode) {
5077 struct ooh323_pvt *p;
5078
5079 p = find_call(call);
5080 if (!p) {
5081 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
5082 return;
5083 }
5084
5085 ast_mutex_lock(&p->lock);
5086
5087 if (gH323Debug)
5088 ast_debug(1, "change mode to %d for %s\n", t38mode, call->callToken);
5089
5090 if (t38mode == p->faxmode) {
5091 if (gH323Debug)
5092 ast_debug(1, "mode for %s is already %d\n", call->callToken,
5093 t38mode);
5094 p->chmodepend = 0;
5096 return;
5097 }
5098
5099 if (p->owner) {
5100 while (p->owner && ast_channel_trylock(p->owner)) {
5101 ast_debug(1,"Failed to grab lock, trying again\n");
5103 }
5104 if (!p->owner) {
5105 p->chmodepend = 0;
5107 ast_log(LOG_ERROR, "Channel has no owner\n");
5108 return;
5109 }
5110 } else {
5111 p->chmodepend = 0;
5113 ast_log(LOG_ERROR, "Channel has no owner\n");
5114 return;
5115 }
5116
5117 if (t38mode) {
5118
5119
5120 if (p->t38support == T38_ENABLED) {
5121 struct ast_control_t38_parameters parameters = { .request_response = 0 };
5122
5123 if ((p->faxdetect & FAXDETECT_T38) && !p->faxdetected) {
5124 const char *target_context;
5125 ast_debug(1, "* Detected T.38 Request\n");
5126 target_context = ast_channel_context(p->owner);
5127 if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
5128 (ast_exists_extension(p->owner, target_context, "fax", 1,
5130 ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", ast_channel_name(p->owner));
5132 if (ast_async_goto(p->owner, target_context, "fax", 1)) {
5133 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context);
5134 }
5135 }
5136 p->faxdetected = 1;
5137 }
5138
5139/* AST_T38_CONTROL mode */
5140
5142 if (call->T38FarMaxDatagram) {
5143 ast_udptl_set_far_max_datagram(p->udptl, call->T38FarMaxDatagram);
5144 } else {
5146 }
5147 if (call->T38Version) {
5148 parameters.version = call->T38Version;
5149 }
5150 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
5151 parameters.rate = AST_T38_RATE_14400;
5153 &parameters, sizeof(parameters));
5154 p->faxmode = 1;
5155
5156
5157 }
5158 } else {
5159 if (p->t38support == T38_ENABLED) {
5160 struct ast_control_t38_parameters parameters = { .request_response = 0 };
5162 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
5163 parameters.rate = AST_T38_RATE_14400;
5165 &parameters, sizeof(parameters));
5166 }
5167 p->faxmode = 0;
5168 p->faxdetected = 0;
5169 p->t38_init = 0;
5170 }
5171
5172 p->chmodepend = 0;
5175}
5176
5177
5178
5180{
5181 switch (cause) {
5183 return OO_REASON_REMOTE_REJECTED;
5185 return OO_REASON_NOUSER;
5186 case AST_CAUSE_BUSY:
5187 return OO_REASON_REMOTE_BUSY;
5189 return OO_REASON_NOCOMMON_CAPABILITIES;
5191 return OO_REASON_REMOTE_BUSY;
5193 return OO_REASON_REMOTE_NOANSWER;
5194 case AST_CAUSE_NORMAL:
5195 return OO_REASON_REMOTE_CLEARED;
5196 case AST_CAUSE_FAILURE:
5197 default:
5198 return OO_REASON_UNKNOWN;
5199 }
5200
5201 return 0;
5202
5203
5204}
5205
5207{
5208 switch (cause) {
5209 case OO_REASON_REMOTE_REJECTED:
5211 case OO_REASON_NOUSER:
5212 return AST_CAUSE_UNALLOCATED;
5213 case OO_REASON_REMOTE_BUSY:
5214 case OO_REASON_LOCAL_BUSY:
5215 return AST_CAUSE_BUSY;
5216 case OO_REASON_NOCOMMON_CAPABILITIES: /* No codecs approved */
5218 case OO_REASON_REMOTE_CONGESTED:
5219 case OO_REASON_LOCAL_CONGESTED:
5220 return AST_CAUSE_CONGESTION;
5221 case OO_REASON_REMOTE_NOANSWER:
5222 return AST_CAUSE_NO_ANSWER;
5223 case OO_REASON_UNKNOWN:
5224 case OO_REASON_INVALIDMESSAGE:
5225 case OO_REASON_TRANSPORTFAILURE:
5226 return AST_CAUSE_FAILURE;
5227 case OO_REASON_REMOTE_CLEARED:
5228 return AST_CAUSE_NORMAL;
5229 default:
5230 return AST_CAUSE_NORMAL;
5231 }
5232 /* Never reached */
5233 return 0;
5234}
5235
5236#if 0
5237void ast_ooh323c_exit()
5238{
5239 ooGkClientDestroy();
5240}
5241#endif
5242
5243AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Objective Systems H323 Channel",
5244 .support_level = AST_MODULE_SUPPORT_EXTENDED,
5245 .load = load_module,
5246 .unload = unload_module,
5248 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
5249 .requires = "udptl",
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
@ AST_JB_FORCED
Definition: abstract_jb.h:46
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:545
char digit
#define TRUE
Definition: app_minivm.c:524
#define FALSE
Definition: app_minivm.c:527
void ast_unregister_atexit(void(*func)(void))
Unregister a function registered with ast_register_atexit().
Definition: asterisk.c:1060
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: clicompat.c:13
#define PATH_MAX
Definition: asterisk.h:40
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static int tmp()
Definition: bt_open.c:389
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
Definition: callerid.h:540
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:123
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:98
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:130
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:116
#define AST_CAUSE_FAILURE
Definition: causes.h:150
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:122
#define AST_CAUSE_NORMAL
Definition: causes.h:151
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:125
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:120
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:111
#define AST_CAUSE_BUSY
Definition: causes.h:149
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:109
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
#define AST_CAUSE_USER_BUSY
Definition: causes.h:107
enum cc_state state
Definition: ccss.c:393
static PGresult * result
Definition: cel_pgsql.c:84
static int ooh323_digit_begin(struct ast_channel *ast, char digit)
Definition: chan_ooh323.c:928
static int gIncomingLimit
Definition: chan_ooh323.c:379
static int ooh323_do_reload(void)
Definition: chan_ooh323.c:2705
static int gFastStart
Definition: chan_ooh323.c:367
static ast_mutex_t ooh323c_cn_lock
Definition: chan_ooh323.c:336
static ast_mutex_t usecnt_lock
Definition: chan_ooh323.c:333
static struct ast_peer_list peerl
int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
Definition: chan_ooh323.c:1798
static int gEarlyDirect
Definition: chan_ooh323.c:372
static ast_mutex_t iflock
Definition: chan_ooh323.c:252
#define DEFAULT_H323ACCNT
Definition: chan_ooh323.c:86
static char vendor[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:390
static int gANIasDNI
Definition: chan_ooh323.c:385
int reload_config(int reload)
Definition: chan_ooh323.c:2813
int onOutgoingCall(ooCallData *call)
Definition: chan_ooh323.c:2016
void setup_rtp_connection(ooCallData *call, const char *remoteIp, int remotePort)
Definition: chan_ooh323.c:4775
static int gRTDRCount
Definition: chan_ooh323.c:383
void ooh323_delete_peer(struct ooh323_peer *peer)
Definition: chan_ooh323.c:2328
static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
Definition: chan_ooh323.c:4485
static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
Definition: chan_ooh323.c:4442
static struct ast_jb_conf default_jbconf
Definition: chan_ooh323.c:115
#define T38_FAXGW
Definition: chan_ooh323.c:103
int onCallEstablished(ooCallData *call)
Definition: chan_ooh323.c:2181
void close_rtp_connection(ooCallData *call)
Definition: chan_ooh323.c:4810
static int usecnt
Definition: chan_ooh323.c:332
static char gCallerID[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:355
static int g729onlyA
Definition: chan_ooh323.c:375
static struct ast_rtp_glue ooh323_rtp
Definition: chan_ooh323.c:172
static struct ast_sched_context * sched
Definition: chan_ooh323.c:400
static int gTOS
Definition: chan_ooh323.c:373
static char * handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3327
#define H323_DISABLEGK
Definition: chan_ooh323.c:96
#define H323_OUTGOING
Definition: chan_ooh323.c:93
static char * handle_cli_ooh323_show_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3497
int ooh323_destroy(struct ooh323_pvt *p)
Definition: chan_ooh323.c:4117
static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout)
Definition: chan_ooh323.c:990
void onModeChanged(ooCallData *call, int t38mode)
Definition: chan_ooh323.c:5076
static char gIP[2+8 *4+7]
Definition: chan_ooh323.c:352
static int t35countrycode
Definition: chan_ooh323.c:387
static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
Definition: chan_ooh323.c:1460
static struct ast_format_cap * gCap
Definition: chan_ooh323.c:357
static char * handle_cli_ooh323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3466
int onAlerting(ooCallData *call)
Definition: chan_ooh323.c:1682
int onProgress(ooCallData *call)
Definition: chan_ooh323.c:1738
#define DEFAULT_H323ID
Definition: chan_ooh323.c:84
static const char type[]
Definition: chan_ooh323.c:109
#define DEFAULT_LOGFILE
Definition: chan_ooh323.c:85
OOBOOL gH323Debug
Definition: chan_ooh323.c:381
static char * handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3285
static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
Definition: chan_ooh323.c:1212
OOH323EndPoint gH323ep
int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
Definition: chan_ooh323.c:4599
struct ast_module * myself
Definition: chan_ooh323.c:113
static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
Definition: chan_ooh323.c:4420
static struct ast_cli_entry cli_ooh323[]
Definition: chan_ooh323.c:3673
static int gIsGateway
Definition: chan_ooh323.c:366
static int gOutgoingLimit
Definition: chan_ooh323.c:380
char * handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:2778
static int ooh323_answer(struct ast_channel *ast)
Definition: chan_ooh323.c:1154
struct ooh323_user * find_user(const char *name, const char *ip)
Definition: chan_ooh323.c:832
#define DEFAULT_CONTEXT
Definition: chan_ooh323.c:83
static int gT38Support
Definition: chan_ooh323.c:361
static char gGatekeeper[100]
Definition: chan_ooh323.c:362
int delete_peers()
Definition: chan_ooh323.c:4230
static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: chan_ooh323.c:1522
#define T38_ENABLED
Definition: chan_ooh323.c:102
#define IPTOS_MINCOST
Definition: chan_ooh323.c:77
static char gLogFile[PATH_MAX]
Definition: chan_ooh323.c:349
static const char tdesc[]
Definition: chan_ooh323.c:110
static struct ast_user_list userl
static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
Definition: chan_ooh323.c:962
static long callnumber
Definition: chan_ooh323.c:335
#define FORMAT1
static void * do_monitor(void *data)
Definition: chan_ooh323.c:3998
static struct ooh323_user * build_user(const char *name, struct ast_variable *v)
Definition: chan_ooh323.c:2368
int v6mode
Definition: chan_ooh323.c:354
static int gTRCLVL
Definition: chan_ooh323.c:382
static int reload_module(void)
Definition: chan_ooh323.c:3981
static struct ooh323_config ooconfig
static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
Definition: chan_ooh323.c:4532
struct ast_sockaddr bindaddr
Definition: chan_ooh323.c:353
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
static struct ooh323_pvt * find_call(ooCallData *call)
Definition: chan_ooh323.c:810
int restart_monitor(void)
Definition: chan_ooh323.c:4082
#define H323_ALREADYGONE
Definition: chan_ooh323.c:94
static char gAccountcode[80]
Definition: chan_ooh323.c:376
static struct ast_channel_tech ooh323_tech
Definition: chan_ooh323.c:150
static int gFAXdetect
Definition: chan_ooh323.c:360
static int gDTMFMode
Definition: chan_ooh323.c:358
void close_udptl_connection(ooCallData *call)
Definition: chan_ooh323.c:4901
static int gTunneling
Definition: chan_ooh323.c:368
static struct ooAliases * gAliasList
Definition: chan_ooh323.c:356
static struct ast_frame * ooh323_read(struct ast_channel *ast)
Definition: chan_ooh323.c:1194
static char * handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3188
static int gNat
Definition: chan_ooh323.c:384
static const char config[]
Definition: chan_ooh323.c:111
static int gMediaWaitForConnect
Definition: chan_ooh323.c:370
int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
Definition: chan_ooh323.c:1840
static struct ooh323_pvt * iflist
#define FAXDETECT_T38
Definition: chan_ooh323.c:106
void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
Definition: chan_ooh323.c:1625
static int gPort
Definition: chan_ooh323.c:351
static int gRTPTimeout
Definition: chan_ooh323.c:374
struct ooh323_peer * find_friend(const char *name, int port)
Definition: chan_ooh323.c:858
static ast_mutex_t monlock
Definition: chan_ooh323.c:405
static int gRTDRInterval
Definition: chan_ooh323.c:383
static int gBeMaster
Definition: chan_ooh323.c:369
static char * handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3424
static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
OOH323 Dialplan function - reads ooh323 settings.
Definition: chan_ooh323.c:3685
int update_our_aliases(ooCallData *call, struct ooh323_pvt *p)
Definition: chan_ooh323.c:4949
static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
Definition: chan_ooh323.c:1280
#define T38_DISABLED
Definition: chan_ooh323.c:101
static struct ast_jb_conf global_jbconf
Definition: chan_ooh323.c:122
static ast_mutex_t h323_reload_lock
Definition: chan_ooh323.c:329
int onCallCleared(ooCallData *call)
Definition: chan_ooh323.c:2236
int onNewCallCreated(ooCallData *call)
Definition: chan_ooh323.c:2089
static struct io_context * io
Definition: chan_ooh323.c:401
struct ooh323_peer * find_peer(const char *name, int port)
Definition: chan_ooh323.c:890
static int manufacturer
Definition: chan_ooh323.c:389
static char gContext[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:378
static int load_module(void)
Definition: chan_ooh323.c:3787
struct ast_frame * ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
Definition: chan_ooh323.c:4978
#define FORMAT
int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format)
Definition: chan_ooh323.c:4506
static int gAMAFLAGS
Definition: chan_ooh323.c:377
int ooh323_convert_hangupcause_h323ToAsterisk(int cause)
Definition: chan_ooh323.c:5206
static int gDirectRTP
Definition: chan_ooh323.c:371
static int unload_module(void)
Definition: chan_ooh323.c:4296
static int h323_reloading
Definition: chan_ooh323.c:328
static struct ooh323_peer * build_peer(const char *name, struct ast_variable *v, int friend_type)
Definition: chan_ooh323.c:2515
static struct ast_channel * ooh323_new(struct ooh323_pvt *i, int state, const char *host, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
Definition: chan_ooh323.c:413
static int gDTMFCodec
Definition: chan_ooh323.c:359
static int t35extensions
Definition: chan_ooh323.c:388
static struct ooh323_pvt * ooh323_alloc(int callref, char *callToken)
Definition: chan_ooh323.c:556
void setup_udptl_connection(ooCallData *call, const char *remoteIp, int remotePort)
Definition: chan_ooh323.c:4839
void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
Definition: chan_ooh323.c:1553
int delete_users()
Definition: chan_ooh323.c:4265
static char gInitError[256]
Definition: chan_ooh323.c:350
static char gRASIP[2+8 *4+7]
Definition: chan_ooh323.c:363
static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
OOH323 Dialplan function - writes ooh323 settings.
Definition: chan_ooh323.c:3730
#define H323_NEEDDESTROY
Definition: chan_ooh323.c:95
#define FAXDETECT_CNG
Definition: chan_ooh323.c:105
void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort)
Definition: chan_ooh323.c:4736
#define FORMAT_STRING_SIZE
Definition: chan_ooh323.c:80
static int ooh323_hangup(struct ast_channel *ast)
Definition: chan_ooh323.c:1087
static pthread_t monitor_thread
Definition: chan_ooh323.c:410
int ooh323_convert_hangupcause_asteriskToH323(int cause)
Definition: chan_ooh323.c:5179
static struct ast_channel * ooh323_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Definition: chan_ooh323.c:624
static char * handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3558
static enum RasGatekeeperMode gRasGkMode
Definition: chan_ooh323.c:364
static int call(void *data)
Definition: chan_pjsip.c:2391
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_rings_set(struct ast_channel *chan, int value)
@ AST_CHAN_TP_WANTSJITTER
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:960
@ AST_CHAN_TP_CREATESJITTER
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:965
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
int ast_channel_fdno(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:878
@ T38_STATE_UNAVAILABLE
Definition: channel.h:879
@ T38_STATE_UNKNOWN
Definition: channel.h:880
@ T38_STATE_NEGOTIATED
Definition: channel.h:883
@ T38_STATE_NEGOTIATING
Definition: channel.h:881
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
const char * ast_channel_context(const struct ast_channel *chan)
#define ast_channel_trylock(chan)
Definition: channel.h:2924
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:871
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5761
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4372
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1121
@ AST_SOFTHANGUP_APPUNLOAD
Definition: channel.h:1143
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5802
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2458
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4359
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9105
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define AST_MAX_EXTENSION
Definition: channel.h:134
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_RING
Definition: channelstate.h:40
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_STATE_DOWN
Definition: channelstate.h:36
@ AST_STATE_UP
Definition: channelstate.h:42
@ AST_STATE_RESERVED
Definition: channelstate.h:37
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7385
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define RESULT_SUCCESS
Definition: cli.h:40
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
short word
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1783
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress,...
Definition: dsp.c:1499
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
#define DSP_FAXMODE_DETECT_CED
Definition: dsp.h:48
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1857
#define DSP_FAXMODE_DETECT_CNG
Definition: dsp.h:47
int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
Set fax mode.
Definition: dsp.c:1883
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
char connected
Definition: eagi_proxy.c:82
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct ast_format * ast_format_gsm
Built-in cached gsm format.
Definition: format_cache.c:96
struct ast_format * ast_format_speex
Built-in cached speex format.
Definition: format_cache.c:131
struct ast_format * ast_format_h263
Built-in cached h263 format.
Definition: format_cache.c:166
struct ast_format * ast_format_g726
Built-in cached g726 format.
Definition: format_cache.c:111
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
struct ast_format * ast_format_g723
Built-in cached g723.1 format.
Definition: format_cache.c:146
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct ast_format * ast_format_g726_aal2
Built-in cached g726 aal2 format.
Definition: format_cache.c:116
struct ast_format * ast_format_g729
Built-in cached g729 format.
Definition: format_cache.c:151
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:523
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:581
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:613
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition: format_cap.c:136
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
static const char name[]
Definition: format_mp3.c:68
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
const char * ext
Definition: http.c:150
char * strsep(char **str, const char *delims)
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEUNCHANGED
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:3827
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
@ AST_T38_REQUEST_PARMS
@ AST_T38_TERMINATED
@ AST_T38_REFUSED
@ AST_T38_REQUEST_TERMINATE
@ AST_T38_NEGOTIATED
@ AST_T38_REQUEST_NEGOTIATE
#define AST_FRAME_DTMF
#define ast_frdup(fr)
Copies a frame.
#define AST_OPTION_DIGIT_DETECT
#define ast_frfree(fr)
@ AST_T38_RATE_14400
#define AST_OPTION_T38_STATE
@ AST_FRAME_NULL
@ AST_FRAME_IMAGE
@ AST_FRAME_VOICE
@ AST_FRAME_MODEM
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HOLD
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_PVT_CAUSE_CODE
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_NOTICE
#define LOG_WARNING
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition: io.c:81
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:278
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:479
#define AST_PTHREADT_STOP
Definition: lock.h:67
#define ast_mutex_unlock(a)
Definition: lock.h:190
pthread_cond_t ast_cond_t
Definition: lock.h:178
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:189
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:520
#define ast_cond_signal(cond)
Definition: lock.h:203
int errno
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:317
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2544
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ AST_MODPRI_CHANNEL_DRIVER
Definition: module.h:327
@ AST_MODULE_SUPPORT_EXTENDED
Definition: module.h:122
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7765
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7775
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
static char * ast_sockaddr_stringify_host(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:327
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
int ooh323c_stop_stack_thread(void)
int ooh323c_start_call_thread(ooCallData *call)
int ooh323c_stop_call_thread(ooCallData *call)
int ooh323c_set_capability(struct ast_format_cap *cap, int dtmf, int dtmfcodec)
int ooh323c_set_capability_for_call(ooCallData *call, struct ast_format_cap *cap, int dtmf, int dtmfcodec, int t38support, int g729onlyA)
int ooh323c_start_stack_thread()
#define H323_DTMF_H245ALPHANUMERIC
Definition: ooh323cDriver.h:28
#define H323_DTMF_RFC2833
Definition: ooh323cDriver.h:26
#define H323_DTMF_INBAND
Definition: ooh323cDriver.h:30
#define H323_DTMF_INBANDRELAX
Definition: ooh323cDriver.h:32
#define H323_DTMF_Q931
Definition: ooh323cDriver.h:27
#define H323_DTMF_H245SIGNAL
Definition: ooh323cDriver.h:29
#define H323_DTMF_CISCO
Definition: ooh323cDriver.h:31
const char * ast_config_AST_LOG_DIR
Definition: options.c:159
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:6969
static char user[512]
static int reload(void)
#define NULL
Definition: resample.c:96
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:457
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:486
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2196
ast_rtp_glue_result
Definition: rtp_engine.h:158
@ AST_RTP_GLUE_RESULT_LOCAL
Definition: rtp_engine.h:164
@ AST_RTP_GLUE_RESULT_REMOTE
Definition: rtp_engine.h:162
@ AST_RTP_GLUE_RESULT_FORBID
Definition: rtp_engine.h:160
#define ast_rtp_instance_get_and_cmp_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to, comparing its address to another.
Definition: rtp_engine.h:1274
int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Early bridge two channels that use RTP instances.
Definition: rtp_engine.c:2350
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1238
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2094
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:599
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1571
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:726
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:664
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:589
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1126
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)
Send a comfort noise packet to the RTP instance.
Definition: rtp_engine.c:2809
@ AST_RTP_OPT_G726_NONSTANDARD
Definition: rtp_engine.h:144
@ AST_RTP_PROPERTY_NAT
Definition: rtp_engine.h:115
@ AST_RTP_PROPERTY_RTCP
Definition: rtp_engine.h:123
@ AST_RTP_PROPERTY_DTMF
Definition: rtp_engine.h:117
int ast_rtp_codecs_payloads_set_rtpmap_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload, char *mimetype, char *mimesubtype, enum ast_rtp_options options)
Record tx payload type information that was seen in an a=rtpmap: SDP line.
Definition: rtp_engine.c:1441
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
Definition: rtp_engine.c:2182
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:893
int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
Stop sending a DTMF digit.
Definition: rtp_engine.c:2108
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
Definition: rtp_engine.c:2173
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:748
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2205
void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
Indicate that the RTP marker bit should be set on an RTP stream.
Definition: rtp_engine.c:2164
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2707
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:407
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:786
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:433
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216
#define ast_str_alloca(init_len)
Definition: strings.h:848
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition: channel.h:628
struct ast_format_cap * capabilities
Definition: channel.h:632
const char *const type
Definition: channel.h:629
Main Channel structure associated with a channel.
const char * data
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
enum ast_control_t38_rate rate
enum ast_control_t38 request_response
Definition: dsp.c:407
Structure used to handle boolean flags.
Definition: utils.h:199
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
const char * src
General jitterbuffer configuration.
Definition: abstract_jb.h:70
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
Definition: abstract_jb.h:72
struct ast_module * self
Definition: module.h:342
Structure for mutex and tracking information.
Definition: lock.h:135
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
Connected Line/Party information.
Definition: channel.h:456
struct ast_party_id id
Connected party ID.
Definition: channel.h:458
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:279
char * str
Subscriber name (Malloced)
Definition: channel.h:264
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:297
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
struct ooh323_peer * peers
Definition: chan_ooh323.c:323
ast_mutex_t lock
Definition: chan_ooh323.c:324
const char * type
Definition: rtp_engine.h:768
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:489
struct ast_set_party_id id
Definition: channel.h:491
unsigned char name
Definition: channel.h:363
Socket address structure.
Definition: netsock2.h:97
Support for dynamic strings.
Definition: strings.h:623
Structure for an UDPTL session.
Definition: udptl.c:154
struct ooh323_user * users
Definition: chan_ooh323.c:318
ast_mutex_t lock
Definition: chan_ooh323.c:319
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Global IO variables are now in a struct in order to be made threadsafe.
Definition: io.c:71
Number structure.
Definition: app_followme.c:154
char ip[4 *8+7+2]
Definition: chan_ooh323.c:297
char accountcode[20]
Definition: chan_ooh323.c:290
struct OOH323Regex * rtpmask
Definition: chan_ooh323.c:304
char * email
Definition: chan_ooh323.c:300
int h245tunneling
Definition: chan_ooh323.c:308
char rtpmaskstr[120]
Definition: chan_ooh323.c:305
unsigned outgoinglimit
Definition: chan_ooh323.c:287
struct ooh323_peer * next
Definition: chan_ooh323.c:312
unsigned outUse
Definition: chan_ooh323.c:288
int rtdrinterval
Definition: chan_ooh323.c:306
char name[256]
Definition: chan_ooh323.c:286
struct ast_format_cap * cap
Definition: chan_ooh323.c:289
char * url
Definition: chan_ooh323.c:301
char * e164
Definition: chan_ooh323.c:302
char * h323id
Definition: chan_ooh323.c:299
ast_mutex_t lock
Definition: chan_ooh323.c:285
char * user
Definition: chan_ooh323.c:205
char callee_h323id[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:221
char * host
Definition: chan_ooh323.c:214
ast_cond_t rtpcond
Definition: chan_ooh323.c:186
char * callToken
Definition: chan_ooh323.c:212
int t38support
Definition: chan_ooh323.c:191
int earlydirect
Definition: chan_ooh323.c:240
unsigned int call_reference
Definition: chan_ooh323.c:211
struct OOH323Regex * rtpmask
Definition: chan_ooh323.c:243
char caller_h323id[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:217
int h245tunneling
Definition: chan_ooh323.c:246
char context[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:233
char rtpmaskstr[120]
Definition: chan_ooh323.c:244
struct ast_rtp_instance * vrtp
Definition: chan_ooh323.c:189
int faxdetected
Definition: chan_ooh323.c:193
time_t lastrtptx
Definition: chan_ooh323.c:208
char exten[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:232
int rtdrinterval
Definition: chan_ooh323.c:245
struct ooh323_pvt * next
Definition: chan_ooh323.c:248
char * peer
Definition: chan_ooh323.c:206
struct ast_rtp_instance * rtp
Definition: chan_ooh323.c:187
struct ast_sockaddr redirip
Definition: chan_ooh323.c:188
char * callerid_name
Definition: chan_ooh323.c:215
struct ast_channel * owner
Definition: chan_ooh323.c:203
int rtptimeout
Definition: chan_ooh323.c:194
struct ast_format_cap * cap
Definition: chan_ooh323.c:229
struct ast_udptl * udptl
Definition: chan_ooh323.c:195
char * username
Definition: chan_ooh323.c:213
struct ast_sockaddr udptlredirip
Definition: chan_ooh323.c:199
time_t lastrtprx
Definition: chan_ooh323.c:209
int chmodepend
Definition: chan_ooh323.c:201
char caller_email[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:219
struct ast_dsp * vad
Definition: chan_ooh323.c:242
char callee_url[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:224
struct ast_format * writeformat
Definition: chan_ooh323.c:228
unsigned int flags
Definition: chan_ooh323.c:210
char * callerid_num
Definition: chan_ooh323.c:216
char accountcode[256]
Definition: chan_ooh323.c:234
char callee_dialedDigits[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:222
struct ast_format * readformat
Definition: chan_ooh323.c:227
ast_mutex_t lock
Definition: chan_ooh323.c:185
time_t lastTxT38
Definition: chan_ooh323.c:200
char caller_url[256]
Definition: chan_ooh323.c:220
char caller_dialedDigits[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:218
char callee_email[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:223
union ooh323_pvt::@3 neighbor
int t38_tx_enable
Definition: chan_ooh323.c:197
struct ooh323_user * next
Definition: chan_ooh323.c:280
char accountcode[20]
Definition: chan_ooh323.c:261
struct OOH323Regex * rtpmask
Definition: chan_ooh323.c:271
int h245tunneling
Definition: chan_ooh323.c:275
char context[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:258
char rtpmaskstr[120]
Definition: chan_ooh323.c:272
int rtdrinterval
Definition: chan_ooh323.c:273
int incominglimit
Definition: chan_ooh323.c:259
char name[256]
Definition: chan_ooh323.c:257
struct ast_format_cap * cap
Definition: chan_ooh323.c:263
char mIP[4 *8+7+2]
Definition: chan_ooh323.c:270
unsigned inUse
Definition: chan_ooh323.c:260
ast_mutex_t lock
Definition: chan_ooh323.c:256
Definition: sched.c:76
const char * name
structure to hold users read from users.conf
Definition: ast_expr2.c:325
int value
Definition: syslog.c:37
static struct test_val a
static struct test_val c
void ast_udptl_destroy(struct ast_udptl *udptl)
Definition: udptl.c:1148
int ast_udptl_fd(const struct ast_udptl *udptl)
Definition: udptl.c:728
void ast_udptl_set_peer(struct ast_udptl *udptl, const struct ast_sockaddr *them)
Definition: udptl.c:1128
void ast_udptl_set_tag(struct ast_udptl *udptl, const char *format,...)
Associates a character string 'tag' with a UDPTL session.
Definition: udptl.c:1110
unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
retrieves far max ifp
Definition: udptl.c:1014
void ast_udptl_get_us(const struct ast_udptl *udptl, struct ast_sockaddr *us)
Definition: udptl.c:1138
struct ast_frame * ast_udptl_read(struct ast_udptl *udptl)
Definition: udptl.c:760
struct ast_udptl * ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, struct io_context *io, int callbackmode, struct ast_sockaddr *in)
Definition: udptl.c:1026
int ast_udptl_write(struct ast_udptl *udptl, struct ast_frame *f)
Definition: udptl.c:1159
void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
sets far max datagram size. If max_datagram is = 0, the far max datagram size is set to a default val...
Definition: udptl.c:995
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70