Asterisk - The Open Source Telephony Project  18.5.0
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, [email protected] */
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 */
109 static const char type[] = "OOH323";
110 static const char tdesc[] = "Objective Systems H323 Channel Driver";
111 static 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 */
125 static 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);
127 static int ooh323_digit_begin(struct ast_channel *ast, char digit);
128 static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
129 static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout);
130 static int ooh323_hangup(struct ast_channel *ast);
131 static int ooh323_answer(struct ast_channel *ast);
132 static struct ast_frame *ooh323_read(struct ast_channel *ast);
133 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f);
134 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
135 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
136 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
137 static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
138 static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
139 
140 static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
141 static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
142 static 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);
144 static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result);
145 void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort);
146 
147 struct ooh323_peer *find_friend(const char *name, int port);
148 
149 
150 static struct ast_channel_tech ooh323_tech = {
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 
172 static 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 
181 struct ooh323_user;
182 
183 /* H.323 channel private structure */
184 static 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 */
195  struct ast_udptl *udptl;
196  int faxmode;
198  int t38_init;
200  time_t lastTxT38;
202 
203  struct ast_channel *owner; /* Master Channel */
204  union {
205  char *user; /* cooperating user/peer */
206  char *peer;
207  } neighbor;
208  time_t lastrtptx;
209  time_t lastrtprx;
210  unsigned int flags;
211  unsigned int call_reference;
212  char *callToken;
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 */
230  int dtmfmode;
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;
236  int amaflags;
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 */
249 } *iflist = NULL;
250 
251 /* Protect the channel/interface list (ooh323_pvt) */
253 
254 /* Profile of H.323 user registered with PBX*/
255 struct ooh323_user{
257  char name[256];
260  unsigned inUse;
261  char accountcode[20];
262  int amaflags;
264  int dtmfmode;
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;
279  int aniasdni;
280  struct ooh323_user *next;
281 };
282 
283 /* Profile of valid asterisk peers */
284 struct ooh323_peer{
286  char name[256];
287  unsigned outgoinglimit;
288  unsigned outUse;
290  char accountcode[20];
291  int amaflags;
292  int dtmfmode;
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;
312  struct ooh323_peer *next;
313 };
314 
315 
316 /* List of H.323 users known to PBX */
317 static struct ast_user_list {
320 } userl;
321 
322 static struct ast_peer_list {
325 } peerl;
326 
327 /* Mutex to protect H.323 reload process */
328 static int h323_reloading = 0;
330 
331 /* Mutex to protect usage counter */
332 static int usecnt = 0;
334 
335 static long callnumber = 0;
337 
338 /* stack callbacks */
339 int onAlerting(ooCallData *call);
340 int onProgress(ooCallData *call);
341 int onNewCallCreated(ooCallData *call);
342 int onOutgoingCall(ooCallData *call);
343 int onCallEstablished(ooCallData *call);
344 int onCallCleared(ooCallData *call);
345 void onModeChanged(ooCallData *call, int t38mode);
346 
347 extern OOH323EndPoint gH323ep;
348 
350 static char gInitError[256] = "";
351 static int gPort = 1720;
352 static char gIP[2+8*4+7]; /* Max for IPv6 addr */
354 int v6mode = 0;
355 static char gCallerID[AST_MAX_EXTENSION] = "";
356 static struct ooAliases *gAliasList;
357 static struct ast_format_cap *gCap;
359 static int gDTMFCodec = 101;
361 static int gT38Support = T38_FAXGW;
362 static char gGatekeeper[100];
363 static char gRASIP[2+8*4+7]; /* Max for IPv6 addr */
364 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
365 
366 static int gIsGateway = 0;
367 static int gFastStart = 1;
368 static int gTunneling = 1;
369 static int gBeMaster = 0;
370 static int gMediaWaitForConnect = 0;
371 static int gDirectRTP = 0;
372 static int gEarlyDirect = 0;
373 static int gTOS = 0;
374 static int gRTPTimeout = 60;
375 static int g729onlyA = 0;
376 static char gAccountcode[80] = DEFAULT_H323ACCNT;
377 static int gAMAFLAGS;
379 static int gIncomingLimit = 1024;
380 static int gOutgoingLimit = 1024;
381 OOBOOL gH323Debug = FALSE;
382 static int gTRCLVL = OOTRCLVLERR;
383 static int gRTDRCount = 0, gRTDRInterval = 0;
384 static int gNat = FALSE;
385 static int gANIasDNI = 0;
386 
387 static int t35countrycode = 0;
388 static int t35extensions = 0;
389 static int manufacturer = 0;
390 static char vendor[AST_MAX_EXTENSION] = "";
391 static char version[AST_MAX_EXTENSION] = "";
392 
393 static struct ooh323_config
394 {
397 } ooconfig;
398 
399 /** Asterisk RTP stuff*/
400 static struct ast_sched_context *sched;
401 static 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 
413 static 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 */
429  ast_mutex_unlock(&i->lock);
431  ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,
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) {
440  ast_channel_tech_set(ch, &ooh323_tech);
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 
453  ast_channel_set_rawwriteformat(ch, tmpfmt);
454  ast_channel_set_rawreadformat(ch, tmpfmt);
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)
462  ast_channel_rings_set(ch, 1);
463 
466  i->owner = ch;
467  ast_module_ref(myself);
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;
477  if (i->dtmfmode & H323_DTMF_INBANDRELAX) {
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 
505  if(!ast_test_flag(i, H323_OUTGOING)) {
506 
507  if (!ast_strlen_zero(i->caller_h323id)) {
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 
524  if (!ast_strlen_zero(i->accountcode))
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));
534  ast_channel_unlock(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 
556 static 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)
590  pvt->callToken = ast_strdup(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  */
624 static 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 {
628  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
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{
688  ast_mutex_unlock(&p->lock);
689  ooh323_destroy(p);
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);
735  ast_mutex_unlock(&p->lock);
736  ooh323_destroy(p);
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;
746  p->dtmfcodec = gDTMFCodec;
747  p->faxdetect = gFAXdetect;
748  p->t38support = gT38Support;
749  p->rtptimeout = gRTPTimeout;
750  p->nat = gNat;
753  p->rtdrcount = gRTDRCount;
754  p->faststart = gFastStart;
756  p->directrtp = gDirectRTP;
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 
774  ast_mutex_unlock(&p->lock);
775 
776  if (!chan) {
778  ooh323_destroy(p);
780  } else {
781  ast_mutex_lock(&p->lock);
782  p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
783  if(!p->callToken) {
784  ast_mutex_unlock(&p->lock);
786  ooh323_destroy(p);
788  ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
789  return NULL;
790  }
791 
792  ast_cond_init(&p->rtpcond, NULL);
793  ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
794  if (!p->rtp) {
795  ast_cond_wait(&p->rtpcond, &p->lock);
796  }
797  ast_mutex_unlock(&p->lock);
799  }
800 
801  restart_monitor();
802  if (gH323Debug)
803  ast_verb(0, "+++ ooh323_request\n");
804 
805  return chan;
806 
807 }
808 
809 
810 static 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 
832 struct 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 
858 struct 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 
890 struct 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 
928 static 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))) {
944  ast_rtp_instance_dtmf_begin(p->rtp, digit);
945  } else if (((p->dtmfmode & H323_DTMF_Q931) ||
947  (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
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  }
954  ast_mutex_unlock(&p->lock);
955 
956  if (gH323Debug) {
957  ast_verb(0, "+++ ooh323_digit_begin, res = %d\n", res);
958  }
959  return res;
960 }
961 
962 static 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)) ) {
976  ast_rtp_instance_dtmf_end(p->rtp, digit);
977  } else if(p->dtmfmode & H323_DTMF_INBAND) {
978  res = -1; // tell Asterisk to stop inband indications
979  }
980 
981  ast_mutex_unlock(&p->lock);
982 
983  if (gH323Debug) {
984  ast_verb(0, "+++ ooh323_digit_end, res = %d\n", res);
985  }
986  return res;
987 }
988 
989 
990 static 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) {
1016  ast_free(p->callerid_num);
1018  }
1019 
1020  if (ast_channel_connected(ast)->id.name.valid && ast_channel_connected(ast)->id.name.str) {
1021  ast_free(p->callerid_name);
1023  } else if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
1024  ast_free(p->callerid_name);
1026  } else {
1027  ast_channel_connected(ast)->id.name.valid = 1;
1028  ast_free(ast_channel_connected(ast)->id.name.str);
1030  ast_free(p->callerid_name);
1032  }
1033 
1034  /* Retrieve vars */
1035 
1036 
1037  if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
1038  ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
1039  }
1040 
1041  if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
1043  if(!p->callerid_num)
1044  p->callerid_num = ast_strdup(val);
1045  }
1046 
1047  if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
1048  ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
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 
1076  ast_mutex_unlock(&p->lock);
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 
1087 static 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);
1122  if (!ast_test_flag(p, H323_ALREADYGONE)) {
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;
1133  ast_module_unref(myself);
1134  }
1135 
1136  ast_mutex_unlock(&p->lock);
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 
1154 static 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);
1165  callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
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  }
1177  ast_setstate(ast, AST_STATE_UP);
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) {
1183  ast_free(callToken);
1184  }
1185  ast_mutex_unlock(&p->lock);
1186  }
1187 
1188  if (gH323Debug)
1189  ast_verb(0, "+++ ooh323_answer\n");
1190 
1191  return 0;
1192 }
1193 
1194 static 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); */
1208  ast_mutex_unlock(&p->lock);
1209  return fr;
1210 }
1211 
1212 static 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);
1227  ast_mutex_unlock(&p->lock);
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  }
1256  ast_mutex_unlock(&p->lock);
1257  return 0;
1258  }
1259 
1260  if (p->rtp)
1261  res = ast_rtp_instance_write(p->rtp, f);
1262 
1263  ast_mutex_unlock(&p->lock);
1264 
1265  } else if (f->frametype == AST_FRAME_IMAGE) {
1266  ast_mutex_unlock(&p->lock);
1267  return 0;
1268  } else {
1269  ast_log(LOG_WARNING, "Can't send %u type frames with OOH323 write\n",
1270  f->frametype);
1271  ast_mutex_unlock(&p->lock);
1272  return 0;
1273  }
1274 
1275  }
1276 
1277  return res;
1278 }
1279 
1280 static 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);
1290  callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
1291  ast_mutex_unlock(&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  */
1314  if (!ast_test_flag(p, H323_ALREADYGONE)) {
1315  ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
1316  }
1317  break;
1318  case AST_CONTROL_BUSY:
1319  if (!ast_test_flag(p, H323_ALREADYGONE)) {
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;
1329  case AST_CONTROL_PROGRESS:
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;
1340  case AST_CONTROL_RINGING:
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;
1352  case AST_CONTROL_SRCUPDATE:
1353  if (p->rtp) {
1355  }
1356  break;
1357  case AST_CONTROL_SRCCHANGE:
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 
1425  case AST_T38_REQUEST_PARMS:
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));
1430  res = AST_T38_REQUEST_PARMS;
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 
1450  ast_mutex_unlock(&p->lock);
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 
1460 static 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 
1477  case AST_OPTION_T38_STATE:
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 {
1489  state = T38_STATE_UNKNOWN;
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 
1515  ast_mutex_unlock(&p->lock);
1516 
1517  return res;
1518 }
1519 
1520 
1521 
1522 static 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);
1534  ast_mutex_unlock(&p->lock);
1535  return -1;
1536  }
1537 
1538  if (p->owner == oldchan) {
1539  p->owner = newchan;
1540  } else {
1541  p->owner = oldchan;
1542  }
1543 
1544  ast_mutex_unlock(&p->lock);
1545 
1546  if (gH323Debug)
1547  ast_verb(0, "+++ ooh323c ooh323_fixup \n");
1548 
1549  return 0;
1550 }
1551 
1552 
1553 void 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");
1582  DEADLOCK_AVOIDANCE(&p->lock);
1583  }
1584  if (!p->owner) {
1585  ast_mutex_unlock(&p->lock);
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 
1619  ast_mutex_unlock(&p->lock);
1620 
1621  if (gH323Debug)
1622  ast_verb(0, "+++ ooh323_update_writeformat\n");
1623 }
1624 
1625 void 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");
1654  DEADLOCK_AVOIDANCE(&p->lock);
1655  }
1656  if (!p->owner) {
1657  ast_mutex_unlock(&p->lock);
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 
1675  ast_mutex_unlock(&p->lock);
1676 
1677  if (gH323Debug)
1678  ast_verb(0, "+++ ooh323_update_readformat\n");
1679 }
1680 
1681 
1682 int 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) {
1698  ast_mutex_unlock(&p->lock);
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");
1704  DEADLOCK_AVOIDANCE(&p->lock);
1705  }
1706  if (!p->owner) {
1707  ast_mutex_unlock(&p->lock);
1708  ast_log(LOG_ERROR, "Channel has no owner\n");
1709  return 0;
1710  }
1711  c = p->owner;
1712 
1713  if (call->remoteDisplayName) {
1714  struct ast_party_connected_line connected;
1715  struct ast_set_party_connected_line update_connected;
1716 
1717  memset(&update_connected, 0, sizeof(update_connected));
1718  update_connected.id.name = 1;
1719  ast_party_connected_line_init(&connected);
1720  connected.id.name.valid = 1;
1721  connected.id.name.str = (char *) call->remoteDisplayName;
1723  ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1724  }
1725  if (ast_channel_state(c) != AST_STATE_UP)
1727 
1729  ast_channel_unlock(c);
1730  ast_mutex_unlock(&p->lock);
1731 
1732  if (gH323Debug)
1733  ast_verb(0, "+++ onAlerting %s\n", call->callToken);
1734 
1735  return OO_OK;
1736 }
1737 
1738 int 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) {
1754  ast_mutex_unlock(&p->lock);
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");
1760  DEADLOCK_AVOIDANCE(&p->lock);
1761  }
1762  if (!p->owner) {
1763  ast_mutex_unlock(&p->lock);
1764  ast_log(LOG_ERROR, "Channel has no owner\n");
1765  return 0;
1766  }
1767  c = p->owner;
1768 
1769  if (call->remoteDisplayName) {
1770  struct ast_party_connected_line connected;
1771  struct ast_set_party_connected_line update_connected;
1772 
1773  memset(&update_connected, 0, sizeof(update_connected));
1774  update_connected.id.name = 1;
1775  ast_party_connected_line_init(&connected);
1776  connected.id.name.valid = 1;
1777  connected.id.name.str = (char *) call->remoteDisplayName;
1779  ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1780  }
1781  if (ast_channel_state(c) != AST_STATE_UP)
1783 
1785  ast_channel_unlock(c);
1786  ast_mutex_unlock(&p->lock);
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  */
1798 int 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");
1827  DEADLOCK_AVOIDANCE(&p->lock);
1828  }
1829  if (!p->owner) {
1830  ast_mutex_unlock(&p->lock);
1831  ast_log(LOG_ERROR, "Channel has no owner\n");
1832  return 0;
1833  }
1834  res = ast_queue_frame(p->owner, &f);
1836  ast_mutex_unlock(&p->lock);
1837  return res;
1838 }
1839 
1840 int 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) {
1866  p->callerid_num = ast_strdup(number);
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 {
1899  update_our_aliases(call, p);
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;
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 {
1971  ast_mutex_unlock(&p->lock);
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 */
1989  c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL, NULL);
1990  if(!c) {
1991  ast_mutex_unlock(&p->lock);
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)) {
2000  ast_mutex_unlock(&p->lock);
2001  ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
2002  return -1;
2003  }
2004 
2005  ast_mutex_unlock(&p->lock);
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 
2016 int 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 
2049  if (!ast_strlen_zero(p->caller_h323id))
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 (ooIsDailedDigit(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)) {
2076  ast_mutex_unlock(&p->lock);
2077  return OO_FAILED;
2078  }
2079 
2080  ast_mutex_unlock(&p->lock);
2081  }
2082 
2083  if (gH323Debug)
2084  ast_verb(0, "+++ onOutgoingCall %s\n", call->callToken);
2085  return OO_OK;
2086 }
2087 
2088 
2089 int 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);
2098  if (ooh323c_start_call_thread(call)) {
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 
2130  if (!ast_strlen_zero(p->caller_h323id))
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 (ooIsDailedDigit(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 (ooIsDailedDigit(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 
2170  configure_local_rtp(p, call);
2171  ast_cond_signal(&p->rtpcond);
2172  ast_mutex_unlock(&p->lock);
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 
2181 int 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 
2194  if(ast_test_flag(p, H323_OUTGOING)) {
2195  ast_mutex_lock(&p->lock);
2196  if (!p->owner) {
2197  ast_mutex_unlock(&p->lock);
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");
2204  DEADLOCK_AVOIDANCE(&p->lock);
2205  }
2206  if (p->owner) {
2207  struct ast_channel* c = p->owner;
2208 
2209  if (call->remoteDisplayName) {
2210  struct ast_party_connected_line connected;
2211  struct ast_set_party_connected_line update_connected;
2212 
2213  memset(&update_connected, 0, sizeof(update_connected));
2214  update_connected.id.name = 1;
2215  ast_party_connected_line_init(&connected);
2216  connected.id.name.valid = 1;
2217  connected.id.name.str = (char *) call->remoteDisplayName;
2219  ast_channel_queue_connected_line_update(c, &connected, &update_connected);
2220  }
2221 
2225  }
2226  ast_mutex_unlock(&p->lock);
2227 
2228  }
2229 
2230  if (gH323Debug)
2231  ast_verb(0, "+++ onCallEstablished %s\n", call->callToken);
2232 
2233  return OO_OK;
2234 }
2235 
2236 int 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");
2252  DEADLOCK_AVOIDANCE(&p->lock);
2253  } else {
2254  ownerLock = 1; break;
2255  }
2256  }
2257 
2258  if (ownerLock) {
2259  if (!ast_test_flag(p, H323_ALREADYGONE)) {
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;
2272  ast_module_unref(myself);
2273  }
2274 
2275  if (!p->rtp) {
2276  ast_cond_signal(&p->rtpcond);
2277  }
2278 
2280 
2282 
2283  ast_mutex_unlock(&p->lock);
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 
2368 static 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  }
2445  ast_format_cap_update_by_allow_disallow(user->cap, tcodecs, 1);
2446  } else if (!strcasecmp(v->name, "amaflags")) {
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"))
2465  else if (!strcasecmp(v->value, "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)) {
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 
2515 static 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;
2633  ast_copy_string(peer->rtpmaskstr, v->value,
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  }
2643  ast_format_cap_update_by_allow_disallow(peer->cap, tcodecs, 1);
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"))
2650  peer->dtmfmode = H323_DTMF_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 
2705 static 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 
2778 char *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  }
2805  restart_monitor();
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));
2896  if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
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")) {
2919  gIsGateway = ast_true(v->value);
2920  } else if (!strcasecmp(v->name, "faststart")) {
2921  gFastStart = ast_true(v->value);
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")) {
2933  gTunneling = ast_true(v->value);
2934  if (gTunneling)
2935  ooH323EpEnableH245Tunneling();
2936  else
2937  ooH323EpDisableH245Tunneling();
2938  } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2939  gDirectRTP = ast_true(v->value);
2940  gEarlyDirect = ast_true(v->value);
2941  } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2942  gEarlyDirect = ast_true(v->value);
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 */
2961  ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
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")) {
3015  ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
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"))
3057  gTOS = IPTOS_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  }
3075  ast_format_cap_update_by_allow_disallow(gCap, tcodecs, 1);
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 
3188 static 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/chan_sip 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 
3285 static 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 
3327 static 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/chan_sip 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 
3424 static 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 
3466 static 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
3491 static int ooh323_show_channels(int fd, int argc, char *argv[])
3492 {
3493  return RESULT_SUCCESS;
3494 }
3495 #endif
3496 
3497 static char *handle_cli_ooh323_show_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3498 {
3499  char value[FORMAT_STRING_SIZE];
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 
3558 static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3559 {
3560  char value[FORMAT_STRING_SIZE];
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");
3620  } else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC) {
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/chan_sip compatible");
3637  }
3638  if (gFAXdetect == (FAXDETECT_CNG | FAXDETECT_T38)) {
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 
3673 static 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 */
3685 static 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")) {
3707  ast_copy_string(buf, p->caller_h323id, len);
3708  } else if (!strcasecmp(data, "caller_dialeddigits")) {
3709  ast_copy_string(buf, p->caller_dialedDigits, len);
3710  } else if (!strcasecmp(data, "caller_email")) {
3711  ast_copy_string(buf, p->caller_email, len);
3712  } else if (!strcasecmp(data, "h323id_url")) {
3713  ast_copy_string(buf, p->caller_url, len);
3714  } else if (!strcasecmp(data, "callee_h323id")) {
3715  ast_copy_string(buf, p->callee_h323id, len);
3716  } else if (!strcasecmp(data, "callee_dialeddigits")) {
3717  ast_copy_string(buf, p->callee_dialedDigits, len);
3718  } else if (!strcasecmp(data, "callee_email")) {
3719  ast_copy_string(buf, p->callee_email, len);
3720  } else if (!strcasecmp(data, "callee_url")) {
3721  ast_copy_string(buf, p->callee_url, len);
3722  }
3723  ast_mutex_unlock(&p->lock);
3724 
3725  ast_channel_unlock(chan);
3726  return 0;
3727 }
3728 
3729 /*! \brief OOH323 Dialplan function - writes ooh323 settings */
3730 static 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")) {
3762  p->faxdetect |= FAXDETECT_CNG;
3763  } else if (!strcasecmp(word, "t38")) {
3764  p->faxdetect |= FAXDETECT_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  }
3781  ast_mutex_unlock(&p->lock);
3782  ast_channel_unlock(chan);
3783 
3784  return res;
3785 }
3786 
3787 static 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  };
3807  return AST_MODULE_LOAD_DECLINE;
3808  }
3810  ao2_ref(gCap, -1);
3811  gCap = NULL;
3812  return AST_MODULE_LOAD_DECLINE;
3813  }
3816 
3817  myself = ast_module_info->self;
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;
3846  ao2_ref(ooh323_tech.capabilities, -1);
3847  ooh323_tech.capabilities = NULL;
3848  return AST_MODULE_LOAD_DECLINE;
3849  }
3850 
3851  /* Make sure we can register our OOH323 channel type */
3852  if (ast_channel_register(&ooh323_tech)) {
3853  ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
3854  ao2_ref(gCap, -1);
3855  gCap = NULL;
3856  ao2_ref(ooh323_tech.capabilities, -1);
3857  ooh323_tech.capabilities = NULL;
3858  return AST_MODULE_LOAD_DECLINE;
3859  }
3860  ast_rtp_glue_register(&ooh323_rtp);
3861  ast_cli_register_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
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 */
3939  if (ooh323c_set_capability(gCap, gDTMFMode, gDTMFCodec) < 0) {
3940  ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
3941  ao2_ref(gCap, -1);
3942  gCap = NULL;
3943  ao2_ref(ooh323_tech.capabilities, -1);
3944  ooh323_tech.capabilities = 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;
3956  ao2_ref(ooh323_tech.capabilities, -1);
3957  ooh323_tech.capabilities = 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;
3967  ao2_ref(ooh323_tech.capabilities, -1);
3968  ooh323_tech.capabilities = NULL;
3969  return 1;
3970  }
3971  /* And start the monitor for the first time */
3972  restart_monitor();
3973  } else {
3974  ast_log(LOG_ERROR, "Can't load ooh323 config file, OOH323 Disabled\n");
3975  return AST_MODULE_LOAD_DECLINE;
3976  }
3977 
3978  return 0;
3979 }
3980 
3981 static 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  }
3990  restart_monitor();
3991 
3992  if (gH323Debug)
3993  ast_verb(0, "+++ ooh323_reload\n");
3994 
3995  return 0;
3996 }
3997 
3998 static 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");
4014  ooh323_do_reload();
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));
4043  ast_channel_unlock(h323->owner);
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) {
4074  ast_sched_runq(sched);
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;
4192  ast_module_unref(myself);
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 
4296 static 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 */
4305  ast_cli_unregister_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
4306  ast_rtp_glue_unregister(&ooh323_rtp);
4307  ast_channel_unregister(&ooh323_tech);
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;
4415  ao2_ref(ooh323_tech.capabilities, -1);
4416  ooh323_tech.capabilities = NULL;
4417  return 0;
4418 }
4419 
4420 static 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;
4520  } else if (ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) {
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 
4532 static 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 
4563  callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
4564 
4565  if (!callToken) {
4566  if (gH323Debug) {
4567  ast_verb(0, " set_rtp_peer - No callToken\n");
4568  }
4569  ast_mutex_unlock(&p->lock);
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),
4578  ast_sockaddr_port(&p->redirip));
4579  }
4580  ooUpdateLogChannels(callToken, ast_sockaddr_stringify_addr(&p->redirip),
4581  ast_sockaddr_port(&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 
4590  ast_mutex_unlock(&p->lock);
4591  ast_free(callToken);
4592  return 0;
4593 
4594 }
4595 
4596 
4597 
4598 
4599 int 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)) {
4612  ast_sockaddr_copy(&tmp, &bindaddr);
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");
4632  DEADLOCK_AVOIDANCE(&p->lock);
4633  }
4634  if (!p->owner) {
4635  ast_mutex_unlock(&p->lock);
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++) {
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) {
4717  ast_udptl_get_us(p->udptl, &tmp);
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 
4736 void 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 
4765  ast_mutex_unlock(&p->lock);
4766 
4767  if (gH323Debug) {
4768  ast_verb(0, "+++ setup_rtp_remote\n");
4769  }
4770 
4771  return;
4772 }
4773 
4774 
4775 void 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 
4802  ast_mutex_unlock(&p->lock);
4803 
4804  if(gH323Debug)
4805  ast_verb(0, "+++ setup_rtp_connection\n");
4806 
4807  return;
4808 }
4809 
4810 void close_rtp_connection(ooCallData *call)
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  }
4827  ast_mutex_unlock(&p->lock);
4828 
4829  if(gH323Debug)
4830  ast_verb(0, "+++ close_rtp_connection\n");
4831 
4832  return;
4833 }
4834 
4835 /*
4836  udptl handling functions
4837  */
4838 
4839 void 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");
4860  DEADLOCK_AVOIDANCE(&p->lock);
4861  }
4862  if (!p->owner) {
4863  ast_mutex_unlock(&p->lock);
4864  ast_log(LOG_ERROR, "Channel has no owner\n");
4865  return;
4866  }
4867  } else {
4868  ast_mutex_unlock(&p->lock);
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 };
4882  parameters.request_response = AST_T38_NEGOTIATED;
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 
4893  ast_mutex_unlock(&p->lock);
4894 
4895  if(gH323Debug)
4896  ast_verb(0, "+++ setup_udptl_connection\n");
4897 
4898  return;
4899 }
4900 
4901 void close_udptl_connection(ooCallData *call)
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");
4918  DEADLOCK_AVOIDANCE(&p->lock);
4919  }
4920  if (!p->owner) {
4921  ast_mutex_unlock(&p->lock);
4922  ast_log(LOG_ERROR, "Channel has no owner\n");
4923  return;
4924  }
4925  } else {
4926  ast_mutex_unlock(&p->lock);
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 };
4934  parameters.request_response = AST_T38_TERMINATED;
4935  ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
4936  }
4937 
4939  ast_mutex_unlock(&p->lock);
4940 
4941  if(gH323Debug)
4942  ast_verb(0, "+++ close_udptl_connection\n");
4943 
4944  return;
4945 }
4946 
4947 /* end of udptl handling */
4948 
4949 int 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 
4978 struct 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) {
5021  ast_format_cap_append(caps, f->subclass.format, 0);
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 = S_OR(ast_channel_macrocontext(p->owner), 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 
5076 void 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;
5095  ast_mutex_unlock(&p->lock);
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");
5102  DEADLOCK_AVOIDANCE(&p->lock);
5103  }
5104  if (!p->owner) {
5105  p->chmodepend = 0;
5106  ast_mutex_unlock(&p->lock);
5107  ast_log(LOG_ERROR, "Channel has no owner\n");
5108  return;
5109  }
5110  } else {
5111  p->chmodepend = 0;
5112  ast_mutex_unlock(&p->lock);
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 = S_OR(ast_channel_macrocontext(p->owner), 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;
5174  ast_mutex_unlock(&p->lock);
5175 }
5176 
5177 
5178 
5180 {
5181  switch (cause) {
5183  return OO_REASON_REMOTE_REJECTED;
5184  case AST_CAUSE_UNALLOCATED:
5185  return OO_REASON_NOUSER;
5186  case AST_CAUSE_BUSY:
5187  return OO_REASON_REMOTE_BUSY;
5189  return OO_REASON_NOCOMMON_CAPABILITIES;
5190  case AST_CAUSE_CONGESTION:
5191  return OO_REASON_REMOTE_BUSY;
5192  case AST_CAUSE_NO_ANSWER:
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:
5210  return AST_CAUSE_CALL_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
5237 void ast_ooh323c_exit()
5238 {
5239  ooGkClientDestroy();
5240 }
5241 #endif
5242 
5243 AST_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,
5247  .reload = reload_module,
5248  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
5249  .requires = "udptl",
5250 );
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:290
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:278
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char rtpmaskstr[120]
Definition: chan_ooh323.c:244
static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
Definition: chan_ooh323.c:1280
struct ast_variable * next
static const char type[]
Definition: chan_ooh323.c:109
struct ast_format * ast_format_g726
Built-in cached g726 format.
Definition: format_cache.c:116
unsigned outgoinglimit
Definition: chan_ooh323.c:287
enum sip_cc_notify_state state
Definition: chan_sip.c:959
struct ooh323_pvt * next
Definition: chan_ooh323.c:248
char accountcode[20]
Definition: chan_ooh323.c:290
#define H323_OUTGOING
Definition: chan_ooh323.c:93
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define T38_ENABLED
Definition: chan_ooh323.c:102
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:1494
static struct ast_frame * ooh323_read(struct ast_channel *ast)
Definition: chan_ooh323.c:1194
Main Channel structure associated with a channel.
static char gContext[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:378
unsigned inUse
Definition: chan_ooh323.c:260
static struct ooAliases * gAliasList
Definition: chan_ooh323.c:356
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
struct ast_format * ast_format_g723
Built-in cached g723.1 format.
Definition: format_cache.c:151
#define ast_frdup(fr)
Copies a frame.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
const char *const type
Definition: channel.h:630
#define H323_ALREADYGONE
Definition: chan_ooh323.c:94
static int gFastStart
Definition: chan_ooh323.c:367
static int ooh323_answer(struct ast_channel *ast)
Definition: chan_ooh323.c:1154
#define FALSE
Definition: app_minivm.c:521
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
static int gDTMFCodec
Definition: chan_ooh323.c:359
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
static struct ast_cli_entry cli_ooh323[]
Definition: chan_ooh323.c:3673
static int ooh323_digit_begin(struct ast_channel *ast, char digit)
Definition: chan_ooh323.c:928
static struct ast_sched_context * sched
Definition: chan_ooh323.c:400
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
static int manufacturer
Definition: chan_ooh323.c:389
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 gTunneling
Definition: chan_ooh323.c:368
struct ooh323_peer * find_peer(const char *name, int port)
Definition: chan_ooh323.c:890
void close_udptl_connection(ooCallData *call)
Definition: chan_ooh323.c:4901
static int gPort
Definition: chan_ooh323.c:351
static struct ast_peer_list peerl
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:961
static const char config[]
Definition: chan_ooh323.c:111
static pthread_t monitor_thread
Definition: chan_ooh323.c:410
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:2160
Definition: ast_expr2.c:325
static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
Definition: chan_ooh323.c:1460
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
static char gIP[2+8 *4+7]
Definition: chan_ooh323.c:352
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:121
struct ooh323_peer * next
Definition: chan_ooh323.c:312
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static int h323_reloading
Definition: chan_ooh323.c:328
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:171
char context[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:258
char * email
Definition: chan_ooh323.c:300
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
int onNewCallCreated(ooCallData *call)
Definition: chan_ooh323.c:2089
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
struct ast_module * myself
Definition: chan_ooh323.c:113
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout)
Definition: chan_ooh323.c:990
int rtptimeout
Definition: chan_ooh323.c:194
static int unload_module(void)
Definition: chan_ooh323.c:4296
static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
Definition: chan_ooh323.c:4442
char callee_dialedDigits[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:222
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
#define ast_set_flag(p, flag)
Definition: utils.h:70
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:727
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
descriptor for a cli entry.
Definition: cli.h:171
struct ast_sockaddr redirip
Definition: chan_ooh323.c:188
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
static int gRTDRInterval
Definition: chan_ooh323.c:383
char caller_h323id[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:217
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
char * username
Definition: chan_ooh323.c:213
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
static int gANIasDNI
Definition: chan_ooh323.c:385
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
static int gDirectRTP
Definition: chan_ooh323.c:371
char name[256]
Definition: chan_ooh323.c:257
static int timeout
Definition: cdr_mysql.c:86
static int tmp()
Definition: bt_open.c:389
int ooh323c_start_call_thread(ooCallData *call)
char callee_h323id[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:221
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:2337
struct ooh323_user * next
Definition: chan_ooh323.c:280
time_t lastrtprx
Definition: chan_ooh323.c:209
Structure for variables, used for configurations and for channel variables.
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:2169
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:847
static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
Definition: chan_ooh323.c:4420
struct ooh323_peer * peers
Definition: chan_ooh323.c:323
struct ast_format * ast_format_g726_aal2
Built-in cached g726 aal2 format.
Definition: format_cache.c:121
#define FORMAT1
enum ast_control_t38 request_response
Definition: cli.h:152
struct ast_frame * ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
Definition: chan_ooh323.c:4978
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:605
#define IPTOS_MINCOST
Definition: chan_ooh323.c:77
Structure for an UDPTL session.
Definition: udptl.c:156
#define DEFAULT_LOGFILE
Definition: chan_ooh323.c:85
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int t38support
Definition: chan_ooh323.c:191
char * str
Subscriber name (Malloced)
Definition: channel.h:265
int ooh323c_stop_call_thread(ooCallData *call)
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4418
Definition of a media format.
Definition: format.c:43
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:879
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
char * url
Definition: chan_ooh323.c:301
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
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
int onOutgoingCall(ooCallData *call)
Definition: chan_ooh323.c:2016
int earlydirect
Definition: chan_ooh323.c:240
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
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2670
static int gRTDRCount
Definition: chan_ooh323.c:383
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:997
#define ast_mutex_lock(a)
Definition: lock.h:187
static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
Definition: chan_ooh323.c:1212
static struct test_val c
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
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static int call(void *data)
Definition: chan_pjsip.c:2358
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:1558
char * callerid_name
Definition: chan_ooh323.c:215
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition: format_cap.c:136
static struct ooh323_pvt * ooh323_alloc(int callref, char *callToken)
Definition: chan_ooh323.c:556
#define NULL
Definition: resample.c:96
void ast_udptl_destroy(struct ast_udptl *udptl)
Definition: udptl.c:1150
const char * data
char accountcode[256]
Definition: chan_ooh323.c:234
void setup_udptl_connection(ooCallData *call, const char *remoteIp, int remotePort)
Definition: chan_ooh323.c:4839
struct ast_udptl * udptl
Definition: chan_ooh323.c:195
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:119
int value
Definition: syslog.c:37
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
#define AST_FRAME_DTMF
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
Definition: chan_ooh323.c:1625
const char * ext
Definition: http.c:147
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
int delete_users()
Definition: chan_ooh323.c:4265
Socket address structure.
Definition: netsock2.h:97
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_verb(level,...)
Definition: logger.h:463
time_t lastrtptx
Definition: chan_ooh323.c:208
const char * type
Definition: rtp_engine.h:722
char * peer
Definition: chan_ooh323.c:206
#define FAXDETECT_T38
Definition: chan_ooh323.c:106
static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: chan_ooh323.c:1522
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 v6mode
Definition: chan_ooh323.c:354
struct ast_frame_subclass subclass
#define T38_FAXGW
Definition: chan_ooh323.c:103
time_t lastTxT38
Definition: chan_ooh323.c:200
static int gTOS
Definition: chan_ooh323.c:373
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
pthread_cond_t ast_cond_t
Definition: lock.h:176
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
struct ooh323_peer * find_friend(const char *name, int port)
Definition: chan_ooh323.c:858
OOBOOL gH323Debug
Definition: chan_ooh323.c:381
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:583
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
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
char context[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:233
Number structure.
Definition: app_followme.c:154
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
void ast_udptl_get_us(const struct ast_udptl *udptl, struct ast_sockaddr *us)
Definition: udptl.c:1140
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4405
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
int onAlerting(ooCallData *call)
Definition: chan_ooh323.c:1682
int t38_tx_enable
Definition: chan_ooh323.c:197
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
int h245tunneling
Definition: chan_ooh323.c:308
#define H323_DTMF_CISCO
Definition: ooh323cDriver.h:31
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int restart_monitor(void)
Start the channel monitor thread.
Definition: chan_ooh323.c:4082
#define ast_log
Definition: astobj2.c:42
static int gFAXdetect
Definition: chan_ooh323.c:360
struct ast_format_cap * cap
Definition: chan_ooh323.c:289
char callee_email[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:223
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
static char gCallerID[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:355
int onCallCleared(ooCallData *call)
Definition: chan_ooh323.c:2236
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2183
char rtpmaskstr[120]
Definition: chan_ooh323.c:272
#define ast_config_load(filename, flags)
Load a config file.
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
static int ooh323_do_reload(void)
Definition: chan_ooh323.c:2705
struct ast_module * self
Definition: module.h:342
static int gNat
Definition: chan_ooh323.c:384
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:9202
static int ooh323_hangup(struct ast_channel *ast)
Definition: chan_ooh323.c:1087
ast_mutex_t lock
Definition: chan_ooh323.c:324
void ast_channel_rings_set(struct ast_channel *chan, int value)
#define H323_DTMF_Q931
Definition: ooh323cDriver.h:27
#define DEFAULT_CONTEXT
Definition: chan_ooh323.c:83
const char * src
int h245tunneling
Definition: chan_ooh323.c:275
struct ast_dsp * vad
Definition: chan_ooh323.c:242
void ast_unregister_atexit(void(*func)(void))
Unregister a function registered with ast_register_atexit().
Definition: asterisk.c:1022
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
int rtdrinterval
Definition: chan_ooh323.c:306
static int reload_module(void)
Definition: chan_ooh323.c:3981
const int fd
Definition: cli.h:159
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
static ast_mutex_t monlock
Definition: chan_ooh323.c:405
Definition: dsp.c:405
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
static struct io_context * io
Definition: chan_ooh323.c:401
OOH323EndPoint gH323ep
#define DEFAULT_H323ACCNT
Definition: chan_ooh323.c:86
#define AST_PTHREADT_NULL
Definition: lock.h:66
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
static int gIncomingLimit
Definition: chan_ooh323.c:379
Global IO variables are now in a struct in order to be made threadsafe.
Definition: io.c:71
ast_mutex_t lock
Definition: chan_ooh323.c:256
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
struct ast_format * ast_format_gsm
Built-in cached gsm format.
Definition: format_cache.c:101
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ooh323_convert_hangupcause_asteriskToH323(int cause)
Definition: chan_ooh323.c:5179
#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:85
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
static char * handle_cli_ooh323_show_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3497
enum ast_control_t38_rate rate
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: clicompat.c:13
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
Set fax mode.
Definition: dsp.c:1870
struct ast_format * writeformat
Definition: chan_ooh323.c:228
static long callnumber
Definition: chan_ooh323.c:335
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
static int gRTPTimeout
Definition: chan_ooh323.c:374
void ooh323_delete_peer(struct ooh323_peer *peer)
Definition: chan_ooh323.c:2328
char rtpmaskstr[120]
Definition: chan_ooh323.c:305
int ooh323c_stop_stack_thread(void)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
static struct ast_jb_conf default_jbconf
Definition: chan_ooh323.c:115
static struct ast_user_list userl
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:4179
ast_rtp_glue_result
Definition: rtp_engine.h:158
static int usecnt
Definition: chan_ooh323.c:332
struct ast_format_cap * cap
Definition: chan_ooh323.c:229
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
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:1428
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:629
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
const char * ast_channel_exten(const struct ast_channel *chan)
struct OOH323Regex * rtpmask
Definition: chan_ooh323.c:271
static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
Definition: chan_ooh323.c:4485
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
ast_mutex_t lock
Definition: chan_ooh323.c:185
ast_mutex_t lock
Definition: chan_ooh323.c:319
char exten[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:232
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:525
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
int ooh323c_start_stack_thread()
#define CONFIG_STATUS_FILEUNCHANGED
char caller_email[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:219
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
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 struct ast_rtp_glue ooh323_rtp
Definition: chan_ooh323.c:172
int ast_channel_fdno(const struct ast_channel *chan)
const char *const * argv
Definition: cli.h:161
#define AST_CAUSE_NORMAL
Definition: causes.h:150
#define AST_CAUSE_FAILURE
Definition: causes.h:149
int onProgress(ooCallData *call)
Definition: chan_ooh323.c:1738
#define AST_OPTION_DIGIT_DETECT
unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
retrieves far max ifp
Definition: udptl.c:1016
int update_our_aliases(ooCallData *call, struct ooh323_pvt *p)
Definition: chan_ooh323.c:4949
static ast_mutex_t ooh323c_cn_lock
Definition: chan_ooh323.c:336
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define H323_DTMF_H245ALPHANUMERIC
Definition: ooh323cDriver.h:28
char * callerid_num
Definition: chan_ooh323.c:216
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
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
int onCallEstablished(ooCallData *call)
Definition: chan_ooh323.c:2181
#define H323_NEEDDESTROY
Definition: chan_ooh323.c:95
void onModeChanged(ooCallData *call, int t38mode)
Definition: chan_ooh323.c:5076
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
int faxdetected
Definition: chan_ooh323.c:193
void ast_udptl_set_peer(struct ast_udptl *udptl, const struct ast_sockaddr *them)
Definition: udptl.c:1130
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int gMediaWaitForConnect
Definition: chan_ooh323.c:370
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
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:2772
struct ast_format * ast_format_speex
Built-in cached speex format.
Definition: format_cache.c:136
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 DSP_FAXMODE_DETECT_CED
Definition: dsp.h:48
#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:1080
int rtdrinterval
Definition: chan_ooh323.c:245
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int load_module(void)
Definition: chan_ooh323.c:3787
int errno
static char gRASIP[2+8 *4+7]
Definition: chan_ooh323.c:363
#define T38_DISABLED
Definition: chan_ooh323.c:101
Connected Line/Party information.
Definition: channel.h:457
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2081
static ast_mutex_t h323_reload_lock
Definition: chan_ooh323.c:329
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:7866
int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
Definition: chan_ooh323.c:4599
#define FORMAT
#define ast_cond_destroy(cond)
Definition: lock.h:200
int incominglimit
Definition: chan_ooh323.c:259
static int gTRCLVL
Definition: chan_ooh323.c:382
#define LOG_NOTICE
Definition: logger.h:263
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:736
ast_mutex_t lock
Definition: chan_ooh323.c:285
char * user
Definition: chan_ooh323.c:205
const char * ast_config_AST_LOG_DIR
Definition: options.c:159
struct ast_format_cap * capabilities
Definition: channel.h:633
struct ast_format * readformat
Definition: chan_ooh323.c:227
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
Definition: chan_ooh323.c:1798
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void * do_monitor(void *data)
Definition: chan_ooh323.c:3998
char * handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:2778
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
static const char name[]
Definition: cdr_mysql.c:74
int source
Information about the source of an update.
Definition: channel.h:483
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
struct ast_sockaddr udptlredirip
Definition: chan_ooh323.c:199
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
static int reload(void)
Definition: cdr_mysql.c:741
struct ooh323_user * find_user(const char *name, const char *ip)
Definition: chan_ooh323.c:832
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
int ast_udptl_fd(const struct ast_udptl *udptl)
Definition: udptl.c:730
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: main/config.c:3657
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:2192
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
struct ast_format_cap * cap
Definition: chan_ooh323.c:263
unsigned outUse
Definition: chan_ooh323.c:288
static const char tdesc[]
Definition: chan_ooh323.c:110
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
Definition: abstract_jb.h:72
char callee_url[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:224
void setup_rtp_connection(ooCallData *call, const char *remoteIp, int remotePort)
Definition: chan_ooh323.c:4775
structure to hold users read from users.conf
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:643
Structure used to handle boolean flags.
Definition: utils.h:199
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
char accountcode[20]
Definition: chan_ooh323.c:261
static char vendor[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:390
static int gBeMaster
Definition: chan_ooh323.c:369
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
int reload_config(int reload)
Definition: chan_ooh323.c:2813
static int gOutgoingLimit
Definition: chan_ooh323.c:380
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
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
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:1028
const char * usage
Definition: cli.h:177
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
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...
struct ast_frame * ast_udptl_read(struct ast_udptl *udptl)
Definition: udptl.c:762
static char * handle_cli_ooh323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3466
struct ast_frame ast_null_frame
Definition: main/frame.c:79
char mIP[4 *8+7+2]
Definition: chan_ooh323.c:270
#define CLI_SUCCESS
Definition: cli.h:44
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
struct ast_set_party_id id
Definition: channel.h:492
#define H323_DTMF_H245SIGNAL
Definition: ooh323cDriver.h:29
char caller_dialedDigits[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:218
void close_rtp_connection(ooCallData *call)
Definition: chan_ooh323.c:4810
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:124
static char gInitError[256]
Definition: chan_ooh323.c:350
char * strsep(char **str, const char *delims)
unsigned char name
Definition: channel.h:364
static struct ast_channel_tech ooh323_tech
Definition: chan_ooh323.c:150
#define ao2_replace(dst, src)
Definition: astobj2.h:517
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ooh323c_set_capability(struct ast_format_cap *cap, int dtmf, int dtmfcodec)
static struct ast_format_cap * gCap
Definition: chan_ooh323.c:357
int ast_channel_hangupcause(const struct ast_channel *chan)
struct OOH323Regex * rtpmask
Definition: chan_ooh323.c:304
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static ast_mutex_t usecnt_lock
Definition: chan_ooh323.c:333
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
static struct ooh323_peer * build_peer(const char *name, struct ast_variable *v, int friend_type)
Definition: chan_ooh323.c:2515
const char * ast_channel_name(const struct ast_channel *chan)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
#define TRUE
Definition: app_minivm.c:518
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
char * callToken
Definition: chan_ooh323.c:212
struct ast_channel * owner
Definition: chan_ooh323.c:203
static struct ooh323_user * build_user(const char *name, struct ast_variable *v)
Definition: chan_ooh323.c:2368
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 ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define AST_PTHREADT_STOP
Definition: lock.h:67
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
static int gAMAFLAGS
Definition: chan_ooh323.c:377
ast_cond_t rtpcond
Definition: chan_ooh323.c:186
#define ast_frfree(fr)
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:7011
int ast_udptl_write(struct ast_udptl *udptl, struct ast_frame *f)
Definition: udptl.c:1161
static char gGatekeeper[100]
Definition: chan_ooh323.c:362
static PGresult * result
Definition: cel_pgsql.c:88
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
static int t35countrycode
Definition: chan_ooh323.c:387
int ooh323_destroy(struct ooh323_pvt *p)
Definition: chan_ooh323.c:4117
#define AST_CAUSE_BUSY
Definition: causes.h:148
static struct ooh323_pvt * iflist
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:431
static int gEarlyDirect
Definition: chan_ooh323.c:372
void ast_udptl_set_tag(struct ast_udptl *udptl, const char *format,...)
Associates a character string &#39;tag&#39; with a UDPTL session.
Definition: udptl.c:1112
Data structure associated with a single frame of data.
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
Definition: chan_ooh323.c:962
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 struct ast_jb_conf global_jbconf
Definition: chan_ooh323.c:122
static int t35extensions
Definition: chan_ooh323.c:388
#define FAXDETECT_CNG
Definition: chan_ooh323.c:105
struct ast_rtp_instance * rtp
Definition: chan_ooh323.c:187
int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
Definition: chan_ooh323.c:1840
#define DSP_FAXMODE_DETECT_CNG
Definition: dsp.h:47
const char * ast_channel_context(const struct ast_channel *chan)
static char * handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_ooh323.c:3327
char * host
Definition: chan_ooh323.c:214
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
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:705
static int gIsGateway
Definition: chan_ooh323.c:366
union ast_frame::@263 data
static enum RasGatekeeperMode gRasGkMode
Definition: chan_ooh323.c:364
enum ast_frame_type frametype
#define PATH_MAX
Definition: asterisk.h:40
int chmodepend
Definition: chan_ooh323.c:201
#define DEFAULT_H323ID
Definition: chan_ooh323.c:84
#define ast_mutex_init(pmutex)
Definition: lock.h:184
char * e164
Definition: chan_ooh323.c:302
#define ast_channel_trylock(chan)
Definition: channel.h:2947
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
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
char name[256]
Definition: chan_ooh323.c:286
struct ast_format * ast_format_g729
Built-in cached g729 format.
Definition: format_cache.c:156
void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
Definition: chan_ooh323.c:1553
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
#define ast_mutex_destroy(a)
Definition: lock.h:186
#define H323_DTMF_INBAND
Definition: ooh323cDriver.h:30
struct ast_format * format
#define H323_DTMF_INBANDRELAX
Definition: ooh323cDriver.h:32
const char * ast_channel_macrocontext(const struct ast_channel *chan)
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:465
static int gDTMFMode
Definition: chan_ooh323.c:358
void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort)
Definition: chan_ooh323.c:4736
char caller_url[256]
Definition: chan_ooh323.c:220
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define RESULT_SUCCESS
Definition: cli.h:40
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
static int gT38Support
Definition: chan_ooh323.c:361
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:2151
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct OOH323Regex * rtpmask
Definition: chan_ooh323.c:243
char * h323id
Definition: chan_ooh323.c:299
static snd_pcm_format_t format
Definition: chan_alsa.c:102
struct ooh323_user * users
Definition: chan_ooh323.c:318
int ooh323_convert_hangupcause_h323ToAsterisk(int cause)
Definition: chan_ooh323.c:5206
struct ast_format * ast_format_h263
Built-in cached h263 format.
Definition: format_cache.c:171
#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:1192
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
unsigned int flags
Definition: chan_ooh323.c:210
#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:1228
char ip[4 *8+7+2]
Definition: chan_ooh323.c:297
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
int rtdrinterval
Definition: chan_ooh323.c:273
General jitterbuffer configuration.
Definition: abstract_jb.h:69
int ooh323c_set_capability_for_call(ooCallData *call, struct ast_format_cap *cap, int dtmf, int dtmfcodec, int t38support, int g729onlyA)
static struct ooh323_pvt * find_call(ooCallData *call)
Definition: chan_ooh323.c:810
#define FORMAT_STRING_SIZE
Definition: chan_ooh323.c:80
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
static struct ooh323_config ooconfig
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
static ast_mutex_t iflock
Definition: chan_ooh323.c:252
struct ast_rtp_instance * vrtp
Definition: chan_ooh323.c:189
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:518
int delete_peers()
Definition: chan_ooh323.c:4230
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:615
#define H323_DTMF_RFC2833
Definition: ooh323cDriver.h:26
Structure for mutex and tracking information.
Definition: lock.h:135
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844
#define AST_OPTION_T38_STATE
struct ast_sockaddr bindaddr
Definition: chan_ooh323.c:353
union ooh323_pvt::@7 neighbor
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578
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 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:331
unsigned int call_reference
Definition: chan_ooh323.c:211
int h245tunneling
Definition: chan_ooh323.c:246
short word
#define ast_mutex_unlock(a)
Definition: lock.h:188
int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format)
Definition: chan_ooh323.c:4506
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:966
static char gLogFile[PATH_MAX]
Definition: chan_ooh323.c:349
static char gAccountcode[80]
Definition: chan_ooh323.c:376
static struct test_val a
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
Stop sending a DTMF digit.
Definition: rtp_engine.c:2095
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443
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
#define H323_DISABLEGK
Definition: chan_ooh323.c:96