Asterisk - The Open Source Telephony Project  GIT-master-b7027de
chan_ooh323.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2005 by Objective Systems, Inc.
3  *
4  * This software is furnished under an open source license and may be
5  * used and copied only in accordance with the terms of this license.
6  * The text of the license may generally be found in the root
7  * directory of this installation in the COPYING file. It
8  * can also be viewed online at the following URL:
9  *
10  * http://www.obj-sys.com/open/license.html
11  *
12  * Any redistributions of this file including modified versions must
13  * maintain this copyright notice.
14  *
15  *****************************************************************************/
16 
17 /* Reworked version I, Nov-2009, by Alexandr Anikin, may@telecom-service.ru */
18 
19 
20 /*** MODULEINFO
21  <defaultenabled>no</defaultenabled>
22  <support_level>extended</support_level>
23  ***/
24 
25 /*** DOCUMENTATION
26 <info name="CHANNEL" language="en_US" tech="OOH323">
27  <enumlist>
28  <enum name="faxdetect">
29  <para>R/W Fax Detect</para>
30  <para>Returns 0 or 1</para>
31  <para>Write yes or no</para>
32  </enum>
33  <enum name="t38support">
34  <para>R/W t38support</para>
35  <para>Returns 0 or 1</para>
36  <para>Write yes or no</para>
37  </enum>
38  <enum name="h323id_url">
39  <para>R/0 Returns caller URL</para>
40  </enum>
41  <enum name="caller_h323id">
42  <para>R/0 Returns caller h323id</para>
43  </enum>
44  <enum name="caller_dialeddigits">
45  <para>R/0 Returns caller dialed digits</para>
46  </enum>
47  <enum name="caller_email">
48  <para>R/0 Returns caller email</para>
49  </enum>
50  <enum name="callee_email">
51  <para>R/0 Returns callee email</para>
52  </enum>
53  <enum name="callee_dialeddigits">
54  <para>R/0 Returns callee dialed digits</para>
55  </enum>
56  <enum name="caller_url">
57  <para>R/0 Returns caller URL</para>
58  </enum>
59  <enum name="max_forwards">
60  <para>R/W Get or set the maximum number of call forwards for this channel.
61 
62  This number describes the number of times a call may be forwarded by this channel
63  before the call fails. "Forwards" in this case refers to redirects by phones as well
64  as calls to local channels.
65 
66  Note that this has no relation to the SIP Max-Forwards header.
67  </para>
68  </enum>
69  </enumlist>
70 </info>
71  ***/
72 
73 #include "chan_ooh323.h"
74 #include <math.h>
75 
76 #ifndef IPTOS_MINCOST
77 #define IPTOS_MINCOST 0x02
78 #endif
79 
80 #define FORMAT_STRING_SIZE 512
81 
82 /* Defaults */
83 #define DEFAULT_CONTEXT "default"
84 #define DEFAULT_H323ID "Asterisk PBX"
85 #define DEFAULT_LOGFILE "h323_log"
86 #define DEFAULT_H323ACCNT "ast_h323"
87 
88 /* Flags */
89 #define H323_SILENCESUPPRESSION (1<<0)
90 #define H323_GKROUTED (1<<1)
91 #define H323_TUNNELING (1<<2)
92 #define H323_FASTSTART (1<<3)
93 #define H323_OUTGOING (1<<4)
94 #define H323_ALREADYGONE (1<<5)
95 #define H323_NEEDDESTROY (1<<6)
96 #define H323_DISABLEGK (1<<7)
97 #define H323_NEEDSTART (1<<8)
98 
99 #define MAXT30 240
100 #define T38TOAUDIOTIMEOUT 30
101 #define T38_DISABLED 0
102 #define T38_ENABLED 1
103 #define T38_FAXGW 1
104 
105 #define FAXDETECT_CNG 1
106 #define FAXDETECT_T38 2
107 
108 /* Channel description */
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.