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