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