Fix compile of chan_ooh323.c from IPv6 integration.
[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 ast_sockaddr tmp;
464         struct in_addr ipAddr;
465         if (gH323Debug)
466                 ast_verbose("---   ooh323_alloc\n");
467
468         if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
469                 ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
470                 return NULL;
471         }
472
473         ast_mutex_init(&pvt->lock);
474         ast_mutex_lock(&pvt->lock);
475
476
477         if (!inet_aton(gIP, &ipAddr)) {
478                 ast_log(LOG_ERROR, "Invalid OOH323 driver ip address\n");
479                 ast_mutex_unlock(&pvt->lock);
480                 ast_mutex_destroy(&pvt->lock);
481                 ast_free(pvt);
482                 return NULL;
483         }
484
485         ouraddr.sin_family = AF_INET;
486         ouraddr.sin_addr = ipAddr;
487         ast_sockaddr_from_sin(&tmp, &ouraddr);
488         if (!(pvt->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
489                 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", 
490                                   strerror(errno));
491                 ast_mutex_unlock(&pvt->lock);
492                 ast_mutex_destroy(&pvt->lock);
493                 ast_free(pvt);
494                 return NULL;
495         }
496  
497         ast_rtp_instance_set_qos(pvt->rtp, gTOS, 0, "ooh323-rtp");
498
499         if (!(pvt->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, ipAddr))) {
500                 ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
501                                 strerror(errno));
502                 ast_mutex_unlock(&pvt->lock);
503                 ast_mutex_destroy(&pvt->lock);
504                 ast_free(pvt);
505                 return NULL;
506         }
507
508         ast_udptl_set_error_correction_scheme(pvt->udptl, UDPTL_ERROR_CORRECTION_NONE);
509         pvt->faxmode = 0;
510         pvt->t38support = gT38Support;
511         pvt->rtptimeout = gRTPTimeout;
512         pvt->rtdrinterval = gRTDRInterval;
513         pvt->rtdrcount = gRTDRCount;
514
515         pvt->call_reference = callref;
516         if (callToken)
517                 pvt->callToken = strdup(callToken);
518
519         /* whether to use gk for this call */
520         if (gRasGkMode == RasNoGatekeeper)
521                 OO_SETFLAG(pvt->flags, H323_DISABLEGK);
522
523         pvt->dtmfmode = gDTMFMode;
524         pvt->dtmfcodec = gDTMFCodec;
525         ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
526         ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
527
528         pvt->amaflags = gAMAFLAGS;
529         pvt->capability = gCapability;
530         memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
531
532         ast_mutex_unlock(&pvt->lock); 
533         /* Add to interface list */
534         ast_mutex_lock(&iflock);
535         pvt->next = iflist;
536         iflist = pvt;
537         ast_mutex_unlock(&iflock);
538
539         if (gH323Debug)
540                 ast_verbose("+++   ooh323_alloc\n");
541
542         return pvt;
543 }
544
545
546 /*
547         Possible data values - peername, exten/peername, exten@ip
548  */
549 static struct ast_channel *ooh323_request(const char *type, format_t format,
550                 const struct ast_channel *requestor, void *data, int *cause)
551
552 {
553         struct ast_channel *chan = NULL;
554         struct ooh323_pvt *p = NULL;
555         struct ooh323_peer *peer = NULL;
556         char *dest = NULL; 
557         char *ext = NULL;
558         char tmp[256];
559         char formats[FORMAT_STRING_SIZE];
560         int oldformat;
561         int port = 0;
562
563         if (gH323Debug)
564                 ast_verbose("---   ooh323_request - data %s format %s\n", (char*)data,  
565                                                                                 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,format));
566
567         oldformat = format;
568         format &= AST_FORMAT_AUDIO_MASK;
569         if (!format) {
570                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%lld'\n", (long long) format);
571                 return NULL;
572         }
573
574         p = ooh323_alloc(0,0); /* Initial callRef is zero */
575
576         if (!p) {
577                 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char*)data);
578                 return NULL;
579         }
580         ast_mutex_lock(&p->lock);
581
582         /* This is an outgoing call, since ooh323_request is called */
583         ast_set_flag(p, H323_OUTGOING);
584
585
586         ast_copy_string(tmp, data, sizeof(tmp));
587
588         dest = strchr(tmp, '/');
589
590         if (dest) {  
591                 *dest = '\0';
592                 dest++;
593                 ext = dest;
594                 dest = tmp;
595         } else if ((dest = strchr(tmp, '@'))) {
596                 *dest = '\0';
597                 dest++;
598                 ext = tmp;
599         } else {
600                 dest = tmp;
601                 ext = NULL;
602         }
603
604 #if 0
605         if ((sport = strchr(dest, ':'))) {
606                 *sport = '\0';
607                 sport++;
608                 port = atoi(sport);
609         }
610 #endif
611
612         if (dest) {
613                 peer = find_peer(dest, port);
614         } else{
615                 ast_mutex_lock(&iflock);
616                 ast_mutex_unlock(&p->lock);
617                 ooh323_destroy(p);
618                 ast_mutex_unlock(&iflock);
619                 ast_log(LOG_ERROR, "Destination format is not supported\n");
620                 return NULL;
621         }
622
623         if (peer) {
624                 p->username = strdup(peer->name);
625                 p->host = strdup(peer->ip);
626                 p->port = peer->port;
627                 /* Disable gk as we are going to call a known peer*/
628                 /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
629
630                 if (ext)
631                         ast_copy_string(p->exten, ext, sizeof(p->exten));
632
633                 p->capability = peer->capability;
634                 memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
635                 p->dtmfmode |= peer->dtmfmode;
636                 p->dtmfcodec  = peer->dtmfcodec;
637                 p->t38support = peer->t38support;
638                 p->rtptimeout = peer->rtptimeout;
639                 if (peer->rtpmask && peer->rtpmaskstr[0]) {
640                         p->rtpmask = peer->rtpmask;
641                         ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
642                 }
643
644                 if (peer->rtdrinterval) {
645                         p->rtdrinterval = peer->rtdrinterval;
646                         p->rtdrcount = peer->rtdrcount;
647                 }
648
649                 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
650                 p->amaflags = peer->amaflags;
651         } else {
652                 if (gRasGkMode ==  RasNoGatekeeper) {
653                         /* no gk and no peer */
654                         ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
655                         ast_mutex_lock(&iflock);
656                         ast_mutex_unlock(&p->lock);
657                         ooh323_destroy(p);
658                         ast_mutex_unlock(&iflock);
659                         return NULL;
660                 }
661                 p->dtmfmode = gDTMFMode;
662                 p->dtmfcodec = gDTMFCodec;
663                 p->t38support = gT38Support;
664                 p->rtptimeout = gRTPTimeout;
665                 p->capability = gCapability;
666                 p->rtdrinterval = gRTDRInterval;
667                 p->rtdrcount = gRTDRCount;
668
669                 memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));
670                 p->username = strdup(dest);
671
672                 p->host = strdup(dest);
673                 if (port > 0) {
674                         p->port = port;
675                 }
676                 if (ext) {
677                         ast_copy_string(p->exten, ext, sizeof(p->exten));
678                 }
679         }
680
681
682         chan = ooh323_new(p, AST_STATE_DOWN, p->username, format,
683                                  requestor ? requestor->linkedid : NULL);
684         
685         ast_mutex_unlock(&p->lock);
686
687         if (!chan) {
688                 ast_mutex_lock(&iflock);
689                 ooh323_destroy(p);
690                 ast_mutex_unlock(&iflock);
691         } else {
692                 ast_mutex_lock(&p->lock);
693                 p->callToken = (char*)ast_malloc(AST_MAX_EXTENSION);
694                 if(!p->callToken) {
695                         ast_mutex_unlock(&p->lock);
696                         ast_mutex_lock(&iflock);
697                         ooh323_destroy(p);
698                         ast_mutex_unlock(&iflock);
699                         ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
700                         return NULL;
701                 }
702
703                 ast_mutex_unlock(&p->lock);
704                 ast_mutex_lock(&ooh323c_cmd_lock);
705                 ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
706                 ast_mutex_unlock(&ooh323c_cmd_lock);
707         }
708
709         restart_monitor();
710         if (gH323Debug)
711                 ast_verbose("+++   ooh323_request\n");
712
713         return chan;
714
715 }
716
717
718 static struct ooh323_pvt* find_call(ooCallData *call)
719 {
720         struct ooh323_pvt *p;
721
722         if (gH323Debug)
723                 ast_verbose("---   find_call\n");
724
725         ast_mutex_lock(&iflock);
726
727         for (p = iflist; p; p = p->next) {
728                 if (p->callToken && !strcmp(p->callToken, call->callToken)) {
729                         break;
730                 }
731         }
732         ast_mutex_unlock(&iflock);
733
734         if (gH323Debug)
735                 ast_verbose("+++   find_call\n");
736
737         return p;
738 }
739
740 struct ooh323_user *find_user(const char * name, const char* ip)
741 {
742         struct ooh323_user *user;
743
744         if (gH323Debug)
745       ast_verbose("---   find_user: %s, %s\n",name,ip);
746
747         ast_mutex_lock(&userl.lock);
748
749         for (user = userl.users; user; user = user->next) {
750                 if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
751                         break;
752                 }
753                 if (name && !strcmp(user->name, name)) {
754                         break;
755                 }
756         }
757
758         ast_mutex_unlock(&userl.lock);
759
760         if (gH323Debug)
761                 ast_verbose("+++   find_user\n");
762
763         return user;
764 }
765
766 struct ooh323_peer *find_friend(const char *name, int port)
767 {
768         struct ooh323_peer *peer;  
769
770         if (gH323Debug)
771                 ast_verbose("---   find_friend \"%s\"\n", name);
772
773
774         ast_mutex_lock(&peerl.lock);
775         for (peer = peerl.peers; peer; peer = peer->next) {
776                 if (gH323Debug) {
777                         ast_verbose("           comparing with \"%s\"\n", peer->ip);
778                 }
779                 if (!strcmp(peer->ip, name)) {
780                         if (port <= 0 || (port > 0 && peer->port == port)) {
781                                 break;
782                         }
783                 }
784         }
785         ast_mutex_unlock(&peerl.lock);
786
787         if (gH323Debug) {
788                 if (peer) {
789                         ast_verbose("           found matching friend\n");
790                 }
791                 ast_verbose("+++   find_friend \"%s\"\n", name);
792         }
793
794         return peer;            
795 }
796
797
798 struct ooh323_peer *find_peer(const char * name, int port)
799 {
800         struct ooh323_peer *peer;
801
802         if (gH323Debug)
803                 ast_verbose("---   find_peer \"%s\"\n", name);
804
805
806         ast_mutex_lock(&peerl.lock);
807         for (peer = peerl.peers; peer; peer = peer->next) {
808                 if (gH323Debug) {
809                         ast_verbose("           comparing with \"%s\"\n", peer->ip);
810                 }
811                 if (!strcasecmp(peer->name, name))
812                         break;
813                 if (peer->h323id && !strcasecmp(peer->h323id, name))
814                         break;
815                 if (peer->e164 && !strcasecmp(peer->e164, name))
816                         break;
817                 /*
818                 if (!strcmp(peer->ip, name)) {
819                         if (port > 0 && peer->port == port) { break; }
820                         else if (port <= 0) { break; }
821                 }
822                 */
823         }
824         ast_mutex_unlock(&peerl.lock);
825
826         if (gH323Debug) {
827                 if (peer) {
828                         ast_verbose("           found matching peer\n");
829                 }
830                 ast_verbose("+++   find_peer \"%s\"\n", name);
831         }
832
833         return peer;            
834 }
835
836 static int ooh323_digit_begin(struct ast_channel *chan, char digit)
837 {
838         char dtmf[2];
839         struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
840         
841         if (gH323Debug)
842                 ast_verbose("---   ooh323_digit_begin\n");
843
844         if (!p) {
845                 ast_log(LOG_ERROR, "No private structure for call\n");
846                 return -1;
847         }
848         ast_mutex_lock(&p->lock);
849
850
851         if (digit == 'e' && !p->faxmode && p->t38support != T38_DISABLED)  {
852                 if (!p->chmodepend) {
853                         if (gH323Debug)
854                                 ast_verbose("request to change %s to t.38 because fax cng\n",
855                                                 p->callToken);
856                         p->chmodepend = 1;
857                         ooRequestChangeMode(p->callToken, 1);
858                 }
859
860         } else if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
861                 ast_rtp_instance_dtmf_begin(p->rtp, digit);
862         } else if (((p->dtmfmode & H323_DTMF_Q931) ||
863                                                  (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
864                                                  (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
865                 dtmf[0] = digit;
866                 dtmf[1] = '\0';
867                 ooSendDTMFDigit(p->callToken, dtmf);
868         }
869         ast_mutex_unlock(&p->lock);
870         if (gH323Debug)
871                 ast_verbose("+++   ooh323_digit_begin\n");
872
873         return 0;
874 }
875
876 static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
877 {
878         struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
879
880         if (gH323Debug)
881                 ast_verbose("---   ooh323_digit_end\n");
882
883         if (!p) {
884                 ast_log(LOG_ERROR, "No private structure for call\n");
885                 return -1;
886         }
887         ast_mutex_lock(&p->lock);
888         if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) 
889                 ast_rtp_instance_dtmf_end(p->rtp, digit);
890
891         ast_mutex_unlock(&p->lock);
892         if (gH323Debug)
893                 ast_verbose("+++   ooh323_digit_end\n");
894
895         return 0;
896 }
897
898
899 static int ooh323_call(struct ast_channel *ast, char *dest, int timeout)
900 {
901         struct ooh323_pvt *p = ast->tech_pvt;
902         char destination[256];
903         int res=0, i;
904         const char *val = NULL;
905         ooCallOptions opts = {
906                 .fastStart = TRUE,
907                 .tunneling = TRUE,
908                 .disableGk = TRUE,
909                 .callMode = OO_CALLMODE_AUDIOCALL,
910                 .transfercap = 0
911         };
912
913         if (gH323Debug)
914                 ast_verbose("---   ooh323_call- %s\n", dest);
915
916
917    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) 
918    {
919                 ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
920                                                                         "reserved\n", ast->name);
921                 return -1;
922         }
923         ast_mutex_lock(&p->lock);
924         ast_set_flag(p, H323_OUTGOING);
925         if (ast->connected.id.number) {
926                 if(p->callerid_num)   free(p->callerid_num);
927                 p->callerid_num = strdup(ast->connected.id.number);
928         }
929
930         if (ast->connected.id.name) {
931                 if(p->callerid_name)
932                         free(p->callerid_name);
933                 p->callerid_name = strdup(ast->connected.id.name);
934         } else if (ast->connected.id.number) {
935                 if(p->callerid_name)
936                         free(p->callerid_name);
937                 p->callerid_name = strdup(ast->connected.id.number);
938         } else {
939                 ast->connected.id.name = strdup(gCallerID);
940                 if(p->callerid_name)
941                         free(p->callerid_name);
942                 p->callerid_name = strdup(ast->connected.id.name);
943         }
944
945         /* Retrieve vars */
946
947
948         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
949                 ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
950         }
951         
952         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
953                 ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
954                 if(!p->callerid_num)
955                         p->callerid_num = strdup(val);
956         }
957
958         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
959                 ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
960         }
961
962         if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
963                 ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
964         }
965
966         if (p->host && p->port != 0)
967                 snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
968         else if (p->host)
969                 snprintf(destination, sizeof(destination), "%s", p->host);
970         else
971                 ast_copy_string(destination, dest, sizeof(destination));
972
973         destination[sizeof(destination)-1]='\0';
974
975         opts.transfercap = ast->transfercapability;
976
977         for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
978
979         if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
980                 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
981         } else {
982                 res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
983         }
984
985         ast_mutex_unlock(&p->lock);
986         if (res != OO_OK) {
987                 ast_log(LOG_ERROR, "Failed to make call\n");
988                 return -1; /* ToDO: cleanup */
989         }
990         if (gH323Debug)
991                 ast_verbose("+++   ooh323_call\n");
992
993   return 0;
994 }
995
996 static int ooh323_hangup(struct ast_channel *ast)
997 {
998         struct ooh323_pvt *p = ast->tech_pvt;
999         int q931cause = AST_CAUSE_NORMAL_CLEARING;
1000
1001         if (gH323Debug)
1002                 ast_verbose("---   ooh323_hangup\n");
1003
1004         if (p) {
1005                 ast_mutex_lock(&p->lock);
1006
1007         if (ast->hangupcause) {
1008                 q931cause = ast->hangupcause;
1009         } else {
1010                 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
1011                 if (cause) {
1012                         if (!strcmp(cause, "CONGESTION")) {
1013                                 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1014                         } else if (!strcmp(cause, "BUSY")) {
1015                                 q931cause = AST_CAUSE_USER_BUSY;
1016                         } else if (!strcmp(cause, "CHANISUNVAIL")) {
1017                                 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1018                         } else if (!strcmp(cause, "NOANSWER")) {
1019                                 q931cause = AST_CAUSE_NO_ANSWER;
1020                         } else if (!strcmp(cause, "CANCEL")) {
1021                                 q931cause = AST_CAUSE_CALL_REJECTED;
1022                         }
1023                 }
1024         }
1025
1026
1027
1028                 if (gH323Debug)
1029                         ast_verbose("    hanging %s with cause: %d\n", p->username, q931cause);
1030                 ast->tech_pvt = NULL; 
1031                 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1032                         ooHangCall(p->callToken, 
1033                                 ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
1034                         ast_set_flag(p, H323_ALREADYGONE);
1035                         /* ast_mutex_unlock(&p->lock); */
1036                 } else 
1037                         ast_set_flag(p, H323_NEEDDESTROY);
1038                 /* detach channel here */
1039                 if (p->owner) {
1040                         p->owner->tech_pvt = NULL;
1041                         p->owner = NULL;
1042                         ast_module_unref(myself);
1043                 }
1044
1045                 ast_mutex_unlock(&p->lock);
1046                 ast_mutex_lock(&usecnt_lock);
1047                 usecnt--;
1048                 ast_mutex_unlock(&usecnt_lock);
1049
1050                 /* Notify the module monitors that use count for resource has changed */
1051                 ast_update_use_count();
1052           
1053         } else {
1054                 ast_debug(1, "No call to hangup\n" );
1055         }
1056         
1057         if (gH323Debug)
1058                 ast_verbose("+++   ooh323_hangup\n");
1059
1060   return 0;
1061 }
1062
1063 static int ooh323_answer(struct ast_channel *ast)
1064 {
1065         struct ooh323_pvt *p = ast->tech_pvt;
1066
1067         if (gH323Debug)
1068                 ast_verbose("--- ooh323_answer\n");
1069
1070         if (p) {
1071
1072                 ast_mutex_lock(&p->lock);
1073                 if (ast->_state != AST_STATE_UP) {
1074                         ast_channel_lock(ast);
1075                         ast_setstate(ast, AST_STATE_UP);
1076                         if (option_debug)
1077                                 ast_debug(1, "ooh323_answer(%s)\n", ast->name);
1078                         ast_channel_unlock(ast);
1079                         ooAnswerCall(p->callToken);
1080                 }
1081                 ast_mutex_unlock(&p->lock);
1082         }
1083
1084         if (gH323Debug)
1085                 ast_verbose("+++ ooh323_answer\n");
1086
1087   return 0;
1088 }
1089
1090 static struct ast_frame *ooh323_read(struct ast_channel *ast)
1091 {
1092         struct ast_frame *fr;
1093         static struct ast_frame null_frame = { AST_FRAME_NULL, };
1094         struct ooh323_pvt *p = ast->tech_pvt;
1095
1096         if (!p) return &null_frame;
1097
1098         ast_mutex_lock(&p->lock);
1099         if (p->rtp)
1100                 fr = ooh323_rtp_read(ast, p);
1101         else
1102                 fr = &null_frame;
1103         /* time(&p->lastrtprx); */
1104         ast_mutex_unlock(&p->lock);
1105         return fr;
1106 }
1107
1108 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
1109 {
1110         struct ooh323_pvt *p = ast->tech_pvt;
1111         int res = 0;
1112         char buf[256];
1113
1114         if (p) {
1115                 ast_mutex_lock(&p->lock);
1116
1117                 if (f->frametype == AST_FRAME_MODEM) {
1118                         ast_debug(1, "Send UDPTL %d/%d len %d for %s\n",
1119                                 f->frametype, f->subclass.integer, f->datalen, ast->name);
1120                         if (p->udptl)
1121                                 res = ast_udptl_write(p->udptl, f);
1122                         ast_mutex_unlock(&p->lock);
1123                         return res;
1124                 }
1125
1126         
1127                 if (f->frametype == AST_FRAME_VOICE) {
1128 /* sending progress for first */
1129                         if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
1130                                         p->callToken) {
1131                                 ooManualProgress(p->callToken);
1132                                 p->progsent = 1;
1133                         }
1134
1135
1136                         if (!(f->subclass.codec & ast->nativeformats)) {
1137                                 if (ast->nativeformats != 0) {
1138                                         ast_log(LOG_WARNING,
1139                                                         "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1140                                                         ast_getformatname(f->subclass.codec),
1141                                                         ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
1142                                                         ast_getformatname(ast->readformat),
1143                                                         ast_getformatname(ast->writeformat));
1144
1145                                         ast_set_write_format(ast, f->subclass.codec);
1146                                 } else {
1147                                         /* ast_set_write_format(ast, f->subclass);
1148                                         ast->nativeformats = f->subclass; */
1149                                 }
1150                         ast_mutex_unlock(&p->lock);
1151                         return 0;
1152                         }
1153
1154                 if (p->rtp)
1155                         res = ast_rtp_instance_write(p->rtp, f);
1156
1157                 ast_mutex_unlock(&p->lock);
1158
1159                 } else if (f->frametype == AST_FRAME_IMAGE) {
1160                         ast_mutex_unlock(&p->lock);
1161                         return 0;
1162                 } else {
1163                         ast_log(LOG_WARNING, "Can't send %d type frames with OOH323 write\n", 
1164                                                                          f->frametype);
1165                         ast_mutex_unlock(&p->lock);
1166                         return 0;
1167                 }
1168
1169         }
1170
1171         return res;
1172 }
1173
1174 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1175 {
1176
1177         struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
1178         char *callToken = (char *)NULL;
1179
1180         if (!p) return -1;
1181
1182         ast_mutex_lock(&p->lock);
1183         callToken = (p->callToken ? strdup(p->callToken) : NULL);
1184         ast_mutex_unlock(&p->lock);
1185
1186         if (!callToken) {
1187                 if (gH323Debug)
1188                         ast_verbose("   ooh323_indicate - No callToken\n");
1189                 return -1;
1190         }
1191
1192         if (gH323Debug)
1193                 ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken);
1194          
1195         ast_mutex_lock(&p->lock);
1196         switch (condition) {
1197         case AST_CONTROL_CONGESTION:
1198                 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1199                         ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, 
1200                                                 AST_CAUSE_SWITCH_CONGESTION);
1201                         ast_set_flag(p, H323_ALREADYGONE);
1202                 }
1203                 break;
1204         case AST_CONTROL_BUSY:
1205                 if (!ast_test_flag(p, H323_ALREADYGONE)) {
1206                         ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
1207                         ast_set_flag(p, H323_ALREADYGONE);
1208                 }
1209                 break;
1210         case AST_CONTROL_HOLD:
1211                 ast_moh_start(ast, data, NULL);         
1212                 break;
1213         case AST_CONTROL_UNHOLD:
1214                 ast_moh_stop(ast);
1215                 break;
1216         case AST_CONTROL_PROGRESS:
1217                 if (ast->_state != AST_STATE_UP) {
1218                         if (!p->progsent) {
1219                                 if (gH323Debug) 
1220                                         ast_log(LOG_DEBUG,"Sending manual progress for %s, res = %d\n", callToken,
1221                                         ooManualProgress(callToken));   
1222                                 else
1223                                         ooManualProgress(callToken);
1224                                 p->progsent = 1;
1225                         }
1226                 }
1227             break;
1228       case AST_CONTROL_RINGING:
1229             if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) {
1230                 if (gH323Debug) 
1231                         ast_log(LOG_DEBUG,"Sending manual ringback for %s, res = %d\n", 
1232                         callToken,
1233                         ooManualRingback(callToken));
1234                  else
1235                         ooManualRingback(callToken);
1236             }
1237          break;
1238         case AST_CONTROL_SRCUPDATE:
1239                 ast_rtp_instance_update_source(p->rtp);
1240                 break;
1241         case AST_CONTROL_SRCCHANGE:
1242                 ast_rtp_instance_change_source(p->rtp);
1243                 break;
1244         case AST_CONTROL_CONNECTED_LINE:
1245                 if (!ast_strlen_zero(ast->connected.id.name)) {
1246                         if (gH323Debug)
1247                                 ast_log(LOG_DEBUG, "Sending connected line info for %s (%s)\n",
1248                                 callToken, ast->connected.id.name);
1249                         ooSetANI(callToken, ast->connected.id.name);
1250                 }
1251                 break;
1252
1253       case AST_CONTROL_T38_PARAMETERS:
1254                 if (p->t38support != T38_ENABLED) {
1255                         struct ast_control_t38_parameters parameters = { .request_response = 0 };
1256                         parameters.request_response = AST_T38_REFUSED;
1257                         ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
1258                                                  &parameters, sizeof(parameters));
1259                         break;
1260                 }
1261                 if (datalen != sizeof(struct ast_control_t38_parameters)) {
1262                         ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
1263                                            "Expected %d, got %d\n",
1264                                 (int)sizeof(enum ast_control_t38), (int)datalen);
1265                 } else {
1266                         const struct ast_control_t38_parameters *parameters = data;
1267                         enum ast_control_t38 message = parameters->request_response;
1268                         switch (message) {
1269
1270                         case AST_T38_REQUEST_NEGOTIATE:
1271
1272                                 if (!p->chmodepend && !p->faxmode) {
1273                                         ooRequestChangeMode(p->callToken, 1);
1274                                         p->chmodepend = 1;
1275                                 }
1276                                 break;
1277
1278                         case AST_T38_REQUEST_TERMINATE:
1279
1280                                 if (!p->chmodepend && p->faxmode) {
1281                                         ooRequestChangeMode(p->callToken, 0);
1282                                         p->chmodepend = 1;
1283                                 }
1284                                 break;
1285
1286
1287                         default:
1288                                 ;
1289
1290                         }
1291
1292                 }
1293                 break;
1294       case AST_CONTROL_PROCEEDING:
1295         case -1:
1296                 break;
1297         default:
1298                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
1299                                                                         condition, callToken);
1300         }
1301
1302         ast_mutex_unlock(&p->lock);
1303
1304         if (gH323Debug)
1305                 ast_verbose("++++  ooh323_indicate %d on %s\n", condition, callToken);
1306
1307         free(callToken);
1308         return -1;
1309 }
1310
1311 static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1312 {
1313
1314         struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
1315         int res = -1;
1316         enum ast_t38_state state = T38_STATE_UNAVAILABLE;
1317         char* cp;
1318
1319         if (!p) return -1;
1320
1321         ast_mutex_lock(&p->lock);
1322
1323         if (gH323Debug)
1324                 ast_verbose("----- ooh323_queryoption %d on channel %s\n", option, ast->name);
1325          
1326         switch (option) {
1327
1328                 case AST_OPTION_T38_STATE:
1329
1330                         if (*datalen != sizeof(enum ast_t38_state)) {
1331                                 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
1332                                 " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
1333                                 break;
1334                         }
1335                         if (p->t38support != T38_DISABLED)
1336                                 state = T38_STATE_UNKNOWN;
1337                         if (p->faxmode)
1338                                 state = (p->chmodepend) ? T38_STATE_UNKNOWN : T38_STATE_NEGOTIATED;
1339                         else if (p->chmodepend)
1340                                 state = T38_STATE_NEGOTIATING;
1341
1342
1343                         *((enum ast_t38_state *) data) = state;
1344                         res = 0;
1345                         break;
1346
1347
1348                 case AST_OPTION_DIGIT_DETECT:
1349
1350                         cp = (char *) data;
1351                         *cp = p->vad ? 1 : 0;
1352                         ast_debug(1, "Reporting digit detection %sabled on %s\n",
1353                                                          *cp ? "en" : "dis", ast->name);
1354
1355                         res = 0;
1356                         break;
1357
1358                 default:        ;
1359
1360         }
1361
1362         if (gH323Debug)
1363                 ast_verbose("+++++ ooh323_queryoption %d on channel %s\n", option, ast->name);
1364          
1365         ast_mutex_unlock(&p->lock);
1366
1367         return res;
1368 }
1369
1370
1371
1372 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1373 {
1374         struct ooh323_pvt *p = newchan->tech_pvt;
1375
1376         if (!p) return -1;
1377
1378         if (gH323Debug)
1379                 ast_verbose("--- ooh323c ooh323_fixup\n");
1380
1381         ast_mutex_lock(&p->lock);
1382         if (p->owner != oldchan) {
1383                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
1384                 ast_mutex_unlock(&p->lock);
1385                 return -1;
1386         }
1387
1388         if (p->owner == oldchan) {
1389                 p->owner = newchan;
1390         } else {
1391                 p->owner = oldchan;
1392         }
1393
1394         ast_mutex_unlock(&p->lock);
1395
1396         if (gH323Debug)
1397                 ast_verbose("+++ ooh323c ooh323_fixup \n");
1398
1399         return 0;
1400 }
1401
1402
1403 void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
1404 {
1405         struct ooh323_pvt *p = NULL;
1406         char formats[FORMAT_STRING_SIZE];
1407
1408         if (gH323Debug)
1409                 ast_verbose("---   ooh323_update_writeformat %s/%d\n", 
1410                                 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt), txframes);
1411         
1412         p = find_call(call);
1413         if (!p) {
1414                 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1415                 return;
1416         }
1417
1418         ast_mutex_lock(&p->lock);
1419
1420         p->writeformat = fmt;
1421
1422         if (p->owner) {
1423                 while (p->owner && ast_channel_trylock(p->owner)) {
1424                         ast_debug(1,"Failed to grab lock, trying again\n");
1425                         DEADLOCK_AVOIDANCE(&p->lock);
1426                 }
1427                 if (!p->owner) {
1428                         ast_mutex_unlock(&p->lock);
1429                         ast_log(LOG_ERROR, "Channel has no owner\n");
1430                         return;
1431                 }
1432                 if (gH323Debug)
1433                         ast_verbose("Writeformat before update %s/%s\n", 
1434                           ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->writeformat),
1435                           ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->nativeformats));
1436                 if (txframes)
1437                         ast_codec_pref_setsize(&p->prefs, fmt, txframes);
1438                 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
1439                 if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
1440                         ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1441                                  p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
1442                 }
1443                 if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
1444                         ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
1445                                  p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
1446                 }
1447
1448                 p->owner->nativeformats = fmt;
1449                 ast_set_write_format(p->owner, p->owner->writeformat);
1450                 ast_set_read_format(p->owner, p->owner->readformat);
1451                 ast_channel_unlock(p->owner);
1452         } else
1453                 ast_log(LOG_ERROR, "No owner found\n");
1454
1455
1456         ast_mutex_unlock(&p->lock);
1457
1458         if (gH323Debug)
1459                 ast_verbose("+++   ooh323_update_writeformat\n");
1460 }
1461
1462 void ooh323_set_read_format(ooCallData *call, int fmt)
1463 {
1464         struct ooh323_pvt *p = NULL;
1465         char formats[FORMAT_STRING_SIZE];
1466
1467         if (gH323Debug)
1468                 ast_verbose("---   ooh323_update_readformat %s\n", 
1469                                 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt));
1470         
1471         p = find_call(call);
1472         if (!p) {
1473                 ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
1474                 return;
1475         }
1476
1477         ast_mutex_lock(&p->lock);
1478
1479         p->readformat = fmt;
1480
1481
1482         if (p->owner) {
1483                 while (p->owner && ast_channel_trylock(p->owner)) {
1484                         ast_debug(1,"Failed to grab lock, trying again\n");
1485                         DEADLOCK_AVOIDANCE(&p->lock);
1486                 }
1487                 if (!p->owner) {
1488                         ast_mutex_unlock(&p->lock);
1489                         ast_log(LOG_ERROR, "Channel has no owner\n");
1490                         return;
1491                 }
1492
1493                 if (gH323Debug)
1494                         ast_verbose("Readformat before update %s\n", 
1495                                   ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->readformat));
1496                 p->owner->nativeformats = fmt;
1497                 ast_set_read_format(p->owner, p->owner->readformat);
1498                 ast_channel_unlock(p->owner);
1499         } else
1500                 ast_log(LOG_ERROR, "No owner found\n");
1501
1502         ast_mutex_unlock(&p->lock);
1503
1504         if (gH323Debug)
1505                 ast_verbose("+++   ooh323_update_readformat\n");
1506 }
1507
1508
1509 int onAlerting(ooCallData *call)
1510 {
1511         struct ooh323_pvt *p = NULL;
1512         struct ast_channel *c = NULL;
1513
1514         if (gH323Debug)
1515                 ast_verbose("--- onAlerting %s\n", call->callToken);
1516
1517         p = find_call(call);
1518
1519         if(!p) {
1520                 ast_log(LOG_ERROR, "No matching call found\n");
1521                 return -1;
1522         }  
1523         ast_mutex_lock(&p->lock);
1524         if (!p->owner) {
1525                 ast_mutex_unlock(&p->lock);
1526                 ast_log(LOG_ERROR, "Channel has no owner\n");
1527                 return 0;
1528         }
1529         while (p->owner && ast_channel_trylock(p->owner)) {
1530                 ast_debug(1,"Failed to grab lock, trying again\n");
1531                 DEADLOCK_AVOIDANCE(&p->lock);
1532         }
1533         if (!p->owner) {
1534                 ast_mutex_unlock(&p->lock);
1535                 ast_log(LOG_ERROR, "Channel has no owner\n");
1536                 return 0;
1537         }
1538         c = p->owner;
1539
1540         if (call->remoteDisplayName) {
1541                 struct ast_party_connected_line connected;
1542                 ast_party_connected_line_init(&connected);
1543                 connected.id.name = (char *) call->remoteDisplayName;
1544                 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1545                 ast_channel_queue_connected_line_update(c, &connected);
1546         }
1547         if (c->_state != AST_STATE_UP)
1548                 ast_setstate(c, AST_STATE_RINGING);
1549
1550         ast_queue_control(c, AST_CONTROL_RINGING);
1551         ast_channel_unlock(c);
1552         ast_mutex_unlock(&p->lock);
1553
1554         if (gH323Debug)
1555                 ast_verbose("+++ onAlerting %s\n", call->callToken);
1556
1557         return OO_OK;
1558 }
1559
1560 int onProgress(ooCallData *call)
1561 {
1562         struct ooh323_pvt *p = NULL;
1563         struct ast_channel *c = NULL;
1564
1565         if (gH323Debug)
1566                 ast_verbose("--- onProgress %s\n", call->callToken);
1567
1568         p = find_call(call);
1569
1570         if(!p) {
1571                 ast_log(LOG_ERROR, "No matching call found\n");
1572                 return -1;
1573         }  
1574         ast_mutex_lock(&p->lock);
1575         if (!p->owner) {
1576                 ast_mutex_unlock(&p->lock);
1577                 ast_log(LOG_ERROR, "Channel has no owner\n");
1578                 return 0;
1579         }
1580         while (p->owner && ast_channel_trylock(p->owner)) {
1581                 ast_debug(1,"Failed to grab lock, trying again\n");
1582                 DEADLOCK_AVOIDANCE(&p->lock);
1583         }
1584         if (!p->owner) {
1585                 ast_mutex_unlock(&p->lock);
1586                 ast_log(LOG_ERROR, "Channel has no owner\n");
1587                 return 0;
1588         }
1589         c = p->owner;
1590
1591         if (call->remoteDisplayName) {
1592                 struct ast_party_connected_line connected;
1593                 ast_party_connected_line_init(&connected);
1594                 connected.id.name = (char *) call->remoteDisplayName;
1595                 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1596                 ast_channel_queue_connected_line_update(c, &connected);
1597         }
1598         if (c->_state != AST_STATE_UP)
1599                 ast_setstate(c, AST_STATE_RINGING);
1600
1601         ast_queue_control(c, AST_CONTROL_PROGRESS);
1602         ast_channel_unlock(c);
1603         ast_mutex_unlock(&p->lock);
1604
1605         if (gH323Debug)
1606                 ast_verbose("+++ onProgress %s\n", call->callToken);
1607
1608         return OO_OK;
1609 }
1610
1611 /**
1612   * Callback for sending digits from H.323 up to asterisk
1613   *
1614   */
1615 int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit)
1616 {
1617         struct ooh323_pvt *p = NULL;
1618         struct ast_frame f;
1619         int res;
1620
1621         ast_debug(1, "Received Digit: %c\n", digit[0]);
1622         p = find_call(call);
1623         if (!p) {
1624                 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1625                 return -1;
1626         }
1627         if (!p->owner) {
1628                 ast_log(LOG_ERROR, "Channel has no owner\n");
1629                 return -1;
1630         }
1631         ast_mutex_lock(&p->lock);
1632         memset(&f, 0, sizeof(f));
1633         f.frametype = AST_FRAME_DTMF;
1634         f.subclass.integer = digit[0];
1635         f.datalen = 0;
1636         f.samples = 800;
1637         f.offset = 0;
1638         f.data.ptr = NULL;
1639         f.mallocd = 0;
1640         f.src = "SEND_DIGIT";
1641
1642         while (p->owner && ast_channel_trylock(p->owner)) {
1643                 ast_debug(1,"Failed to grab lock, trying again\n");
1644                 DEADLOCK_AVOIDANCE(&p->lock);
1645         }
1646         if (!p->owner) {
1647                 ast_mutex_unlock(&p->lock);
1648                 ast_log(LOG_ERROR, "Channel has no owner\n");
1649                 return 0;
1650         }
1651         res = ast_queue_frame(p->owner, &f);
1652         ast_channel_unlock(p->owner);
1653         ast_mutex_unlock(&p->lock);
1654         return res;
1655 }
1656
1657 int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
1658 {
1659         struct ooh323_pvt *p = NULL;
1660         struct ooh323_user *user = NULL;
1661         struct ast_channel *c = NULL;
1662         ooAliases *alias = NULL;
1663         char *at = NULL;
1664         char number [OO_MAX_NUMBER_LENGTH];
1665
1666         if (gH323Debug)
1667                 ast_verbose("---   ooh323_onReceivedSetup %s\n", call->callToken);
1668
1669
1670         if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
1671                 ast_log(LOG_ERROR, "Failed to create a new call.\n");
1672                 return -1;
1673         }
1674         ast_mutex_lock(&p->lock);
1675         ast_clear_flag(p, H323_OUTGOING);
1676   
1677
1678         if (call->remoteDisplayName) {
1679                 p->callerid_name = strdup(call->remoteDisplayName);
1680         }
1681
1682         if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
1683                 p->callerid_num = strdup(number);
1684         }
1685
1686         if (call->remoteAliases) {
1687                 for (alias = call->remoteAliases; alias; alias = alias->next) {
1688                         if (alias->type == T_H225AliasAddress_h323_ID) {
1689                                 if (!p->callerid_name) {
1690                                         p->callerid_name = strdup(alias->value);
1691                                 }
1692                                 ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
1693                                 }
1694          else if(alias->type == T_H225AliasAddress_dialedDigits)
1695          {
1696             if(!p->callerid_num)
1697                p->callerid_num = strdup(alias->value);
1698                                 ast_copy_string(p->caller_dialedDigits, alias->value, 
1699                                                                                                                         sizeof(p->caller_dialedDigits));
1700          }
1701          else if(alias->type == T_H225AliasAddress_email_ID)
1702          {
1703                                 ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
1704          }
1705          else if(alias->type == T_H225AliasAddress_url_ID)
1706          {
1707                                 ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
1708                         }
1709                 }
1710         }
1711
1712         number[0] = '\0';
1713         if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
1714                 strncpy(p->exten, number, sizeof(p->exten)-1);
1715         } else {
1716                 update_our_aliases(call, p);
1717                 if (!ast_strlen_zero(p->callee_dialedDigits)) {
1718                         ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
1719                 } else if(!ast_strlen_zero(p->callee_h323id)) {
1720                         ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
1721                 } else if(!ast_strlen_zero(p->callee_email)) {
1722                         ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
1723                         if ((at = strchr(p->exten, '@'))) {
1724                                 *at = '\0';
1725                         }
1726                 }
1727         }
1728
1729         /* if no extension found, set to default 's' */
1730         if (ast_strlen_zero(p->exten)) {
1731                 p->exten[0]='s';
1732                 p->exten[1]='\0';
1733         }
1734
1735         user = find_user(p->callerid_name, call->remoteIP);
1736         if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
1737                 ast_mutex_lock(&user->lock);
1738                 p->username = strdup(user->name);
1739                 p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
1740                                                   ast_strdup(user->name);
1741                 ast_copy_string(p->context, user->context, sizeof(p->context));
1742                 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
1743                 p->amaflags = user->amaflags;
1744                 p->capability = user->capability;
1745                 memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
1746                 p->dtmfmode |= user->dtmfmode;
1747                 p->dtmfcodec = user->dtmfcodec;
1748                 p->t38support = user->t38support;
1749                 p->rtptimeout = user->rtptimeout;
1750                 if (user->rtpmask && user->rtpmaskstr[0]) {
1751                         p->rtpmask = user->rtpmask;
1752                         ast_copy_string(p->rtpmaskstr, user->rtpmaskstr, 
1753                                                          sizeof(p->rtpmaskstr));
1754                 }
1755                 if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
1756                         p->rtdrcount = user->rtdrcount;
1757                         p->rtdrinterval = user->rtdrinterval;
1758                 }
1759                 if (user->incominglimit) user->inUse++;
1760                 ast_mutex_unlock(&user->lock);
1761         } else {
1762          if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
1763                 p->username = strdup(call->remoteIP);
1764         } else {
1765           ast_mutex_unlock(&p->lock);
1766           ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
1767           if (!user) 
1768            ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
1769           else
1770            ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
1771           ast_set_flag(p, H323_NEEDDESTROY);
1772           return -1;
1773          }
1774         }
1775
1776         ooh323c_set_capability_for_call(call, &p->prefs, p->capability, p->dtmfmode, p->dtmfcodec,
1777                                          p->t38support);
1778         configure_local_rtp(p, call);
1779
1780 /* Incoming call */
1781         c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL);
1782         if(!c) {
1783         ast_mutex_unlock(&p->lock);
1784         ast_log(LOG_ERROR, "Could not create ast_channel\n");
1785          return -1;
1786   }
1787         ast_mutex_unlock(&p->lock);
1788
1789         if (gH323Debug)
1790                 ast_verbose("+++   ooh323_onReceivedSetup - Determined context %s, "
1791                                                 "extension %s\n", p->context, p->exten);
1792
1793         return OO_OK;
1794 }
1795
1796
1797
1798 int onOutgoingCall(ooCallData *call)
1799 {
1800         struct ooh323_pvt *p = NULL;
1801         int i = 0;
1802
1803         if (gH323Debug)
1804                 ast_verbose("---   onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
1805
1806         if (!strcmp(call->callType, "outgoing")) {
1807                 p = find_call(call);
1808                 if (!p) {
1809                         ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1810                         return -1;
1811                 }
1812                 ast_mutex_lock(&p->lock);
1813
1814                 if (!ast_strlen_zero(p->callerid_name)) {
1815                         ooCallSetCallerId(call, p->callerid_name);
1816                 }
1817                 if (!ast_strlen_zero(p->callerid_num)) {
1818                         i = 0;
1819                         while (*(p->callerid_num + i) != '\0') {
1820                                 if(!isdigit(*(p->callerid_num+i))) { break; }
1821                                 i++;
1822                         }
1823                         if(*(p->callerid_num+i) == '\0')
1824                                 ooCallSetCallingPartyNumber(call, p->callerid_num);
1825                         else {
1826                                 if(!p->callerid_name)
1827                                         ooCallSetCallerId(call, p->callerid_num);
1828                         }
1829                 }
1830                 
1831                 if (!ast_strlen_zero(p->caller_h323id))
1832                         ooCallAddAliasH323ID(call, p->caller_h323id);
1833
1834                 if (!ast_strlen_zero(p->caller_dialedDigits)) {
1835                         if (gH323Debug) {
1836                                 ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits);
1837                         }
1838                         ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
1839                 } else if (!ast_strlen_zero(p->callerid_num)) {
1840                         if (ooIsDailedDigit(p->callerid_num)) {
1841                                 if (gH323Debug) {
1842                                         ast_verbose("setting callid number %s\n", p->callerid_num);
1843                                 }
1844                                 ooCallAddAliasDialedDigits(call, p->callerid_num);
1845                         } else if (ast_strlen_zero(p->caller_h323id)) {
1846                                 ooCallAddAliasH323ID(call, p->callerid_num);
1847                         }
1848                 }
1849                 if (p->rtpmask && p->rtpmaskstr[0]) {
1850                         call->rtpMask = p->rtpmask;
1851                         ast_mutex_lock(&call->rtpMask->lock);
1852                         call->rtpMask->inuse++;
1853                         ast_mutex_unlock(&call->rtpMask->lock);
1854                         ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
1855                 }
1856
1857                 ast_mutex_unlock(&p->lock);
1858         }
1859
1860         if (gH323Debug)
1861                 ast_verbose("+++   onOutgoingCall %s\n", call->callToken);
1862         return OO_OK;
1863 }
1864
1865
1866 int onNewCallCreated(ooCallData *call)
1867 {
1868         struct ooh323_pvt *p = NULL;
1869         int i = 0;
1870
1871         if (gH323Debug)
1872                 ast_verbose("---   onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
1873
1874         ast_mutex_lock(&call->Lock);
1875         if (ooh323c_start_call_thread(call)) {
1876                 ast_log(LOG_ERROR,"Failed to create call thread.\n");
1877                 ast_mutex_unlock(&call->Lock);
1878                 return -1;
1879         }
1880
1881         if (!strcmp(call->callType, "outgoing")) {
1882                 p = find_call(call);
1883                 if (!p) {
1884                         ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1885                         ast_mutex_unlock(&call->Lock);
1886                         return -1;
1887                 }
1888                 ast_mutex_lock(&p->lock);
1889
1890                 if (!ast_strlen_zero(p->callerid_name)) {
1891                         ooCallSetCallerId(call, p->callerid_name);
1892                 }
1893                 if (!ast_strlen_zero(p->callerid_num)) {
1894                         i = 0;
1895                         while (*(p->callerid_num + i) != '\0') {
1896                                 if(!isdigit(*(p->callerid_num+i))) { break; }
1897                                 i++;
1898                         }
1899                         if(*(p->callerid_num+i) == '\0')
1900                                 ooCallSetCallingPartyNumber(call, p->callerid_num);
1901                         else {
1902                                 if(ast_strlen_zero(p->callerid_name))
1903                                         ooCallSetCallerId(call, p->callerid_num);
1904                         }
1905                 }
1906                 
1907                 if (!ast_strlen_zero(p->caller_h323id))
1908                         ooCallAddAliasH323ID(call, p->caller_h323id);
1909
1910                 if (!ast_strlen_zero(p->caller_dialedDigits)) {
1911                         if (gH323Debug) {
1912                                 ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits);
1913                         }
1914                         ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
1915                 } else if (!ast_strlen_zero(p->callerid_num)) {
1916                         if (ooIsDailedDigit(p->callerid_num)) {
1917                                 if (gH323Debug) {
1918                                         ast_verbose("setting callid number %s\n", p->callerid_num);
1919                                 }
1920                                 ooCallAddAliasDialedDigits(call, p->callerid_num);
1921                         } else if (ast_strlen_zero(p->caller_h323id)) {
1922                                 ooCallAddAliasH323ID(call, p->callerid_num);
1923                         }
1924                 }
1925   
1926
1927                 if (!ast_strlen_zero(p->exten))  {
1928                         if (ooIsDailedDigit(p->exten)) {
1929                                 ooCallSetCalledPartyNumber(call, p->exten);
1930                                 ooCallAddRemoteAliasDialedDigits(call, p->exten);
1931                         } else {
1932                           ooCallAddRemoteAliasH323ID(call, p->exten);
1933                         }
1934                 }
1935
1936                 if (gH323Debug) {
1937                         char prefsBuf[256];
1938                         ast_codec_pref_string(&p->prefs, prefsBuf, sizeof(prefsBuf));
1939                         ast_verbose(" Outgoing call %s(%s) - Codec prefs - %s\n", 
1940                                 p->username?p->username:"NULL", call->callToken, prefsBuf);
1941                 }
1942
1943                 ooh323c_set_capability_for_call(call, &p->prefs, p->capability, 
1944                                      p->dtmfmode, p->dtmfcodec, p->t38support);
1945
1946                 configure_local_rtp(p, call);
1947                 ast_mutex_unlock(&p->lock);
1948         }
1949
1950         ast_mutex_unlock(&call->Lock);
1951         if (gH323Debug)
1952                 ast_verbose("+++   onNewCallCreated %s\n", call->callToken);
1953         return OO_OK;
1954 }
1955
1956 int onCallEstablished(ooCallData *call)
1957 {
1958         struct ooh323_pvt *p = NULL;
1959
1960         if (gH323Debug)
1961                 ast_verbose("---   onCallEstablished %s\n", call->callToken);
1962
1963
1964         if (!(p = find_call(call))) {
1965                 ast_log(LOG_ERROR, "Failed to find a matching call.\n");
1966                 return -1;
1967         }
1968
1969         if(ast_test_flag(p, H323_OUTGOING)) {
1970                 ast_mutex_lock(&p->lock);
1971                 if (!p->owner) {
1972                         ast_mutex_unlock(&p->lock);
1973                         ast_log(LOG_ERROR, "Channel has no owner\n");
1974                         return -1;
1975                 }
1976         
1977                 while (p->owner && ast_channel_trylock(p->owner)) {
1978                         ast_debug(1,"Failed to grab lock, trying again\n");
1979                         DEADLOCK_AVOIDANCE(&p->lock);
1980                 }
1981                 if (p->owner) {
1982                         struct ast_channel* c = p->owner;
1983
1984                         if (call->remoteDisplayName) {
1985                                 struct ast_party_connected_line connected;
1986                                 ast_party_connected_line_init(&connected);
1987                                 connected.id.name = (char *) call->remoteDisplayName;
1988                                 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1989                                 ast_channel_queue_connected_line_update(c, &connected);
1990                         }
1991
1992                         ast_queue_control(c, AST_CONTROL_ANSWER);
1993                         ast_channel_unlock(p->owner);
1994                         manager_event(EVENT_FLAG_SYSTEM,"ChannelUpdate","Channel: %s\r\nChanneltype: %s\r\n"
1995                                 "CallRef: %d\r\n", c->name, "OOH323", p->call_reference);
1996                 }
1997                 ast_mutex_unlock(&p->lock);
1998
1999         }
2000
2001         if (gH323Debug)
2002                 ast_verbose("+++   onCallEstablished %s\n", call->callToken);
2003
2004         return OO_OK;
2005 }
2006
2007 int onCallCleared(ooCallData *call)
2008 {
2009         struct ooh323_pvt *p = NULL;
2010         int ownerLock = 0;
2011
2012         if (gH323Debug)
2013                 ast_verbose("---   onCallCleared %s \n", call->callToken);
2014
2015
2016    if ((p = find_call(call))) {
2017         ast_mutex_lock(&p->lock);
2018   
2019         while (p->owner) {
2020                 if (ast_channel_trylock(p->owner)) {
2021                         ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
2022                         ast_log(LOG_DEBUG,"Failed to grab lock, trying again\n");
2023                         DEADLOCK_AVOIDANCE(&p->lock);
2024                 } else {
2025                         ownerLock = 1; break;
2026                 }
2027         }
2028
2029         if (ownerLock) {
2030                 if (!ast_test_flag(p, H323_ALREADYGONE)) { 
2031
2032                         ast_set_flag(p, H323_ALREADYGONE);
2033                         p->owner->hangupcause = call->q931cause;
2034                         p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
2035                         ast_queue_hangup_with_cause(p->owner,call->q931cause);
2036                 }
2037         }
2038
2039         if(p->owner) {
2040                 p->owner->tech_pvt = NULL;
2041                 ast_channel_unlock(p->owner);
2042                 p->owner = NULL;
2043                 ast_module_unref(myself);
2044         }
2045
2046         ast_set_flag(p, H323_NEEDDESTROY);
2047
2048         ooh323c_stop_call_thread(call);
2049
2050         ast_mutex_unlock(&p->lock);
2051         ast_mutex_lock(&usecnt_lock);
2052         usecnt--;
2053         ast_mutex_unlock(&usecnt_lock);
2054
2055     }
2056
2057         if (gH323Debug)
2058                 ast_verbose("+++   onCallCleared\n");
2059
2060         return OO_OK;
2061 }
2062
2063 /* static void ooh323_delete_user(struct ooh323_user *user)
2064 {
2065         struct ooh323_user *prev = NULL, *cur = NULL;
2066
2067         if (gH323Debug)
2068                 ast_verbose("---   ooh323_delete_user\n");
2069
2070         if (user) {     
2071                 cur = userl.users;
2072                 ast_mutex_lock(&userl.lock);
2073                 while (cur) {
2074                         if (cur == user) break;
2075                         prev = cur;
2076                         cur = cur->next;
2077                 }
2078
2079                 if (cur) {
2080                         if (prev)
2081                                 prev->next = cur->next;
2082                         else
2083                                 userl.users = cur->next;
2084                 }
2085                 ast_mutex_unlock(&userl.lock);
2086
2087                 free(user);
2088         }  
2089
2090         if (gH323Debug)
2091                 ast_verbose("+++   ooh323_delete_user\n");
2092
2093 } */
2094
2095 void ooh323_delete_peer(struct ooh323_peer *peer)
2096 {
2097         struct ooh323_peer *prev = NULL, *cur = NULL;
2098
2099         if (gH323Debug)
2100                 ast_verbose("---   ooh323_delete_peer\n");
2101
2102         if (peer) {     
2103       cur = peerl.peers;
2104                 ast_mutex_lock(&peerl.lock);
2105       while(cur) {
2106          if(cur==peer) break;
2107          prev = cur;
2108          cur = cur->next;
2109                 }
2110
2111                 if (cur) {
2112          if(prev)
2113                                 prev->next = cur->next;
2114          else
2115                                 peerl.peers = cur->next;
2116                         }
2117                 ast_mutex_unlock(&peerl.lock);
2118
2119       if(peer->h323id)   free(peer->h323id);
2120       if(peer->email)    free(peer->email);
2121       if(peer->url)      free(peer->url);
2122       if(peer->e164)     free(peer->e164);
2123
2124                 free(peer);
2125         }  
2126
2127         if (gH323Debug)
2128                 ast_verbose("+++   ooh323_delete_peer\n");
2129
2130 }
2131
2132
2133
2134 static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
2135 {
2136         struct ooh323_user *user = NULL;
2137
2138         if (gH323Debug)
2139                 ast_verbose("---   build_user\n");
2140
2141         user = ast_calloc(1,sizeof(struct ooh323_user));
2142         if (user) {
2143                 memset(user, 0, sizeof(struct ooh323_user));
2144                 ast_mutex_init(&user->lock);
2145                 ast_copy_string(user->name, name, sizeof(user->name));
2146                 user->capability = gCapability;
2147                 memcpy(&user->prefs, &gPrefs, sizeof(user->prefs));
2148                 user->rtptimeout = gRTPTimeout;
2149                 user->dtmfmode = gDTMFMode;
2150                 user->dtmfcodec = gDTMFCodec;
2151                 user->t38support = gT38Support;
2152                 /* set default context */
2153                 ast_copy_string(user->context, gContext, sizeof(user->context));
2154                 ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
2155                 user->amaflags = gAMAFLAGS;
2156
2157                 while (v) {
2158                         if (!strcasecmp(v->name, "context")) {
2159                                 ast_copy_string(user->context, v->value, sizeof(user->context));
2160                         } else if (!strcasecmp(v->name, "incominglimit")) {
2161                                 user->incominglimit = atoi(v->value);
2162                                 if (user->incominglimit < 0)
2163                                         user->incominglimit = 0;
2164                         } else if (!strcasecmp(v->name, "accountcode")) {
2165                                 strncpy(user->accountcode, v->value, 
2166                                                 sizeof(user->accountcode)-1);
2167                         } else if (!strcasecmp(v->name, "roundtrip")) {
2168                                 sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
2169                         } else if (!strcasecmp(v->name, "rtptimeout")) {
2170                                 user->rtptimeout = atoi(v->value);
2171                                 if (user->rtptimeout < 0)
2172                                         user->rtptimeout = gRTPTimeout;
2173                         } else if (!strcasecmp(v->name, "rtpmask")) {
2174                                 if ((user->rtpmask = malloc(sizeof(struct OOH323Regex))) &&
2175                                         (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED) 
2176                                                                                         == 0)) {
2177                                         ast_mutex_init(&user->rtpmask->lock);
2178                                         user->rtpmask->inuse = 1;
2179                                         ast_copy_string(user->rtpmaskstr, v->value, 
2180                                                                 sizeof(user->rtpmaskstr));
2181                                 } else user->rtpmask = NULL;
2182                         } else if (!strcasecmp(v->name, "disallow")) {
2183                                 ast_parse_allow_disallow(&user->prefs, 
2184                                         &user->capability,  v->value, 0);
2185                         } else if (!strcasecmp(v->name, "allow")) {
2186                                 const char* tcodecs = v->value;
2187                                 if (!strcasecmp(v->value, "all")) {
2188                                         tcodecs = "ulaw,alaw,g729,g723,gsm";
2189                                 }
2190                                 ast_parse_allow_disallow(&user->prefs,
2191                                          &user->capability,  tcodecs, 1);
2192                         } else if (!strcasecmp(v->name, "amaflags")) {
2193                                 user->amaflags = ast_cdr_amaflags2int(v->value);
2194                         } else if (!strcasecmp(v->name, "ip")) {
2195                                 strncpy(user->mIP, v->value, sizeof(user->mIP)-1);
2196                                 user->mUseIP = 1;
2197                         } else if (!strcasecmp(v->name, "host")) {
2198                                 strncpy(user->mIP, v->value, sizeof(user->mIP)-1);
2199                                 user->mUseIP = 1;
2200                         } else if (!strcasecmp(v->name, "dtmfmode")) {
2201                                 if (!strcasecmp(v->value, "rfc2833"))
2202                                         user->dtmfmode = H323_DTMF_RFC2833;
2203                                 if (!strcasecmp(v->value, "cisco"))
2204                                         user->dtmfmode = H323_DTMF_CISCO;
2205                                 else if (!strcasecmp(v->value, "q931keypad"))
2206                                         user->dtmfmode = H323_DTMF_Q931;
2207                                 else if (!strcasecmp(v->value, "h245alphanumeric"))
2208                                         user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2209                                 else if (!strcasecmp(v->value, "h245signal"))
2210                                         user->dtmfmode = H323_DTMF_H245SIGNAL;
2211                                 else if (!strcasecmp(v->value, "inband"))
2212                                         user->dtmfmode = H323_DTMF_INBAND;
2213                         } else if (!strcasecmp(v->name, "relaxdtmf")) {
2214                                 user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2215                         } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2216                                 user->dtmfcodec = atoi(v->value);
2217                         } else if (!strcasecmp(v->name, "t38support")) {
2218                                 if (!strcasecmp(v->value, "disabled"))
2219                                         user->t38support = T38_DISABLED;
2220                                 if (!strcasecmp(v->value, "no"))
2221                                         user->t38support = T38_DISABLED;
2222                                 else if (!strcasecmp(v->value, "faxgw"))
2223                                         user->t38support = T38_FAXGW;
2224                                 else if (!strcasecmp(v->value, "yes"))
2225                                         user->t38support = T38_ENABLED;
2226                         }
2227                         v = v->next;
2228                 }
2229         }
2230
2231         if (gH323Debug)
2232                 ast_verbose("+++   build_user\n");
2233
2234         return user;
2235 }
2236
2237 static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
2238 {
2239         struct ooh323_peer *peer = NULL;
2240
2241         if (gH323Debug)
2242                 ast_verbose("---   build_peer\n");
2243
2244         peer = ast_calloc(1, sizeof(*peer));
2245         if (peer) {
2246                 memset(peer, 0, sizeof(struct ooh323_peer));
2247                 ast_mutex_init(&peer->lock);
2248                 ast_copy_string(peer->name, name, sizeof(peer->name));
2249                 peer->capability = gCapability;
2250                 memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs));
2251                 peer->rtptimeout = gRTPTimeout;
2252                 ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
2253                 peer->amaflags = gAMAFLAGS;
2254                 peer->dtmfmode = gDTMFMode;
2255                 peer->dtmfcodec = gDTMFCodec;
2256                 peer->t38support = gT38Support;
2257                 peer->port = 1720;
2258                 if (0 == friend_type) {
2259                         peer->mFriend = 1;
2260                 }
2261
2262                 while (v) {
2263                         if (!strcasecmp(v->name, "h323id")) {
2264             if (!(peer->h323id = ast_strdup(v->value))) {
2265                                         ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2266                                                                                          "peer %s\n", name);
2267                                         ooh323_delete_peer(peer);
2268                                         return NULL;
2269                                 }
2270                         } else if (!strcasecmp(v->name, "e164")) {
2271                                 if (!(peer->e164 = ast_strdup(v->value))) {
2272                                         ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
2273                                                                                          "peer %s\n", name);
2274                                         ooh323_delete_peer(peer);
2275                                         return NULL;
2276                                 }
2277                         } else  if (!strcasecmp(v->name, "email")) {
2278                                 if (!(peer->email = ast_strdup(v->value))) {
2279                                         ast_log(LOG_ERROR, "Could not allocate memory for email of "
2280                                                                                          "peer %s\n", name);
2281                                         ooh323_delete_peer(peer);
2282                                         return NULL;
2283                                 }
2284                         } else if (!strcasecmp(v->name, "url")) {
2285                                 if (!(peer->url = ast_strdup(v->value))) {
2286                                         ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
2287                                                                                          "peer %s\n", name);
2288                                         ooh323_delete_peer(peer);
2289                                         return NULL;
2290                                 }
2291                         } else if (!strcasecmp(v->name, "port")) {
2292                                 peer->port = atoi(v->value);
2293                         } else if (!strcasecmp(v->name, "ip")) {
2294                                 ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2295                         } else if (!strcasecmp(v->name, "host")) {
2296                                 ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
2297                         } else if (!strcasecmp(v->name, "outgoinglimit")) {
2298                                 peer->outgoinglimit = atoi(v->value);
2299                                 if (peer->outgoinglimit < 0)
2300                                         peer->outgoinglimit = 0;
2301                         } else if (!strcasecmp(v->name, "accountcode")) {
2302                                 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
2303                         } else if (!strcasecmp(v->name, "rtptimeout")) {
2304                                 peer->rtptimeout = atoi(v->value);
2305                                 if(peer->rtptimeout < 0)
2306                                         peer->rtptimeout = gRTPTimeout;
2307                         } else if (!strcasecmp(v->name, "rtpmask")) {
2308                                 if ((peer->rtpmask = malloc(sizeof(struct OOH323Regex))) &&
2309                                         (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED) 
2310                                                                                         == 0)) {
2311                                         ast_mutex_init(&peer->rtpmask->lock);
2312                                         peer->rtpmask->inuse = 1;
2313                                         ast_copy_string(peer->rtpmaskstr, v->value, 
2314                                                                 sizeof(peer->rtpmaskstr));
2315                                 } else peer->rtpmask = NULL;
2316                         } else if (!strcasecmp(v->name, "disallow")) {
2317                                 ast_parse_allow_disallow(&peer->prefs, &peer->capability, 
2318                                                                                                  v->value, 0); 
2319                         } else if (!strcasecmp(v->name, "allow")) {
2320                                 const char* tcodecs = v->value;
2321                                 if (!strcasecmp(v->value, "all")) {
2322                                         tcodecs = "ulaw,alaw,g729,g723,gsm";
2323                                 }
2324                                 ast_parse_allow_disallow(&peer->prefs, &peer->capability, 
2325                                                                                                  tcodecs, 1);                            
2326                         } else if (!strcasecmp(v->name,  "amaflags")) {
2327                                 peer->amaflags = ast_cdr_amaflags2int(v->value);
2328                         } else if (!strcasecmp(v->name, "roundtrip")) {
2329                                 sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
2330                         } else if (!strcasecmp(v->name, "dtmfmode")) {
2331                                 if (!strcasecmp(v->value, "rfc2833"))
2332                                         peer->dtmfmode = H323_DTMF_RFC2833;
2333                                 if (!strcasecmp(v->value, "cisco"))
2334                                         peer->dtmfmode = H323_DTMF_CISCO;
2335                                 else if (!strcasecmp(v->value, "q931keypad"))
2336                                         peer->dtmfmode = H323_DTMF_Q931;
2337                                 else if (!strcasecmp(v->value, "h245alphanumeric"))
2338                                         peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
2339                                 else if (!strcasecmp(v->value, "h245signal"))
2340                                         peer->dtmfmode = H323_DTMF_H245SIGNAL;
2341                                 else if (!strcasecmp(v->value, "inband"))
2342                                         peer->dtmfmode = H323_DTMF_INBAND;
2343                         } else if (!strcasecmp(v->name, "relaxdtmf")) {
2344                                 peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2345                         } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2346                                 peer->dtmfcodec = atoi(v->value);
2347                         } else if (!strcasecmp(v->name, "t38support")) {
2348                                 if (!strcasecmp(v->value, "disabled"))
2349                                         peer->t38support = T38_DISABLED;
2350                                 if (!strcasecmp(v->value, "no"))
2351                                         peer->t38support = T38_DISABLED;
2352                                 else if (!strcasecmp(v->value, "faxgw"))
2353                                         peer->t38support = T38_FAXGW;
2354                                 else if (!strcasecmp(v->value, "yes"))
2355                                         peer->t38support = T38_ENABLED;
2356                         }
2357                         v = v->next;
2358                 }
2359         }
2360
2361         if (gH323Debug)
2362                 ast_verbose("+++   build_peer\n");
2363
2364         return peer;
2365 }
2366
2367 static int ooh323_do_reload(void)
2368 {
2369         if (gH323Debug) {
2370                 ast_verbose("---   ooh323_do_reload\n");
2371         }
2372
2373         reload_config(1);
2374
2375         if (gH323Debug) {
2376                 ast_verbose("+++   ooh323_do_reload\n");
2377         }
2378
2379         return 0;
2380 }
2381
2382 /*--- h323_reload: Force reload of module from cli ---*/
2383
2384 char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2385 {
2386
2387        switch (cmd) {
2388        case CLI_INIT:
2389                e->command = "ooh323 reload";
2390                e->usage =
2391                        "Usage: ooh323 reload\n"
2392                        "                Reload OOH323 config.\n";
2393                return NULL;
2394        case CLI_GENERATE:
2395                return NULL;
2396        }
2397
2398        if (a->argc != 2)
2399                return CLI_SHOWUSAGE;
2400
2401         if (gH323Debug)
2402                 ast_verbose("---   ooh323_reload\n");
2403
2404         ast_mutex_lock(&h323_reload_lock);
2405         if (h323_reloading) {
2406                 ast_verbose("Previous OOH323 reload not yet done\n");
2407    } else {
2408                 h323_reloading = 1;
2409         }
2410         ast_mutex_unlock(&h323_reload_lock);
2411         restart_monitor();
2412
2413         if (gH323Debug)
2414                 ast_verbose("+++   ooh323_reload\n");
2415
2416         return 0;
2417 }
2418
2419 int reload_config(int reload)
2420 {
2421         int format;
2422         struct ooAliases  *pNewAlias = NULL, *cur, *prev;
2423         struct ast_config *cfg;
2424         struct ast_variable *v;
2425         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2426         struct ooh323_user *user = NULL;
2427         struct ooh323_peer *peer = NULL;
2428         char *cat;
2429         const char *utype;
2430
2431         if (gH323Debug)
2432                 ast_verbose("---   reload_config\n");
2433
2434         cfg = ast_config_load((char*)config, config_flags);
2435
2436         /* We *must* have a config file otherwise stop immediately */
2437         if (!cfg) {
2438                 ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
2439                 return 1;
2440         } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
2441                 return RESULT_SUCCESS;
2442
2443         if (reload) {
2444                 delete_users();
2445                 delete_peers();
2446                 if (gH323Debug) {
2447                         ast_verbose("  reload_config - Freeing up alias list\n");
2448                 }
2449                 cur = gAliasList;
2450                 while (cur) {
2451                         prev = cur;
2452                         cur = cur->next;
2453                         free(prev->value);
2454                         free(prev);
2455                 }
2456                 gAliasList = NULL;
2457         }
2458
2459         /* Inintialize everything to default */
2460         strcpy(gLogFile, DEFAULT_LOGFILE);
2461         gPort = 1720;
2462         gIP[0] = '\0';
2463         strcpy(gCallerID, DEFAULT_H323ID);
2464         gCapability = AST_FORMAT_ALAW;
2465         memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
2466         gDTMFMode = H323_DTMF_RFC2833;
2467         gDTMFCodec = 101;
2468         gT38Support = T38_FAXGW;
2469         gTRCLVL = OOTRCLVLERR;
2470         gRasGkMode = RasNoGatekeeper;
2471         gGatekeeper[0] = '\0';
2472         gRTPTimeout = 60;
2473         gRTDRInterval = 0;
2474         gRTDRCount = 0;
2475         strcpy(gAccountcode, DEFAULT_H323ACCNT);
2476         gFastStart = 1;
2477         gTunneling = 1;
2478         gTOS = 0;
2479         strcpy(gContext, DEFAULT_CONTEXT);
2480         gAliasList = NULL;
2481         gMediaWaitForConnect = 0;
2482         ooconfig.mTCPPortStart = 12030;
2483         ooconfig.mTCPPortEnd = 12230;
2484         memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2485
2486         v = ast_variable_browse(cfg, "general");
2487         while (v) {
2488
2489                 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
2490                         v = v->next;
2491                         continue;
2492                 }
2493         
2494                 if (!strcasecmp(v->name, "port")) {
2495                         gPort = (int)strtol(v->value, NULL, 10);
2496                 } else if (!strcasecmp(v->name, "bindaddr")) {
2497                         ast_copy_string(gIP, v->value, sizeof(gIP));
2498                 } else if (!strcasecmp(v->name, "h225portrange")) {
2499                         char* endlimit = 0;
2500                         char temp[512];
2501                         ast_copy_string(temp, v->value, sizeof(temp));
2502                         endlimit = strchr(temp, ',');
2503                         if (endlimit) {
2504                                 *endlimit = '\0';
2505                                 endlimit++;
2506                                 ooconfig.mTCPPortStart = atoi(temp);
2507                                 ooconfig.mTCPPortEnd = atoi(endlimit);
2508
2509                         } else {
2510                                 ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
2511                         }
2512                 } else if (!strcasecmp(v->name, "gateway")) {
2513                         gIsGateway = ast_true(v->value);
2514                 } else if (!strcasecmp(v->name, "faststart")) {
2515                         gFastStart = ast_true(v->value);
2516                         if (gFastStart)
2517                                 ooH323EpEnableFastStart();
2518                         else
2519                                 ooH323EpDisableFastStart();
2520                 } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
2521                         gMediaWaitForConnect = ast_true(v->value);
2522                         if (gMediaWaitForConnect)
2523                                 ooH323EpEnableMediaWaitForConnect();
2524                         else 
2525                                 ooH323EpDisableMediaWaitForConnect();
2526                 } else if (!strcasecmp(v->name, "h245tunneling")) {
2527                         gTunneling = ast_true(v->value);
2528                         if (gTunneling)
2529                                 ooH323EpEnableH245Tunneling();
2530                         else
2531                                 ooH323EpDisableH245Tunneling();
2532                 } else if (!strcasecmp(v->name, "roundtrip")) {
2533                         sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
2534                 } else if (!strcasecmp(v->name, "trybemaster")) {
2535                         gBeMaster = ast_true(v->value);
2536                         if (gBeMaster)
2537                                 ooH323EpTryBeMaster(1);
2538                         else 
2539                                 ooH323EpTryBeMaster(0);
2540                 } else if (!strcasecmp(v->name, "h323id")) {
2541                         pNewAlias = malloc(sizeof(struct ooAliases));
2542                         if (!pNewAlias) {
2543                                 ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
2544                                 return 1;
2545                         }
2546                         if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
2547                                 ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2548                         }
2549                         pNewAlias->type =  T_H225AliasAddress_h323_ID;
2550                         pNewAlias->value = strdup(v->value);
2551                         pNewAlias->next = gAliasList;
2552                         gAliasList = pNewAlias;
2553                         pNewAlias = NULL;
2554                 } else if (!strcasecmp(v->name, "e164")) {
2555                         pNewAlias = malloc(sizeof(struct ooAliases));
2556                         if (!pNewAlias) {
2557                                 ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
2558                                 return 1;
2559                         }
2560                         pNewAlias->type =  T_H225AliasAddress_dialedDigits;
2561                         pNewAlias->value = strdup(v->value);
2562                         pNewAlias->next = gAliasList;
2563                         gAliasList = pNewAlias;
2564                         pNewAlias = NULL;
2565                 } else if (!strcasecmp(v->name, "email")) {
2566                         pNewAlias = malloc(sizeof(struct ooAliases));
2567                         if (!pNewAlias) {
2568                                 ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
2569                                 return 1;
2570                         }
2571                         pNewAlias->type =  T_H225AliasAddress_email_ID;
2572                         pNewAlias->value = strdup(v->value);
2573                         pNewAlias->next = gAliasList;
2574                         gAliasList = pNewAlias;
2575                         pNewAlias = NULL;
2576       } else if (!strcasecmp(v->name, "t35country")) {
2577          t35countrycode = atoi(v->value);
2578       } else if (!strcasecmp(v->name, "t35extensions")) {
2579          t35extensions = atoi(v->value);
2580       } else if (!strcasecmp(v->name, "manufacturer")) {
2581          manufacturer = atoi(v->value);
2582       } else if (!strcasecmp(v->name, "vendorid")) {
2583          ast_copy_string(vendor, v->value, sizeof(vendor));
2584       } else if (!strcasecmp(v->name, "versionid")) {
2585          ast_copy_string(version, v->value, sizeof(version));
2586                 } else if (!strcasecmp(v->name, "callerid")) {
2587                         ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
2588                 } else if (!strcasecmp(v->name, "incominglimit")) {
2589                         gIncomingLimit = atoi(v->value);
2590                 } else if (!strcasecmp(v->name, "outgoinglimit")) {
2591                         gOutgoingLimit = atoi(v->value);
2592                 } else if (!strcasecmp(v->name, "gatekeeper")) {
2593                         if (!strcasecmp(v->value, "DISABLE")) {
2594                                 gRasGkMode = RasNoGatekeeper;
2595                         } else if (!strcasecmp(v->value, "DISCOVER")) {
2596                                 gRasGkMode = RasDiscoverGatekeeper;
2597                         } else {
2598                                 gRasGkMode = RasUseSpecificGatekeeper;
2599                                 strncpy(gGatekeeper, v->value, sizeof(gGatekeeper)-1);
2600                         }
2601                 } else if (!strcasecmp(v->name, "logfile")) {
2602          strncpy(gLogFile, v->value, sizeof(gLogFile)-1);
2603                 } else if (!strcasecmp(v->name, "context")) {
2604          strncpy(gContext, v->value, sizeof(gContext)-1);
2605          ast_verbose(VERBOSE_PREFIX_3 "  == Setting default context to %s\n", 
2606                                                       gContext);
2607                 } else if (!strcasecmp(v->name, "rtptimeout")) {
2608                         gRTPTimeout = atoi(v->value);
2609                         if (gRTPTimeout <= 0)
2610                                 gRTPTimeout = 60;
2611                 } else if (!strcasecmp(v->name, "tos")) {
2612                         if (sscanf(v->value, "%30i", &format) == 1)
2613                                 gTOS = format & 0xff;
2614                         else if (!strcasecmp(v->value, "lowdelay"))
2615                                 gTOS = IPTOS_LOWDELAY;
2616                         else if (!strcasecmp(v->value, "throughput"))
2617                                 gTOS = IPTOS_THROUGHPUT;
2618                         else if (!strcasecmp(v->value, "reliability"))
2619                                 gTOS = IPTOS_RELIABILITY;
2620                         else if (!strcasecmp(v->value, "mincost"))
2621                                 gTOS = IPTOS_MINCOST;
2622                         else if (!strcasecmp(v->value, "none"))
2623                                 gTOS = 0;
2624                         else
2625                                 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be "
2626                                                                                         "'lowdelay', 'throughput', 'reliability', "
2627                                                                                         "'mincost', or 'none'\n", v->lineno);
2628                 } else if (!strcasecmp(v->name, "amaflags")) {
2629                         gAMAFLAGS = ast_cdr_amaflags2int(v->value);
2630                 } else if (!strcasecmp(v->name, "accountcode")) {
2631          ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode));
2632                 } else if (!strcasecmp(v->name, "disallow")) {
2633                         ast_parse_allow_disallow(&gPrefs, &gCapability, v->value, 0);
2634                 } else if (!strcasecmp(v->name, "allow")) {
2635                         const char* tcodecs = v->value;
2636                         if (!strcasecmp(v->value, "all")) {
2637                                 tcodecs = "ulaw,alaw,g729,g723,gsm";
2638                         }
2639                         ast_parse_allow_disallow(&gPrefs, &gCapability, tcodecs, 1);
2640                 } else if (!strcasecmp(v->name, "dtmfmode")) {
2641                         if (!strcasecmp(v->value, "inband"))
2642                                 gDTMFMode = H323_DTMF_INBAND;
2643                         else if (!strcasecmp(v->value, "rfc2833"))
2644                                 gDTMFMode = H323_DTMF_RFC2833;
2645                         else if (!strcasecmp(v->value, "cisco"))
2646                                 gDTMFMode = H323_DTMF_CISCO;
2647                         else if (!strcasecmp(v->value, "q931keypad"))
2648                                 gDTMFMode = H323_DTMF_Q931;
2649                         else if (!strcasecmp(v->value, "h245alphanumeric"))
2650                                 gDTMFMode = H323_DTMF_H245ALPHANUMERIC;
2651                         else if (!strcasecmp(v->value, "h245signal"))
2652                                 gDTMFMode = H323_DTMF_H245SIGNAL;
2653                         else {
2654             ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", 
2655                                                                     v->value);
2656                                 gDTMFMode = H323_DTMF_RFC2833;
2657                         }
2658                 } else if (!strcasecmp(v->name, "relaxdtmf")) {
2659                         gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
2660                 } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
2661                         gDTMFCodec = atoi(v->value);
2662                 } else if (!strcasecmp(v->name, "t38support")) {
2663                         if (!strcasecmp(v->value, "disabled"))
2664                                 gT38Support = T38_DISABLED;
2665                         if (!strcasecmp(v->value, "no"))
2666                                 gT38Support = T38_DISABLED;
2667                         else if (!strcasecmp(v->value, "faxgw"))
2668                                 gT38Support = T38_FAXGW;
2669                         else if (!strcasecmp(v->value, "yes"))
2670                                 gT38Support = T38_ENABLED;
2671                 } else if (!strcasecmp(v->name, "tracelevel")) {
2672                         gTRCLVL = atoi(v->value);
2673                         ooH323EpSetTraceLevel(gTRCLVL);
2674                 }
2675                 v = v->next;
2676         }
2677         
2678         for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
2679                 if (strcasecmp(cat, "general")) {
2680                         int friend_type = 0;
2681                         utype = ast_variable_retrieve(cfg, cat, "type");
2682                         if (utype) {
2683                                 friend_type = strcasecmp(utype, "friend");
2684                                 if (!strcmp(utype, "user") || 0 == friend_type) {
2685                                         user = build_user(cat, ast_variable_browse(cfg, cat));
2686                                         if (user) {
2687                                                 ast_mutex_lock(&userl.lock);
2688                                                 user->next = userl.users;
2689                                                 userl.users = user;
2690                                                 ast_mutex_unlock(&userl.lock);
2691                                         } else {
2692                                                 ast_log(LOG_WARNING, "Failed to build user %s\n", cat);
2693                                         }
2694                                 }
2695                                 if (!strcasecmp(utype, "peer") || 0 == friend_type) {
2696                                         peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type);
2697                                         if (peer) {
2698                                                 ast_mutex_lock(&peerl.lock);
2699                                                 peer->next = peerl.peers;
2700                                                 peerl.peers = peer;
2701                                                 ast_mutex_unlock(&peerl.lock);
2702                                         } else {
2703                                                 ast_log(LOG_WARNING, "Failed to build peer %s\n", cat);
2704                                         }
2705                                 }
2706                         }
2707                 }
2708         }
2709         ast_config_destroy(cfg);
2710
2711
2712         /* Determine ip address if neccessary */
2713         if (ast_strlen_zero(gIP)) {
2714                 ooGetLocalIPAddress(gIP);
2715                 if (!strcmp(gIP, "127.0.0.1")) {
2716                         ast_log(LOG_NOTICE, "Failed to determine local ip address. Please "
2717                                                                          "specify it in ooh323.conf. OOH323 Disabled\n");
2718                         return 1;
2719                 }
2720         }
2721
2722         if (gH323Debug)
2723                 ast_verbose("+++   reload_config\n");
2724
2725         return 0;
2726
2727 }
2728
2729
2730 static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2731 {
2732         char ip_port[30];
2733         struct ooh323_peer *prev = NULL, *peer = NULL;
2734         
2735         switch (cmd) {
2736         case CLI_INIT:
2737                 e->command = "ooh323 show peer";
2738                 e->usage =
2739                         "Usage: ooh323 show peer <name>\n"
2740                         "                List details of specific OOH323 peer.\n";
2741                 return NULL;
2742         case CLI_GENERATE:
2743                 return NULL;
2744         }
2745
2746         if (a->argc != 4)
2747                 return CLI_SHOWUSAGE;
2748
2749  
2750         ast_mutex_lock(&peerl.lock);
2751         peer = peerl.peers;
2752         while (peer) {
2753                 ast_mutex_lock(&peer->lock);
2754                 if(!strcmp(peer->name, a->argv[3]))
2755                         break;
2756                 else {
2757                         prev = peer;
2758                         peer = peer->next;
2759                         ast_mutex_unlock(&prev->lock);
2760                 }
2761         }
2762
2763         if (peer) {
2764       sprintf(ip_port, "%s:%d", peer->ip, peer->port);
2765       ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
2766       ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
2767       print_codec_to_cli(a->fd, &peer->prefs);
2768       ast_cli(a->fd, ")\n");
2769       ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
2770                 if (peer->dtmfmode & H323_DTMF_CISCO) {
2771          ast_cli(a->fd, "%s\n", "cisco");
2772          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
2773                 } else if (peer->dtmfmode & H323_DTMF_RFC2833) {
2774          ast_cli(a->fd, "%s\n", "rfc2833");
2775          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
2776                 } else if (peer->dtmfmode & H323_DTMF_Q931)
2777          ast_cli(a->fd, "%s\n", "q931keypad");
2778                 else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC)
2779          ast_cli(a->fd, "%s\n", "h245alphanumeric");
2780                 else if (peer->dtmfmode & H323_DTMF_H245SIGNAL)
2781          ast_cli(a->fd, "%s\n", "h245signal");
2782                 else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX)
2783          ast_cli(a->fd, "%s\n", "inband-relaxed");
2784                 else if (peer->dtmfmode & H323_DTMF_INBAND)
2785          ast_cli(a->fd, "%s\n", "inband");
2786                 else
2787          ast_cli(a->fd, "%s\n", "unknown");
2788
2789         ast_cli(a->fd,"%-15s", "T.38 Mode: ");
2790         if (peer->t38support == T38_DISABLED)
2791                 ast_cli(a->fd, "%s\n", "disabled");
2792         else if (peer->t38support == T38_FAXGW)
2793                 ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
2794
2795         ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode);
2796         ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", 
2797                 ast_cdr_flags2str(peer->amaflags));
2798         ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port);
2799         ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit);
2800         ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout);
2801         if (peer->rtpmaskstr[0])
2802                 ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr);
2803         if (peer->rtdrcount && peer->rtdrinterval) 
2804                 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval);
2805         ast_mutex_unlock(&peer->lock);
2806         } else {
2807         ast_cli(a->fd, "Peer %s not found\n", a->argv[3]);
2808         ast_cli(a->fd, "\n");
2809         }
2810         ast_mutex_unlock(&peerl.lock);
2811
2812         return CLI_SUCCESS;
2813 }
2814
2815 static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2816 {
2817         struct ooh323_peer *prev = NULL, *peer = NULL;
2818    char formats[FORMAT_STRING_SIZE];
2819    char ip_port[30];
2820 #define FORMAT  "%-15.15s  %-15.15s  %-23.23s  %-s\n"
2821
2822         switch (cmd) {
2823         case CLI_INIT:
2824                 e->command = "ooh323 show peers";
2825                 e->usage =
2826                         "Usage: ooh323 show peers\n"
2827                         "                Lists all known OOH323 peers.\n";
2828                 return NULL;
2829         case CLI_GENERATE:
2830                 return NULL;
2831         }
2832
2833         if (a->argc != 3)
2834                 return CLI_SHOWUSAGE;
2835
2836    ast_cli(a->fd, FORMAT, "Name", "Accountcode", "ip:port", "Formats");
2837
2838         ast_mutex_lock(&peerl.lock);
2839         peer = peerl.peers;
2840         while (peer) {
2841                 ast_mutex_lock(&peer->lock);
2842                 snprintf(ip_port, sizeof(ip_port), "%s:%d", peer->ip, peer->port);
2843      ast_cli(a->fd, FORMAT, peer->name, 
2844                                         peer->accountcode,
2845                                         ip_port,
2846                  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->capability));
2847                 prev = peer;
2848                 peer = peer->next;
2849                 ast_mutex_unlock(&prev->lock);
2850
2851         }
2852         ast_mutex_unlock(&peerl.lock);
2853 #undef FORMAT
2854         return CLI_SUCCESS;
2855 }
2856
2857 /*! \brief Print codec list from preference to CLI/manager */
2858 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
2859 {
2860         int x, codec;
2861
2862         for (x = 0; x < 32; x++) {
2863                 codec = ast_codec_pref_index(pref, x);
2864                 if (!codec)
2865                         break;
2866                 ast_cli(fd, "%s", ast_getformatname(codec));
2867                 ast_cli(fd, ":%d", pref->framing[x]);
2868                 if (x < 31 && ast_codec_pref_index(pref, x + 1))
2869                         ast_cli(fd, ",");
2870         }
2871         if (!x)
2872                 ast_cli(fd, "none");
2873 }
2874
2875 static char *handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2876 {
2877         struct ooh323_user *prev = NULL, *user = NULL;
2878
2879         switch (cmd) {
2880         case CLI_INIT:
2881                 e->command = "ooh323 show user";
2882                 e->usage =
2883                         "Usage: ooh323 show user <name>\n"
2884                         "                List details of specific OOH323 user.\n";
2885                 return NULL;
2886         case CLI_GENERATE:
2887                 return NULL;
2888         }
2889
2890         if (a->argc != 4)
2891                 return CLI_SHOWUSAGE;
2892
2893
2894         ast_mutex_lock(&userl.lock);
2895         user = userl.users;
2896         while (user) {
2897                 ast_mutex_lock(&user->lock);
2898       if(!strcmp(user->name, a->argv[3])) {
2899                         break;
2900       } else {
2901                         prev = user;
2902                         user = user->next;
2903                         ast_mutex_unlock(&prev->lock);
2904                 }
2905         }
2906
2907         if (user) {
2908       ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
2909       ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
2910       print_codec_to_cli(a->fd, &user->prefs);
2911       ast_cli(a->fd, ")\n");
2912       ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
2913                 if (user->dtmfmode & H323_DTMF_CISCO) {
2914          ast_cli(a->fd, "%s\n", "cisco");
2915          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
2916                 } else if (user->dtmfmode & H323_DTMF_RFC2833) {
2917          ast_cli(a->fd, "%s\n", "rfc2833");
2918          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
2919                 } else if (user->dtmfmode & H323_DTMF_Q931)
2920          ast_cli(a->fd, "%s\n", "q931keypad");
2921                 else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC)
2922          ast_cli(a->fd, "%s\n", "h245alphanumeric");
2923                 else if (user->dtmfmode & H323_DTMF_H245SIGNAL)
2924          ast_cli(a->fd, "%s\n", "h245signal");
2925                 else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX)
2926          ast_cli(a->fd, "%s\n", "inband-relaxed");
2927                 else if (user->dtmfmode & H323_DTMF_INBAND)
2928          ast_cli(a->fd, "%s\n", "inband");
2929                 else
2930          ast_cli(a->fd, "%s\n", "unknown");
2931
2932         ast_cli(a->fd,"%-15s", "T.38 Mode: ");
2933         if (user->t38support == T38_DISABLED)
2934                 ast_cli(a->fd, "%s\n", "disabled");
2935         else if (user->t38support == T38_FAXGW)
2936                 ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
2937
2938       ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode);
2939       ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", 
2940                                             ast_cdr_flags2str(user->amaflags));
2941       ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context);
2942       ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit);
2943       ast_cli(a->fd, "%-15.15s%d\n", "InUse: ", user->inUse);
2944       ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout);
2945         if (user->rtpmaskstr[0])
2946                 ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr);
2947                 ast_mutex_unlock(&user->lock);
2948         if (user->rtdrcount && user->rtdrinterval) 
2949                 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval);
2950         } else {
2951      ast_cli(a->fd, "User %s not found\n", a->argv[3]);
2952      ast_cli(a->fd, "\n");
2953         }
2954         ast_mutex_unlock(&userl.lock);
2955
2956         return CLI_SUCCESS;
2957 }
2958
2959 static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2960 {
2961         struct ooh323_user *prev = NULL, *user = NULL;
2962    char formats[FORMAT_STRING_SIZE];
2963 #define FORMAT1  "%-15.15s  %-15.15s  %-15.15s  %-s\n"
2964
2965         switch (cmd) {
2966         case CLI_INIT:
2967                 e->command = "ooh323 show users";
2968                 e->usage =
2969                         "Usage: ooh323 show users \n"
2970                         "                Lists all known OOH323 users.\n";
2971                 return NULL;
2972         case CLI_GENERATE:
2973                 return NULL;
2974         }
2975
2976         if (a->argc != 3)
2977                 return CLI_SHOWUSAGE;
2978
2979
2980    ast_cli(a->fd, FORMAT1, "Username", "Accountcode", "Context", "Formats");
2981
2982         ast_mutex_lock(&userl.lock);
2983         user = userl.users;
2984    while(user)
2985    {
2986                 ast_mutex_lock(&user->lock);
2987                 ast_cli(a->fd, FORMAT1, user->name, 
2988                                         user->accountcode, user->context,
2989                                         ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->capability));
2990                 prev = user;
2991                 user = user->next;
2992                 ast_mutex_unlock(&prev->lock);
2993
2994         }
2995         ast_mutex_unlock(&userl.lock);
2996 #undef FORMAT1
2997    return RESULT_SUCCESS;
2998
2999 }
3000
3001 static char *handle_cli_ooh323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3002 {
3003         switch (cmd) {
3004         case CLI_INIT:
3005                 e->command = "ooh323 set debug [off]";
3006                 e->usage =
3007                         "Usage: ooh323 set debug [off]\n"
3008                         "                Enables/Disables debugging of OOH323 channel driver\n";
3009                 return NULL;
3010         case CLI_GENERATE:
3011                 return NULL;
3012         }
3013
3014         if (a->argc < 3 || a->argc > 4)
3015                 return CLI_SHOWUSAGE;
3016         if (a->argc == 4 && strcasecmp(a->argv[3], "off"))
3017                 return CLI_SHOWUSAGE;
3018
3019         gH323Debug = (a->argc == 4) ? FALSE : TRUE;
3020         ast_cli(a->fd, "OOH323 Debugging %s\n", gH323Debug ? "Enabled" : "Disabled");
3021
3022         return CLI_SUCCESS;
3023 }
3024
3025 #if 0
3026 static int ooh323_show_channels(int fd, int argc, char *argv[])
3027 {
3028         return RESULT_SUCCESS;
3029 }
3030 #endif
3031
3032 static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3033 {
3034         char value[FORMAT_STRING_SIZE];
3035         ooAliases *pAlias = NULL, *pAliasNext = NULL;;
3036
3037         switch (cmd) {
3038         case CLI_INIT:
3039                 e->command = "ooh323 show config";
3040                 e->usage =
3041                         "Usage: ooh323 show config\n"
3042                         "                Shows global configuration of H.323 channel driver\n";
3043                 return NULL;
3044         case CLI_GENERATE:
3045                 return NULL;
3046         }
3047
3048         if (a->argc != 3)
3049                 return CLI_SHOWUSAGE;
3050
3051
3052
3053    ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n");
3054         snprintf(value, sizeof(value), "%s:%d", gIP, gPort);
3055    ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value);
3056    ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ", 
3057       ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd);
3058    ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no");
3059    ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
3060    ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
3061    ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect", 
3062       gMediaWaitForConnect?"yes":"no");
3063
3064 #if (0)
3065                 extern OOH323EndPoint gH323ep;
3066    ast_cli(a->fd, "%-20s%s\n", "FASTSTART", 
3067                         (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no");
3068    ast_cli(a->fd, "%-20s%s\n", "TUNNELING", 
3069                         (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no");
3070    ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN",
3071                         (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no");
3072 #endif
3073
3074         if (gRasGkMode == RasNoGatekeeper)
3075                 snprintf(value, sizeof(value), "%s", "No Gatekeeper");
3076         else if (gRasGkMode == RasDiscoverGatekeeper)
3077                 snprintf(value, sizeof(value), "%s", "Discover");
3078         else
3079                 snprintf(value, sizeof(value), "%s", gGatekeeper);
3080
3081    ast_cli(a->fd,  "%-20s%s\n", "Gatekeeper:", value);
3082
3083    ast_cli(a->fd,  "%-20s%s\n", "H.323 LogFile:", gLogFile);   
3084
3085    ast_cli(a->fd,  "%-20s%s\n", "Context:", gContext);
3086    
3087    ast_cli(a->fd,  "%-20s%s\n", "Capability:", 
3088            ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCapability));
3089
3090    ast_cli(a->fd, "%-20s", "DTMF Mode: ");
3091         if (gDTMFMode & H323_DTMF_CISCO) {
3092       ast_cli(a->fd, "%s\n", "cisco");
3093       ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec);
3094         } else if (gDTMFMode & H323_DTMF_RFC2833) {
3095       ast_cli(a->fd, "%s\n", "rfc2833");
3096       ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec);
3097         } else if (gDTMFMode & H323_DTMF_Q931)
3098       ast_cli(a->fd, "%s\n", "q931keypad");
3099         else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC)
3100       ast_cli(a->fd, "%s\n", "h245alphanumeric");
3101         else if (gDTMFMode & H323_DTMF_H245SIGNAL)
3102       ast_cli(a->fd, "%s\n", "h245signal");
3103                 else if (gDTMFMode & H323_DTMF_INBAND && gDTMFMode & H323_DTMF_INBANDRELAX)
3104          ast_cli(a->fd, "%s\n", "inband-relaxed");
3105                 else if (gDTMFMode & H323_DTMF_INBAND)
3106          ast_cli(a->fd, "%s\n", "inband");
3107         else
3108                 ast_cli(a->fd, "%s\n", "unknown");
3109
3110         ast_cli(a->fd,"%-20s", "T.38 Mode: ");
3111         if (gT38Support == T38_DISABLED)
3112                 ast_cli(a->fd, "%s\n", "disabled");
3113         else if (gT38Support == T38_FAXGW)
3114                 ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
3115
3116         if (gRTDRCount && gRTDRInterval)
3117                 ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval);
3118
3119    ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber);
3120    ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode);
3121
3122    ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_cdr_flags2str(gAMAFLAGS));
3123
3124         pAlias = gAliasList;
3125    if(pAlias) {
3126      ast_cli(a->fd, "%-20s\n", "Aliases: ");
3127    }
3128         while (pAlias) {
3129                 pAliasNext = pAlias->next;
3130                 if (pAliasNext) {
3131          ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value);
3132                         pAlias = pAliasNext->next;
3133       }
3134       else{
3135          ast_cli(a->fd,"\t%-30s\n",pAlias->value);
3136                         pAlias = pAlias->next;
3137                 }
3138         }
3139         return CLI_SUCCESS;
3140 }
3141
3142 static struct ast_cli_entry cli_ooh323[] = {
3143         AST_CLI_DEFINE(handle_cli_ooh323_set_debug,     "Enable/Disable OOH323 debugging"),
3144         AST_CLI_DEFINE(handle_cli_ooh323_show_config, "Show details on global configuration of H.323 channel driver"),
3145         AST_CLI_DEFINE(handle_cli_ooh323_show_peer,     "Show details on specific OOH323 peer"),
3146         AST_CLI_DEFINE(handle_cli_ooh323_show_peers,  "Show defined OOH323 peers"),
3147         AST_CLI_DEFINE(handle_cli_ooh323_show_user,     "Show details on specific OOH323 user"),
3148         AST_CLI_DEFINE(handle_cli_ooh323_show_users,  "Show defined OOH323 users"),
3149         AST_CLI_DEFINE(handle_cli_ooh323_reload, "reload ooh323 config")
3150 };
3151
3152
3153 static int load_module(void)
3154 {
3155         int res;
3156         struct ooAliases * pNewAlias = NULL;
3157         struct ooh323_peer *peer = NULL;
3158         OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0};
3159
3160         OOH323CALLBACKS h323Callbacks = {
3161                 .onNewCallCreated = onNewCallCreated,
3162                 .onAlerting = onAlerting,
3163                 .onProgress = onProgress,
3164                 .onIncomingCall = NULL,
3165                 .onOutgoingCall = onOutgoingCall,
3166                 .onCallEstablished = onCallEstablished,
3167                 .onCallCleared = onCallCleared,
3168                 .openLogicalChannels = NULL,
3169                 .onReceivedDTMF = ooh323_onReceivedDigit,
3170                 .onModeChanged = onModeChanged
3171         };
3172
3173         myself = ast_module_info->self;
3174
3175         h225Callbacks.onReceivedSetup = &ooh323_onReceivedSetup;
3176
3177         userl.users = NULL;
3178         ast_mutex_init(&userl.lock);
3179         peerl.peers = NULL;
3180         ast_mutex_init(&peerl.lock);
3181  
3182 #if 0           
3183         ast_register_atexit(&ast_ooh323c_exit);
3184 #endif
3185
3186         if (!(sched = sched_context_create())) {
3187                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
3188         }
3189         if (!(io = io_context_create())) {
3190                 ast_log(LOG_WARNING, "Unable to create I/O context\n");
3191         }
3192
3193
3194         if (!(res = reload_config(0))) {
3195                 /* Make sure we can register our OOH323 channel type */
3196                 if (ast_channel_register(&ooh323_tech)) {
3197                         ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
3198                         return 0;
3199                 }
3200                 ast_rtp_glue_register(&ooh323_rtp);
3201                 ast_udptl_proto_register(&ooh323_udptl);
3202                 ast_cli_register_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
3203
3204                  /* fire up the H.323 Endpoint */                
3205                 if (OO_OK != ooH323EpInitialize(OO_CALLMODE_AUDIOCALL, gLogFile)) {
3206          ast_log(LOG_ERROR, "Failed to initialize OOH323 endpoint-"
3207                             "OOH323 Disabled\n");
3208                         return 1;
3209                 }
3210
3211                 if (gIsGateway)
3212                         ooH323EpSetAsGateway();
3213
3214                 ooH323EpSetVersionInfo(t35countrycode, t35extensions, manufacturer,
3215                                                                          vendor, version);
3216                 ooH323EpDisableAutoAnswer();
3217                 ooH323EpSetH225MsgCallbacks(h225Callbacks);
3218                 ooH323EpSetTraceLevel(gTRCLVL);
3219                 ooH323EpSetLocalAddress(gIP, gPort);
3220                 ooH323EpSetCallerID(gCallerID);
3221  
3222       if(ooH323EpSetTCPPortRange(ooconfig.mTCPPortStart, 
3223                                  ooconfig.mTCPPortEnd) == OO_FAILED) {
3224          ast_log(LOG_ERROR, "h225portrange: Failed to set range\n");
3225       }
3226
3227                 /* Set aliases if any */
3228                 for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
3229                         switch (pNewAlias->type) {
3230                         case T_H225AliasAddress_h323_ID:
3231                                 ooH323EpAddAliasH323ID(pNewAlias->value);
3232                                 break;
3233                         case T_H225AliasAddress_dialedDigits:   
3234                                 ooH323EpAddAliasDialedDigits(pNewAlias->value);
3235                                 break;
3236                         case T_H225AliasAddress_email_ID:       
3237                                 ooH323EpAddAliasEmailID(pNewAlias->value);
3238                                 break;
3239          default:
3240             ;
3241                         }
3242                 }
3243
3244                 ast_mutex_lock(&peerl.lock);
3245                 peer = peerl.peers;
3246                 while (peer) {
3247          if(peer->h323id) ooH323EpAddAliasH323ID(peer->h323id);
3248          if(peer->email)  ooH323EpAddAliasEmailID(peer->email);
3249          if(peer->e164)   ooH323EpAddAliasDialedDigits(peer->e164);
3250          if(peer->url)    ooH323EpAddAliasURLID(peer->url);
3251                         peer = peer->next;
3252                 }
3253                 ast_mutex_unlock(&peerl.lock);
3254         
3255
3256                 if (gMediaWaitForConnect)
3257                         ooH323EpEnableMediaWaitForConnect();
3258                 else 
3259                         ooH323EpDisableMediaWaitForConnect();
3260
3261                 /* Fast start and tunneling options */
3262                 if (gFastStart)
3263                         ooH323EpEnableFastStart();
3264                 else
3265                         ooH323EpDisableFastStart();
3266
3267                 if (!gTunneling)
3268                         ooH323EpDisableH245Tunneling();
3269
3270                 if (gBeMaster)
3271                         ooH323EpTryBeMaster(1);
3272
3273                 ooH323EpEnableManualRingback();
3274
3275                 /* Gatekeeper */
3276                 if (gRasGkMode == RasUseSpecificGatekeeper)
3277                         ooGkClientInit(gRasGkMode, gGatekeeper, 0);
3278                 else if (gRasGkMode == RasDiscoverGatekeeper)
3279                         ooGkClientInit(gRasGkMode, 0, 0);
3280
3281                 /* Register callbacks */
3282                 ooH323EpSetH323Callbacks(h323Callbacks);
3283
3284                 /* Add endpoint capabilities */
3285                 if (ooh323c_set_capability(&gPrefs, gCapability, gDTMFMode, gDTMFCodec) < 0) {
3286                         ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
3287                         return 1;
3288                 }
3289   
3290                 /* Create H.323 listener */
3291                 if (ooCreateH323Listener() != OO_OK) {
3292          ast_log(LOG_ERROR, "OOH323 Listener Creation failure. "
3293                             "OOH323 DISABLED\n");
3294                 
3295                         ooH323EpDestroy();
3296                         return 1;
3297                 }
3298
3299                 if (ooh323c_start_stack_thread() < 0) {
3300          ast_log(LOG_ERROR, "Failed to start OOH323 stack thread. "
3301                             "OOH323 DISABLED\n");
3302                         ooH323EpDestroy();
3303                         return 1;
3304                 }
3305                 /* And start the monitor for the first time */
3306                 restart_monitor();
3307         }
3308
3309         return 0;
3310 }
3311
3312
3313 static void *do_monitor(void *data)
3314 {
3315         int res;
3316         int reloading;
3317         struct ooh323_pvt *h323 = NULL;
3318         time_t t;
3319
3320         for (;;) {
3321                 struct ooh323_pvt *h323_next;
3322                 /* Check for a reload request */
3323                 ast_mutex_lock(&h323_reload_lock);
3324                 reloading = h323_reloading;
3325                 h323_reloading = 0;
3326                 ast_mutex_unlock(&h323_reload_lock);
3327                 if (reloading) {
3328                         ast_verb(1, "Reloading H.323\n");
3329                         ooh323_do_reload();
3330                 }
3331
3332                 /* Check for interfaces needing to be killed */
3333                 ast_mutex_lock(&iflock);
3334                 time(&t);
3335                 h323 = iflist;
3336                 while (h323) {
3337                         h323_next = h323->next;
3338
3339                         /* TODO: Need to add rtptimeout keepalive support */
3340                         if (ast_test_flag(h323, H323_NEEDDESTROY)) {
3341                                 ooh323_destroy (h323);
3342          } /* else if (ast_test_flag(h323, H323_NEEDSTART) && h323->owner) {
3343           ast_channel_lock(h323->owner);
3344           if (ast_pbx_start(h323->owner)) {
3345             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", h323->owner->name);
3346             ast_channel_unlock(h323->owner);
3347             ast_hangup(h323->owner);
3348           }
3349           ast_channel_unlock(h323->owner);
3350           ast_clear_flag(h323, H323_NEEDSTART);
3351          } */
3352                         h323 = h323_next;
3353                 }
3354                 ast_mutex_unlock(&iflock);
3355                 pthread_testcancel();
3356
3357                 /* Wait for sched or io */
3358                 res = ast_sched_wait(sched);
3359                 if ((res < 0) || (res > 1000)) {
3360                         res = 1000;
3361                 }
3362                 res = ast_io_wait(io, res);
3363                 pthread_testcancel();
3364                 ast_mutex_lock(&monlock);
3365                 if (res >= 0) {
3366                         ast_sched_runq(sched);
3367                 }
3368                 ast_mutex_unlock(&monlock);
3369         }
3370         /* Never reached */
3371         return NULL;
3372 }
3373
3374 int restart_monitor(void)
3375 {
3376         pthread_attr_t attr;
3377
3378         /* If we're supposed to be stopped -- stay stopped */
3379         if (monitor_thread == AST_PTHREADT_STOP)
3380                 return 0;
3381         if (ast_mutex_lock(&monlock)) {
3382                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
3383                 return -1;
3384         }
3385         if (monitor_thread == pthread_self()) {
3386                 ast_mutex_unlock(&monlock);
3387                 ast_log(LOG_WARNING, "Cannot kill myself\n");
3388                 return -1;
3389         }
3390         if (monitor_thread != AST_PTHREADT_NULL) {
3391                 /* Wake up the thread */
3392                 pthread_kill(monitor_thread, SIGURG);
3393         } else {
3394                 pthread_attr_init(&attr);
3395                 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3396                 /* Start a new monitor */
3397                 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
3398                         ast_mutex_unlock(&monlock);
3399                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
3400                         return -1;
3401                 }
3402         }
3403         ast_mutex_unlock(&monlock);
3404         return 0;
3405 }
3406
3407
3408
3409 int ooh323_destroy(struct ooh323_pvt *p)
3410 {
3411         /* NOTE: Assumes iflock already acquired */
3412         struct ooh323_pvt *prev = NULL, *cur = NULL;
3413         struct ooh323_user *user = NULL;
3414
3415         if (gH323Debug) {
3416                 ast_verbose("---   ooh323_destroy \n");
3417
3418                 if (p)
3419                         ast_verbose(" Destroying %s\n", p->username);
3420         }
3421
3422         cur = iflist;
3423         while (cur) {
3424                 if (cur == p) { break; }
3425                 prev = cur;
3426                 cur = cur->next;
3427         }
3428
3429         if (cur) {
3430                 ast_mutex_lock(&cur->lock);
3431                 if (prev)
3432                         prev->next = cur->next;
3433                 else
3434                         iflist = cur->next;
3435
3436                 if (cur->callToken) {
3437                         if (gH323Debug) 
3438                                 ast_verbose(" Destroying %s\n", cur->callToken);
3439                         ast_free(cur->callToken);
3440                         cur->callToken = 0;
3441                 }
3442
3443                 if (cur->username) {
3444                         free(cur->username);
3445                         cur->username = 0;
3446                 }
3447
3448                 if (cur->host) {
3449                         free(cur->host);
3450                         cur->host = 0;
3451                 }
3452
3453                 if (cur->callerid_name) {
3454                         free(cur->callerid_name);
3455                         cur->callerid_name = 0;
3456                 }
3457                 
3458                 if (cur->callerid_num) {
3459                         free(cur->callerid_num);
3460                         cur->callerid_num = 0;
3461                 }
3462
3463                 if (cur->rtp) {
3464                         ast_rtp_instance_destroy(cur->rtp);
3465                         cur->rtp = NULL;
3466                 }
3467
3468                 if (cur->udptl) {
3469                         ast_udptl_destroy(cur->udptl);
3470                         cur->udptl = NULL;
3471                 }
3472         
3473                 /* Unlink us from the owner if we have one */
3474                 if (cur->owner) {
3475                         while(ast_channel_trylock(cur->owner)) {
3476                                 ast_debug(1,"Failed to grab lock, trying again\n");
3477                                 DEADLOCK_AVOIDANCE(&cur->lock);
3478                         }           
3479                         ast_debug(1, "Detaching from %s\n", cur->owner->name);
3480                         cur->owner->tech_pvt = NULL;
3481                         ast_channel_unlock(cur->owner);
3482                         cur->owner = NULL;
3483                         ast_module_unref(myself);
3484                 }
3485   
3486                 if (cur->vad) {
3487                         ast_dsp_free(cur->vad);
3488                         cur->vad = NULL;
3489                 }
3490
3491 /* decrement user/peer count */
3492