Merge "app_stasis: Don't hang up if app is not registered"
[asterisk/asterisk.git] / addons / chan_ooh323.c
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 #include "chan_ooh323.h"
26 #include <math.h>
27
28 #define FORMAT_STRING_SIZE      512
29
30 /* Defaults */
31 #define DEFAULT_CONTEXT "default"
32 #define DEFAULT_H323ID "Asterisk PBX"
33 #define DEFAULT_LOGFILE "/var/log/asterisk/h323_log"
34 #define DEFAULT_H323ACCNT "ast_h323"
35
36 /* Flags */
37 #define H323_SILENCESUPPRESSION (1<<0)
38 #define H323_GKROUTED           (1<<1)
39 #define H323_TUNNELING          (1<<2)
40 #define H323_FASTSTART          (1<<3)
41 #define H323_OUTGOING           (1<<4)
42 #define H323_ALREADYGONE        (1<<5)
43 #define H323_NEEDDESTROY        (1<<6)
44 #define H323_DISABLEGK          (1<<7)
45 #define H323_NEEDSTART          (1<<8)
46
47 #define MAXT30  240
48 #define T38TOAUDIOTIMEOUT 30
49 #define T38_DISABLED 0
50 #define T38_ENABLED 1
51 #define T38_FAXGW 1
52
53 #define FAXDETECT_CNG   1
54 #define FAXDETECT_T38   2
55
56 /* Channel description */
57 static const char type[] = "OOH323";
58 static const char tdesc[] = "Objective Systems H323 Channel Driver";
59 static const char config[] = "ooh323.conf";
60
61 struct ast_module *myself;
62
63 static struct ast_jb_conf default_jbconf =
64 {
65         .flags = 0,
66         .max_size = -1,
67         .resync_threshold = -1,
68         .impl = ""
69 };
70 static struct ast_jb_conf global_jbconf;
71
72 /* Channel Definition */
73 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
74                         const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,  const char *data, int *cause);
75 static int ooh323_digit_begin(struct ast_channel *ast, char digit);
76 static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
77 static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout);
78 static int ooh323_hangup(struct ast_channel *ast);
79 static int ooh323_answer(struct ast_channel *ast);
80 static struct ast_frame *ooh323_read(struct ast_channel *ast);
81 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f);
82 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
83 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
84 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
85 static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
86 static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
87
88 static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
89 static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
90 static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, 
91           struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active);
92 static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result);
93 void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort);
94
95 struct ooh323_peer *find_friend(const char *name, int port);
96
97
98 static struct ast_channel_tech ooh323_tech = {
99         .type = type,
100         .description = tdesc,
101         .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
102         .requester = ooh323_request,
103         .send_digit_begin = ooh323_digit_begin,
104         .send_digit_end = ooh323_digit_end,
105         .call = ooh323_call,
106         .hangup = ooh323_hangup,
107         .answer = ooh323_answer,
108         .read = ooh323_read,
109         .write = ooh323_write,
110         .exception = ooh323_read,
111         .indicate = ooh323_indicate,
112         .fixup = ooh323_fixup,
113         .send_html = 0,
114         .queryoption = ooh323_queryoption,
115         .early_bridge = ast_rtp_instance_early_bridge,
116         .func_channel_read = function_ooh323_read,
117         .func_channel_write = function_ooh323_write,
118 };
119
120 static struct ast_rtp_glue ooh323_rtp = {
121         .type = type,
122         .get_rtp_info = ooh323_get_rtp_peer,
123         .get_vrtp_info = ooh323_get_vrtp_peer,
124         .update_peer = ooh323_set_rtp_peer,
125         .get_codec = ooh323_get_codec,
126 };
127
128
129 struct ooh323_user;
130
131 /* H.323 channel private structure */
132 static struct ooh323_pvt {
133         ast_mutex_t lock;               /* Channel private lock */
134         ast_cond_t rtpcond;             /* RTP condition */
135         struct ast_rtp_instance *rtp;
136         struct ast_sockaddr redirip;    /* redir ip */
137         struct ast_rtp_instance *vrtp; /* Placeholder for now */
138
139         int t38support;                 /* T.38 mode - disable, transparent, faxgw */
140         int faxdetect;
141         int faxdetected;
142         int rtptimeout;
143         struct ast_udptl *udptl;
144         int faxmode;
145         int t38_tx_enable;
146         int t38_init;
147         struct ast_sockaddr udptlredirip;
148         time_t lastTxT38;
149         int chmodepend;
150
151         struct ast_channel *owner;      /* Master Channel */
152         union {
153                 char  *user;    /* cooperating user/peer */
154                 char  *peer;
155         } neighbor;
156         time_t lastrtptx;
157         time_t lastrtprx;
158         unsigned int flags;
159         unsigned int call_reference;
160         char *callToken;
161         char *username;
162         char *host;
163         char *callerid_name;
164         char *callerid_num;
165         char caller_h323id[AST_MAX_EXTENSION];
166         char caller_dialedDigits[AST_MAX_EXTENSION];
167         char caller_email[AST_MAX_EXTENSION];
168         char caller_url[256];
169         char callee_h323id[AST_MAX_EXTENSION];
170         char callee_dialedDigits[AST_MAX_EXTENSION];
171         char callee_email[AST_MAX_EXTENSION];
172         char callee_url[AST_MAX_EXTENSION];
173  
174         int port;
175         struct ast_format *readformat;   /* negotiated read format */
176         struct ast_format *writeformat;  /* negotiated write format */
177         struct ast_format_cap *cap;
178         int dtmfmode;
179         int dtmfcodec;
180         char exten[AST_MAX_EXTENSION];  /* Requested extension */
181         char context[AST_MAX_EXTENSION];        /* Context where to start */
182         char accountcode[256];  /* Account code */
183         int nat;
184         int amaflags;
185         int progsent;                   /* progress is sent */
186         int alertsent;                  /* alerting is sent */
187         int directrtp;                  /* direct rtp */
188         int earlydirect;                /* early direct rtp */
189         int g729onlyA;                  /* G.729 only A */
190         struct ast_dsp *vad;
191         struct OOH323Regex *rtpmask;    /* rtp ip regexp */
192         char rtpmaskstr[120];
193         int rtdrcount, rtdrinterval;    /* roundtripdelayreq */
194         int faststart, h245tunneling;   /* faststart & h245 tunneling */
195         int aniasdni;                   /* use dialed number as answering identification */
196         struct ooh323_pvt *next;        /* Next entity */
197 } *iflist = NULL;
198
199 /* Protect the channel/interface list (ooh323_pvt) */
200 AST_MUTEX_DEFINE_STATIC(iflock);
201
202 /* Profile of H.323 user registered with PBX*/
203 struct ooh323_user{
204         ast_mutex_t lock;
205         char            name[256];
206         char            context[AST_MAX_EXTENSION];
207         int             incominglimit;
208         unsigned        inUse;
209         char            accountcode[20];
210         int             amaflags;
211         struct ast_format_cap *cap;
212         int             dtmfmode;
213         int             dtmfcodec;
214         int             faxdetect;
215         int             t38support;
216         int             rtptimeout;
217         int             mUseIP;        /* Use IP address or H323-ID to search user */
218         char            mIP[4*8+7+2];  /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
219         struct OOH323Regex *rtpmask;
220         char            rtpmaskstr[120];
221         int             rtdrcount, rtdrinterval;
222         int             nat;
223         int             faststart, h245tunneling;
224         int             directrtp;
225         int             earlydirect;
226         int             g729onlyA;
227         int             aniasdni;
228         struct ooh323_user *next;
229 };
230
231 /* Profile of valid asterisk peers */
232 struct ooh323_peer{
233         ast_mutex_t lock;
234         char        name[256];
235         unsigned    outgoinglimit;
236         unsigned    outUse;
237         struct ast_format_cap *cap;
238         char        accountcode[20];
239         int         amaflags;
240         int         dtmfmode;
241         int         dtmfcodec;
242         int         faxdetect;
243         int         t38support;
244         int         mFriend;    /* indicates defined as friend */
245         char        ip[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
246         int         port;
247         char        *h323id;    /* H323-ID alias, which asterisk will register with gk to reach this peer*/
248         char        *email;     /* Email alias, which asterisk will register with gk to reach this peer*/
249         char        *url;       /* url alias, which asterisk will register with gk to reach this peer*/
250         char        *e164;      /* e164 alias, which asterisk will register with gk to reach this peer*/
251         int         rtptimeout;
252         struct OOH323Regex          *rtpmask;
253         char        rtpmaskstr[120];
254         int         rtdrcount,rtdrinterval;
255         int         nat;
256         int         faststart, h245tunneling;
257         int         directrtp;
258         int         earlydirect;
259         int         g729onlyA;
260         struct ooh323_peer *next;
261 };
262
263
264 /* List of H.323 users known to PBX */
265 static struct ast_user_list {
266         struct ooh323_user *users;
267         ast_mutex_t lock;
268 } userl;
269
270 static struct ast_peer_list {
271         struct ooh323_peer *peers;
272         ast_mutex_t lock;
273 } peerl;
274
275 /* Mutex to protect H.323 reload process */
276 static int h323_reloading = 0;
277 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
278
279 /* Mutex to protect usage counter */
280 static int usecnt = 0;
281 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
282
283 static long callnumber = 0;
284 AST_MUTEX_DEFINE_STATIC(ooh323c_cn_lock);
285
286 /* stack callbacks */
287 int onAlerting(ooCallData *call);
288 int onProgress(ooCallData *call);
289 int onNewCallCreated(ooCallData *call);
290 int onOutgoingCall(ooCallData *call);
291 int onCallEstablished(ooCallData *call);
292 int onCallCleared(ooCallData *call);
293 void onModeChanged(ooCallData *call, int t38mode);
294
295 extern OOH323EndPoint gH323ep;
296
297 static char gLogFile[256] = DEFAULT_LOGFILE;
298 static int  gPort = 1720;
299 static char gIP[2+8*4+7];       /* Max for IPv6 addr */
300 struct ast_sockaddr bindaddr;
301 int v6mode = 0;
302 static char gCallerID[AST_MAX_EXTENSION] = "";
303 static struct ooAliases *gAliasList;
304 static struct ast_format_cap *gCap;
305 static int  gDTMFMode = H323_DTMF_RFC2833;
306 static int  gDTMFCodec = 101;
307 static int  gFAXdetect = FAXDETECT_CNG;
308 static int  gT38Support = T38_FAXGW;
309 static char gGatekeeper[100];
310 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
311
312 static int  gIsGateway = 0;
313 static int  gFastStart = 1;
314 static int  gTunneling = 1;
315 static int  gBeMaster = 0;
316 static int  gMediaWaitForConnect = 0;
317 static int  gDirectRTP = 0;
318 static int  gEarlyDirect = 0;
319 static int  gTOS = 0;
320 static int  gRTPTimeout = 60;
321 static int  g729onlyA = 0;
322 static char gAccountcode[80] = DEFAULT_H323ACCNT;
323 static int  gAMAFLAGS;
324 static char gContext[AST_MAX_EXTENSION] = DEFAULT_CONTEXT;
325 static int  gIncomingLimit = 1024;
326 static int  gOutgoingLimit = 1024;
327 OOBOOL gH323Debug = FALSE;
328 static int gTRCLVL = OOTRCLVLERR;
329 static int gRTDRCount = 0, gRTDRInterval = 0;
330 static int gNat = FALSE;
331 static int gANIasDNI = 0;
332
333 static int t35countrycode = 0;
334 static int t35extensions = 0;
335 static int manufacturer = 0;
336 static char vendor[AST_MAX_EXTENSION] =  "";
337 static char version[AST_MAX_EXTENSION] = "";
338
339 static struct ooh323_config
340 {
341    int  mTCPPortStart;
342    int  mTCPPortEnd;
343 } ooconfig;
344
345 /** Asterisk RTP stuff*/
346 static struct ast_sched_context *sched;
347 static struct io_context *io;
348
349 /* Protect the monitoring thread, so only one process can kill or start it, 
350    and not when it's doing something critical. */
351 AST_MUTEX_DEFINE_STATIC(monlock);
352
353
354 /* This is the thread for the monitor which checks for input on the channels
355    which are not currently in use.  */
356 static pthread_t monitor_thread = AST_PTHREADT_NULL;
357
358
359 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
360                                              const char *host, struct ast_format_cap *cap, 
361                                                                                          const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
362 {
363         struct ast_format_cap *caps = NULL;
364         struct ast_channel *ch = NULL;
365         struct ast_format *tmpfmt = NULL;
366         int features = 0;
367
368         if (gH323Debug) {
369                 ast_verb(0, "---   ooh323_new - %s\n", host);
370         }
371
372         caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
373
374         /* Don't hold a h323 pvt lock while we allocate a channel */
375         ast_mutex_unlock(&i->lock);
376         ast_mutex_lock(&ooh323c_cn_lock);
377         ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name, 
378                                 i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags,
379                                 "OOH323/%s-%ld", host, callnumber);
380         callnumber++;
381         ast_mutex_unlock(&ooh323c_cn_lock);
382    
383         ast_mutex_lock(&i->lock);
384
385         if (ch && caps) {
386                 ast_channel_tech_set(ch, &ooh323_tech);
387
388                 if (cap) {
389                         tmpfmt = ast_format_cap_get_format(cap, 0);
390                 }
391                 if (!tmpfmt) {
392                         tmpfmt = ast_format_cap_get_format(i->cap, 0);
393                 }
394
395                 ast_format_cap_append(caps, tmpfmt, 0);
396                 ast_channel_nativeformats_set(ch, caps);
397                 ao2_ref(caps, -1);
398
399                 ast_channel_set_rawwriteformat(ch, tmpfmt);
400                 ast_channel_set_rawreadformat(ch, tmpfmt);
401                 ast_set_write_format(ch, tmpfmt);
402                 ast_set_read_format(ch, tmpfmt);
403                 ao2_ref(tmpfmt, -1);
404
405                 ast_jb_configure(ch, &global_jbconf);
406
407                 if (state == AST_STATE_RING)
408                         ast_channel_rings_set(ch, 1);
409
410                 ast_channel_adsicpe_set(ch, AST_ADSI_UNAVAILABLE);
411                 ast_channel_tech_pvt_set(ch, i);
412                 i->owner = ch;
413                 ast_module_ref(myself);
414
415                 /* Allocate dsp for in-band DTMF support */
416                 if ((i->dtmfmode & H323_DTMF_INBAND) || (i->faxdetect & FAXDETECT_CNG)) {
417                         i->vad = ast_dsp_new();
418                 }
419
420                 /* inband DTMF*/
421                 if (i->dtmfmode & H323_DTMF_INBAND) {
422                         features |= DSP_FEATURE_DIGIT_DETECT;
423                         if (i->dtmfmode & H323_DTMF_INBANDRELAX) {
424                                 ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
425                         }
426                 }
427
428                 /* fax detection*/
429                 if (i->faxdetect & FAXDETECT_CNG) {
430                         features |= DSP_FEATURE_FAX_DETECT;
431                         ast_dsp_set_faxmode(i->vad,
432                                         DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
433                 }
434
435                 if (features) {
436                         ast_dsp_set_features(i->vad, features);
437                 }
438
439                 ast_mutex_lock(&usecnt_lock);
440                 usecnt++;
441                 ast_mutex_unlock(&usecnt_lock);
442
443                 /* Notify the module monitors that use count for resource has changed*/
444                 ast_update_use_count();
445
446                 ast_channel_context_set(ch, i->context);
447                 ast_channel_exten_set(ch, i->exten);
448
449                 ast_channel_priority_set(ch, 1);
450
451                 if(!ast_test_flag(i, H323_OUTGOING)) {
452                 
453                         if (!ast_strlen_zero(i->caller_h323id)) {
454                                 pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
455
456                         }
457                         if (!ast_strlen_zero(i->caller_dialedDigits)) {
458                                 pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS", 
459                                 i->caller_dialedDigits);
460                         }
461                         if (!ast_strlen_zero(i->caller_email)) {
462                                 pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL", 
463                                 i->caller_email);
464                         }
465                         if (!ast_strlen_zero(i->caller_url)) {
466                                 pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url);
467                         }
468                 }
469
470                 if (!ast_strlen_zero(i->accountcode))
471                         ast_channel_accountcode_set(ch, i->accountcode);
472                 
473                 if (i->amaflags)
474                         ast_channel_amaflags_set(ch, i->amaflags);
475
476                 ast_setstate(ch, state);
477                 if (state != AST_STATE_DOWN) {
478                         if (ast_pbx_start(ch)) {
479                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));
480                                 ast_channel_unlock(ch);
481                                 ast_hangup(ch);
482                                 ch = NULL;
483                         } 
484                 }
485
486                 if (ch) {
487                         ast_publish_channel_state(ch);
488
489                 }
490         } else {
491                 ao2_cleanup(caps);
492                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
493         }
494
495
496         if(ch)   ast_channel_unlock(ch);
497
498         if (gH323Debug) {
499                 ast_verb(0, "+++   h323_new\n");
500         }
501
502         return ch;
503 }
504
505
506
507 static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken) 
508 {
509         struct ooh323_pvt *pvt = NULL;
510
511         if (gH323Debug) {
512                 ast_verb(0, "---   ooh323_alloc\n");
513         }
514
515         if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
516                 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
517                 return NULL;
518         }
519         if (!(pvt->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
520                 ast_free(pvt);
521                 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
522                 return NULL;
523         }
524
525         ast_mutex_init(&pvt->lock);
526         ast_mutex_lock(&pvt->lock);
527
528         pvt->faxmode = 0;
529         pvt->chmodepend = 0;
530         pvt->faxdetected = 0;
531         pvt->faxdetect = gFAXdetect;
532         pvt->t38support = gT38Support;
533         pvt->rtptimeout = gRTPTimeout;
534         pvt->nat = gNat;
535         pvt->rtdrinterval = gRTDRInterval;
536         pvt->rtdrcount = gRTDRCount;
537         pvt->g729onlyA = g729onlyA;
538
539         pvt->call_reference = callref;
540         if (callToken)
541                 pvt->callToken = ast_strdup(callToken);
542
543         /* whether to use gk for this call */
544         if (gRasGkMode == RasNoGatekeeper)
545                 OO_SETFLAG(pvt->flags, H323_DISABLEGK);
546
547         pvt->dtmfmode = gDTMFMode;
548         pvt->dtmfcodec = gDTMFCodec;
549         ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
550         ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
551
552         pvt->amaflags = gAMAFLAGS;
553         ast_format_cap_append_from_cap(pvt->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
554
555         pvt->aniasdni = gANIasDNI;
556
557         ast_mutex_unlock(&pvt->lock); 
558         /* Add to interface list */
559         ast_mutex_lock(&iflock);
560         pvt->next = iflist;
561         iflist = pvt;
562         ast_mutex_unlock(&iflock);
563
564         if (gH323Debug) {
565                 ast_verb(0, "+++   ooh323_alloc\n");
566         }
567
568         return pvt;
569 }
570
571
572 /*
573         Possible data values - peername, exten/peername, exten@ip
574  */
575 static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
576                 const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
577
578 {
579         struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
580         struct ast_channel *chan = NULL;
581         struct ooh323_pvt *p = NULL;
582         struct ooh323_peer *peer = NULL;
583         char *dest = NULL; 
584         char *ext = NULL;
585         char tmp[256];
586         int port = 0;
587
588         if (gH323Debug) {
589                 ast_verb(0, "---   ooh323_request - data %s format %s\n", data, ast_format_cap_get_names(cap, &codec_buf));
590         }
591
592         if (!(ast_format_cap_has_type(cap, AST_MEDIA_TYPE_AUDIO))) {
593                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
594                 return NULL;
595         }
596
597         p = ooh323_alloc(0,0); /* Initial callRef is zero */
598
599         if (!p) {
600                 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", data);
601                 return NULL;
602         }
603         ast_mutex_lock(&p->lock);
604
605         /* This is an outgoing call, since ooh323_request is called */
606         ast_set_flag(p, H323_OUTGOING);
607
608
609         ast_copy_string(tmp, data, sizeof(tmp));
610
611         dest = strchr(tmp, '/');
612
613         if (dest) {  
614                 *dest = '\0';
615                 dest++;
616                 ext = dest;
617                 dest = tmp;
618         } else if ((dest = strchr(tmp, '@'))) {
619                 *dest = '\0';
620                 dest++;
621                 ext = tmp;
622         } else {
623                 dest = tmp;
624                 ext = NULL;
625         }
626
627 #if 0
628         if ((sport = strchr(dest, ':'))) {
629                 *sport = '\0';
630                 sport++;
631                 port = atoi(sport);
632         }
633 #endif
634
635         if (dest) {
636                 peer = find_peer(dest, port);
637         } else{
638                 ast_mutex_lock(&iflock);
639                 ast_mutex_unlock(&p->lock);
640                 ooh323_destroy(p);
641                 ast_mutex_unlock(&iflock);
642                 ast_log(LOG_ERROR, "Destination format is not supported\n");
643                 *cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
644                 return NULL;
645         }
646
647         if (peer) {
648                 p->username = ast_strdup(peer->name);
649                 p->host = ast_strdup(peer->ip);
650                 p->port = peer->port;
651                 /* Disable gk as we are going to call a known peer*/
652                 /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
653
654                 if (ext)
655                         ast_copy_string(p->exten, ext, sizeof(p->exten));
656
657                 ast_format_cap_append_from_cap(p->cap, peer->cap, AST_MEDIA_TYPE_UNKNOWN);
658                 p->g729onlyA = peer->g729onlyA;
659                 p->dtmfmode |= peer->dtmfmode;
660                 p->dtmfcodec  = peer->dtmfcodec;
661                 p->faxdetect = peer->faxdetect;
662                 p->t38support = peer->t38support;
663                 p->rtptimeout = peer->rtptimeout;
664                 p->nat = peer->nat;
665                 p->faststart = peer->faststart;
666                 p->h245tunneling = peer->h245tunneling;
667                 p->directrtp = peer->directrtp;
668                 p->earlydirect = peer->earlydirect;
669                 if (peer->rtpmask && peer->rtpmaskstr[0]) {
670                         p->rtpmask = peer->rtpmask;
671                         ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
672                 }
673
674                 if (peer->rtdrinterval) {
675                         p->rtdrinterval = peer->rtdrinterval;
676                         p->rtdrcount = peer->rtdrcount;
677                 }
678
679                 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
680                 p->amaflags = peer->amaflags;
681         } else {
682                 if (gRasGkMode ==  RasNoGatekeeper) {
683                         /* no gk and no peer */
684                         ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
685                         ast_mutex_lock(&iflock);
686                         ast_mutex_unlock(&p->lock);
687                         ooh323_destroy(p);
688                         ast_mutex_unlock(&iflock);
689                         return NULL;
690                 } else if (!gH323ep.gkClient || (gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered)) {
691                         ast_log(LOG_ERROR, "Gatekeeper client is configured but not registered\n");
692                         *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
693                         return NULL;
694                 }
695                 p->g729onlyA = g729onlyA;
696                 p->dtmfmode = gDTMFMode;
697                 p->dtmfcodec = gDTMFCodec;
698                 p->faxdetect = gFAXdetect;
699                 p->t38support = gT38Support;
700                 p->rtptimeout = gRTPTimeout;
701                 p->nat = gNat;
702                 ast_format_cap_append_from_cap(p->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
703                 p->rtdrinterval = gRTDRInterval;
704                 p->rtdrcount = gRTDRCount;
705                 p->faststart = gFastStart;
706                 p->h245tunneling = gTunneling;
707                 p->directrtp = gDirectRTP;
708                 p->earlydirect = gEarlyDirect;
709
710                 p->username = ast_strdup(dest);
711
712                 p->host = ast_strdup(dest);
713                 if (port > 0) {
714                         p->port = port;
715                 }
716                 if (ext) {
717                         ast_copy_string(p->exten, ext, sizeof(p->exten));
718                 }
719         }
720
721
722         chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
723                                  assignedids, requestor);
724         
725         ast_mutex_unlock(&p->lock);
726
727         if (!chan) {
728                 ast_mutex_lock(&iflock);
729                 ooh323_destroy(p);
730                 ast_mutex_unlock(&iflock);
731         } else {
732                 ast_mutex_lock(&p->lock);
733                 p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
734                 if(!p->callToken) {
735                         ast_mutex_unlock(&p->lock);
736                         ast_mutex_lock(&iflock);
737                         ooh323_destroy(p);
738                         ast_mutex_unlock(&iflock);
739                         ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
740                         return NULL;
741                 }
742
743                 ast_cond_init(&p->rtpcond, NULL);
744                 ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
745                 if (!p->rtp) {
746                         ast_cond_wait(&p->rtpcond, &p->lock);
747                 }
748                 ast_mutex_unlock(&p->lock);
749                 ast_cond_destroy(&p->rtpcond);
750         }
751
752         restart_monitor();
753         if (gH323Debug)
754                 ast_verb(0, "+++   ooh323_request\n");
755
756         return chan;
757
758 }
759
760
761 static struct ooh323_pvt* find_call(ooCallData *call)
762 {
763         struct ooh323_pvt *p;
764
765         if (gH323Debug)
766                 ast_verb(0, "---   find_call\n");
767
768         ast_mutex_lock(&iflock);
769
770         for (p = iflist; p; p = p->next) {
771                 if (p->callToken && !strcmp(p->callToken, call->callToken)) {
772                         break;
773                 }
774         }
775         ast_mutex_unlock(&iflock);
776
777         if (gH323Debug)
778                 ast_verb(0, "+++   find_call\n");
779
780         return p;
781 }
782
783 struct ooh323_user *find_user(const char * name, const char* ip)
784 {
785         struct ooh323_user *user;
786
787         if (gH323Debug)
788       ast_verb(0, "---   find_user: %s, %s\n",name,ip);
789
790         ast_mutex_lock(&userl.lock);
791
792         for (user = userl.users; user; user = user->next) {
793                 if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
794                         break;
795                 }
796                 if (name && !strcmp(user->name, name)) {
797                         break;
798                 }
799         }
800
801         ast_mutex_unlock(&userl.lock);
802
803         if (gH323Debug)
804                 ast_verb(0, "+++   find_user\n");
805
806         return user;
807 }
808
809 struct ooh323_peer *find_friend(const char *name, int port)
810 {
811         struct ooh323_peer *peer;  
812
813         if (gH323Debug)
814                 ast_verb(0, "---   find_friend \"%s\"\n", name);
815
816
817         ast_mutex_lock(&peerl.lock);
818         for (peer = peerl.peers; peer; peer = peer->next) {
819                 if (gH323Debug) {
820                         ast_verb(0, "           comparing with \"%s\"\n", peer->ip);
821                 }
822                 if (!strcmp(peer->ip, name)) {
823                         if (port <= 0 || (port > 0 && peer->port == port)) {
824                                 break;
825                         }
826                 }
827         }
828         ast_mutex_unlock(&peerl.lock);
829
830         if (gH323Debug) {
831                 if (peer) {
832                         ast_verb(0, "           found matching friend\n");
833                 }
834                 ast_verb(0, "+++   find_friend \"%s\"\n", name);
835         }
836
837         return peer;            
838 }
839
840
841 struct ooh323_peer *find_peer(const char * name, int port)
842 {
843         struct ooh323_peer *peer;
844
845         if (gH323Debug)
846                 ast_verb(0, "---   find_peer \"%s\"\n", name);
847
848
849         ast_mutex_lock(&peerl.lock);
850         for (peer = peerl.peers; peer; peer = peer->next) {
851                 if (gH323Debug) {
852                         ast_verb(0, "           comparing with \"%s\"\n", peer->ip);
853                 }
854                 if (!strcasecmp(peer->name, name))
855                         break;
856                 if (peer->h323id && !strcasecmp(peer->h323id, name))
857                         break;
858                 if (peer->e164 && !strcasecmp(peer->e164, name))
859                         break;
860                 /*
861                 if (!strcmp(peer->ip, name)) {
862                         if (port > 0 && peer->port == port) { break; }
863                         else if (port <= 0) { break; }
864                 }
865                 */
866         }
867         ast_mutex_unlock(&peerl.lock);
868
869         if (gH323Debug) {
870                 if (peer) {
871                         ast_verb(0, "           found matching peer\n");
872                 }
873                 ast_verb(0, "+++   find_peer \"%s\"\n", name);
874         }
875
876         return peer;            
877 }
878
879 static int ooh323_digit_begin(struct ast_channel *chan, char digit)
880 {
881         char dtmf[2];
882         struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
883         int res = 0;
884         
885         if (gH323Debug)
886                 ast_verb(0, "---   ooh323_digit_begin\n");
887
888         if (!p) {
889                 ast_log(LOG_ERROR, "No private structure for call\n");
890                 return -1;
891         }
892         ast_mutex_lock(&p->lock);
893
894         if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
895                 ast_rtp_instance_dtmf_begin(p->rtp, digit);
896         } else if (((p->dtmfmode & H323_DTMF_Q931) ||
897                                                  (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
898                                                  (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
899                 dtmf[0] = digit;
900                 dtmf[1] = '\0';
901                 ooSendDTMFDigit(p->callToken, dtmf);
902         } else if (p->dtmfmode & H323_DTMF_INBAND) {
903                 res = -1; // tell Asterisk to generate inband indications
904         }
905         ast_mutex_unlock(&p->lock);
906
907         if (gH323Debug) {
908                 ast_verb(0, "+++   ooh323_digit_begin, res = %d\n", res);
909         }
910         return res;
911 }
912
913 static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
914 {
915         struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
916         int res = 0;
917
918         if (gH323Debug)
919                 ast_verb(0, "---   ooh323_digit_end\n");
920
921         if (!p) {
922                 ast_log(LOG_ERROR, "No private structure for call\n");
923                 return -1;
924         }
925         ast_mutex_lock(&p->lock);
926         if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) {
927                 ast_rtp_instance_dtmf_end(p->rtp, digit);
928         } else if(p->dtmfmode & H323_DTMF_INBAND) {
929                 res = -1; // tell Asterisk to stop inband indications
930         }
931
932         ast_mutex_unlock(&p->lock);
933
934         if (gH323Debug) {
935                 ast_verb(0, "+++   ooh323_digit_end, res = %d\n", res);
936         }
937         return res;
938 }
939
940
941 static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout)
942 {
943         struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
944         char destination[256];
945         int res=0, i;
946         const char *val = NULL;
947         ooCallOptions opts = {
948                 .fastStart = TRUE,
949                 .tunneling = TRUE,
950                 .disableGk = TRUE,
951                 .callMode = OO_CALLMODE_AUDIOCALL,
952                 .transfercap = 0
953         };
954
955         if (gH323Debug)
956                 ast_verb(0, "---   ooh323_call- %s\n", dest);
957
958
959         if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
960                 ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
961                                                                 "reserved\n", ast_channel_name(ast));
962                 return -1;
963         }
964         ast_mutex_lock(&p->lock);
965         ast_set_flag(p, H323_OUTGOING);
966         if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
967                 ast_free(p->callerid_num);
968                 p->callerid_num = ast_strdup(ast_channel_connected(ast)->id.number.str);
969         }
970
971         if (ast_channel_connected(ast)->id.name.valid && ast_channel_connected(ast)->id.name.str) {
972                 ast_free(p->callerid_name);
973                 p->callerid_name = ast_strdup(ast_channel_connected(ast)->id.name.str);
974         } else if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
975                 ast_free(p->callerid_name);
976                 p->callerid_name = ast_strdup(ast_channel_connected(ast)->id.number.str);
977         } else {
978                 ast_channel_connected(ast)->id.name.valid = 1;
979                 ast_free(ast_channel_connected(ast)->id.name.str);
980                 ast_channel_connected(ast)->id.name.str = ast_strdup(gCallerID);
981                 ast_free(p->callerid_name);
982                 p->callerid_name = ast_strdup(ast_channel_connected(ast)->id.name.str);
983         }
984
985         /* Retrieve vars */
986
987
988         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
989                 ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
990         }
991         
992         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
993                 ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
994                 if(!p->callerid_num)
995                         p->callerid_num = ast_strdup(val);
996         }
997
998         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
999                 ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
1000         }
1001
1002         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
1003                 ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
1004         }
1005
1006         if (p->host && p->port != 0)
1007                 snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
1008         else if (p->host)
1009                 snprintf(destination, sizeof(destination), "%s", p->host);
1010         else
1011                 ast_copy_string(destination, dest, sizeof(destination));
1012
1013         destination[sizeof(destination)-1]='\0';
1014
1015         opts.transfercap = ast_channel_transfercapability(ast);
1016         opts.fastStart = p->faststart;
1017         opts.tunneling = p->h245tunneling;
1018
1019         for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
1020
1021         if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
1022                 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
1023         } else {
1024                 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
1025         }
1026
1027         ast_mutex_unlock(&p->lock);
1028         if (res != OO_OK) {
1029                 ast_log(LOG_ERROR, "Failed to make call\n");
1030                 return -1; /* ToDO: cleanup */
1031         }
1032         if (gH323Debug)
1033                 ast_verb(0, "+++   ooh323_call\n");
1034
1035   return 0;
1036 }
1037
1038 static int ooh323_hangup(struct ast_channel *ast)
1039 {
1040         struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1041         int q931cause = AST_CAUSE_NORMAL_CLEARING;
1042
1043         if (gH323Debug)
1044                 ast_verb(0, "---   ooh323_hangup\n");
1045
1046         if (p) {
1047                 ast_mutex_lock(&p->lock);
1048
1049         if (ast_channel_hangupcause(ast)) {
1050                 q931cause = ast_channel_hangupcause(ast);
1051         } else {
1052                 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
1053                 if (cause) {
1054                         if (!strcmp(cause, "CONGESTION")) {
1055                                 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1056                         } else if (!strcmp(cause, "BUSY")) {
1057                                 q931cause = AST_CAUSE_USER_BUSY;
1058                         } else if (!strcmp(cause, "CHANISUNVAIL")) {
1059                                 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1060                         } else if (!strcmp(cause, "NOANSWER")) {
1061                                 q931cause = AST_CAUSE_NO_ANSWER;
1062                         } else if (!strcmp(cause, "CANCEL")) {
1063                                 q931cause = AST_CAUSE_CALL_REJECTED;
1064                         }
1065                 }
1066         }
1067
1068
1069
1070                 if (gH323Debug)
1071                         ast_verb(0, "    hanging %s with cause: %d\n", p->username, q931cause);
1072                 ast_channel_tech_pvt_set(ast, NULL); 
1073                 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1074                         ooHangCall(p->callToken, 
1075                                 ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
1076                         ast_set_flag(p, H323_ALREADYGONE);
1077                         /* ast_mutex_unlock(&p->lock); */
1078                 } else 
1079                         ast_set_flag(p, H323_NEEDDESTROY);
1080                 /* detach channel here */
1081                 if (p->owner) {
1082                         ast_channel_tech_pvt_set(p->owner, NULL);
1083                         p->owner = NULL;
1084                         ast_module_unref(myself);
1085                 }
1086
1087                 ast_mutex_unlock(&p->lock);
1088                 ast_mutex_lock(&usecnt_lock);
1089                 usecnt--;
1090                 ast_mutex_unlock(&usecnt_lock);
1091
1092                 /* Notify the module monitors that use count for resource has changed */
1093                 ast_update_use_count();
1094           
1095         } else {
1096                 ast_debug(1, "No call to hangup\n" );
1097         }
1098         
1099         if (gH323Debug)
1100                 ast_verb(0, "+++   ooh323_hangup\n");
1101
1102   return 0;
1103 }
1104
1105 static int ooh323_answer(struct ast_channel *ast)
1106 {
1107         struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1108         char *callToken = (char *)NULL;
1109
1110         if (gH323Debug)
1111                 ast_verb(0, "--- ooh323_answer\n");
1112
1113         if (p) {
1114
1115                 ast_mutex_lock(&p->lock);
1116                 callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
1117                 if (ast_channel_state(ast) != AST_STATE_UP) {
1118                         ast_channel_lock(ast);
1119                         if (!p->alertsent) {
1120                                 if (gH323Debug) {
1121                                         ast_debug(1, "Sending forced ringback for %s, res = %u\n", 
1122                                                 callToken, ooManualRingback(callToken));
1123                                 } else {
1124                                         ooManualRingback(callToken);
1125                                 }
1126                                 p->alertsent = 1;
1127                         }
1128                         ast_setstate(ast, AST_STATE_UP);
1129                         if (option_debug)
1130                                 ast_debug(1, "ooh323_answer(%s)\n", ast_channel_name(ast));
1131                         ast_channel_unlock(ast);
1132                         ooAnswerCall(p->callToken);
1133                 }
1134                 if (callToken) {
1135                         ast_free(callToken);
1136                 }
1137                 ast_mutex_unlock(&p->lock);
1138         }
1139
1140         if (gH323Debug)
1141                 ast_verb(0, "+++ ooh323_answer\n");
1142
1143   return 0;
1144 }
1145
1146 static struct ast_frame *ooh323_read(struct ast_channel *ast)
1147 {
1148         struct ast_frame *fr;
1149         static struct ast_frame null_frame = { AST_FRAME_NULL, };
1150         struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1151
1152         if (!p) return &null_frame;
1153
1154         ast_mutex_lock(&p->lock);
1155         if (p->rtp)
1156                 fr = ooh323_rtp_read(ast, p);
1157         else
1158                 fr = &null_frame;
1159         /* time(&p->lastrtprx); */
1160         ast_mutex_unlock(&p->lock);
1161         return fr;
1162 }
1163
1164 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
1165 {
1166         struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
1167         int res = 0;
1168
1169         if (p) {
1170                 ast_mutex_lock(&p->lock);
1171
1172                 p->lastrtptx = time(NULL);
1173
1174                 if (f->frametype == AST_FRAME_MODEM) {
1175                         ast_debug(1, "Send UDPTL %u/%d len %d for %s\n",
1176                                 f->frametype, f->subclass.integer, f->datalen, ast_channel_name(ast));
1177                         if (p->udptl)
1178                                 res = ast_udptl_write(p->udptl, f);
1179                         ast_mutex_unlock(&p->lock);
1180                         return res;
1181                 }
1182
1183         
1184                 if (f->frametype == AST_FRAME_VOICE) {
1185 /* sending progress for first */
1186                         if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
1187                                         p->callToken) {
1188                                 ooManualProgress(p->callToken);
1189                                 p->progsent = 1;
1190                         }
1191
1192
1193                         if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
1194                                 if (ast_format_cap_count(ast_channel_nativeformats(ast))) {
1195                                         struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1196                                         ast_log(LOG_WARNING,
1197                                                         "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1198                                                         ast_format_get_name(f->subclass.format),
1199                                                         ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf),
1200                                                         ast_format_get_name(ast_channel_readformat(ast)),
1201                                                         ast_format_get_name(ast_channel_writeformat(ast)));
1202
1203                                         ast_set_write_format(ast, f->subclass.format);
1204                                 } else {
1205                                         /* ast_set_write_format(ast, f->subclass);
1206                                         ast->nativeformats = f->subclass; */
1207                                 }
1208                         ast_mutex_unlock(&p->lock);
1209                         return 0;
1210                         }
1211
1212                 if (p->rtp)
1213                         res = ast_rtp_instance_write(p->rtp, f);
1214
1215                 ast_mutex_unlock(&p->lock);
1216
1217                 } else if (f->frametype == AST_FRAME_IMAGE) {
1218                         ast_mutex_unlock(&p->lock);
1219                         return 0;
1220                 } else {
1221                         ast_log(LOG_WARNING, "Can't send %u type frames with OOH323 write\n", 
1222                                                                          f->frametype);
1223                         ast_mutex_unlock(&p->lock);
1224                         return 0;
1225                 }
1226
1227         }
1228
1229         return res;
1230 }
1231
1232 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1233 {
1234
1235         struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
1236         char *callToken = (char *)NULL;
1237         int res = -1;
1238
1239         if (!p) return -1;
1240
1241         ast_mutex_lock(&p->lock);
1242         callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
1243         ast_mutex_unlock(&p->lock);
1244
1245         if (!callToken) {
1246                 if (gH323Debug)
1247                         ast_verb(0, "   ooh323_indicate - No callToken\n");
1248                 return -1;
1249         }
1250
1251         if (!ast_sockaddr_isnull(&p->redirip)) {
1252                 res = 0;
1253         }
1254
1255         if (gH323Debug) {
1256                 ast_verb(0, "----- ooh323_indicate %d on call %s\n", condition, callToken);
1257         }
1258          
1259         ast_mutex_lock(&p->lock);
1260         switch (condition) {
1261         case AST_CONTROL_INCOMPLETE:
1262                 /* While h323 does support overlapped dialing, this channel driver does not
1263                  * at this time.  Treat a response of Incomplete as if it were congestion.
1264                  */
1265         case AST_CONTROL_CONGESTION:
1266                 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1267                         ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
1268                 }
1269                 break;
1270         case AST_CONTROL_BUSY:
1271                 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1272                         ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
1273                 }
1274                 break;
1275         case AST_CONTROL_HOLD:
1276                 ast_moh_start(ast, data, NULL);
1277                 break;
1278         case AST_CONTROL_UNHOLD:
1279                 ast_moh_stop(ast);
1280                 break;
1281         case AST_CONTROL_PROGRESS:
1282                 if (ast_channel_state(ast) != AST_STATE_UP) {
1283                         if (!p->progsent) {
1284                                 if (gH323Debug) {
1285                                         ast_debug(1, "Sending manual progress for %s, res = %u\n", callToken,
1286                                         ooManualProgress(callToken));   
1287                                 } else {
1288                                         ooManualProgress(callToken);
1289                                 }
1290                                 p->progsent = 1;
1291                         }
1292                 }
1293             break;
1294       case AST_CONTROL_RINGING:
1295                 if (ast_channel_state(ast) == AST_STATE_RING || ast_channel_state(ast) == AST_STATE_RINGING) {
1296                         if (!p->alertsent) {
1297                                 if (gH323Debug) {
1298                                         ast_debug(1, "Sending manual ringback for %s, res = %u\n",
1299                                                 callToken,
1300                                                 ooManualRingback(callToken));
1301                                 } else {
1302                                         ooManualRingback(callToken);
1303                                 }
1304                                 p->alertsent = 1;
1305                         }
1306                         p->alertsent = 1;
1307                 }
1308          break;
1309         case AST_CONTROL_SRCUPDATE:
1310                 if (p->rtp) {
1311                         ast_rtp_instance_update_source(p->rtp);
1312                 }
1313                 break;
1314         case AST_CONTROL_SRCCHANGE:
1315                 if (p->rtp) {
1316                         ast_rtp_instance_change_source(p->rtp);
1317                 }
1318                 break;
1319         case AST_CONTROL_CONNECTED_LINE:
1320                 if (!ast_channel_connected(ast)->id.name.valid
1321                         || ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
1322                         break;
1323                 }
1324                 if (gH323Debug) {
1325                         ast_debug(1, "Sending connected line info for %s (%s)\n",
1326                                 callToken, ast_channel_connected(ast)->id.name.str);
1327                 }
1328                 ooSetANI(callToken, ast_channel_connected(ast)->id.name.str);
1329                 break;
1330
1331       case AST_CONTROL_T38_PARAMETERS:
1332                 if (p->t38support != T38_ENABLED) {
1333                         struct ast_control_t38_parameters parameters = { .request_response = 0 };
1334                         parameters.request_response = AST_T38_REFUSED;
1335                         ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
1336                                                  &parameters, sizeof(parameters));
1337                         break;
1338                 }
1339                 if (datalen != sizeof(struct ast_control_t38_parameters)) {
1340                         ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
1341                                            "Expected %d, got %d\n",
1342                                 (int)sizeof(enum ast_control_t38), (int)datalen);
1343                 } else {
1344                         const struct ast_control_t38_parameters *parameters = data;
1345                         struct ast_control_t38_parameters our_parameters;
1346                         enum ast_control_t38 message = parameters->request_response;
1347                         switch (message) {
1348
1349                         case AST_T38_NEGOTIATED:
1350                                 if (p->faxmode) {
1351                                         res = 0;
1352                                         break;
1353                                 }
1354                         case AST_T38_REQUEST_NEGOTIATE:
1355
1356                                 if (p->faxmode) {
1357                                         /* T.38 already negotiated */
1358                                         our_parameters.request_response = AST_T38_NEGOTIATED;
1359                                         our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1360                                         our_parameters.rate = AST_T38_RATE_14400;
1361                                         ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1362                                 } else if (!p->chmodepend) {
1363                                         p->chmodepend = 1;
1364                                         ooRequestChangeMode(p->callToken, 1);
1365                                         res = 0;
1366                                 }
1367                                 break;
1368
1369                         case AST_T38_REQUEST_TERMINATE:
1370
1371                                 if (!p->faxmode) {
1372                                         /* T.38 already terminated */
1373                                         our_parameters.request_response = AST_T38_TERMINATED;
1374                                         ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1375                                 } else if (!p->chmodepend) {
1376                                         p->chmodepend = 1;
1377                                         ooRequestChangeMode(p->callToken, 0);
1378                                         res = 0;
1379                                 }
1380                                 break;
1381
1382                         case AST_T38_REQUEST_PARMS:
1383                                 our_parameters.request_response = AST_T38_REQUEST_PARMS;
1384                                 our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
1385                                 our_parameters.rate = AST_T38_RATE_14400;
1386                                 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
1387                                 res = AST_T38_REQUEST_PARMS;
1388                                 break;
1389
1390                         default:
1391                                 ;
1392
1393                         }
1394
1395                 }
1396                 break;
1397         case AST_CONTROL_PROCEEDING:
1398         case AST_CONTROL_PVT_CAUSE_CODE:
1399         case AST_CONTROL_MASQUERADE_NOTIFY:
1400         case -1:
1401                 break;
1402         default:
1403                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
1404                                                                         condition, callToken);
1405         }
1406
1407         ast_mutex_unlock(&p->lock);
1408
1409         if (gH323Debug) {
1410                 ast_verb(0, "++++  ooh323_indicate %d on %s is %d\n", condition, callToken, res);
1411         }
1412
1413         ast_free(callToken);
1414         return res;
1415 }
1416
1417 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1418 {
1419
1420         struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
1421         int res = -1;
1422         enum ast_t38_state state = T38_STATE_UNAVAILABLE;
1423         char* cp;
1424
1425         if (!p) return -1;
1426
1427         ast_mutex_lock(&p->lock);
1428
1429         if (gH323Debug)
1430                 ast_verb(0, "----- ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
1431          
1432         switch (option) {
1433
1434                 case AST_OPTION_T38_STATE:
1435
1436                         if (*datalen != sizeof(enum ast_t38_state)) {
1437                                 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
1438                                 " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
1439                                 break;
1440                         }
1441
1442                         if (p->t38support != T38_DISABLED) {
1443                                 if (p->faxmode) {
1444                                         state = (p->chmodepend) ? T38_STATE_NEGOTIATING : T38_STATE_NEGOTIATED;
1445                                 } else {
1446                                         state = T38_STATE_UNKNOWN;
1447                                 }
1448                         }
1449
1450                         *((enum ast_t38_state *) data) = state;
1451                         res = 0;
1452                         break;
1453
1454
1455                 case AST_OPTION_DIGIT_DETECT:
1456
1457                         cp = (char *) data;
1458                         *cp = p->vad ? 1 : 0;
1459                         ast_debug(1, "Reporting digit detection %sabled on %s\n",
1460                                                          *cp ? "en" : "dis", ast_channel_name(ast));
1461
1462                         res = 0;
1463                         break;
1464
1465                 default:        ;
1466
1467         }
1468
1469         if (gH323Debug)
1470                 ast_verb(0, "+++++ ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
1471          
1472         ast_mutex_unlock(&p->lock);
1473
1474         return res;
1475 }
1476
1477
1478
1479 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1480 {
1481         struct ooh323_pvt *p = ast_channel_tech_pvt(newchan);
1482
1483         if (!p) return -1;
1484
1485         if (gH323Debug)
1486                 ast_verb(0, "--- ooh323c ooh323_fixup\n");
1487
1488         ast_mutex_lock(&p->lock);
1489         if (p->owner != oldchan) {
1490                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
1491                 ast_mutex_unlock(&p->lock);
1492                 return -1;
1493         }
1494
1495         if (p->owner == oldchan) {
1496                 p->owner = newchan;
1497         } else {
1498                 p->owner = oldchan;
1499         }
1500
1501         ast_mutex_unlock(&p->lock);
1502
1503         if (gH323Debug)
1504                 ast_verb(0, "+++ ooh323c ooh323_fixup \n");
1505
1506         return 0;
1507 }
1508
1509
1510 void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
1511 {
1512         struct ooh323_pvt *p = NULL;
1513
1514         if (gH323Debug)
1515                 ast_verb(0, "---   ooh323_update_writeformat %s/%d\n", 
1516                                 ast_format_get_name(fmt), txframes);
1517         
1518         p = find_call(call);
1519         if (!p) {
1520                 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1521                 return;
1522         }
1523
1524         ast_mutex_lock(&p->lock);
1525
1526         ao2_replace(p->writeformat, fmt);
1527
1528         if (p->owner) {
1529                 struct ast_format_cap *caps;
1530
1531                 caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1532                 if (!caps) {
1533                         ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
1534                         return;
1535                 }
1536
1537                 while (p->owner && ast_channel_trylock(p->owner)) {
1538                         ast_debug(1,"Failed to grab lock, trying again\n");
1539                         DEADLOCK_AVOIDANCE(&p->lock);
1540                 }
1541                 if (!p->owner) {
1542                         ast_mutex_unlock(&p->lock);
1543                         ast_log(LOG_ERROR, "Channel has no owner\n");
1544                         ao2_ref(caps, -1);
1545                         return;
1546                 }
1547                 if (gH323Debug) {
1548                         struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1549                         ast_verb(0, "Writeformat before update %s/%s\n", 
1550                           ast_format_get_name(ast_channel_writeformat(p->owner)),
1551                           ast_format_cap_get_names(ast_channel_nativeformats(p->owner), &codec_buf));
1552                 }
1553
1554                 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
1555                         ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1556                                  p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
1557                 }
1558                 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
1559                         ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1560                                  p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
1561                 }
1562
1563                 if (txframes) {
1564                         ast_format_cap_set_framing(caps, txframes);
1565                 }
1566                 ast_format_cap_append(caps, fmt, 0);
1567                 ast_channel_nativeformats_set(p->owner, caps);
1568                 ao2_ref(caps, -1);
1569                 ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
1570                 ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
1571                 ast_channel_unlock(p->owner);
1572         } else
1573                 ast_log(LOG_ERROR, "No owner found\n");
1574
1575
1576         ast_mutex_unlock(&p->lock);
1577
1578         if (gH323Debug)
1579                 ast_verb(0, "+++   ooh323_update_writeformat\n");
1580 }
1581
1582 void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
1583 {
1584         struct ooh323_pvt *p = NULL;
1585
1586         if (gH323Debug)
1587                 ast_verb(0, "---   ooh323_update_readformat %s\n", 
1588                                 ast_format_get_name(fmt));
1589         
1590         p = find_call(call);
1591         if (!p) {
1592                 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1593                 return;
1594         }
1595
1596         ast_mutex_lock(&p->lock);
1597
1598         ao2_replace(p->readformat, fmt);
1599
1600         if (p->owner) {
1601                 struct ast_format_cap *caps;
1602
1603                 caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1604                 if (!caps) {
1605                         ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
1606                         return;
1607                 }
1608
1609                 while (p->owner && ast_channel_trylock(p->owner)) {
1610                         ast_debug(1,"Failed to grab lock, trying again\n");
1611                         DEADLOCK_AVOIDANCE(&p->lock);
1612                 }
1613                 if (!p->owner) {
1614                         ast_mutex_unlock(&p->lock);
1615                         ast_log(LOG_ERROR, "Channel has no owner\n");
1616                         ao2_ref(caps, -1);
1617                         return;
1618                 }
1619
1620                 if (gH323Debug) {
1621                         ast_verb(0, "Readformat before update %s\n", 
1622                           ast_format_get_name(ast_channel_readformat(p->owner)));
1623                 }
1624                 ast_format_cap_append(caps, fmt, 0);
1625                 ast_channel_nativeformats_set(p->owner, caps);
1626                 ao2_ref(caps, -1);
1627                 ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
1628                 ast_channel_unlock(p->owner);
1629         } else
1630                 ast_log(LOG_ERROR, "No owner found\n");
1631
1632         ast_mutex_unlock(&p->lock);
1633
1634         if (gH323Debug)
1635                 ast_verb(0, "+++   ooh323_update_readformat\n");
1636 }
1637
1638
1639 int onAlerting(ooCallData *call)
1640 {
1641         struct ooh323_pvt *p = NULL;
1642         struct ast_channel *c = NULL;
1643
1644         if (gH323Debug)
1645                 ast_verb(0, "--- onAlerting %s\n", call->callToken);
1646
1647         p = find_call(call);
1648
1649         if(!p) {
1650                 ast_log(LOG_ERROR, "No matching call found\n");
1651                 return -1;
1652         }  
1653         ast_mutex_lock(&p->lock);
1654         if (!p->owner) {
1655                 ast_mutex_unlock(&p->lock);
1656                 ast_debug(1, "Channel has no owner\n");
1657                 return 0;
1658         }
1659         while (p->owner && ast_channel_trylock(p->owner)) {
1660                 ast_debug(1, "Failed to grab lock, trying again\n");
1661                 DEADLOCK_AVOIDANCE(&p->lock);
1662         }
1663         if (!p->owner) {
1664                 ast_mutex_unlock(&p->lock);
1665                 ast_log(LOG_ERROR, "Channel has no owner\n");
1666                 return 0;
1667         }
1668         c = p->owner;
1669
1670         if (call->remoteDisplayName) {
1671                 struct ast_party_connected_line connected;
1672                 struct ast_set_party_connected_line update_connected;
1673
1674                 memset(&update_connected, 0, sizeof(update_connected));
1675                 update_connected.id.name = 1;
1676                 ast_party_connected_line_init(&connected);
1677                 connected.id.name.valid = 1;
1678                 connected.id.name.str = (char *) call->remoteDisplayName;
1679                 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1680                 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1681         }
1682         if (ast_channel_state(c) != AST_STATE_UP)
1683                 ast_setstate(c, AST_STATE_RINGING);
1684
1685         ast_queue_control(c, AST_CONTROL_RINGING);
1686         ast_channel_unlock(c);
1687         ast_mutex_unlock(&p->lock);
1688
1689         if (gH323Debug)
1690                 ast_verb(0, "+++ onAlerting %s\n", call->callToken);
1691
1692         return OO_OK;
1693 }
1694
1695 int onProgress(ooCallData *call)
1696 {
1697         struct ooh323_pvt *p = NULL;
1698         struct ast_channel *c = NULL;
1699
1700         if (gH323Debug)
1701                 ast_verb(0, "--- onProgress %s\n", call->callToken);
1702
1703         p = find_call(call);
1704
1705         if(!p) {
1706                 ast_log(LOG_ERROR, "No matching call found\n");
1707                 return -1;
1708         }  
1709         ast_mutex_lock(&p->lock);
1710         if (!p->owner) {
1711                 ast_mutex_unlock(&p->lock);
1712                 ast_log(LOG_ERROR, "Channel has no owner\n");
1713                 return 0;
1714         }
1715         while (p->owner && ast_channel_trylock(p->owner)) {
1716                 ast_debug(1, "Failed to grab lock, trying again\n");
1717                 DEADLOCK_AVOIDANCE(&p->lock);
1718         }
1719         if (!p->owner) {
1720                 ast_mutex_unlock(&p->lock);
1721                 ast_log(LOG_ERROR, "Channel has no owner\n");
1722                 return 0;
1723         }
1724         c = p->owner;
1725
1726         if (call->remoteDisplayName) {
1727                 struct ast_party_connected_line connected;
1728                 struct ast_set_party_connected_line update_connected;
1729
1730                 memset(&update_connected, 0, sizeof(update_connected));
1731                 update_connected.id.name = 1;
1732                 ast_party_connected_line_init(&connected);
1733                 connected.id.name.valid = 1;
1734                 connected.id.name.str = (char *) call->remoteDisplayName;
1735                 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1736                 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
1737         }
1738         if (ast_channel_state(c) != AST_STATE_UP)
1739                 ast_setstate(c, AST_STATE_RINGING);
1740
1741         ast_queue_control(c, AST_CONTROL_PROGRESS);
1742         ast_channel_unlock(c);
1743         ast_mutex_unlock(&p->lock);
1744
1745         if (gH323Debug)
1746                 ast_verb(0, "+++ onProgress %s\n", call->callToken);
1747
1748         return OO_OK;
1749 }
1750
1751 /**
1752   * Callback for sending digits from H.323 up to asterisk
1753   *
1754   */
1755 int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
1756 {
1757         struct ooh323_pvt *p = NULL;
1758         struct ast_frame f;
1759         int res;
1760
1761         ast_debug(1, "Received Digit: %c\n", digit[0]);
1762         p = find_call(call);
1763         if (!p) {
1764                 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1765                 return -1;
1766         }
1767         if (!p->owner) {
1768                 ast_log(LOG_ERROR, "Channel has no owner\n");
1769                 return -1;
1770         }
1771         ast_mutex_lock(&p->lock);
1772         memset(&f, 0, sizeof(f));
1773         f.frametype = AST_FRAME_DTMF;
1774         f.subclass.integer = digit[0];
1775         f.datalen = 0;
1776         f.samples = 800;
1777         f.offset = 0;
1778         f.data.ptr = NULL;
1779         f.mallocd = 0;
1780         f.src = "SEND_DIGIT";
1781
1782         while (p->owner && ast_channel_trylock(p->owner)) {
1783                 ast_debug(1, "Failed to grab lock, trying again\n");
1784                 DEADLOCK_AVOIDANCE(&p->lock);
1785         }
1786         if (!p->owner) {
1787                 ast_mutex_unlock(&p->lock);
1788                 ast_log(LOG_ERROR, "Channel has no owner\n");
1789                 return 0;
1790         }
1791         res = ast_queue_frame(p->owner, &f);
1792         ast_channel_unlock(p->owner);
1793         ast_mutex_unlock(&p->lock);
1794         return res;
1795 }
1796
1797 int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
1798 {
1799         struct ooh323_pvt *p = NULL;
1800         struct ooh323_user *user = NULL;
1801         struct ast_channel *c = NULL;
1802         ooAliases *alias = NULL;
1803         char *at = NULL;
1804         char number [OO_MAX_NUMBER_LENGTH];
1805
1806         if (gH323Debug)
1807                 ast_verb(0, "---   ooh323_onReceivedSetup %s\n", call->callToken);
1808
1809
1810         if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
1811                 ast_log(LOG_ERROR, "Failed to create a new call.\n");
1812                 return -1;
1813         }
1814         ast_mutex_lock(&p->lock);
1815         ast_clear_flag(p, H323_OUTGOING);
1816   
1817
1818         if (call->remoteDisplayName) {
1819                 p->callerid_name = ast_strdup(call->remoteDisplayName);
1820         }
1821
1822         if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
1823                 p->callerid_num = ast_strdup(number);
1824         }
1825
1826         if (call->remoteAliases) {
1827                 for (alias = call->remoteAliases; alias; alias = alias->next) {
1828                         if (alias->type == T_H225AliasAddress_h323_ID) {
1829                                 if (!p->callerid_name) {
1830                                         p->callerid_name = ast_strdup(alias->value);
1831                                 }
1832                                 ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
1833                                 }
1834          else if(alias->type == T_H225AliasAddress_dialedDigits)
1835          {
1836             if(!p->callerid_num)
1837                p->callerid_num = ast_strdup(alias->value);
1838                                 ast_copy_string(p->caller_dialedDigits, alias->value, 
1839                                                                                                                         sizeof(p->caller_dialedDigits));
1840          }
1841          else if(alias->type == T_H225AliasAddress_email_ID)
1842          {
1843                                 ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
1844          }
1845          else if(alias->type == T_H225AliasAddress_url_ID)
1846          {
1847                                 ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
1848                         }
1849                 }
1850         }
1851
1852         number[0] = '\0';
1853         if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
1854                 ast_copy_string(p->exten, number, sizeof(p->exten));
1855         } else {
1856                 update_our_aliases(call, p);
1857                 if (!ast_strlen_zero(p->callee_dialedDigits)) {
1858                         ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
1859                 } else if(!ast_strlen_zero(p->callee_h323id)) {
1860                         ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
1861                 } else if(!ast_strlen_zero(p->callee_email)) {
1862                         ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
1863                         if ((at = strchr(p->exten, '@'))) {
1864                                 *at = '\0';
1865                         }
1866                 }
1867         }
1868
1869         /* if no extension found, set to default 's' */
1870         if (ast_strlen_zero(p->exten)) {
1871                 p->exten[0]='s';
1872                 p->exten[1]='\0';
1873         }
1874
1875         user = find_user(p->callerid_name, call->remoteIP);
1876         if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
1877                 ast_mutex_lock(&user->lock);
1878                 p->username = ast_strdup(user->name);
1879                 p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
1880                                                   ast_strdup(user->name);
1881                 ast_copy_string(p->context, user->context, sizeof(p->context));
1882                 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
1883                 p->amaflags = user->amaflags;
1884                 ast_format_cap_append_from_cap(p->cap, user->cap, AST_MEDIA_TYPE_UNKNOWN);
1885                 p->g729onlyA = user->g729onlyA;
1886                 p->dtmfmode |= user->dtmfmode;
1887                 p->dtmfcodec = user->dtmfcodec;
1888                 p->faxdetect = user->faxdetect;
1889                 p->t38support = user->t38support;
1890                 p->rtptimeout = user->rtptimeout;
1891                 p->nat = user->nat;
1892                 p->h245tunneling = user->h245tunneling;
1893                 p->faststart = user->faststart;
1894                 p->directrtp = user->directrtp;
1895                 p->earlydirect = user->earlydirect;
1896
1897                 if (p->faststart)
1898                         OO_SETFLAG(call->flags, OO_M_FASTSTART);
1899                 else
1900                         OO_CLRFLAG(call->flags, OO_M_FASTSTART);
1901                 /* if we disable h245tun for this user then we clear flag */
1902                 /* in any other case we don't must touch this */
1903                 /* ie if we receive setup without h245tun but enabled
1904                                                 we can't enable it per call */
1905                 if (!p->h245tunneling)
1906                         OO_CLRFLAG(call->flags, OO_M_TUNNELING);
1907
1908                 if (user->rtpmask && user->rtpmaskstr[0]) {
1909                         p->rtpmask = user->rtpmask;
1910                         ast_copy_string(p->rtpmaskstr, user->rtpmaskstr, 
1911                                                          sizeof(p->rtpmaskstr));
1912                 }
1913                 if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
1914                         p->rtdrcount = user->rtdrcount;
1915                         p->rtdrinterval = user->rtdrinterval;
1916                 }
1917
1918                 p->aniasdni = user->aniasdni;
1919
1920                 if (user->incominglimit) user->inUse++;
1921                 ast_mutex_unlock(&user->lock);
1922         } else {
1923          if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
1924                 p->username = ast_strdup(call->remoteIP);
1925                 p->directrtp = gDirectRTP;
1926                 p->earlydirect = gEarlyDirect;
1927         } else {
1928           ast_mutex_unlock(&p->lock);
1929           ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
1930           if (!user) {
1931            ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
1932            call->callEndReason = OO_REASON_REMOTE_REJECTED;
1933           }
1934           else {
1935            ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
1936            call->callEndReason = OO_REASON_REMOTE_REJECTED;
1937           }
1938           ast_set_flag(p, H323_NEEDDESTROY);
1939           return -1;
1940          }
1941         }
1942
1943         ooh323c_set_capability_for_call(call, p->cap, p->dtmfmode, p->dtmfcodec,
1944                                          p->t38support, p->g729onlyA);
1945 /* Incoming call */
1946         c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL, NULL);
1947         if(!c) {
1948         ast_mutex_unlock(&p->lock);
1949         ast_log(LOG_ERROR, "Could not create ast_channel\n");
1950          return -1;
1951         }
1952
1953         if (p->aniasdni) {
1954                 ooCallSetCallerId(call, p->exten);
1955         }
1956         if (!configure_local_rtp(p, call)) {
1957                 ast_mutex_unlock(&p->lock);
1958                 ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
1959                 return -1;
1960         }
1961
1962         ast_mutex_unlock(&p->lock);
1963
1964         if (gH323Debug)
1965                 ast_verb(0, "+++   ooh323_onReceivedSetup - Determined context %s, "
1966                                                 "extension %s\n", p->context, p->exten);
1967
1968         return OO_OK;
1969 }
1970
1971
1972
1973 int onOutgoingCall(ooCallData *call)
1974 {
1975         struct ooh323_pvt *p = NULL;
1976         int i = 0;
1977
1978         if (gH323Debug)
1979                 ast_verb(0, "---   onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
1980
1981         if (!strcmp(call->callType, "outgoing")) {
1982                 p = find_call(call);
1983                 if (!p) {
1984                         ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1985                         return -1;
1986                 }
1987                 ast_mutex_lock(&p->lock);
1988
1989                 if (!ast_strlen_zero(p->callerid_name)) {
1990                         ooCallSetCallerId(call, p->callerid_name);
1991                 }
1992                 if (!ast_strlen_zero(p->callerid_num)) {
1993                         i = 0;
1994                         while (*(p->callerid_num + i) != '\0') {
1995                                 if(!isdigit(*(p->callerid_num+i))) { break; }
1996                                 i++;
1997                         }
1998                         if(*(p->callerid_num+i) == '\0')
1999                                 ooCallSetCallingPartyNumber(call, p->callerid_num);
2000                         else {
2001                                 if(!p->callerid_name)
2002                                         ooCallSetCallerId(call, p->callerid_num);
2003                         }
2004                 }
2005                 
2006                 if (!ast_strlen_zero(p->caller_h323id))
2007                         ooCallAddAliasH323ID(call, p->caller_h323id);
2008
2009                 if (!ast_strlen_zero(p->caller_dialedDigits)) {
2010                         if (gH323Debug) {
2011                                 ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
2012                         }
2013                         ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
2014                 } else if (!ast_strlen_zero(p->callerid_num)) {
2015                         if (ooIsDailedDigit(p->callerid_num)) {
2016                                 if (gH323Debug) {
2017                                         ast_verb(0, "setting callid number %s\n", p->callerid_num);
2018                                 }
2019                                 ooCallAddAliasDialedDigits(call, p->callerid_num);
2020                         } else if (ast_strlen_zero(p->caller_h323id)) {
2021                                 ooCallAddAliasH323ID(call, p->callerid_num);
2022                         }
2023                 }
2024                 if (p->rtpmask && p->rtpmaskstr[0]) {
2025                         call->rtpMask = p->rtpmask;
2026                         ast_mutex_lock(&call->rtpMask->lock);
2027                         call->rtpMask->inuse++;
2028                         ast_mutex_unlock(&call->rtpMask->lock);
2029                         ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
2030                 }
2031
2032                 if (!p->rtp && !configure_local_rtp(p, call)) {
2033                         ast_mutex_unlock(&p->lock);
2034                         return OO_FAILED;
2035                 }
2036
2037                 ast_mutex_unlock(&p->lock);
2038         }
2039
2040         if (gH323Debug)
2041                 ast_verb(0, "+++   onOutgoingCall %s\n", call->callToken);
2042         return OO_OK;
2043 }
2044
2045
2046 int onNewCallCreated(ooCallData *call)
2047 {
2048         struct ooh323_pvt *p = NULL;
2049         int i = 0;
2050
2051         if (gH323Debug)
2052                 ast_verb(0, "---   onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
2053
2054         ast_mutex_lock(&call->Lock);
2055         if (ooh323c_start_call_thread(call)) {
2056                 ast_log(LOG_ERROR,"Failed to create call thread.\n");
2057                 ast_mutex_unlock(&call->Lock);
2058                 return -1;
2059         }
2060
2061         if (!strcmp(call->callType, "outgoing")) {
2062                 p = find_call(call);
2063                 if (!p) {
2064                         ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2065                         ast_mutex_unlock(&call->Lock);
2066                         return -1;
2067                 }
2068                 ast_mutex_lock(&p->lock);
2069
2070                 if (!ast_strlen_zero(p->callerid_name)) {
2071                         ooCallSetCallerId(call, p->callerid_name);
2072                 }
2073                 if (!ast_strlen_zero(p->callerid_num)) {
2074                         i = 0;
2075                         while (*(p->callerid_num + i) != '\0') {
2076                                 if(!isdigit(*(p->callerid_num+i))) { break; }
2077                                 i++;
2078                         }
2079                         if(*(p->callerid_num+i) == '\0')
2080                                 ooCallSetCallingPartyNumber(call, p->callerid_num);
2081                         else {
2082                                 if(ast_strlen_zero(p->callerid_name))
2083                                         ooCallSetCallerId(call, p->callerid_num);
2084                         }
2085                 }
2086                 
2087                 if (!ast_strlen_zero(p->caller_h323id))
2088                         ooCallAddAliasH323ID(call, p->caller_h323id);
2089
2090                 if (!ast_strlen_zero(p->caller_dialedDigits)) {
2091                         if (gH323Debug) {
2092                                 ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
2093                         }
2094                         ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
2095                 } else if (!ast_strlen_zero(p->callerid_num)) {
2096                         if (ooIsDailedDigit(p->callerid_num)) {
2097                                 if (gH323Debug) {
2098                                         ast_verb(0, "setting callid number %s\n", p->callerid_num);
2099                                 }
2100                                 ooCallAddAliasDialedDigits(call, p->callerid_num);
2101                         } else if (ast_strlen_zero(p->caller_h323id)) {
2102                                 ooCallAddAliasH323ID(call, p->callerid_num);
2103                         }
2104                 }
2105   
2106
2107                 if (!ast_strlen_zero(p->exten))  {
2108                         if (ooIsDailedDigit(p->exten)) {
2109                                 ooCallSetCalledPartyNumber(call, p->exten);
2110                                 ooCallAddRemoteAliasDialedDigits(call, p->exten);
2111                         } else {
2112                           ooCallAddRemoteAliasH323ID(call, p->exten);
2113                         }
2114                 }
2115
2116                 if (gH323Debug) {
2117                         struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
2118
2119                         ast_verb(0, " Outgoing call %s(%s) - Codec prefs - %s\n", 
2120                                 p->username?p->username:"NULL", call->callToken,
2121                                 ast_format_cap_get_names(p->cap, &codec_buf));
2122                 }
2123
2124                 ooh323c_set_capability_for_call(call, p->cap,
2125                                      p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
2126
2127                 configure_local_rtp(p, call);
2128                 ast_cond_signal(&p->rtpcond);
2129                 ast_mutex_unlock(&p->lock);
2130         }
2131
2132         ast_mutex_unlock(&call->Lock);
2133         if (gH323Debug)
2134                 ast_verb(0, "+++   onNewCallCreated %s\n", call->callToken);
2135         return OO_OK;
2136 }
2137
2138 int onCallEstablished(ooCallData *call)
2139 {
2140         struct ooh323_pvt *p = NULL;
2141
2142         if (gH323Debug)
2143                 ast_verb(0, "---   onCallEstablished %s\n", call->callToken);
2144
2145
2146         if (!(p = find_call(call))) {
2147                 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
2148                 return -1;
2149         }
2150
2151         if(ast_test_flag(p, H323_OUTGOING)) {
2152                 ast_mutex_lock(&p->lock);
2153                 if (!p->owner) {
2154                         ast_mutex_unlock(&p->lock);
2155                         ast_log(LOG_ERROR, "Channel has no owner\n");
2156                         return -1;
2157                 }
2158         
2159                 while (p->owner && ast_channel_trylock(p->owner)) {
2160                         ast_debug(1, "Failed to grab lock, trying again\n");
2161                         DEADLOCK_AVOIDANCE(&p->lock);
2162                 }
2163                 if (p->owner) {
2164                         struct ast_channel* c = p->owner;
2165
2166                         if (call->remoteDisplayName) {
2167                                 struct ast_party_connected_line connected;
2168                                 struct ast_set_party_connected_line update_connected;
2169
2170                                 memset(&update_connected, 0, sizeof(update_connected));
2171                                 update_connected.id.name = 1;
2172                                 ast_party_connected_line_init(&connected);
2173                                 connected.id.name.valid = 1;
2174                                 connected.id.name.str = (char *) call->remoteDisplayName;
2175                                 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
2176                                 ast_channel_queue_connected_line_update(c, &connected, &update_connected);
2177                         }
2178
2179                         ast_queue_control(c, AST_CONTROL_ANSWER);
2180                         ast_publish_channel_state(c);
2181                         ast_channel_unlock(p->owner);
2182                 }
2183                 ast_mutex_unlock(&p->lock);
2184
2185         }
2186
2187         if (gH323Debug)
2188                 ast_verb(0, "+++   onCallEstablished %s\n", call->callToken);
2189
2190         return OO_OK;
2191 }
2192
2193 int onCallCleared(ooCallData *call)
2194 {
2195         struct ooh323_pvt *p = NULL;
2196         int ownerLock = 0;
2197
2198         if (gH323Debug)
2199                 ast_verb(0, "---   onCallCleared %s \n", call->callToken);
2200
2201
2202    if ((p = find_call(call))) {
2203         ast_mutex_lock(&p->lock);
2204   
2205         while (p->owner) {
2206                 if (ast_channel_trylock(p->owner)) {
2207                         ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
2208                         ast_debug(1, "Failed to grab lock, trying again\n");
2209                         DEADLOCK_AVOIDANCE(&p->lock);
2210                 } else {
2211                         ownerLock = 1; break;
2212                 }
2213         }
2214
2215         if (ownerLock) {
2216                 if (!ast_test_flag(p, H323_ALREADYGONE)) { 
2217
2218                         ast_set_flag(p, H323_ALREADYGONE);
2219                         ast_channel_hangupcause_set(p->owner, call->q931cause);
2220                         ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
2221                         ast_queue_hangup_with_cause(p->owner,call->q931cause);
2222                 }
2223         }
2224
2225         if(p->owner) {
2226                 ast_channel_tech_pvt_set(p->owner, NULL);
2227                 ast_channel_unlock(p->owner);
2228                 p->owner = NULL;
2229                 ast_module_unref(myself);
2230         }
2231
2232         if (!p->rtp) {
2233                 ast_cond_signal(&p->rtpcond);
2234         }
2235
2236         ast_set_flag(p, H323_NEEDDESTROY);
2237
2238         ooh323c_stop_call_thread(call);
2239
2240         ast_mutex_unlock(&p->lock);
2241         ast_mutex_lock(&usecnt_lock);
2242         usecnt--;
2243         ast_mutex_unlock(&usecnt_lock);
2244
2245     }
2246
2247         if (gH323Debug)
2248                 ast_verb(0, "+++   onCallCleared\n");
2249
2250         return OO_OK;
2251 }
2252
2253 /* static void ooh323_delete_user(struct ooh323_user *user)
2254 {
2255         struct ooh323_user *prev = NULL, *cur = NULL;
2256
2257         if (gH323Debug)
2258                 ast_verb(0, "---   ooh323_delete_user\n");
2259
2260         if (user) {     
2261                 cur = userl.users;
2262                 ast_mutex_lock(&userl.lock);
2263                 while (cur) {
2264                         if (cur == user) break;
2265                         prev = cur;
2266                         cur = cur->next;
2267                 }
2268
2269                 if (cur) {
2270                         if (prev)
2271                                 prev->next = cur->next;
2272                         else
2273                                 userl.users = cur->next;
2274                 }
2275                 ast_mutex_unlock(&userl.lock);
2276
2277                 ast_free(user);
2278         }  
2279
2280         if (gH323Debug)
2281                 ast_verb(0, "+++   ooh323_delete_user\n");
2282
2283 } */
2284
2285 void ooh323_delete_peer(struct ooh323_peer *peer)
2286 {
2287         struct ooh323_peer *prev = NULL, *cur = NULL;
2288
2289         if (gH323Debug)
2290                 ast_verb(0, "---   ooh323_delete_peer\n");
2291
2292         if (peer) {     
2293       cur = peerl.peers;
2294                 ast_mutex_lock(&peerl.lock);
2295       while(cur) {
2296          if(cur==peer) break;
2297          prev = cur;
2298          cur = cur->next;
2299                 }
2300
2301                 if (cur) {
2302          if(prev)
2303                                 prev->next = cur->next;
2304          else
2305                                 peerl.peers = cur->next;
2306                         }
2307                 ast_mutex_unlock(&peerl.lock);
2308
2309                 ast_free(peer->h323id);
2310                 ast_free(peer->email);
2311                 ast_free(peer->url);
2312                 ast_free(peer->e164);
2313
2314                 ao2_cleanup(peer->cap);
2315                 ast_free(peer);
2316         }  
2317
2318         if (gH323Debug)
2319                 ast_verb(0, "+++   ooh323_delete_peer\n");
2320
2321 }
2322
2323
2324
2325 static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
2326 {
2327         struct ooh323_user *user = NULL;
2328
2329         if (gH323Debug)
2330                 ast_verb(0, "---   build_user\n");
2331
2332         user = ast_calloc(1,sizeof(struct ooh323_user));
2333         if (user) {
2334                 memset(user, 0, sizeof(struct ooh323_user));
2335                 if (!(user->cap = ast_format_cap_alloc(0))) {
2336                         ast_free(user);
2337                         return NULL;
2338                 }
2339                 ast_mutex_init(&user->lock);
2340                 ast_copy_string(user->name, name, sizeof(user->name));
2341                 ast_format_cap_append_from_cap(user->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
2342                 user->rtptimeout = gRTPTimeout;
2343                 user->nat = gNat;
2344                 user->dtmfmode = gDTMFMode;
2345                 user->dtmfcodec = gDTMFCodec;
2346                 user->faxdetect = gFAXdetect;
2347                 user->t38support = gT38Support;
2348                 user->faststart = gFastStart;
2349                 user->h245tunneling = gTunneling;
2350                 user->directrtp = gDirectRTP;
2351                 user->earlydirect = gEarlyDirect;
2352                 user->g729onlyA = g729onlyA;
2353                 /* set default context */
2354                 ast_copy_string(user->context, gContext, sizeof(user->context));
2355                 ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
2356                 user->amaflags = gAMAFLAGS;
2357
2358                 while (v) {
2359                         if (!strcasecmp(v->name, "context")) {
2360                                 ast_copy_string(user->context, v->value, sizeof(user->context));
2361                         } else if (!strcasecmp(v->name, "incominglimit")) {
2362                                 user->incominglimit = atoi(v->value);
2363                                 if (user->incominglimit < 0)
2364                                         user->incominglimit = 0;
2365                         } else if (!strcasecmp(v->name, "accountcode")) {
2366                                 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
2367                         } else if (!strcasecmp(v->name, "roundtrip")) {
2368                                 sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
2369                         } else if (!strcasecmp(v->name, "faststart")) {
2370                                 user->faststart = ast_true(v->value);
2371                         } else if (!strcasecmp(v->name, "h245tunneling")) {
2372                                 user->h245tunneling = ast_true(v->value);
2373                         } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2374                                 user->directrtp = ast_true(v->value);
2375                                 user->earlydirect = ast_true(v->value);
2376                         } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2377                                 user->earlydirect = ast_true(v->value);
2378                         } else if (!strcasecmp(v->name, "g729onlyA")) {
2379                                 user->g729onlyA = ast_true(v->value);
2380                         } else if (!strcasecmp(v->name, "nat")) {
2381                                 user->nat = ast_true(v->value);
2382                         } else if (!strcasecmp(v->name, "rtptimeout")) {
2383                                 user->rtptimeout = atoi(v->value);
2384                                 if (user->rtptimeout < 0)
2385                                         user->rtptimeout = gRTPTimeout;
2386                         } else if (!strcasecmp(v->name, "rtpmask")) {
2387                                 if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2388                                         (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED) 
2389                                                                                         == 0)) {
2390                                         ast_mutex_init(&user->rtpmask->lock);
2391                                         user->rtpmask->inuse = 1;
2392                                         ast_copy_string(user->rtpmaskstr, v->value, 
2393                                                                 sizeof(user->rtpmaskstr));
2394                                 } else user->rtpmask = NULL;
2395                         } else if (!strcasecmp(v->name, "disallow")) {
2396                                 ast_format_cap_update_by_allow_disallow(user->cap,  v->value, 0);
2397                         } else if (!strcasecmp(v->name, "allow")) {
2398                                 const char* tcodecs = v->value;
2399                                 if (!strcasecmp(v->value, "all")) {
2400                                         tcodecs = "ulaw,alaw,g729,g723,gsm";
2401                                 }
2402                                 ast_format_cap_update_by_allow_disallow(user->cap,  tcodecs, 1);
2403                         } else if (!strcasecmp(v->name, "amaflags")) {
2404                                 user->amaflags = ast_channel_string2amaflag(v->value);
2405                         } else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
2406                                 struct ast_sockaddr p;
2407                                 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2408                                         ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
2409                                 } else {        
2410                                         ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
2411                                 }
2412                                 user->mUseIP = 1;
2413                         } else if (!strcasecmp(v->name, "dtmfmode")) {
2414                                 if (!strcasecmp(v->value, "rfc2833"))
2415                                         user->dtmfmode = H323_DTMF_RFC2833;
2416                                 if (!strcasecmp(v->value, "cisco"))
2417                                         user->dtmfmode = H323_DTMF_CISCO;
2418                                 else if (!strcasecmp(v->value, "q931keypad"))
2419                                         user->dtmfmode = H323_DTMF_Q931;
2420                                 else if (!strcasecmp(v->value, "h245alphanumeric"))
2421                                         user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2422                                 else if (!strcasecmp(v->value, "h245signal"))
2423                                         user->dtmfmode = H323_DTMF_H245SIGNAL;
2424                                 else if (!strcasecmp(v->value, "inband"))
2425                                         user->dtmfmode = H323_DTMF_INBAND;
2426                         } else if (!strcasecmp(v->name, "relaxdtmf")) {
2427                                 user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2428                         } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2429                                 user->dtmfcodec = atoi(v->value);
2430                         } else if (!strcasecmp(v->name, "faxdetect")) {
2431                                 if (ast_true(v->value)) {
2432                                         user->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2433                                 } else if (ast_false(v->value)) {
2434                                         user->faxdetect = 0;
2435                                 } else {
2436                                         char *buf = ast_strdupa(v->value);
2437                                         char *word, *next = buf;
2438                                         user->faxdetect = 0;
2439                                         while ((word = strsep(&next, ","))) {
2440                                                 if (!strcasecmp(word, "cng")) {
2441                                                         user->faxdetect |= FAXDETECT_CNG;
2442                                                 } else if (!strcasecmp(word, "t38")) {
2443                                                         user->faxdetect |= FAXDETECT_T38;
2444                                                 } else {
2445                                                         ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2446                                                 }
2447                                         }
2448
2449                                 }
2450                         } else if (!strcasecmp(v->name, "t38support")) {
2451                                 if (!strcasecmp(v->value, "disabled"))
2452                                         user->t38support = T38_DISABLED;
2453                                 if (!strcasecmp(v->value, "no"))
2454                                         user->t38support = T38_DISABLED;
2455                                 else if (!strcasecmp(v->value, "faxgw"))
2456                                         user->t38support = T38_FAXGW;
2457                                 else if (!strcasecmp(v->value, "yes"))
2458                                         user->t38support = T38_ENABLED;
2459                         } else if (!strcasecmp(v->name, "aniasdni")) {
2460                                 user->aniasdni = ast_true(v->value);
2461                         }
2462                         v = v->next;
2463                 }
2464         }
2465
2466         if (gH323Debug)
2467                 ast_verb(0, "+++   build_user\n");
2468
2469         return user;
2470 }
2471
2472 static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
2473 {
2474         struct ooh323_peer *peer = NULL;
2475
2476         if (gH323Debug)
2477                 ast_verb(0, "---   build_peer\n");
2478
2479         peer = ast_calloc(1, sizeof(*peer));
2480         if (peer) {
2481                 memset(peer, 0, sizeof(struct ooh323_peer));
2482                 if (!(peer->cap = ast_format_cap_alloc(0))) {
2483                         ast_free(peer);
2484                         return NULL;
2485                 }
2486                 ast_mutex_init(&peer->lock);
2487                 ast_copy_string(peer->name, name, sizeof(peer->name));
2488                 ast_format_cap_append_from_cap(peer->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
2489                 peer->rtptimeout = gRTPTimeout;
2490                 peer->nat = gNat;
2491                 ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
2492                 peer->amaflags = gAMAFLAGS;
2493                 peer->dtmfmode = gDTMFMode;
2494                 peer->dtmfcodec = gDTMFCodec;
2495                 peer->faxdetect = gFAXdetect;
2496                 peer->t38support = gT38Support;
2497                 peer->faststart = gFastStart;
2498                 peer->h245tunneling = gTunneling;
2499                 peer->directrtp = gDirectRTP;
2500                 peer->earlydirect = gEarlyDirect;
2501                 peer->g729onlyA = g729onlyA;
2502                 peer->port = 1720;
2503                 if (0 == friend_type) {
2504                         peer->mFriend = 1;
2505                 }
2506
2507                 while (v) {
2508                         if (!strcasecmp(v->name, "h323id")) {
2509             if (!(peer->h323id = ast_strdup(v->value))) {
2510                                         ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2511                                                                                          "peer %s\n", name);
2512                                         ooh323_delete_peer(peer);
2513                                         return NULL;
2514                                 }
2515                         } else if (!strcasecmp(v->name, "e164")) {
2516                                 int valid = 1;
2517                                 const char *tmp;
2518                                 for(tmp = v->value; *tmp; tmp++) {
2519                                         if (!isdigit(*tmp)) {
2520                                                 valid = 0;
2521                                                 break;
2522                                         }
2523                                 }
2524                                 if (valid) {
2525                                         if (!(peer->e164 = ast_strdup(v->value))) {
2526                                                 ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
2527                                                                                          "peer %s\n", name);
2528                                                 ooh323_delete_peer(peer);
2529                                                 return NULL;
2530                                         }
2531                                 } else {
2532                                         ast_log(LOG_ERROR, "Invalid e164: %s for peer %s\n", v->value, name);
2533                                 }
2534                         } else  if (!strcasecmp(v->name, "email")) {
2535                                 if (!(peer->email = ast_strdup(v->value))) {
2536                                         ast_log(LOG_ERROR, "Could not allocate memory for email of "
2537                                                                                          "peer %s\n", name);
2538                                         ooh323_delete_peer(peer);
2539                                         return NULL;
2540                                 }
2541                         } else if (!strcasecmp(v->name, "url")) {
2542                                 if (!(peer->url = ast_strdup(v->value))) {
2543                                         ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2544                                                                                          "peer %s\n", name);
2545                                         ooh323_delete_peer(peer);
2546                                         return NULL;
2547                                 }
2548                         } else if (!strcasecmp(v->name, "port")) {
2549                                 peer->port = atoi(v->value);
2550                         } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
2551                                 struct ast_sockaddr p;
2552                                 if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
2553                                         ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
2554                                 } else {        
2555                                         ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2556                                 }
2557                         
2558                         } else if (!strcasecmp(v->name, "outgoinglimit")) {
2559                                 peer->outgoinglimit = atoi(v->value);
2560                                 if (peer->outgoinglimit < 0)
2561                                         peer->outgoinglimit = 0;
2562                         } else if (!strcasecmp(v->name, "accountcode")) {
2563                                 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
2564                         } else if (!strcasecmp(v->name, "faststart")) {
2565                                 peer->faststart = ast_true(v->value);
2566                         } else if (!strcasecmp(v->name, "h245tunneling")) {
2567                                 peer->h245tunneling = ast_true(v->value);
2568                         } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2569                                 peer->directrtp = ast_true(v->value);
2570                                 peer->earlydirect = ast_true(v->value);
2571                         } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2572                                 peer->earlydirect = ast_true(v->value);
2573                         } else if (!strcasecmp(v->name, "g729onlyA")) {
2574                                 peer->g729onlyA = ast_true(v->value);
2575                         } else if (!strcasecmp(v->name, "nat")) {
2576                                 peer->nat = ast_true(v->value);
2577                         } else if (!strcasecmp(v->name, "rtptimeout")) {
2578                                 peer->rtptimeout = atoi(v->value);
2579                                 if(peer->rtptimeout < 0)
2580                                         peer->rtptimeout = gRTPTimeout;
2581                         } else if (!strcasecmp(v->name, "rtpmask")) {
2582                                 if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
2583                                         (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED) 
2584                                                                                         == 0)) {
2585                                         ast_mutex_init(&peer->rtpmask->lock);
2586                                         peer->rtpmask->inuse = 1;
2587                                         ast_copy_string(peer->rtpmaskstr, v->value, 
2588                                                                 sizeof(peer->rtpmaskstr));
2589                                 } else peer->rtpmask = NULL;
2590                         } else if (!strcasecmp(v->name, "disallow")) {
2591                                 ast_format_cap_update_by_allow_disallow(peer->cap, v->value, 0);
2592                         } else if (!strcasecmp(v->name, "allow")) {
2593                                 const char* tcodecs = v->value;
2594                                 if (!strcasecmp(v->value, "all")) {
2595                                         tcodecs = "ulaw,alaw,g729,g723,gsm";
2596                                 }
2597                                 ast_format_cap_update_by_allow_disallow(peer->cap, tcodecs, 1);
2598                         } else if (!strcasecmp(v->name,  "amaflags")) {
2599                                 peer->amaflags = ast_channel_string2amaflag(v->value);
2600                         } else if (!strcasecmp(v->name, "roundtrip")) {
2601                                 sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
2602                         } else if (!strcasecmp(v->name, "dtmfmode")) {
2603                                 if (!strcasecmp(v->value, "rfc2833"))
2604                                         peer->dtmfmode = H323_DTMF_RFC2833;
2605                                 if (!strcasecmp(v->value, "cisco"))
2606                                         peer->dtmfmode = H323_DTMF_CISCO;
2607                                 else if (!strcasecmp(v->value, "q931keypad"))
2608                                         peer->dtmfmode = H323_DTMF_Q931;
2609                                 else if (!strcasecmp(v->value, "h245alphanumeric"))
2610                                         peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2611                                 else if (!strcasecmp(v->value, "h245signal"))
2612                                         peer->dtmfmode = H323_DTMF_H245SIGNAL;
2613                                 else if (!strcasecmp(v->value, "inband"))
2614                                         peer->dtmfmode = H323_DTMF_INBAND;
2615                         } else if (!strcasecmp(v->name, "relaxdtmf")) {
2616                                 peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2617                         } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2618                                 peer->dtmfcodec = atoi(v->value);
2619                         } else if (!strcasecmp(v->name, "faxdetect")) {
2620                                 if (ast_true(v->value)) {
2621                                         peer->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
2622                                 } else if (ast_false(v->value)) {
2623                                         peer->faxdetect = 0;
2624                                 } else {
2625                                         char *buf = ast_strdupa(v->value);
2626                                         char *word, *next = buf;
2627                                         peer->faxdetect = 0;
2628                                         while ((word = strsep(&next, ","))) {
2629                                                 if (!strcasecmp(word, "cng")) {
2630                                                         peer->faxdetect |= FAXDETECT_CNG;
2631                                                 } else if (!strcasecmp(word, "t38")) {
2632                                                         peer->faxdetect |= FAXDETECT_T38;
2633                                                 } else {
2634                                                         ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
2635                                                 }
2636                                         }
2637
2638                                 }
2639                         } else if (!strcasecmp(v->name, "t38support")) {
2640                                 if (!strcasecmp(v->value, "disabled"))
2641                                         peer->t38support = T38_DISABLED;
2642                                 if (!strcasecmp(v->value, "no"))
2643                                         peer->t38support = T38_DISABLED;
2644                                 else if (!strcasecmp(v->value, "faxgw"))
2645                                         peer->t38support = T38_FAXGW;
2646                                 else if (!strcasecmp(v->value, "yes"))
2647                                         peer->t38support = T38_ENABLED;
2648                         }
2649                         v = v->next;
2650                 }
2651         }
2652
2653         if (gH323Debug)
2654                 ast_verb(0, "+++   build_peer\n");
2655
2656         return peer;
2657 }
2658
2659 static int ooh323_do_reload(void)
2660 {
2661         struct ooAliases * pNewAlias = NULL;
2662         struct ooh323_peer *peer = NULL;
2663
2664         if (gH323Debug) {
2665                 ast_verb(0, "---   ooh323_do_reload\n");
2666         }
2667
2668         /* Gatekeeper */
2669         if (gH323ep.gkClient) {
2670                 ooGkClientDestroy();
2671         }
2672
2673         reload_config(1);
2674
2675         /* Gatekeeper */
2676         if (gRasGkMode == RasUseSpecificGatekeeper || 
2677                 gRasGkMode == RasDiscoverGatekeeper) {
2678                 ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ? 
2679                                                                 gGatekeeper : 0, 0);
2680                 ooGkClientStart(gH323ep.gkClient);
2681         }
2682
2683         /* Set aliases if any */
2684         if (gH323Debug) {
2685                 ast_verb(0, "updating local aliases\n");
2686         }
2687
2688         for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
2689                 switch (pNewAlias->type) {
2690                 case T_H225AliasAddress_h323_ID:
2691                         ooH323EpAddAliasH323ID(pNewAlias->value);
2692                         break;
2693                 case T_H225AliasAddress_dialedDigits:   
2694                         ooH323EpAddAliasDialedDigits(pNewAlias->value);
2695                         break;
2696                 case T_H225AliasAddress_email_ID:       
2697                         ooH323EpAddAliasEmailID(pNewAlias->value);
2698                         break;
2699                 default:
2700                         ;
2701                 }
2702         }
2703
2704         ast_mutex_lock(&peerl.lock);
2705         peer = peerl.peers;
2706         while (peer) {
2707                 if(peer->h323id) {
2708                         ooH323EpAddAliasH323ID(peer->h323id);
2709                 }
2710                 if(peer->email) {
2711                         ooH323EpAddAliasEmailID(peer->email);
2712                 }
2713                 if(peer->e164) {
2714                         ooH323EpAddAliasDialedDigits(peer->e164);
2715                 }
2716                 if(peer->url) {
2717                         ooH323EpAddAliasURLID(peer->url);
2718                 }
2719                 peer = peer->next;
2720         }
2721         ast_mutex_unlock(&peerl.lock);
2722
2723         if (gH323Debug) {
2724                 ast_verb(0, "+++   ooh323_do_reload\n");
2725         }
2726
2727         return 0;
2728 }
2729
2730 /*--- h323_reload: Force reload of module from cli ---*/
2731
2732 char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2733 {
2734
2735        switch (cmd) {
2736        case CLI_INIT:
2737                e->command = "ooh323 reload";
2738                e->usage =
2739                        "Usage: ooh323 reload\n"
2740                        "                Reload OOH323 config.\n";
2741                return NULL;
2742        case CLI_GENERATE:
2743                return NULL;
2744        }
2745
2746        if (a->argc != 2)
2747                return CLI_SHOWUSAGE;
2748
2749         if (gH323Debug)
2750                 ast_verb(0, "---   ooh323_reload\n");
2751
2752         ast_mutex_lock(&h323_reload_lock);
2753         if (h323_reloading) {
2754                 ast_verb(0, "Previous OOH323 reload not yet done\n");
2755    } else {
2756                 h323_reloading = 1;
2757         }
2758         ast_mutex_unlock(&h323_reload_lock);
2759         restart_monitor();
2760
2761         if (gH323Debug)
2762                 ast_verb(0, "+++   ooh323_reload\n");
2763
2764         return 0;
2765 }
2766
2767 int reload_config(int reload)
2768 {
2769         int format;
2770         struct ooAliases  *pNewAlias = NULL, *cur, *prev;
2771         struct ast_config *cfg;
2772         struct ast_variable *v;
2773         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2774         struct ooh323_user *user = NULL;
2775         struct ooh323_peer *peer = NULL;
2776         char *cat;
2777         const char *utype;
2778
2779         if (gH323Debug)
2780                 ast_verb(0, "---   reload_config\n");
2781
2782         cfg = ast_config_load((char*)config, config_flags);
2783
2784         /* We *must* have a config file otherwise stop immediately */
2785         if (!cfg) {
2786                 ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
2787                 return 1;
2788         } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
2789                 return RESULT_SUCCESS;
2790
2791         if (reload) {
2792                 delete_users();
2793                 delete_peers();
2794                 if (gH323Debug) {
2795                         ast_verb(0, "  reload_config - Freeing up alias list\n");
2796                 }
2797                 cur = gAliasList;
2798                 while (cur) {
2799                         prev = cur;
2800                         cur = cur->next;
2801                         ast_free(prev->value);
2802                         ast_free(prev);
2803                 }
2804                 gAliasList = NULL;
2805                 ooH323EpClearAllAliases();
2806         }
2807
2808         /* Inintialize everything to default */
2809         strcpy(gLogFile, DEFAULT_LOGFILE);
2810         gPort = 1720;
2811         gIP[0] = '\0';
2812         strcpy(gCallerID, DEFAULT_H323ID);
2813         ast_format_cap_remove_by_type(gCap, AST_MEDIA_TYPE_UNKNOWN);
2814         ast_format_cap_append(gCap, ast_format_ulaw, 0);
2815         gDTMFMode = H323_DTMF_RFC2833;
2816         gDTMFCodec = 101;
2817         gFAXdetect = FAXDETECT_CNG;
2818         gT38Support = T38_FAXGW;
2819         gTRCLVL = OOTRCLVLERR;
2820         gRasGkMode = RasNoGatekeeper;
2821         gGatekeeper[0] = '\0';
2822         gRTPTimeout = 60;
2823         gNat = FALSE;
2824         gRTDRInterval = 0;
2825         gRTDRCount = 0;
2826         strcpy(gAccountcode, DEFAULT_H323ACCNT);
2827         gFastStart = 1;
2828         gTunneling = 1;
2829         gTOS = 0;
2830         strcpy(gContext, DEFAULT_CONTEXT);
2831         gAliasList = NULL;
2832         gMediaWaitForConnect = 0;
2833         ooconfig.mTCPPortStart = 12030;
2834         ooconfig.mTCPPortEnd = 12230;
2835         memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2836
2837         v = ast_variable_browse(cfg, "general");
2838         while (v) {
2839
2840                 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
2841                         v = v->next;
2842                         continue;
2843                 }
2844         
2845                 if (!strcasecmp(v->name, "port")) {
2846                         gPort = (int)strtol(v->value, NULL, 10);
2847                 } else if (!strcasecmp(v->name, "bindaddr")) {
2848                         ast_copy_string(gIP, v->value, sizeof(gIP));
2849                         if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
2850                                 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
2851                                 ast_config_destroy(cfg);
2852                                 return 1;
2853                         }
2854                         if (ast_sockaddr_is_ipv6(&bindaddr)) {
2855                                 v6mode = 1;
2856                         }
2857                 } else if (!strcasecmp(v->name, "h225portrange")) {
2858                         char* endlimit = 0;
2859                         char temp[512];
2860                         ast_copy_string(temp, v->value, sizeof(temp));
2861                         endlimit = strchr(temp, ',');
2862                         if (endlimit) {
2863                                 *endlimit = '\0';
2864                                 endlimit++;
2865                                 ooconfig.mTCPPortStart = atoi(temp);
2866                                 ooconfig.mTCPPortEnd = atoi(endlimit);
2867
2868                         } else {
2869                                 ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
2870                         }
2871                 } else if (!strcasecmp(v->name, "gateway")) {
2872                         gIsGateway = ast_true(v->value);
2873                 } else if (!strcasecmp(v->name, "faststart")) {
2874                         gFastStart = ast_true(v->value);
2875                         if (gFastStart)
2876                                 ooH323EpEnableFastStart();
2877                         else
2878                                 ooH323EpDisableFastStart();
2879                 } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
2880                         gMediaWaitForConnect = ast_true(v->value);
2881                         if (gMediaWaitForConnect)
2882                                 ooH323EpEnableMediaWaitForConnect();
2883                         else 
2884                                 ooH323EpDisableMediaWaitForConnect();
2885                 } else if (!strcasecmp(v->name, "h245tunneling")) {
2886                         gTunneling = ast_true(v->value);
2887                         if (gTunneling)
2888                                 ooH323EpEnableH245Tunneling();
2889                         else
2890                                 ooH323EpDisableH245Tunneling();
2891                 } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
2892                         gDirectRTP = ast_true(v->value);
2893                         gEarlyDirect = ast_true(v->value);
2894                 } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
2895                         gEarlyDirect = ast_true(v->value);
2896                 } else if (!strcasecmp(v->name, "g729onlyA")) {
2897                         g729onlyA = ast_true(v->value);
2898                 } else if (!strcasecmp(v->name, "roundtrip")) {
2899                         sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
2900                 } else if (!strcasecmp(v->name, "trybemaster")) {
2901                         gBeMaster = ast_true(v->value);
2902                         if (gBeMaster)
2903                                 ooH323EpTryBeMaster(1);
2904                         else 
2905                                 ooH323EpTryBeMaster(0);
2906                 } else if (!strcasecmp(v->name, "h323id")) {
2907                         pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2908                         if (!pNewAlias) {
2909                                 ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
2910                                 ast_config_destroy(cfg);
2911                                 return 1;
2912                         }
2913                         if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
2914                                 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2915                         }
2916                         pNewAlias->type =  T_H225AliasAddress_h323_ID;
2917                         pNewAlias->value = ast_strdup(v->value);
2918                         pNewAlias->next = gAliasList;
2919                         gAliasList = pNewAlias;
2920                         pNewAlias = NULL;
2921                 } else if (!strcasecmp(v->name, "e164")) {
2922                         int valid = 1;
2923                         const char *tmp;
2924                         for(tmp = v->value; *tmp; tmp++) {
2925                                 if (!isdigit(*tmp)) {
2926                                         valid = 0;
2927                                         break;
2928                                 }
2929                         }
2930                         if (valid) {
2931                                 pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2932                                 if (!pNewAlias) {
2933                                         ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
2934                                         ast_config_destroy(cfg);
2935                                         return 1;
2936                                 }
2937                                 pNewAlias->type =  T_H225AliasAddress_dialedDigits;
2938                                 pNewAlias->value = ast_strdup(v->value);
2939                                 pNewAlias->next = gAliasList;
2940                                 gAliasList = pNewAlias;
2941                                 pNewAlias = NULL;
2942                         } else {
2943                                 ast_log(LOG_ERROR, "Invalid e164: %s\n", v->value);
2944                         }
2945                 } else if (!strcasecmp(v->name, "email")) {
2946                         pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
2947                         if (!pNewAlias) {
2948                                 ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
2949                                 ast_config_destroy(cfg);
2950                                 return 1;
2951                         }
2952                         pNewAlias->type =  T_H225AliasAddress_email_ID;
2953                         pNewAlias->value = ast_strdup(v->value);
2954                         pNewAlias->next = gAliasList;
2955                         gAliasList = pNewAlias;
2956                         pNewAlias = NULL;
2957       } else if (!strcasecmp(v->name, "t35country")) {
2958          t35countrycode = atoi(v->value);
2959       } else if (!strcasecmp(v->name, "t35extensions")) {
2960          t35extensions = atoi(v->value);
2961       } else if (!strcasecmp(v->name, "manufacturer")) {
2962          manufacturer = atoi(v->value);
2963       } else if (!strcasecmp(v->name, "vendorid")) {
2964          ast_copy_string(vendor, v->value, sizeof(vendor));
2965       } else if (!strcasecmp(v->name, "versionid")) {
2966          ast_copy_string(version, v->value, sizeof(version));
2967                 } else if (!strcasecmp(v->name, "callerid")) {
2968                         ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2969                 } else if (!strcasecmp(v->name, "incominglimit")) {
2970                         gIncomingLimit = atoi(v->value);
2971                 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2972                         gOutgoingLimit = atoi(v->value);
2973                 } else if (!strcasecmp(v->name, "gatekeeper")) {
2974                         if (!strcasecmp(v->value, "DISABLE")) {
2975                                 gRasGkMode = RasNoGatekeeper;
2976                         } else if (!strcasecmp(v->value, "DISCOVER")) {
2977                                 gRasGkMode = RasDiscoverGatekeeper;
2978                         } else {
2979                                 gRasGkMode = RasUseSpecificGatekeeper;
2980                                 ast_copy_string(gGatekeeper, v->value, sizeof(gGatekeeper));
2981                         }
2982                 } else if (!strcasecmp(v->name, "logfile")) {
2983                         ast_copy_string(gLogFile, v->value, sizeof(gLogFile));
2984                 } else if (!strcasecmp(v->name, "context")) {
2985                         ast_copy_string(gContext, v->value, sizeof(gContext));
2986                         ast_verb(3, "  == Setting default context to %s\n", gContext);
2987                 } else if (!strcasecmp(v->name, "nat")) {
2988                         gNat = ast_true(v->value);
2989                 } else if (!strcasecmp(v->name, "rtptimeout")) {
2990                         gRTPTimeout = atoi(v->value);
2991                         if (gRTPTimeout < 0)
2992                                 gRTPTimeout = 60;
2993                 } else if (!strcasecmp(v->name, "tos")) {