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