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