eeeb001ea3915a04901a35e71e21cb4eec5ca1a5
[asterisk/asterisk.git] / channels / chan_h323.c
1 /*
2  * chan_h323.c
3  *
4  * OpenH323 Channel Driver for ASTERISK PBX.
5  *                      By Jeremy McNamara
6  *                      For The NuFone Network 
7  *
8  * This code has been derived from code created by
9  *              Michael Manousos and Mark Spencer
10  *
11  * This file is part of the chan_h323 driver for Asterisk
12  *
13  * chan_h323 is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version. 
17  *
18  * chan_h323 is distributed WITHOUT ANY WARRANTY; without even 
19  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
20  * PURPOSE. See the GNU General Public License for more details. 
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
25  *
26  * Version Info: $Id$
27  */
28
29
30 #include <stdio.h>
31 #include <pthread.h>
32 #include <string.h>
33 #include <asterisk/lock.h>
34 #include <asterisk/logger.h>
35 #include <asterisk/channel.h>
36 #include <asterisk/channel_pvt.h>
37 #include <asterisk/config.h>
38 #include <asterisk/module.h>
39 #include <asterisk/pbx.h>
40 #include <asterisk/options.h>
41 #include <asterisk/lock.h>
42 #include <asterisk/sched.h>
43 #include <asterisk/io.h>
44 #include <asterisk/rtp.h>
45 #include <asterisk/acl.h>
46 #include <asterisk/callerid.h>
47 #include <asterisk/cli.h>
48 #include <asterisk/dsp.h>
49 #include <asterisk/translate.h>
50 #include <sys/socket.h>
51 #include <net/if.h>
52 #include <errno.h>
53 #include <unistd.h>
54 #include <stdlib.h>
55 #include <fcntl.h>
56 #include <netdb.h>
57 #include <sys/signal.h>
58 #include <netinet/ip.h>
59
60
61 #include "h323/chan_h323.h"
62
63 #define TRUE  1
64 #define FALSE 0
65
66 /* from rtp.c to translate RTP's payload type to Asterisk's frame subcode */
67 struct rtpPayloadType {
68         int isAstFormat; // whether the following code is an AST_FORMAT
69         int code;
70 };
71
72 call_options_t global_options;
73
74 static struct sockaddr_in bindaddr;    
75
76 /** String variables required by ASTERISK */
77 static char *type       = "H323";
78 static char *desc       = "The NuFone Network's Open H.323 Channel Driver";
79 static char *tdesc      = "The NuFone Network's Open H.323 Channel Driver";
80 static char *config = "h323.conf";
81
82 static char default_context[AST_MAX_EXTENSION];
83
84 /** H.323 configuration values */
85 static char gatekeeper[100];
86 static int      gatekeeper_disable = 1;
87 static int      gatekeeper_discover = 0;
88 static int  usingGk;
89 static int      port = 1720;
90 static int  gkroute = 0;
91
92 /* to find user by alias is default, alternative is the incomming call's source IP 
93 address*/
94 static int  userbyalias = 1;
95
96 static int  bridge_default = 1;
97
98 /* Just about everybody seems to support ulaw, so make it a nice default */
99 static int capability = AST_FORMAT_ULAW;
100
101 /* TOS flag */
102 static int tos = 0;
103
104 static int dtmfmode = H323_DTMF_RFC2833;
105
106 static char secret[50];
107
108 /** Private structure of a OpenH323 channel */
109 struct oh323_pvt {
110         ast_mutex_t lock;                                       /* Channel private lock */
111         call_options_t calloptions;                             /* Options to be used during call setup */
112         int     alreadygone;                                            /* Whether or not we've already been destroyed by or peer */
113         int needdestroy;                                                /* if we need to be destroyed */
114         call_details_t cd;                                              /* Call details */
115         struct ast_channel *owner;                              /* Who owns us */
116         int capability;                                                 /* Special capability */
117         int nonCodecCapability;
118         int outgoing;                                                   /* Outgoing or incoming call? */
119         int nat;                                                                /* Are we talking to a NAT EP?*/
120         int bridge;                                                             /* Determine of we should native bridge or not*/
121         char exten[AST_MAX_EXTENSION];                  /* Requested extension */
122         char context[AST_MAX_EXTENSION];                /* Context where to start */
123         char dnid[AST_MAX_EXTENSION];                   /* Called number */
124         char rdnis[AST_MAX_EXTENSION];                  /* Redirecting number */
125         char username[81];                                              /* H.323 alias using this channel */
126         char accountcode[256];                                  /* Account code */
127         int amaflags;                                                   /* AMA Flags */
128         char callerid[80];                                              /* Caller*ID if available */
129         struct ast_rtp *rtp;                                    /* RTP Session */
130         int dtmfmode;
131         struct ast_dsp *vad;                                    /* Used for in-band DTMF detection */
132         struct oh323_pvt *next;                                 /* Next channel in list */
133 } *iflist = NULL;
134
135 static struct ast_user_list {
136         struct oh323_user *users;
137         ast_mutex_t lock;
138 } userl = { NULL, AST_MUTEX_INITIALIZER };
139
140 static struct ast_peer_list {
141         struct oh323_peer *peers;
142         ast_mutex_t lock;
143 } peerl = { NULL, AST_MUTEX_INITIALIZER };
144
145 static struct ast_alias_list {
146         struct oh323_alias *aliases;
147         ast_mutex_t lock;
148 } aliasl = { NULL, AST_MUTEX_INITIALIZER };
149
150 /** Asterisk RTP stuff*/
151 static struct sched_context *sched;
152 static struct io_context *io;
153
154 /** Protect the interface list (of oh323_pvt's) */
155 static ast_mutex_t iflock = AST_MUTEX_INITIALIZER;
156
157 /** Usage counter and associated lock */
158 static int usecnt =0;
159 static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
160
161 /* Protect the monitoring thread, so only one process can kill or start it, and not
162    when it's doing something critical. */
163 static ast_mutex_t monlock = AST_MUTEX_INITIALIZER;
164
165 /* This is the thread for the monitor which checks for input on the channels
166    which are not currently in use.  */
167 static pthread_t monitor_thread = 0;
168
169 static int restart_monitor(void);
170
171 static void __oh323_destroy(struct oh323_pvt *p)
172 {
173         struct oh323_pvt *cur, *prev = NULL;
174         
175         if (p->rtp) {
176                 ast_rtp_destroy(p->rtp);
177         }
178         
179         /* Unlink us from the owner if we have one */
180         if (p->owner) {
181                 ast_mutex_lock(&p->owner->lock);
182                 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
183                 p->owner->pvt->pvt = NULL;
184                 ast_mutex_unlock(&p->owner->lock);
185         }
186         cur = iflist;
187         while(cur) {
188                 if (cur == p) {
189                         if (prev)
190                                 prev->next = cur->next;
191                         else
192                                 iflist = cur->next;
193                         break;
194                 }
195                 prev = cur;
196                 cur = cur->next;
197         }
198         if (!cur) {
199                 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
200         } else
201                 free(p);
202 }
203
204 static void oh323_destroy(struct oh323_pvt *p)
205 {
206         ast_mutex_lock(&iflock);
207         __oh323_destroy(p);
208         ast_mutex_unlock(&iflock);
209 }
210
211 static struct oh323_alias *build_alias(char *name, struct ast_variable *v)
212 {
213         struct oh323_alias *alias;
214
215         alias = (struct oh323_alias *)malloc(sizeof(struct oh323_alias));
216
217         if (alias) {
218                 memset(alias, 0, sizeof(struct oh323_alias));
219                 strncpy(alias->name, name, sizeof(alias->name)-1);
220
221                 while (v) {
222                         if (!strcasecmp(v->name, "e164")) {
223                                 strncpy(alias->e164,  v->value, sizeof(alias->e164)-1);
224                         } else if (!strcasecmp(v->name, "prefix")) {
225                                 strncpy(alias->prefix,  v->value, sizeof(alias->prefix)-1);
226                         } else if (!strcasecmp(v->name, "context")) {
227                                 strncpy(alias->context,  v->value, sizeof(alias->context)-1);
228                         } else if (!strcasecmp(v->name, "secret")) {
229                                 strncpy(alias->secret,  v->value, sizeof(alias->secret)-1);
230                         } else {
231                                 if (strcasecmp(v->value, "h323")) {     
232                                         ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->value);
233                                 }
234                         }
235                         v = v->next;
236                 }
237         }
238         return alias;
239 }
240
241 static struct oh323_user *build_user(char *name, struct ast_variable *v)
242 {
243         struct oh323_user *user;
244         int format;
245         
246         user = (struct oh323_user *)malloc(sizeof(struct oh323_user));
247         if (user) {
248                 memset(user, 0, sizeof(struct oh323_user));
249                 strncpy(user->name, name, sizeof(user->name)-1);
250                 
251                 /* set the usage flag to a sane starting value*/
252                 user->inUse = 0;
253                 /* Assume we can native bridge */
254                 user->bridge = bridge_default; 
255
256                 while(v) {
257                         if (!strcasecmp(v->name, "context")) {
258                                 strncpy(user->context, v->value, sizeof(user->context)-1);
259                         } else if (!strcasecmp(v->name, "bridge")) {
260                                 user->bridge = ast_true(v->value);
261                       } else if (!strcasecmp(v->name, "nat")) {
262                               user->nat = ast_true(v->value);
263                         } else if (!strcasecmp(v->name, "noFastStart")) {
264                                 user->call_options.noFastStart = ast_true(v->value);
265                         } else if (!strcasecmp(v->name, "noH245Tunneling")) {
266                                 user->call_options.noH245Tunnelling = ast_true(v->value);
267                         } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
268                                 user->call_options.noSilenceSuppression = ast_true(v->value);
269                         } else if (!strcasecmp(v->name, "secret")) {
270                                 strncpy(user->secret, v->value, sizeof(user->secret)-1);
271                         } else if (!strcasecmp(v->name, "callerid")) {
272                                 strncpy(user->callerid, v->value, sizeof(user->callerid)-1);
273                         } else if (!strcasecmp(v->name, "accountcode")) {
274                                 strncpy(user->accountcode, v->value, sizeof(user->accountcode)-1);
275                         } else if (!strcasecmp(v->name, "progress_setup")) {
276                                 int progress_setup = atoi(v->value);
277                                 if((progress_setup != 0) &&
278                                    (progress_setup != 1) &&
279                                    (progress_setup != 3) &&
280                                    (progress_setup != 8)) {
281                                         ast_log(LOG_WARNING, "Invalid value %d for progress_setup at line %d, assuming 0\n", progress_setup, v->lineno);
282                                         progress_setup = 0;
283                                 }
284                                 user->call_options.progress_setup = progress_setup;
285                         } else if (!strcasecmp(v->name, "progress_alert")) {
286                                 int progress_alert = atoi(v->value);
287                                 if((progress_alert != 0) &&
288                                    (progress_alert != 8)) {
289                                         ast_log(LOG_WARNING, "Invalid value %d for progress_alert at line %d, assuming 0\n", progress_alert, v->lineno);
290                                         progress_alert = 0;
291                                 }
292                                 user->call_options.progress_alert = progress_alert;
293                         } else if (!strcasecmp(v->name, "progress_audio")) {
294                                 user->call_options.progress_audio = ast_true(v->value);
295                         } else if (!strcasecmp(v->name, "incominglimit")) {
296                                 user->incominglimit = atoi(v->value);
297                                 if (user->incominglimit < 0)
298                                         user->incominglimit = 0;
299                         } else if (!strcasecmp(v->name, "host")) {
300                                 if (!strcasecmp(v->value, "dynamic")) {
301                                         ast_log(LOG_ERROR, "Dynamic host configuration not implemented, yet!\n");
302                                         free(user);
303                                         return NULL;
304                                 } else if (ast_get_ip(&user->addr, v->value)) {
305                                         free(user);
306                                         return NULL;
307                                 } 
308                                 /* Let us know we need to use ip authentication */
309                                 user->host = 1;
310                         } else if (!strcasecmp(v->name, "amaflags")) {
311                                 format = ast_cdr_amaflags2int(v->value);
312                                 if (format < 0) {
313                                         ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
314                                 } else {
315                                         user->amaflags = format;
316                                 }
317                         }
318                         v = v->next;
319                 }
320         }
321         return user;
322 }
323
324
325 static struct oh323_peer *build_peer(char *name, struct ast_variable *v)
326 {
327         struct oh323_peer *peer;
328         struct oh323_peer *prev;
329         int found=0;
330         
331         prev = NULL;
332         ast_mutex_lock(&peerl.lock);
333         peer = peerl.peers;
334
335         while(peer) {
336                 if (!strcasecmp(peer->name, name)) {    
337                         break;
338                 }
339                 prev = peer;
340                 peer = peer->next;
341         }
342
343         if (peer) {
344                 found++;
345                 /* Already in the list, remove it and it will be added back (or FREE'd) */
346                 if (prev) {
347                         prev->next = peer->next;
348                 } else {
349                         peerl.peers = peer->next;
350                 }
351                 ast_mutex_unlock(&peerl.lock);
352         } else {
353                 ast_mutex_unlock(&peerl.lock);
354                 peer = malloc(sizeof(struct oh323_peer));
355                 memset(peer, 0, sizeof(struct oh323_peer));
356         }
357         if (peer) {
358                 if (!found) {
359                         strncpy(peer->name, name, sizeof(peer->name)-1);
360                 }
361                 
362                 /* set the usage flag to a sane starting value*/
363                 peer->inUse = 0;
364
365                 while(v) {
366                         if (!strcasecmp(v->name, "context")) {
367                                 strncpy(peer->context, v->value, sizeof(peer->context)-1);
368                         }  else if (!strcasecmp(v->name, "bridge")) {
369                                 peer->bridge = ast_true(v->value);
370                         } else if (!strcasecmp(v->name, "noFastStart")) {
371                                 peer->call_options.noFastStart = ast_true(v->value);
372                         } else if (!strcasecmp(v->name, "noH245Tunneling")) {
373                                 peer->call_options.noH245Tunnelling = ast_true(v->value);
374                         } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
375                                 peer->call_options.noSilenceSuppression = ast_true(v->value);
376                         } else if (!strcasecmp(v->name, "progress_setup")) {
377                                 int progress_setup = atoi(v->value);
378                                 if((progress_setup != 0) &&
379                                    (progress_setup != 1) &&
380                                    (progress_setup != 3) &&
381                                    (progress_setup != 8)) {
382                                         ast_log(LOG_WARNING, "Invalid value %d for progress_setup at line %d, assuming 0\n", progress_setup, v->lineno);
383                                         progress_setup = 0;
384                                 }
385                                 peer->call_options.progress_setup = progress_setup;
386                         } else if (!strcasecmp(v->name, "progress_alert")) {
387                                 int progress_alert = atoi(v->value);
388                                 if((progress_alert != 0) &&
389                                    (progress_alert != 8)) {
390                                         ast_log(LOG_WARNING, "Invalid value %d for progress_alert at line %d, assuming 0\n", progress_alert, v->lineno);
391                                         progress_alert = 0;
392                                 }
393                                 peer->call_options.progress_alert = progress_alert;
394                         } else if (!strcasecmp(v->name, "progress_audio")) {
395                                 peer->call_options.progress_audio = ast_true(v->value);
396                         } else if (!strcasecmp(v->name, "outgoinglimit")) {
397                                 peer->outgoinglimit = atoi(v->value);
398                                 if (peer->outgoinglimit > 0)
399                                         peer->outgoinglimit = 0;
400                         } else if (!strcasecmp(v->name, "host")) {
401                                 if (!strcasecmp(v->value, "dynamic")) {
402                                         ast_log(LOG_ERROR, "Dynamic host configuration not implemented, yet!\n");
403                                         free(peer);
404                                         return NULL;
405                                 }
406                                 if (ast_get_ip(&peer->addr, v->value)) {
407                                                 free(peer);
408                                                 return NULL;
409                                 }
410                         } 
411                         v=v->next;
412                 }
413         }
414         return peer;
415 }
416
417
418
419 /**
420  * Send (play) the specified digit to the channel.
421  * 
422  */
423 static int oh323_digit(struct ast_channel *c, char digit)
424 {
425         struct oh323_pvt *p = c->pvt->pvt;
426         if (p && p->rtp && (p->dtmfmode & H323_DTMF_RFC2833)) {
427                 ast_rtp_senddigit(p->rtp, digit);
428         }
429         /* If in-band DTMF is desired, send that */
430         if (p->dtmfmode & H323_DTMF_INBAND)
431                 h323_send_tone(p->cd.call_token, digit);
432         return 0;
433 }
434
435
436 /**
437  * Make a call over the specified channel to the specified 
438  * destination. This function will parse the destination string
439  * and determine the address-number to call.
440  * Return -1 on error, 0 on success.
441  */
442 static int oh323_call(struct ast_channel *c, char *dest, int timeout)
443 {
444         int res;
445         struct oh323_pvt *p = c->pvt->pvt;
446         char called_addr[256];
447         char *tmp;
448
449         strtok_r(dest, "/", &(tmp));
450
451         ast_log(LOG_DEBUG, "dest=%s, timeout=%d.\n", dest, timeout);
452
453         if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
454                 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name);
455                 return -1;
456         }
457         
458         /* outgoing call */
459         p->outgoing = 1;
460
461         /* Clear the call token */
462         if ((p->cd).call_token == NULL)
463                 (p->cd).call_token = (char *)malloc(128);
464
465         memset((char *)(p->cd).call_token, 0, 128);
466         
467         if (p->cd.call_token == NULL) {
468                 ast_log(LOG_ERROR, "Not enough memory.\n");
469                 return -1;
470         }
471
472         /* Build the address to call */
473         memset(called_addr, 0, sizeof(dest));
474         memcpy(called_addr, dest, sizeof(called_addr));
475
476         /* Copy callerid, if there is any */
477         if (c->callerid) {
478                 char *tmp = strchr(c->callerid, '"');
479                 if (!tmp) {
480                         p->calloptions.callerid = malloc(80); // evil
481                         // sprintf(p->calloptions.callerid, "\"%s\"", c->callerid);
482                         sprintf(p->calloptions.callerid, "\"\" <%s>", c->callerid);
483                 } else {
484                         p->calloptions.callerid = strdup(c->callerid);
485                 }       
486         }
487
488         res = h323_make_call(called_addr, &(p->cd), &p->calloptions);
489
490         if (res) {
491                 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
492                 return -1;
493         }
494
495         ast_setstate(c, AST_STATE_RING);
496         return 0;
497 }
498
499
500 static int oh323_answer(struct ast_channel *c)
501 {
502         int res;
503
504         struct oh323_pvt *p = c->pvt->pvt;
505
506         res = h323_answering_call(p->cd.call_token, 0);
507         
508         if (c->_state != AST_STATE_UP)
509                 ast_setstate(c, AST_STATE_UP);
510
511         return res;
512 }
513
514 static int oh323_hangup(struct ast_channel *c)
515 {
516         struct oh323_pvt *p = c->pvt->pvt;
517         int needcancel = 0;
518         if (h323debug)
519                 ast_log(LOG_DEBUG, "oh323_hangup(%s)\n", c->name);
520         if (!c->pvt->pvt) {
521                 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
522                 return 0;
523         }
524         ast_mutex_lock(&p->lock);
525         /* Determine how to disconnect */
526         if (p->owner != c) {
527                 ast_log(LOG_WARNING, "Huh?  We aren't the owner?\n");
528                 ast_mutex_unlock(&p->lock);
529                 return 0;
530         }
531         if (!c || (c->_state != AST_STATE_UP))
532                 needcancel = 1;
533         /* Disconnect */
534         p = c->pvt->pvt;
535         
536         /* Free dsp used for in-band DTMF detection */
537         if (p->vad) {
538                 ast_dsp_free(p->vad);
539      }
540
541         p->owner = NULL;
542         c->pvt->pvt = NULL;
543
544         /* Start the process if it's not already started */
545         if (!p->alreadygone) {
546                 if (h323_clear_call((p->cd).call_token)) 
547                         ast_log(LOG_DEBUG, "ClearCall failed.\n");
548                 p->needdestroy = 1;
549         }
550
551         /* Update usage counter */
552         ast_mutex_lock(&usecnt_lock);
553         usecnt--;
554         if (usecnt < 0)
555                 ast_log(LOG_WARNING, "Usecnt < 0\n");
556         ast_mutex_unlock(&usecnt_lock);
557         ast_update_use_count();
558
559         ast_mutex_unlock(&p->lock);
560         return 0;
561 }
562
563 /* Pass channel struct too to allow RTCP handling */
564 static struct ast_frame *oh323_rtp_read(struct ast_channel *c, struct oh323_pvt *p)
565 {
566         /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
567         struct ast_frame *f;
568         static struct ast_frame null_frame = { AST_FRAME_NULL, };
569
570         /* Only apply it for the first packet, we just need the correct ip/port */
571         if(p->nat)
572         {
573                 ast_rtp_setnat(p->rtp,p->nat);
574                 p->nat = 0;
575         }
576
577         switch(c->fdno) {
578         case 0: /* RTP stream */
579                 f = ast_rtp_read(p->rtp);
580                 break;
581         case 1: /* RTCP stream */
582                 f = ast_rtcp_read(p->rtp);
583                 break;
584         default:
585                 f = &null_frame;
586         }
587
588         /* Don't send RFC2833 if we're not supposed to */
589         if (f && (f->frametype == AST_FRAME_DTMF) && !(p->dtmfmode & H323_DTMF_RFC2833))
590                 return &null_frame;
591         if (p->owner) {
592                 /* We already hold the channel lock */
593                 if (f->frametype == AST_FRAME_VOICE) {
594                         if (f->subclass != p->owner->nativeformats) {
595                                 /* Must be handled on opening logical channel */
596                                 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
597                                 p->owner->nativeformats = f->subclass;
598                                 ast_set_read_format(p->owner, p->owner->readformat);
599                                 /* Don't set write format because it will be set up when channel started */
600 //                              ast_set_write_format(p->owner, p->owner->writeformat);
601                         }
602                 
603                         /* Do in-band DTMF detection */
604                         if (p->dtmfmode & H323_DTMF_INBAND) {
605                    f = ast_dsp_process(p->owner,p->vad,f,0);
606                                    if (f->frametype == AST_FRAME_DTMF)
607                                         ast_log(LOG_DEBUG, "Got in-band digit %c.\n", f->subclass);
608             }
609                         
610                         
611                 }
612         }
613         return f;
614 }
615
616
617 static struct ast_frame  *oh323_read(struct ast_channel *c)
618 {
619         struct ast_frame *fr;
620         struct oh323_pvt *p = c->pvt->pvt;
621         ast_mutex_lock(&p->lock);
622         /* Pass channel structure to handle other streams than just RTP */
623         fr = oh323_rtp_read(c, p);
624         ast_mutex_unlock(&p->lock);
625         return fr;
626 }
627
628 static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
629 {
630         struct oh323_pvt *p = c->pvt->pvt;
631         int res = 0;
632         int need_frfree = 0;    /* Does ast_frfree() call required? */
633         if (frame->frametype != AST_FRAME_VOICE) {
634                 if (frame->frametype == AST_FRAME_IMAGE)
635                         return 0;
636                 else {
637                         ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
638                         return 0;
639                 }
640         } else {
641                 if (!(frame->subclass & c->nativeformats)) {
642                         if(!(frame->subclass & c->writeformat)) { /* Someone sent frame with old format */
643                                 ast_log(LOG_WARNING, "Asked to transmit frame type %s from %s by '%s', while native formats is %s (read/write = %s/%s)\n",
644                                         ast_getformatname(frame->subclass), frame->src, c->name, ast_getformatname(c->nativeformats), ast_getformatname(c->readformat), ast_getformatname(c->writeformat));
645                                 return (c->nativeformats ? 0 : -1);
646                         } else {
647                                 /* Frame goes from RTP is not in our native
648                                  * format - try to translate it... Or we must
649                                  * just drop it?
650                                  */
651
652                                 /* Sometimes translation table isn't set
653                                  * correctly but writeformat is invalid,
654                                  * so force required translation allocation
655                                  */
656                                 ast_set_write_format(c, c->nativeformats);
657                                 ast_set_write_format(c, frame->subclass);
658
659                                 /* Translate it on-the-fly */
660                                 if (c->pvt->writetrans) {
661                                         struct ast_frame *frame1;
662                                         ast_log(LOG_WARNING, "Asked to transmit frame type %s from %s by '%s', while native formats is %s (read/write = %s/%s) - 2 TRANSLATE\n",
663                                                 ast_getformatname(frame->subclass), frame->src, c->name, ast_getformatname(c->nativeformats), ast_getformatname(c->readformat), ast_getformatname(c->writeformat));
664                                         /* Allocate new frame with translated context.
665                                          * Don't free frame because it will be freed on
666                                          * upper layer (RTP).
667                                          */
668                                         frame1 = ast_translate(c->pvt->writetrans, frame, 0);
669                                         if(frame1) {
670                                                 /* Substitute passed frame with translated and
671                                                    mark it for freeing before return */
672                                                 frame = frame1;
673                                                 need_frfree = 1;
674                                         }
675                                         else
676                                                 ast_log(LOG_WARNING, "Unable to translate frame type %s to %s\n", ast_getformatname(frame->subclass), ast_getformatname(c->nativeformats));
677                                 } else {
678                                         ast_log(LOG_WARNING, "Asked to transmit frame type %s from %s by '%s', while native formats is %s (read/write = %s/%s)\n",
679                                                 ast_getformatname(frame->subclass), frame->src, c->name, ast_getformatname(c->nativeformats), ast_getformatname(c->readformat), ast_getformatname(c->writeformat));
680                                         return -1;
681                                 }
682                         }
683                 }
684         }
685         if (p) {
686                 ast_mutex_lock(&p->lock);
687                 if (p->rtp) {
688                         res =  ast_rtp_write(p->rtp, frame);
689                 }
690                 ast_mutex_unlock(&p->lock);
691         }
692         /* Free translated frame */
693         if(need_frfree)
694                 ast_frfree(frame);
695         return res;
696 }
697
698 /** FIXME: Can I acutally use this or does Open H.323 take care of everything? */
699 static int oh323_indicate(struct ast_channel *c, int condition)
700 {
701
702         struct oh323_pvt *p = c->pvt->pvt;
703         
704         switch(condition) {
705         case AST_CONTROL_RINGING:
706                 if (c->_state == AST_STATE_RING) {
707                 //      transmit_response(p, "180 Ringing", &p->initreq);
708                         break;
709                 }
710                 return 0;
711         case AST_CONTROL_BUSY:
712                 if (c->_state != AST_STATE_UP) {
713                 //      transmit_response(p, "600 Busy everywhere", &p->initreq);
714                         p->alreadygone = 1;
715                         ast_softhangup(c, AST_SOFTHANGUP_DEV);
716                         break;
717                 }
718                 return 0;
719         case AST_CONTROL_CONGESTION:
720                 if (c->_state != AST_STATE_UP) {
721                 //      transmit_response(p, "486 Busy here", &p->initreq);
722                         p->alreadygone = 1;
723                         ast_softhangup(c, AST_SOFTHANGUP_DEV);
724                         break;
725                 }
726                 return 0;
727         case -1:
728                 return 0;
729         default:
730                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
731                 return -1;
732         }
733         return 0;
734 }
735
736 // FIXME: WTF is this? Do I need this???
737 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
738 {
739         struct oh323_pvt *p = newchan->pvt->pvt;
740
741         ast_mutex_lock(&p->lock);
742         if (p->owner != oldchan) {
743                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
744                 return -1;
745         }
746         p->owner = newchan;
747         ast_mutex_unlock(&p->lock);
748         return 0;
749 }
750
751 static struct ast_channel *oh323_new(struct oh323_pvt *i, int state, const char *host)
752 {
753         struct ast_channel *ch;
754         int fmt;
755         ch = ast_channel_alloc(1);
756         
757         if (ch) {
758                 
759 //              snprintf(ch->name, sizeof(ch->name)-1, "H323/%s-%04x", host, rand() & 0xffff);
760                 snprintf(ch->name, sizeof(ch->name)-1, "H323/%s", host);
761                 ch->nativeformats = i->capability;
762                 if (!ch->nativeformats)
763                         ch->nativeformats = capability;
764                 fmt = ast_best_codec(ch->nativeformats);
765                 ch->type = type;
766
767                 /* RTP stream */
768                 ch->fds[0] = ast_rtp_fd(i->rtp);
769
770                 /* RTCP stream */
771                 ch->fds[1] = ast_rtcp_fd(i->rtp);
772
773                 ast_setstate(ch, state);
774                 
775                 if (state == AST_STATE_RING)
776                         ch->rings = 1;
777                 
778                 ch->writeformat = fmt;
779                 ch->pvt->rawwriteformat = fmt;
780                 ch->readformat = fmt;
781                 ch->pvt->rawreadformat = fmt;
782                 
783                 /* Allocate dsp for in-band DTMF support */
784                 if (i->dtmfmode & H323_DTMF_INBAND) {
785                         i->vad = ast_dsp_new();
786                         ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
787                 }
788
789                 /* Register the OpenH323 channel's functions. */
790                 ch->pvt->pvt = i;
791                 ch->pvt->send_digit = oh323_digit;
792                 ch->pvt->call = oh323_call;
793                 ch->pvt->hangup = oh323_hangup;
794                 ch->pvt->answer = oh323_answer;
795                 ch->pvt->read = oh323_read;
796                 ch->pvt->write = oh323_write;
797                 ch->pvt->indicate = oh323_indicate;
798                 ch->pvt->fixup = oh323_fixup;
799 //              ch->pvt->bridge = ast_rtp_bridge;
800
801                 /*  Set the owner of this channel */
802                 i->owner = ch;
803                 
804                 ast_mutex_lock(&usecnt_lock);
805                 usecnt++;
806                 ast_mutex_unlock(&usecnt_lock);
807                 ast_update_use_count();
808                 strncpy(ch->context, i->context, sizeof(ch->context)-1);
809                 strncpy(ch->exten, i->exten, sizeof(ch->exten)-1);              
810                 ch->priority = 1;
811                 if (strlen(i->callerid))
812                         ch->callerid = strdup(i->callerid);
813                 if (strlen(i->dnid))
814                         ch->dnid = strdup(i->dnid);
815                 if (strlen(i->rdnis))
816                         ch->rdnis = strdup(i->rdnis);
817                 if (strlen(i->accountcode))
818                         strncpy(ch->accountcode, i->accountcode, sizeof(ch->accountcode)-1);
819                 if (i->amaflags)
820                         ch->amaflags = i->amaflags;
821                 if (state != AST_STATE_DOWN) {
822                         if (ast_pbx_start(ch)) {
823                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
824                                 ast_hangup(ch);
825                                 ch = NULL;
826                         }
827                 }
828         } else
829                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
830         return ch;
831 }
832
833 static struct oh323_pvt *oh323_alloc(int callid)
834 {
835         struct oh323_pvt *p;
836
837         p = malloc(sizeof(struct oh323_pvt));
838         if (!p) {
839                 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
840                 return NULL;
841         }
842
843         /* Keep track of stuff */
844         memset(p, 0, sizeof(struct oh323_pvt));
845         p->rtp = ast_rtp_new(sched, io, 1, 0);
846
847         if (!p->rtp) {
848                 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
849                 free(p);
850                 return NULL;
851         }
852         ast_rtp_settos(p->rtp, tos);
853         ast_mutex_init(&p->lock);
854         
855         p->cd.call_reference = callid;
856         p->bridge = bridge_default;
857         memcpy(&p->calloptions, &global_options, sizeof(global_options));
858         
859         p->dtmfmode = dtmfmode;
860         if (p->dtmfmode & H323_DTMF_RFC2833)
861                 p->nonCodecCapability |= AST_RTP_DTMF;
862
863         /* Add to interface list */
864         ast_mutex_lock(&iflock);
865         p->next = iflist;
866         iflist = p;
867         ast_mutex_unlock(&iflock);
868         return p;
869 }
870
871 static struct oh323_pvt *find_call(int call_reference)
872 {  
873         struct oh323_pvt *p;
874
875         ast_mutex_lock(&iflock);
876         p = iflist; 
877
878         while(p) {
879                 if (p->cd.call_reference == call_reference) {
880                         /* Found the call */                                            
881                         ast_mutex_unlock(&iflock);
882                         return p;
883                 }
884                 p = p->next; 
885         }
886         ast_mutex_unlock(&iflock);
887
888         return NULL;
889 }
890
891 static struct ast_channel *oh323_request(char *type, int format, void *data)
892 {
893         int oldformat;
894         struct oh323_pvt *p;
895         struct ast_channel *tmpc = NULL;
896         char *dest = data;
897         char *ext, *host;
898         char *h323id = NULL;
899         char tmp[256];
900
901         
902         ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);
903
904         oldformat = format;
905         format &= capability;
906         if (!format) {
907                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
908                 return NULL;
909         }
910         
911         strncpy(tmp, dest, sizeof(tmp) - 1);
912                 
913         host = strchr(tmp, '@');
914         if (host) {
915                 *host = '\0';
916                 host++;
917                 ext = tmp;
918         } else {
919                 host = tmp;
920                 ext = NULL;
921         }
922
923         strtok_r(host, "/", &(h323id));
924                 
925         if (*h323id) {
926                 h323_set_id(h323id);
927         }
928                 
929         
930         p = oh323_alloc(0);
931
932         if (!p) {
933                 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
934                 return NULL;
935         }
936
937         /* Assign a default capability */
938         p->capability = capability;
939
940         if (p->dtmfmode) {
941                 if (p->dtmfmode & H323_DTMF_RFC2833)
942                         p->nonCodecCapability |= AST_RTP_DTMF;
943                 else
944                         p->nonCodecCapability &= ~AST_RTP_DTMF;
945         }
946
947
948         ast_log(LOG_DEBUG, "Host: %s\tUsername: %s\n", host, p->username);
949
950         if (ext)
951                 strncpy(p->username, ext, sizeof(p->username) - 1);
952         tmpc = oh323_new(p, AST_STATE_DOWN, host);
953         if (!tmpc)
954                 oh323_destroy(p);
955         
956         restart_monitor();
957         
958         return tmpc;
959 }
960
961 struct oh323_alias *find_alias(call_details_t cd)
962 {
963         struct oh323_alias *a, *a_e164 = NULL, *a_pfx = NULL;
964         char *s, *p;
965         int a_pfxlen, numlen;
966
967         a = aliasl.aliases;
968         a_pfxlen = 0;
969         numlen = strlen(cd.call_dest_e164);
970
971         while(a) {
972
973                 if (!strcasecmp(a->name, cd.call_dest_alias)) {
974                         break;
975                 }
976                 /* Check for match of E164 number */
977                 if (!strcasecmp(a->e164, cd.call_dest_e164))
978                         a_e164 = a;
979                 else { /* Check for match called number with prefixes */
980                         for(s = a->prefix; *s; ) {
981                                 for(; *s == ' '; ++s);
982                                 if(!(p = strchr(s, ',')))
983                                         p = s + strlen(s);
984                                 if((p - s > a_pfxlen) && (numlen >= p - s) && (strncasecmp(s, cd.call_dest_e164, p - s) == 0)) {
985                                         a_pfxlen = p - s;
986                                         a_pfx = a;
987                                 }
988                                 s = p;
989                                 if(*s == ',')
990                                   ++s;
991                         }
992                 }
993                 a = a->next;
994         }
995         if(a)
996                 return a;
997         if(a_e164)
998                 return a_e164;
999         return a_pfx;
1000 }
1001
1002 struct oh323_user *find_user(const call_details_t cd)
1003 {
1004         struct oh323_user *u;
1005
1006         u = userl.users;
1007         if(userbyalias == 1){
1008                 while(u) {
1009                         if (!strcasecmp(u->name, cd.call_source_aliases)) {
1010                                 break;
1011                         }
1012                         u = u->next;
1013                 }
1014
1015         } else {
1016                 while(u) {
1017                         if (!strcasecmp(cd.sourceIp, inet_ntoa(u->addr.sin_addr))) {
1018                                 break;
1019                         }
1020                         u = u->next;
1021                 }
1022
1023         
1024         }
1025         return u;
1026
1027 }
1028
1029 struct oh323_peer *find_peer(char *dest_peer)
1030 {
1031         struct oh323_peer *p;
1032
1033         p = peerl.peers;
1034
1035         while(p) {
1036                 if (!strcasecmp(p->name, dest_peer)) {
1037                         break;
1038                 }
1039                 p = p->next;
1040         }
1041         return p;
1042
1043 }
1044
1045 static int progress(unsigned call_reference, int inband)
1046 {
1047         struct oh323_pvt *p;
1048         
1049         ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
1050         p = find_call(call_reference);
1051
1052         if (!p) {
1053                 ast_log(LOG_ERROR, "Private structure not found in send_digit.\n");
1054                 return -1;
1055         }
1056         if (!p->owner) {
1057                 ast_log(LOG_ERROR, "No asterisk's channel associated with private structure.\n");
1058                 return -1;
1059         }
1060
1061         ast_queue_control(p->owner, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING), 0);
1062         
1063         return 0;
1064 }
1065
1066 /**
1067   * Callback for sending digits from H.323 up to asterisk
1068   *
1069   */
1070 int send_digit(unsigned call_reference, char digit)
1071 {
1072         struct oh323_pvt *p;
1073         struct ast_frame f;
1074
1075         ast_log(LOG_DEBUG, "Recieved Digit: %c\n", digit);
1076         p = find_call(call_reference);
1077         
1078         if (!p) {
1079                 ast_log(LOG_ERROR, "Private structure not found in send_digit.\n");
1080                 return -1;
1081         }
1082         memset(&f, 0, sizeof(f));
1083         f.frametype = AST_FRAME_DTMF;
1084         f.subclass = digit;
1085         f.datalen = 0;
1086         f.samples = 300;
1087         f.offset = 0;
1088         f.data = NULL;
1089         f.mallocd = 0;
1090         f.src = "SEND_DIGIT";
1091         
1092         return ast_queue_frame(p->owner, &f, 1);        
1093 }
1094
1095 /**
1096   * Call-back function that gets called when any H.323 connection is made
1097   *
1098   * Returns the local RTP information
1099   */
1100 struct rtp_info *create_connection(unsigned call_reference)
1101 {       
1102         struct oh323_pvt *p;
1103         struct sockaddr_in us;
1104         struct sockaddr_in them;
1105         struct rtp_info *info;
1106
1107         info = malloc(sizeof(struct rtp_info));
1108
1109         p = find_call(call_reference);
1110
1111         if (!p) {
1112                 ast_log(LOG_ERROR, "Unable to allocate private structure, this is very bad.\n");
1113                 return NULL;
1114         }
1115
1116         /* figure out our local RTP port and tell the H.323 stack about it*/
1117         ast_rtp_get_us(p->rtp, &us);
1118         ast_rtp_get_peer(p->rtp, &them);
1119
1120
1121         info->addr = inet_ntoa(us.sin_addr);
1122         info->port = ntohs(us.sin_port);
1123
1124
1125         return info;
1126 }
1127
1128 /**
1129  *  Call-back function for incoming calls
1130  *
1131  *  Returns 1 on success
1132  */
1133
1134 call_options_t *setup_incoming_call(call_details_t cd)
1135 {
1136         
1137         struct oh323_pvt *p = NULL;
1138         struct ast_channel *c = NULL;
1139         struct oh323_user *user = NULL;
1140         struct oh323_alias *alias = NULL;
1141         call_options_t *call_options = NULL;
1142
1143         /* allocate the call*/
1144         p = oh323_alloc(cd.call_reference);
1145
1146         if (!p) {
1147                 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
1148                 return NULL;
1149         }
1150
1151         /* Populate the call details in the private structure */
1152         p->cd.call_token = cd.call_token;
1153         p->cd.call_source_aliases = cd.call_source_aliases;
1154         p->cd.call_dest_alias = cd.call_dest_alias;
1155         p->cd.call_source_e164 = cd.call_source_e164;
1156         p->cd.call_dest_e164 = cd.call_dest_e164;
1157
1158         if (h323debug) {
1159                 ast_verbose(VERBOSE_PREFIX_2 "Setting up Call\n");
1160                 ast_verbose(VERBOSE_PREFIX_3 "Calling party name:  [%s]\n", p->cd.call_source_aliases);
1161                 ast_verbose(VERBOSE_PREFIX_3 "Calling party number:  [%s]\n", p->cd.call_source_e164);
1162                 ast_verbose(VERBOSE_PREFIX_3 "Called party name:  [%s]\n", p->cd.call_dest_alias);
1163                 ast_verbose(VERBOSE_PREFIX_3 "Called party number:  [%s]\n", p->cd.call_dest_e164);
1164                 ast_verbose(VERBOSE_PREFIX_3 "Redirecting party number:  [%s]\n", p->cd.call_redir_e164);
1165         }
1166
1167         /* Decide if we are allowing Gatekeeper routed calls*/
1168         if ((!strcasecmp(cd.sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk == 1)) {
1169                 
1170                 if (strlen(cd.call_dest_e164)) {
1171                        char *ctx;
1172
1173                        alias = find_alias(cd);
1174                        ctx = alias ? alias->context : default_context;
1175
1176                        strncpy(p->dnid, cd.call_dest_e164, sizeof(p->dnid)-1);
1177                        strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1);
1178                        strncpy(p->context, ctx, sizeof(p->context)-1);
1179                 } else {
1180                         alias = find_alias(cd);
1181                 
1182                         if (!alias) {
1183                                 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd.call_dest_alias);
1184                                 return 0;
1185                         }
1186                         strncpy(p->exten, alias->name, sizeof(p->exten)-1);
1187                         strncpy(p->context, alias->context, sizeof(p->context)-1);
1188                 }
1189
1190                 /* Asterisk prefers user name to be quoted */
1191                 sprintf(p->callerid, "\"%s\" <%s>", p->cd.call_source_aliases, p->cd.call_source_e164);
1192
1193         } else { 
1194                 /* Either this call is not from the Gatekeeper 
1195                    or we are not allowing gk routed calls */
1196                 
1197
1198                 user  = find_user(cd);
1199
1200
1201                 if (!user) {
1202                         /* Asterisk prefers user name to be quoted */
1203                         sprintf(p->callerid, "\"%s\" <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); 
1204                         if (strlen(p->cd.call_dest_e164)) {
1205                                 strncpy(p->dnid, cd.call_dest_e164, sizeof(p->dnid)-1);
1206                                 strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1);
1207                         } else {
1208                                 strncpy(p->exten, cd.call_dest_alias, sizeof(p->exten)-1);
1209                         }
1210                         if (!strlen(default_context)) {
1211                                 ast_log(LOG_ERROR, "Call from user '%s' rejected due to no default context\n", p->cd.call_source_aliases);
1212                                 return 0;
1213                         }
1214                         strncpy(p->context, default_context, sizeof(p->context)-1);
1215                         ast_log(LOG_DEBUG, "Sending %s to context [%s]\n", cd.call_source_aliases, p->context);
1216                 } else {
1217                         call_options = &user->call_options;
1218                         if (user->host) {
1219                                 if (strcasecmp(cd.sourceIp, inet_ntoa(user->addr.sin_addr))){
1220                                         
1221                                         if(!strlen(default_context)) {
1222                                                 ast_log(LOG_ERROR, "Call from user '%s' rejected due to non-matching IP address of '%s'\n", user->name, cd.sourceIp);
1223                                                 return NULL;
1224                                         }
1225                                         
1226                                         strncpy(p->context, default_context, sizeof(p->context)-1);
1227                                         sprintf(p->exten,"i");
1228
1229                                         goto exit;                                      
1230                                 }
1231                         }
1232                         if (user->incominglimit > 0) {
1233                                 if (user->inUse >= user->incominglimit) {
1234                                         ast_log(LOG_ERROR, "Call from user '%s' rejected due to usage limit of %d\n", user->name, user->incominglimit);
1235                                         return NULL;
1236                                 }
1237                         }
1238                         strncpy(p->context, user->context, sizeof(p->context)-1);
1239                         p->bridge = user->bridge;
1240                         p->nat = user->nat;
1241
1242                         if (strlen(user->callerid)) 
1243                                 strncpy(p->callerid, user->callerid, sizeof(p->callerid) - 1);
1244                         else
1245                                 sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); 
1246
1247                         if (strlen(p->cd.call_dest_e164)) {
1248                                 strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1);
1249                         } else {
1250                                 strncpy(p->exten, cd.call_dest_alias, sizeof(p->exten)-1);              
1251                         }
1252                         if (strlen(user->accountcode)) {
1253                                 strncpy(p->accountcode, user->accountcode, sizeof(p->accountcode)-1);
1254                         } 
1255
1256                         /* Increment the usage counter */
1257                         user->inUse++;
1258                 } 
1259         }
1260
1261 /* I know this is horrid, don't kill me saddam */
1262 exit:
1263 //      if(strlen(p->cd.call_redir_e164))
1264 //              strncpy(p->rdnis, cd.call_redir_e164, sizeof(p->rdnis)-1);
1265         /* allocate a channel and tell asterisk about it */
1266         c = oh323_new(p, AST_STATE_RINGING, cd.call_token);
1267         if (!c) {
1268                 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
1269                 return NULL;
1270         }
1271
1272         ast_queue_control(c, AST_CONTROL_RINGING, 0);
1273
1274         if(!call_options)
1275                 return &global_options;
1276
1277         return call_options;
1278 }
1279
1280 /**
1281  * Call-back function to establish an outgoing H.323 call
1282  * 
1283  * Returns 1 on success 
1284  */
1285 int setup_outgoing_call(call_details_t cd)
1286 {       
1287         return 1;
1288 }
1289
1290 #if 0
1291 if (p->inUse >= p->outgoinglimit) {
1292         ast_log(LOG_ERROR, "Call to %s rejected due to usage limit of %d outgoing channels\n", p->name, p->inUse);
1293         return 0;
1294 }
1295
1296 if (!p) {
1297         ast_log(LOG_ERROR, "Rejecting call: peer %s not found\n", dest_peer);
1298         return 0;
1299 }
1300 #endif
1301
1302 /**
1303   * Call-back function that gets called for each rtp channel opened 
1304   *
1305   * Returns nothing 
1306   */
1307 void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, int direction, int payloadType)
1308 {
1309         struct oh323_pvt *p = NULL;
1310         struct sockaddr_in them;
1311         struct rtpPayloadType payload;
1312         struct ast_channel *chan;
1313
1314         /* Find the call or allocate a private structure if call not found */
1315         p = find_call(call_reference);
1316
1317         if (!p) {
1318                 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
1319                 return;
1320         }
1321
1322         them.sin_family = AF_INET;
1323         them.sin_addr.s_addr = inet_addr(remoteIp); // only works for IPv4
1324         them.sin_port = htons(remotePort);
1325
1326         /* Find RTP payload <=> asterisk's subcode association */
1327         payload = ast_rtp_lookup_pt(p->rtp, payloadType);
1328
1329         ast_log(LOG_DEBUG, "Setting up %sbound RTP connection for %s:%d with payload %s (RTP code %d)\n", (direction ? "out" : "in"), inet_ntoa(them.sin_addr), remotePort, ast_getformatname(payload.code), payloadType);
1330
1331         /* Set channel's native codec and prepare translation table
1332          * for given direction and currently used format
1333          */
1334         if ((chan = p->owner)) {
1335                 if (payload.isAstFormat) {
1336                         /* Don't allow any transmission until codec is changed */
1337 //                      ast_mutex_lock(&chan->lock);
1338                         chan->nativeformats = payload.code;
1339                         if(direction)
1340                                 ast_set_write_format(chan, chan->writeformat);
1341                         else
1342                                 ast_set_read_format(chan, chan->readformat);
1343 //                      ast_mutex_unlock(&chan->lock);
1344                 }
1345         }
1346
1347         ast_rtp_set_peer(p->rtp, &them);
1348         
1349         if(p->calloptions.progress_audio)
1350                 progress(call_reference, TRUE);
1351
1352         return;
1353 }
1354
1355 /* Not used for now - set RTP peer's address */
1356 void setup_rtp_peer(unsigned call_reference, const char *remoteIp, int remotePort)
1357 {
1358         struct oh323_pvt *p = NULL;
1359         struct sockaddr_in them;
1360
1361         /* Find the call or allocate a private structure if call not found */
1362         p = find_call(call_reference);
1363
1364         if (!p) {
1365                 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
1366                 return;
1367         }
1368
1369         them.sin_family = AF_INET;
1370         them.sin_addr.s_addr = inet_addr(remoteIp); // only works for IPv4
1371         them.sin_port = htons(remotePort);
1372         ast_rtp_set_peer(p->rtp, &them);
1373 }
1374
1375 /**  
1376   *     Call-back function to signal asterisk that the channel has been answered 
1377   * Returns nothing
1378   */
1379 void connection_made(unsigned call_reference)
1380 {
1381         struct ast_channel *c = NULL;
1382         struct oh323_pvt *p = NULL;
1383         
1384         p = find_call(call_reference);
1385         
1386         if (!p)
1387                 ast_log(LOG_ERROR, "Something is wrong: connection\n");
1388
1389
1390         if (!p->owner) {
1391                 ast_log(LOG_ERROR, "Channel has no owner\n");
1392                 return;
1393         }
1394         c = p->owner;   
1395
1396         ast_setstate(c, AST_STATE_UP);
1397         return;
1398 }
1399
1400 /**
1401   * Call-back function to cleanup communication
1402   * Returns nothing,
1403   */
1404 void cleanup_connection(call_details_t cd)
1405 {       
1406         struct oh323_pvt *p = NULL;
1407 //      struct oh323_peer *peer = NULL;
1408         struct oh323_user *user = NULL;
1409         struct ast_rtp *rtp = NULL;
1410
1411         ast_log(LOG_DEBUG, "Cleaning up our mess\n");
1412         
1413         p = find_call(cd.call_reference);
1414
1415         if (!p) {
1416                 return;
1417         }
1418
1419         /* Decrement usage counter */
1420         if (!p->outgoing) {
1421                 user = find_user(cd);
1422                 
1423                 if(user)
1424                         user->inUse--;
1425         }
1426
1427 #if 0
1428                 if (p->outgoing) {
1429                 peer = find_peer(cd.call_dest_alias);
1430                 peer->inUse--;
1431         } else {
1432                 user = find_user(cd);
1433                 user->inUse--;
1434         }
1435 #endif
1436         
1437         if (p->rtp) {
1438                 rtp = p->rtp;
1439                 p->rtp = NULL;
1440                 /* Immediately stop RTP */
1441                 ast_rtp_destroy(rtp);
1442         }
1443         
1444         p->alreadygone = 1;
1445
1446         /* Send hangup */       
1447         if (p->owner)
1448                 ast_queue_hangup(p->owner, 1);
1449
1450         p = NULL;
1451         return; 
1452 }
1453
1454 static void *do_monitor(void *data)
1455 {
1456         int res;
1457         struct oh323_pvt *oh323 = NULL;
1458         
1459                 for(;;) {
1460                 /* Check for interfaces needing to be killed */
1461                 ast_mutex_lock(&iflock);
1462 restartsearch:          
1463                 oh323 = iflist;
1464                 while(oh323) {
1465                         if (oh323->needdestroy) {
1466                                 __oh323_destroy(oh323);
1467                                 goto restartsearch;
1468                         }
1469                         oh323 = oh323->next;
1470                 }
1471                 ast_mutex_unlock(&iflock);
1472
1473                 /* Wait for sched or io */
1474                 res = ast_sched_wait(sched);
1475                 if ((res < 0) || (res > 1000))
1476                         res = 1000;
1477                 res = ast_io_wait(io, res);
1478
1479                 /* Check for thread cancellation */
1480                 pthread_testcancel();
1481
1482                 ast_mutex_lock(&monlock);
1483                 if (res >= 0) 
1484                         ast_sched_runq(sched);
1485                 ast_mutex_unlock(&monlock);
1486         }
1487         /* Never reached */
1488         return NULL;
1489         
1490 }
1491
1492 static int restart_monitor(void)
1493 {
1494         /* If we're supposed to be stopped -- stay stopped */
1495         if (monitor_thread == -2)
1496                 return 0;
1497         if (ast_mutex_lock(&monlock)) {
1498                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
1499                 return -1;
1500         }
1501         if (monitor_thread == pthread_self()) {
1502                 ast_mutex_unlock(&monlock);
1503                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1504                 return -1;
1505         }
1506         if (monitor_thread) {
1507                 /* Wake up the thread */
1508                 pthread_kill(monitor_thread, SIGURG);
1509         } else {
1510                 /* Start a new monitor */
1511                 if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
1512                         ast_mutex_unlock(&monlock);
1513                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1514                         return -1;
1515                 }
1516         }
1517         ast_mutex_unlock(&monlock);
1518         return 0;
1519 }
1520
1521 static int h323_do_trace(int fd, int argc, char *argv[])
1522 {
1523         if (argc != 3)
1524                 return RESULT_SHOWUSAGE;
1525         
1526         h323_debug(1, atoi(argv[2]));
1527         ast_cli(fd, "H.323 trace set to level %s\n", argv[2]);
1528         return RESULT_SUCCESS;
1529 }
1530
1531 static int h323_no_trace(int fd, int argc, char *argv[])
1532 {
1533         if (argc != 3)
1534                 return RESULT_SHOWUSAGE;
1535
1536         h323_debug(0,0);
1537         ast_cli(fd, "H.323 trace disabled\n");
1538         return RESULT_SUCCESS;
1539 }
1540
1541 static int h323_do_debug(int fd, int argc, char *argv[])
1542 {
1543         if (argc != 2)
1544                 return RESULT_SHOWUSAGE;
1545         
1546         h323debug = 1;
1547         ast_cli(fd, "H323 debug enabled\n");
1548         return RESULT_SUCCESS;
1549 }
1550
1551 static int h323_no_debug(int fd, int argc, char *argv[])
1552 {
1553         if (argc != 3)
1554                 return RESULT_SHOWUSAGE;
1555
1556         h323debug = 0;
1557         ast_cli(fd, "H323 Debug disabled\n");
1558         return RESULT_SUCCESS;
1559 }
1560
1561 static int h323_gk_cycle(int fd, int argc, char *argv[])
1562 {
1563         if (argc != 3)
1564                 return RESULT_SHOWUSAGE;
1565                 
1566         h323_gk_urq();
1567         
1568         /* Possibly register with a GK */
1569         if (gatekeeper_disable == 0) {
1570                 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
1571                         ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
1572                         h323_end_process();
1573                 }
1574         }
1575
1576         return RESULT_SUCCESS;
1577 }
1578
1579
1580 static char trace_usage[] = 
1581 "Usage: h.323 trace <level num>\n"
1582 "       Enables H.323 stack tracing for debugging purposes\n";
1583
1584 static char no_trace_usage[] = 
1585 "Usage: h.323 no trace\n"
1586 "       Disables H.323 stack tracing for debugging purposes\n";
1587
1588 static char debug_usage[] = 
1589 "Usage: h.323 debug\n"
1590 "       Enables chan_h323 debug output\n";
1591
1592 static char no_debug_usage[] = 
1593 "Usage: h.323 no debug\n"
1594 "       Disables chan_h323 debug output\n";
1595
1596 static char show_codec_usage[] = 
1597 "Usage: h.323 show codec\n"
1598 "       Shows all enabled codecs\n";
1599
1600 static char show_cycle_usage[] = 
1601 "Usage: h.323 gk cycle\n"
1602 "       Manually re-register with the Gatekeper\n";
1603
1604
1605 static struct ast_cli_entry  cli_trace =
1606         { { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage };
1607 static struct ast_cli_entry  cli_no_trace =
1608         { { "h.323", "no", "trace", NULL }, h323_no_trace, "Disable H.323 Stack Tracing", no_trace_usage };
1609 static struct ast_cli_entry  cli_debug =
1610         { { "h.323", "debug", NULL }, h323_do_debug, "Enable chan_h323 debug", debug_usage };
1611 static struct ast_cli_entry  cli_no_debug =
1612         { { "h.323", "no", "debug", NULL }, h323_no_debug, "Disable chan_h323 debug", no_debug_usage };
1613 static struct ast_cli_entry  cli_show_codecs =
1614         { { "h.323", "show", "codecs", NULL }, h323_show_codec, "Show enabled codecs", show_codec_usage };
1615 static struct ast_cli_entry  cli_gk_cycle =
1616         { { "h.323", "gk", "cycle", NULL }, h323_gk_cycle, "Manually re-register with the Gatekeper", show_cycle_usage };
1617
1618
1619
1620 int reload_config(void)
1621 {
1622         
1623         int format;
1624         struct ast_config *cfg;
1625         struct ast_variable *v;
1626         struct oh323_peer *peer   = NULL;
1627         struct oh323_user *user   = NULL;
1628         struct oh323_alias *alias = NULL;
1629         struct hostent *hp;
1630         char *cat;
1631         char *utype;
1632         
1633         cfg = ast_load(config);
1634
1635         /* We *must* have a config file otherwise stop immediately */
1636         if (!cfg) {
1637                 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
1638                 return 1;
1639         }
1640         
1641        /* fire up the H.323 Endpoint */       
1642         if (!h323_end_point_exist()) {
1643                h323_end_point_create();        
1644         }
1645         h323debug=0;
1646         dtmfmode = H323_DTMF_RFC2833;
1647         /* Fill global variables with pre-determined values */
1648         memset(&global_options, 0, sizeof(global_options));
1649
1650         memset(&bindaddr, 0, sizeof(bindaddr));
1651
1652         v = ast_variable_browse(cfg, "general");
1653         while(v) {
1654                 /* Create the interface list */
1655                 if (!strcasecmp(v->name, "port")) {
1656                         port = (int)strtol(v->value, NULL, 10);
1657                 } else if (!strcasecmp(v->name, "bindaddr")) {
1658                         if (!(hp = gethostbyname(v->value))) {
1659                                 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
1660                         } else {
1661                                 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
1662                         }
1663                 } else if (!strcasecmp(v->name, "allow")) {
1664                         format = ast_getformatbyname(v->value);
1665                         if (format < 1) 
1666                                 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
1667                         else
1668                                 capability |= format;
1669                 } else if (!strcasecmp(v->name, "disallow")) {
1670                         format = ast_getformatbyname(v->value);
1671                         if (format < 1) 
1672                                 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
1673                         else
1674                                 capability &= ~format;
1675                 } else if (!strcasecmp(v->name, "tos")) {
1676                         if (sscanf(v->value, "%i", &format) == 1)
1677                                 tos = format & 0xff;
1678                         else if (!strcasecmp(v->value, "lowdelay"))
1679                                 tos = IPTOS_LOWDELAY;
1680                         else if (!strcasecmp(v->value, "throughput"))
1681                                 tos = IPTOS_THROUGHPUT;
1682                         else if (!strcasecmp(v->value, "reliability"))
1683                                 tos = IPTOS_RELIABILITY;
1684                         else if (!strcasecmp(v->value, "mincost"))
1685                                 tos = IPTOS_MINCOST;
1686                         else if (!strcasecmp(v->value, "none"))
1687                                 tos = 0;
1688                         else
1689                                 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
1690                 } else if (!strcasecmp(v->name, "gatekeeper")) {
1691                         if (!strcasecmp(v->value, "DISABLE")) {
1692                                 gatekeeper_disable = 1;
1693                                 usingGk = 0;
1694                         } else if (!strcasecmp(v->value, "DISCOVER")) {
1695                                 gatekeeper_disable = 0;
1696                                 gatekeeper_discover = 1;
1697                                 usingGk = 1;
1698                         } else {
1699                                 gatekeeper_disable = 0;
1700                                 usingGk = 1;
1701                                 strncpy(gatekeeper, v->value, sizeof(gatekeeper)-1);
1702                         }
1703                 } else if (!strcasecmp(v->name, "secret")) {
1704                                 strncpy(secret, v->value, sizeof(secret)-1);
1705                 } else if (!strcasecmp(v->name, "AllowGKRouted")) {
1706                                 gkroute = ast_true(v->value);
1707                 } else if (!strcasecmp(v->name, "context")) {
1708                         strncpy(default_context, v->value, sizeof(default_context)-1);
1709                         ast_verbose(VERBOSE_PREFIX_3 "  == Setting default context to %s\n", default_context);  
1710                 } else if (!strcasecmp(v->name, "dtmfmode")) {
1711                         if (!strcasecmp(v->value, "inband"))
1712                                 dtmfmode=H323_DTMF_INBAND;
1713                         else if (!strcasecmp(v->value, "rfc2833"))
1714                                 dtmfmode = H323_DTMF_RFC2833;
1715                         else {
1716                                 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
1717                                 dtmfmode = H323_DTMF_RFC2833;
1718                         }
1719                 /* Setup global parameters */
1720                 } else if (!strcasecmp(v->name, "noFastStart")) {
1721                         global_options.noFastStart = ast_true(v->value);
1722                 } else if (!strcasecmp(v->name, "noH245Tunneling")) {
1723                         global_options.noH245Tunnelling = ast_true(v->value);
1724                 } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
1725                         global_options.noSilenceSuppression = ast_true(v->value);
1726                 } else if (!strcasecmp(v->name, "progress_setup")) {
1727                         int progress_setup = atoi(v->value);
1728                         if((progress_setup != 0) &&
1729                            (progress_setup != 1) &&
1730                            (progress_setup != 3) &&
1731                            (progress_setup != 8)) {
1732                                 ast_log(LOG_WARNING, "Invalid value %d for progress_setup at line %d, assuming 0\n", progress_setup, v->lineno);
1733                                 progress_setup = 0;
1734                         }
1735                         global_options.progress_setup = progress_setup;
1736                 } else if (!strcasecmp(v->name, "progress_alert")) {
1737                         int progress_alert = atoi(v->value);
1738                         if((progress_alert != 0) &&
1739                            (progress_alert != 8)) {
1740                                 ast_log(LOG_WARNING, "Invalid value %d for progress_alert at line %d, assuming 0\n", progress_alert, v->lineno);
1741                                 progress_alert = 0;
1742                         }
1743                         global_options.progress_alert = progress_alert;
1744                 } else if (!strcasecmp(v->name, "progress_audio")) {
1745                         global_options.progress_audio = ast_true(v->value);
1746                 } else if (!strcasecmp(v->name, "UserByAlias")) {
1747                         userbyalias = ast_true(v->value);
1748                 } else if (!strcasecmp(v->name, "bridge")) {
1749                         bridge_default = ast_true(v->value);
1750                 }
1751                 v = v->next;    
1752         }
1753         
1754         cat = ast_category_browse(cfg, NULL);
1755         while(cat) {
1756                 if (strcasecmp(cat, "general")) {
1757                         utype = ast_variable_retrieve(cfg, cat, "type");
1758                         if (utype) {
1759                                 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
1760                                         user = build_user(cat, ast_variable_browse(cfg, cat));
1761                                         if (user) {
1762                                                 ast_mutex_lock(&userl.lock);
1763                                                 user->next = userl.users;
1764                                                 userl.users = user;
1765                                                 ast_mutex_unlock(&userl.lock);
1766                                         }
1767                                 }  else if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
1768                                         peer = build_peer(cat, ast_variable_browse(cfg, cat));
1769                                         if (peer) {
1770                                                 ast_mutex_lock(&peerl.lock);
1771                                                 peer->next = peerl.peers;
1772                                                 peerl.peers = peer;
1773                                                 ast_mutex_unlock(&peerl.lock);
1774                                         }
1775                                 }  else if (!strcasecmp(utype, "h323")) {                       
1776                                         alias = build_alias(cat, ast_variable_browse(cfg, cat));
1777                                         if (alias) {
1778                                                 ast_mutex_lock(&aliasl.lock);
1779                                                 alias->next = aliasl.aliases;
1780                                                 aliasl.aliases = alias;
1781                                                 ast_mutex_unlock(&aliasl.lock);
1782                                         }
1783                                 } else {
1784                                         ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
1785                                 }
1786                         } else
1787                                 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
1788                 }
1789                 cat = ast_category_browse(cfg, cat);
1790         }
1791
1792         /* Register our H.323 aliases if any*/
1793         while (alias) {         
1794                 if (h323_set_alias(alias)) {
1795                         ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
1796                         return -1;
1797                 }       
1798                 alias = alias->next;
1799         }
1800
1801         /* Add some capabilities */
1802         if(h323_set_capability(capability, dtmfmode)) {
1803                 ast_log(LOG_ERROR, "Capabilities failure, this is bad.\n");
1804                 return -1;
1805         }       
1806         ast_destroy(cfg);
1807
1808         return 0;
1809 }
1810
1811 void delete_users(void)
1812 {
1813         struct oh323_user *user, *userlast;
1814         struct oh323_peer *peer;
1815         
1816         /* Delete all users */
1817         ast_mutex_lock(&userl.lock);
1818         for (user=userl.users;user;) {
1819                 userlast = user;
1820                 user=user->next;
1821                 free(userlast);
1822         }
1823         userl.users=NULL;
1824         ast_mutex_unlock(&userl.lock);
1825         ast_mutex_lock(&peerl.lock);
1826         for (peer=peerl.peers;peer;) {
1827                 /* Assume all will be deleted, and we'll find out for sure later */
1828                 peer->delme = 1;
1829                 peer = peer->next;
1830         }
1831         ast_mutex_unlock(&peerl.lock);
1832 }
1833
1834 void delete_aliases(void)
1835 {
1836         struct oh323_alias *alias, *aliaslast;
1837                 
1838         /* Delete all users */
1839         ast_mutex_lock(&aliasl.lock);
1840         for (alias=aliasl.aliases;alias;) {
1841                 aliaslast = alias;
1842                 alias=alias->next;
1843                 free(aliaslast);
1844         }
1845         aliasl.aliases=NULL;
1846         ast_mutex_unlock(&aliasl.lock);
1847 }
1848
1849 void prune_peers(void)
1850 {
1851         /* Prune peers who still are supposed to be deleted */
1852         struct oh323_peer *peer, *peerlast, *peernext;
1853         ast_mutex_lock(&peerl.lock);
1854         peerlast = NULL;
1855         for (peer=peerl.peers;peer;) {
1856                 peernext = peer->next;
1857                 if (peer->delme) {
1858                         free(peer);
1859                         if (peerlast)
1860                                 peerlast->next = peernext;
1861                         else
1862                                 peerl.peers = peernext;
1863                 } else
1864                         peerlast = peer;
1865                 peer=peernext;
1866         }
1867         ast_mutex_unlock(&peerl.lock);
1868 }
1869
1870 int reload(void)
1871 {
1872         delete_users();
1873         delete_aliases();
1874         prune_peers();
1875
1876         reload_config();
1877
1878
1879 #if 0
1880
1881 This code causes seg on -r
1882
1883         if (strlen(gatekeeper)) {
1884                 h323_gk_urq();
1885         }
1886
1887
1888         /* Possibly register with a GK */
1889         if (!gatekeeper_disable) {
1890                 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
1891                         ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
1892                         h323_end_process();
1893                         return -1;
1894                 }
1895         }
1896 #endif
1897
1898         restart_monitor();
1899         return 0;
1900 }
1901
1902
1903 static struct ast_rtp *oh323_get_rtp_peer(struct ast_channel *chan)
1904 {
1905         struct oh323_pvt *p;
1906         p = chan->pvt->pvt;
1907         if (p && p->rtp && p->bridge) {
1908                 return p->rtp;
1909         }
1910         return NULL;
1911 }
1912
1913 static struct ast_rtp *oh323_get_vrtp_peer(struct ast_channel *chan)
1914 {
1915         return NULL;
1916 }
1917
1918 static char *convertcap(int cap)
1919 {
1920         switch (cap) {
1921         case AST_FORMAT_G723_1:
1922                 return "G.723";
1923         case AST_FORMAT_GSM:
1924                 return "GSM";
1925         case AST_FORMAT_ULAW:
1926                 return "ULAW";
1927         case AST_FORMAT_ALAW:
1928                 return "ALAW";
1929         case AST_FORMAT_ADPCM:
1930                 return "G.728";
1931         case AST_FORMAT_G729A:
1932                 return "G.729";
1933         case AST_FORMAT_SPEEX:
1934                 return "SPEEX";
1935         case AST_FORMAT_ILBC:
1936                 return "ILBC";
1937         default:
1938                 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap);
1939                 return NULL;
1940         }
1941
1942 }
1943
1944 static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp)
1945 {
1946         /* XXX Deal with Video */
1947         struct oh323_pvt *p;
1948         struct sockaddr_in them;
1949         struct sockaddr_in us;
1950         char *mode;
1951
1952         mode = convertcap(chan->writeformat); 
1953
1954         if (!rtp) {
1955                 return 0;
1956         }
1957
1958         p = chan->pvt->pvt;
1959         if (!p) {
1960                 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
1961                 return -1;
1962         }
1963
1964         ast_rtp_get_peer(rtp, &them);   
1965         ast_rtp_get_us(rtp, &us);
1966
1967
1968         h323_native_bridge(p->cd.call_token, inet_ntoa(them.sin_addr), mode);
1969         
1970         return 0;
1971         
1972 }
1973
1974 static struct ast_rtp_protocol oh323_rtp = {
1975         get_rtp_info: oh323_get_rtp_peer,
1976         get_vrtp_info: oh323_get_vrtp_peer,
1977         set_rtp_peer: oh323_set_rtp_peer,
1978 };
1979
1980
1981 int load_module()
1982 {
1983         int res;
1984
1985         res = reload_config();
1986
1987         if (res) {
1988                 return 0;
1989         } else {
1990                 /* Make sure we can register our channel type */
1991                 if (ast_channel_register(type, tdesc, capability, oh323_request)) {
1992                         ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
1993                         h323_end_process();
1994                         return -1;
1995                 }
1996                 ast_cli_register(&cli_debug);
1997                 ast_cli_register(&cli_no_debug);
1998                 ast_cli_register(&cli_trace);
1999                 ast_cli_register(&cli_no_trace);
2000                 ast_cli_register(&cli_show_codecs);
2001                 ast_cli_register(&cli_gk_cycle);
2002
2003                 oh323_rtp.type = type;
2004                 ast_rtp_proto_register(&oh323_rtp);
2005
2006                 sched = sched_context_create();
2007                 if (!sched) {
2008                         ast_log(LOG_WARNING, "Unable to create schedule context\n");
2009                 }
2010                 io = io_context_create();
2011                 if (!io) {
2012                         ast_log(LOG_WARNING, "Unable to create I/O context\n");
2013                 }
2014                 
2015                 /* Register our callback functions */
2016                 h323_callback_register(setup_incoming_call, 
2017                                                            setup_outgoing_call,                                                  
2018                                                            create_connection, 
2019                                                            setup_rtp_connection, 
2020                                                            cleanup_connection, 
2021                                                            connection_made,
2022                                                            send_digit,
2023                                                            progress);
2024         
2025
2026                 /* start the h.323 listener */
2027                 if (h323_start_listener(port, bindaddr)) {
2028                         ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
2029 //                      h323_end_process();
2030                         return -1;
2031                 }
2032
2033                 /* Possibly register with a GK */
2034                 if (gatekeeper_disable == 0) {
2035                         if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
2036                                 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
2037 //                              h323_end_process();
2038                                 return 0;
2039                         }
2040                 }
2041                 /* And start the monitor for the first time */
2042                 restart_monitor();
2043         }
2044         return res;
2045 }
2046 int unload_module() 
2047 {
2048         struct oh323_pvt *p, *pl;
2049                 
2050         if (!ast_mutex_lock(&iflock)) {
2051         /* hangup all interfaces if they have an owner */
2052         p = iflist;
2053         while(p) {
2054                 if (p->owner)
2055                         ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
2056                 p = p->next;
2057         }
2058         iflist = NULL;
2059         ast_mutex_unlock(&iflock);
2060         } else {
2061                 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
2062                 return -1;
2063         }
2064                 
2065         if (!ast_mutex_lock(&iflock)) {
2066                 /* destroy all the interfaces and free their memory */
2067                 p = iflist;
2068                 while(p) {
2069                         pl = p;
2070                         p = p->next;
2071                         /* free associated memory */
2072                         free(pl);
2073                 }
2074                 iflist = NULL;
2075                 ast_mutex_unlock(&iflock);
2076         } else {
2077                 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
2078                 return -1;
2079         }
2080         h323_gk_urq();
2081         h323_debug(0,0);
2082         h323_end_process();
2083
2084         /* unregister rtp */
2085         ast_rtp_proto_unregister(&oh323_rtp);
2086         
2087         /* unregister commands */
2088         ast_cli_unregister(&cli_debug);
2089         ast_cli_unregister(&cli_no_debug);
2090         ast_cli_unregister(&cli_trace);
2091         ast_cli_unregister(&cli_no_trace);
2092         ast_cli_unregister(&cli_show_codecs);
2093         ast_cli_unregister(&cli_gk_cycle);
2094
2095         /* unregister channel type */
2096         ast_channel_unregister(type);
2097
2098         return 0;
2099
2100 }
2101
2102 int usecount()
2103 {
2104         int res;
2105         ast_mutex_lock(&usecnt_lock);
2106         res = usecnt;
2107         ast_mutex_unlock(&usecnt_lock);
2108         return res;
2109 }
2110
2111 char *description()
2112 {
2113         return desc;
2114 }
2115
2116 char *key()
2117 {
2118         return ASTERISK_GPL_KEY;
2119 }