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