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