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