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