Add MGCP audit
[asterisk/asterisk.git] / channels / chan_mgcp.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Implementation of Media Gateway Control Protocol
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <stdio.h>
15 #include <pthread.h>
16 #include <string.h>
17 #include <asterisk/lock.h>
18 #include <asterisk/channel.h>
19 #include <asterisk/channel_pvt.h>
20 #include <asterisk/config.h>
21 #include <asterisk/logger.h>
22 #include <asterisk/module.h>
23 #include <asterisk/pbx.h>
24 #include <asterisk/options.h>
25 #include <asterisk/lock.h>
26 #include <asterisk/sched.h>
27 #include <asterisk/io.h>
28 #include <asterisk/rtp.h>
29 #include <asterisk/acl.h>
30 #include <asterisk/callerid.h>
31 #include <asterisk/cli.h>
32 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <net/if.h>
35 #include <errno.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <fcntl.h>
39 #include <netdb.h>
40 #include <arpa/inet.h>
41 #include <sys/signal.h>
42 #include <asterisk/dsp.h>
43 #include <ctype.h>
44
45 #define MGCPDUMPER
46 #define DEFAULT_EXPIREY 120
47 #define MAX_EXPIREY     3600
48
49 static char *desc = "Media Gateway Control Protocol (MGCP)";
50 static char *type = "MGCP";
51 static char *tdesc = "Media Gateway Control Protocol (MGCP)";
52 static char *config = "mgcp.conf";
53
54 #define DEFAULT_MGCP_PORT       2427/* From RFC 2705 */
55 #define MGCP_MAX_PACKET 1500            /* Also from RFC 2543, should sub headers tho */
56
57 static int usecnt =0;
58 static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
59 static int oseq;
60
61 /* Protect the monitoring thread, so only one process can kill or start it, and not
62    when it's doing something critical. */
63 static pthread_mutex_t netlock = AST_MUTEX_INITIALIZER;
64
65 static pthread_mutex_t monlock = AST_MUTEX_INITIALIZER;
66
67 /* This is the thread for the monitor which checks for input on the channels
68    which are not currently in use.  */
69 static pthread_t monitor_thread = 0;
70
71 static int restart_monitor(void);
72
73 /* Just about everybody seems to support ulaw, so make it a nice default */
74 static int capability = AST_FORMAT_ULAW;
75 static int nonCodecCapability = AST_RTP_DTMF;
76
77 static char ourhost[256];
78 static struct in_addr __ourip;
79 static int ourport;
80
81 static int mgcpdebug = 0;
82
83 static struct sched_context *sched;
84 static struct io_context *io;
85 /* The private structures of the  mgcp channels are linked for
86    selecting outgoing channels */
87    
88 #define MGCP_MAX_HEADERS                64
89 #define MGCP_MAX_LINES          64
90
91 struct mgcp_request {
92         int len;
93         char *verb;
94         char *identifier;
95         char *endpoint;
96         char *version;
97         int headers;                                    /* MGCP Headers */
98         char *header[MGCP_MAX_HEADERS];
99         int lines;                                              /* SDP Content */
100         char *line[MGCP_MAX_LINES];
101         char data[MGCP_MAX_PACKET];
102 };
103
104 static struct mgcp_pkt {
105         int retrans;
106         struct mgcp_endpoint *owner;
107         int packetlen;
108         char data[MGCP_MAX_PACKET];
109         struct mgcp_pkt *next;
110 } *packets = NULL;      
111
112 /* MGCP message for queuing up */
113 struct mgcp_message {
114         unsigned int seqno;
115         int len;
116         struct mgcp_message *next;
117         unsigned char buf[0];
118 };
119
120 #define TYPE_TRUNK              1
121 #define TYPE_LINE               2
122
123 struct mgcp_endpoint {
124         pthread_mutex_t lock;
125         char name[80];
126         char accountcode[80];
127         char exten[AST_MAX_EXTENSION];          /* Extention where to start */
128         char context[AST_MAX_EXTENSION];
129         char language[MAX_LANGUAGE];
130         char callerid[256];                                     /* Caller*ID */
131         char curtone[80];                                       /* Current tone */
132         char txident[80];
133         char cxident[80];
134         char callid[80];
135         int hascallerid;
136         int dtmfinband;
137         int amaflags;
138         int type;
139         int group;
140         int iseq;
141         int nat;
142         int lastout;
143         int alreadygone;
144         int needdestroy;
145         int capability;
146         int nonCodecCapability;
147         int outgoing;
148         struct ast_dsp *vad;
149         struct ast_channel *owner;
150         struct ast_rtp *rtp;
151         struct sockaddr_in tmpdest;
152         struct mgcp_message *msgs;                      /* Message queue */
153         int messagepending;
154         struct mgcp_endpoint *next;
155         struct mgcp_gateway *parent;
156 };
157
158 struct mgcp_gateway {
159         /* A gateway containing one or more endpoints */
160         char name[80];
161         struct sockaddr_in addr;
162         struct sockaddr_in defaddr;
163         struct in_addr ourip;
164         int dynamic;
165         int expire;             /* XXX Should we ever expire dynamic registrations? XXX */
166         struct mgcp_endpoint *endpoints;
167         struct ast_ha *ha;
168         struct mgcp_gateway *next;
169 } *gateways;
170
171 static pthread_mutex_t gatelock  = AST_MUTEX_INITIALIZER;
172
173 static int mgcpsock  = -1;
174
175 static struct sockaddr_in bindaddr;
176
177 static struct ast_frame  *mgcp_read(struct ast_channel *ast);
178 static int transmit_response(struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest);
179 static int transmit_notify_request(struct mgcp_endpoint *p, char *tone, int offhook);
180 static int transmit_connection_del(struct mgcp_endpoint *p);
181 static int transmit_notify_request_with_callerid(struct mgcp_endpoint *p, char *tone, int offhook, char *callerid);
182 static int transmit_audit_endpoint(struct mgcp_endpoint *p);
183
184 static int __mgcp_xmit(struct mgcp_endpoint *p, char *data, int len)
185 {
186         int res;
187         if (p->parent->addr.sin_addr.s_addr)
188             res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&p->parent->addr, sizeof(struct sockaddr_in));
189         else 
190             res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&p->parent->defaddr, sizeof(struct sockaddr_in));
191         if (res != len) {
192                 ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
193         }
194         return res;
195 }
196
197 static int send_response(struct mgcp_endpoint *p, struct mgcp_request *req)
198 {
199         int res;
200         if (mgcpdebug)
201                 ast_verbose("Transmitting:\n%s\n to %s:%d\n", req->data, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
202         res = __mgcp_xmit(p, req->data, req->len);
203         if (res > 0)
204                 res = 0;
205         return res;
206 }
207
208 static void dump_queue(struct mgcp_endpoint *p)
209 {
210         struct mgcp_message *cur;
211         while(p->msgs) {
212                 cur = p->msgs;
213                 p->msgs = p->msgs->next;
214                 free(cur);
215         }
216         p->messagepending = 0;
217         p->msgs = NULL;
218 }
219
220 static int mgcp_postrequest(struct mgcp_endpoint *p, unsigned char *data, int len, unsigned int seqno)
221 {
222         struct mgcp_message *msg = malloc(sizeof(struct mgcp_message) + len);
223         struct mgcp_message *cur;
224         if (!msg)
225                 return -1;
226         msg->seqno = seqno;
227         msg->next = NULL;
228         msg ->len = len;
229         memcpy(msg->buf, data, msg->len);
230         cur = p->msgs;
231         if (cur) {
232                 while(cur->next)
233                         cur = cur->next;
234                 cur->next = msg;
235         } else
236                 p->msgs = msg;
237         if (!p->messagepending) {
238                 p->messagepending = 1;
239                 p->lastout = seqno;
240                 __mgcp_xmit(p, msg->buf, msg->len);
241                 /* XXX Should schedule retransmission XXX */
242         } else
243                 ast_log(LOG_DEBUG, "Deferring transmission of transaction %d\n", seqno);
244         return 0;
245 }
246
247 static int send_request(struct mgcp_endpoint *p, struct mgcp_request *req, unsigned int seqno)
248 {
249         int res;
250         if (mgcpdebug)
251                 ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
252                 
253         res = mgcp_postrequest(p, req->data, req->len, seqno);
254         return res;
255 }
256
257 static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
258 {
259         int res;
260         struct mgcp_endpoint *p;
261         
262         p = ast->pvt->pvt;
263         if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
264                 ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name);
265                 return -1;
266         }
267
268         res = 0;
269         p->outgoing = 1;
270         if (p->type == TYPE_LINE) {
271                 transmit_notify_request_with_callerid(p, "L/rg", 0, ast->callerid);
272                 ast_setstate(ast, AST_STATE_RINGING);
273                 ast_queue_control(ast, AST_CONTROL_RINGING, 0);
274         } else {
275                 ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n");
276                 res = -1;
277         }
278         return res;
279 }
280
281 /* Interface lookup code courtesy Tilghman of DrunkCoder.com.  Thanks! */
282
283 struct my_ifreq {
284     union
285       {
286         char ifrn_name[IFNAMSIZ];       /* Interface name, e.g. "en0".  */
287       } ifr_ifrn;
288
289     union
290       {
291         struct sockaddr_in ifru_addr;
292         char ifru_data[512];
293       } ifr_ifru;
294 };
295
296 struct in_addr *lookup_iface(char *iface) {
297         int mysock;
298         int res;
299         static struct  my_ifreq ifreq;
300         strncpy(ifreq.ifr_ifrn.ifrn_name,iface,sizeof(ifreq.ifr_ifrn.ifrn_name));
301
302         mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
303         res = ioctl(mysock,SIOCGIFADDR,&ifreq);
304         
305         close(mysock);
306         if (res < 0) {
307                 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
308                 return &__ourip;
309         }
310         return( (struct in_addr *) &ifreq.ifr_ifru.ifru_addr.sin_addr );
311 }
312
313 static struct in_addr *myaddrfor(struct in_addr *them)
314 {
315         FILE *PROC;
316         struct in_addr *temp = NULL;
317         unsigned int remote_ip;
318         char line[256];
319         remote_ip = them->s_addr;
320         
321         PROC = fopen("/proc/net/route","r");
322         if (!PROC) {
323                 /* If /proc/net/route doesn't exist, fall back to the old method */
324                 return &__ourip;
325         }
326         /* First line contains headers */
327         fgets(line,sizeof(line),PROC);
328
329         while (!feof(PROC)) {
330                 char iface[8];
331                 unsigned int dest, gateway, mask;
332                 int i,aoffset;
333                 char *fields[40];
334
335                 fgets(line,sizeof(line),PROC);
336
337                 aoffset = 0;
338                 for (i=0;i<sizeof(line);i++) {
339                         char *boffset;
340
341                         fields[aoffset++] = line + i;
342                         boffset = strchr(line + i,'\t');
343                         if (boffset == NULL) {
344                                 /* Exit loop */
345                                 break;
346                         } else {
347                                 *boffset = '\0';
348                                 i = boffset - line;
349                         }
350                 }
351
352                 sscanf(fields[0],"%s",iface);
353                 sscanf(fields[1],"%x",&dest);
354                 sscanf(fields[2],"%x",&gateway);
355                 sscanf(fields[7],"%x",&mask);
356 #if 0
357                 printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
358 #endif          
359                 if (((remote_ip & mask) ^ dest) == 0) {
360
361                         if (mgcpdebug)
362                                         ast_verbose("Interface is %s\n",iface);
363                         temp = lookup_iface(iface);
364                         if (mgcpdebug)
365                                 ast_verbose("IP Address is %s\n",inet_ntoa(*temp));
366                         break;
367                 }
368         }
369         fclose(PROC);
370         if (!temp) {
371                 ast_log(LOG_WARNING, "Couldn't figure out how to get to %s.  Using default\n", inet_ntoa(*them));
372                 temp = &__ourip;
373         }
374         return temp;
375 }
376
377
378 static int mgcp_hangup(struct ast_channel *ast)
379 {
380         struct mgcp_endpoint *p = ast->pvt->pvt;
381         if (option_debug)
382                 ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name);
383         if (!ast->pvt->pvt) {
384                 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
385                 return 0;
386         }
387         if ((p->dtmfinband) && (p->vad != NULL)){
388             ast_dsp_free(p->vad);
389         }
390         ast_pthread_mutex_lock(&p->lock);
391         p->owner = NULL;
392         if (strlen(p->cxident))
393                 transmit_connection_del(p);
394         strcpy(p->cxident, "");
395         if (!p->alreadygone && (!p->outgoing || (ast->_state == AST_STATE_UP)))
396                 transmit_notify_request(p, "ro", 1);
397         else
398                 transmit_notify_request(p, "", 0);
399         ast->pvt->pvt = NULL;
400         p->alreadygone = 0;
401         p->outgoing = 0;
402         strcpy(p->callid, "");
403         /* Reset temporary destination */
404         memset(&p->tmpdest, 0, sizeof(p->tmpdest));
405         if (p->rtp) {
406                 ast_rtp_destroy(p->rtp);
407                 p->rtp = NULL;
408         }
409         ast_pthread_mutex_unlock(&p->lock);
410         return 0;
411 }
412
413 static int mgcp_show_endpoints(int fd, int argc, char *argv[])
414 {
415         struct mgcp_gateway  *g;
416         struct mgcp_endpoint *e;
417         int hasendpoints = 0;
418         if (argc != 3) 
419                 return RESULT_SHOWUSAGE;
420         ast_pthread_mutex_lock(&gatelock);
421         g = gateways;
422         while(g) {
423                 e = g->endpoints;
424                 ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? inet_ntoa(g->addr.sin_addr) : inet_ntoa(g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static");
425                 while(e) {
426                         ast_cli(fd, "   -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->owner ? "active" : "idle");
427                         hasendpoints = 1;
428                         e = e->next;
429                 }
430                 if (!hasendpoints) {
431                         ast_cli(fd, "   << No Endpoints Defined >>     ");
432                 }
433                 g = g->next;
434         }
435         ast_pthread_mutex_unlock(&gatelock);
436         return RESULT_SUCCESS;
437 }
438
439 static char show_endpoints_usage[] = 
440 "Usage: mgcp show endpoints\n"
441 "       Lists all endpoints known to the MGCP (Media Gateawy Control Protocol) subsystem.\n";
442
443 static struct ast_cli_entry  cli_show_endpoints = 
444         { { "mgcp", "show", "endpoints", NULL }, mgcp_show_endpoints, "Show defined MGCP endpoints", show_endpoints_usage };
445
446 static int mgcp_audit_endpoint(int fd, int argc, char *argv[])
447 {
448         struct mgcp_gateway  *g;
449         struct mgcp_endpoint *e;
450         int found = 0;
451     char *ename,*gname;
452         if (!mgcpdebug) {
453                 return RESULT_SHOWUSAGE;
454     }
455         if (argc != 4) 
456                 return RESULT_SHOWUSAGE;
457     /* split the name into parts by null */
458     ename = argv[3];
459     gname = ename;
460     while (*gname) {
461         if (*gname == '@') {
462             *gname = 0;
463             gname++;
464             break;
465         }
466         gname++;
467     }
468
469         ast_pthread_mutex_lock(&gatelock);
470         g = gateways;
471         while(g) {
472         if (!strcasecmp(g->name, gname)) {
473             e = g->endpoints;
474             while(e) {
475                 if (!strcasecmp(e->name, ename)) {
476                     found = 1;
477                     transmit_audit_endpoint(e);
478                     break;
479                 }
480                 e = e->next;
481             }
482             if (found) {
483                 break;
484             }
485         }
486         g = g->next;
487         }
488     if (!found) {
489         ast_cli(fd, "   << Could not find endpoint >>     ");
490     }
491         ast_pthread_mutex_unlock(&gatelock);
492         return RESULT_SUCCESS;
493 }
494
495 static char audit_endpoint_usage[] = 
496 "Usage: mgcp audit endpoint <endpointid>\n"
497 "       List the capabilities of an endpoint in the MGCP (Media Gateawy Control Protocol) subsystem.\n"
498 "       mgcp debug MUST be on to see the results of this command.\n";
499
500 static struct ast_cli_entry  cli_audit_endpoint = 
501         { { "mgcp", "audit", "endpoint", NULL }, mgcp_audit_endpoint, "Audit specified MGCP endpoint", audit_endpoint_usage };
502
503 static int mgcp_answer(struct ast_channel *ast)
504 {
505         int res = 0;
506         struct mgcp_endpoint *p = ast->pvt->pvt;
507         if (ast->_state != AST_STATE_UP) {
508                 ast_setstate(ast, AST_STATE_UP);
509                 if (option_debug)
510                         ast_log(LOG_DEBUG, "mgcp_answer(%s)\n", ast->name);
511                 transmit_notify_request(p, "", 1);
512         }
513         return res;
514 }
515
516 static struct ast_frame *mgcp_rtp_read(struct mgcp_endpoint *p)
517 {
518         /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
519         struct ast_frame *f;
520         f = ast_rtp_read(p->rtp);
521         if (p->owner) {
522                 /* We already hold the channel lock */
523                 if (f->frametype == AST_FRAME_VOICE) {
524                         if (f->subclass != p->owner->nativeformats) {
525                                 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
526                                 p->owner->nativeformats = f->subclass;
527                                 ast_set_read_format(p->owner, p->owner->readformat);
528                                 ast_set_write_format(p->owner, p->owner->writeformat);
529                         }
530                 }
531         }
532         return f;
533 }
534
535
536 static struct ast_frame  *mgcp_read(struct ast_channel *ast)
537 {
538         struct ast_frame *fr;
539         struct mgcp_endpoint *p = ast->pvt->pvt;
540         ast_pthread_mutex_lock(&p->lock);
541         fr = mgcp_rtp_read(p);
542         ast_pthread_mutex_unlock(&p->lock);
543         return fr;
544 }
545
546 static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
547 {
548         struct mgcp_endpoint *p = ast->pvt->pvt;
549         int res = 0;
550         if (frame->frametype != AST_FRAME_VOICE) {
551                 if (frame->frametype == AST_FRAME_IMAGE)
552                         return 0;
553                 else {
554                         ast_log(LOG_WARNING, "Can't send %d type frames with MGCP write\n", frame->frametype);
555                         return 0;
556                 }
557         } else {
558                 if (!(frame->subclass & ast->nativeformats)) {
559                         ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
560                                 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
561                         return -1;
562                 }
563         }
564         if (p) {
565                 ast_pthread_mutex_lock(&p->lock);
566                 if (p->rtp) {
567                         res =  ast_rtp_write(p->rtp, frame);
568                 }
569                 ast_pthread_mutex_unlock(&p->lock);
570         }
571         return res;
572 }
573
574 static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
575 {
576         struct mgcp_endpoint *p = newchan->pvt->pvt;
577         ast_pthread_mutex_lock(&p->lock);
578         if (p->owner != oldchan) {
579                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
580                 return -1;
581         }
582         p->owner = newchan;
583         ast_pthread_mutex_unlock(&p->lock);
584         return 0;
585 }
586
587 static int mgcp_senddigit(struct ast_channel *ast, char digit)
588 {
589         struct mgcp_endpoint *p = ast->pvt->pvt;
590         char tmp[2];
591         tmp[0] = digit;
592         tmp[1] = '\0';
593         transmit_notify_request(p, tmp, 1);
594         return -1;
595 }
596
597
598 static int mgcp_indicate(struct ast_channel *ast, int ind)
599 {
600         struct mgcp_endpoint *p = ast->pvt->pvt;
601         switch(ind) {
602         case AST_CONTROL_RINGING:
603                 transmit_notify_request(p, "rt", 1);
604                 break;
605         case AST_CONTROL_BUSY:
606                 transmit_notify_request(p, "bz", 1);
607                 break;
608         case AST_CONTROL_CONGESTION:
609                 transmit_notify_request(p, "nbz", 1);
610                 break;
611         case -1:
612                 transmit_notify_request(p, "", 1);
613                 break;          
614         default:
615                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
616                 return -1;
617         }
618         return 0;
619 }
620
621 static struct ast_channel *mgcp_new(struct mgcp_endpoint *i, int state)
622 {
623         struct ast_channel *tmp;
624         int fmt;
625         tmp = ast_channel_alloc(1);
626         if (tmp) {
627                 tmp->nativeformats = i->capability;
628                 if (!tmp->nativeformats)
629                         tmp->nativeformats = capability;
630                 fmt = ast_best_codec(tmp->nativeformats);
631                 snprintf(tmp->name, sizeof(tmp->name), "MGCP/%s@%s", i->name, i->parent->name);
632                 if (i->rtp)
633                         tmp->fds[0] = ast_rtp_fd(i->rtp);
634                 tmp->type = type;
635                 if (i->dtmfinband) {
636                     i->vad = ast_dsp_new();
637                     ast_dsp_set_features(i->vad,DSP_FEATURE_DTMF_DETECT);
638                 } else {
639                     i->vad = NULL;
640                 }
641                 ast_setstate(tmp, state);
642                 if (state == AST_STATE_RING)
643                         tmp->rings = 1;
644                 tmp->writeformat = fmt;
645                 tmp->pvt->rawwriteformat = fmt;
646                 tmp->readformat = fmt;
647                 tmp->pvt->rawreadformat = fmt;
648                 tmp->pvt->pvt = i;
649                 tmp->pvt->call = mgcp_call;
650                 tmp->pvt->hangup = mgcp_hangup;
651                 tmp->pvt->answer = mgcp_answer;
652                 tmp->pvt->read = mgcp_read;
653                 tmp->pvt->write = mgcp_write;
654                 tmp->pvt->indicate = mgcp_indicate;
655                 tmp->pvt->fixup = mgcp_fixup;
656                 tmp->pvt->send_digit = mgcp_senddigit;
657                 tmp->pvt->bridge = ast_rtp_bridge;
658                 if (strlen(i->language))
659                         strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
660                 i->owner = tmp;
661                 ast_pthread_mutex_lock(&usecnt_lock);
662                 usecnt++;
663                 ast_pthread_mutex_unlock(&usecnt_lock);
664                 ast_update_use_count();
665                 strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
666                 strncpy(tmp->exten, i->exten, sizeof(tmp->exten)-1);
667                 if (strlen(i->callerid))
668                         tmp->callerid = strdup(i->callerid);
669                 tmp->priority = 1;
670                 if (state != AST_STATE_DOWN) {
671                         if (ast_pbx_start(tmp)) {
672                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
673                                 ast_hangup(tmp);
674                                 tmp = NULL;
675                         }
676                 }
677         } else
678                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
679         return tmp;
680 }
681
682 static char* get_sdp_by_line(char* line, char *name, int nameLen) {
683   if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
684     char* r = line + nameLen + 1;
685     while (*r && (*r < 33)) ++r;
686     return r;
687   }
688
689   return "";
690 }
691
692 static char *get_sdp(struct mgcp_request *req, char *name) {
693   int x;
694   int len = strlen(name);
695   char *r;
696
697   for (x=0; x<req->lines; x++) {
698     r = get_sdp_by_line(req->line[x], name, len);
699     if (r[0] != '\0') return r;
700   }
701   return "";
702 }
703
704 static void sdpLineNum_iterator_init(int* iterator) {
705   *iterator = 0;
706 }
707
708 static char* get_sdp_iterate(int* iterator,
709                              struct mgcp_request *req, char *name) {
710   int len = strlen(name);
711   char *r;
712   while (*iterator < req->lines) {
713     r = get_sdp_by_line(req->line[(*iterator)++], name, len);
714     if (r[0] != '\0') return r;
715   }
716   return "";
717 }
718
719 static char *__get_header(struct mgcp_request *req, char *name, int *start)
720 {
721         int x;
722         int len = strlen(name);
723         char *r;
724         for (x=*start;x<req->headers;x++) {
725                 if (!strncasecmp(req->header[x], name, len) && 
726                                 (req->header[x][len] == ':')) {
727                                         r = req->header[x] + len + 1;
728                                         while(*r && (*r < 33))
729                                                         r++;
730                                         *start = x+1;
731                                         return r;
732                 }
733         }
734         /* Don't return NULL, so get_header is always a valid pointer */
735         return "";
736 }
737
738 static char *get_header(struct mgcp_request *req, char *name)
739 {
740         int start = 0;
741         return __get_header(req, name, &start);
742 }
743
744 #if 0
745 static int rtpready(struct ast_rtp *rtp, struct ast_frame *f, void *data)
746 {
747         /* Just deliver the audio directly */
748         struct mgcp_endpoint *p = data;
749         ast_pthread_mutex_lock(&p->lock);
750         if (p->owner) {
751                 /* Generally, you lock in the order channel lock, followed by private
752                    lock.  Since here we are doing the reverse, there is the possibility
753                    of deadlock.  As a result, in the case of a deadlock, we simply fail out
754                    here. */
755                 if (!pthread_mutex_trylock(&p->owner->lock)) {
756                         if (f->frametype == AST_FRAME_VOICE) {
757                                 if (f->subclass != p->owner->nativeformats) {
758                                         ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
759                                         p->owner->nativeformats = f->subclass;
760                                         ast_set_read_format(p->owner, p->owner->readformat);
761                                         ast_set_write_format(p->owner, p->owner->writeformat);
762                                 }
763                                 if (p->dtmfinband) {
764                                     f = ast_dsp_process(p->owner,p->vad,f,0);
765                                 }
766                         }
767                         ast_queue_frame(p->owner, f, 0);
768                         pthread_mutex_unlock(&p->owner->lock);
769                 }
770         }
771         ast_pthread_mutex_unlock(&p->lock);
772         return 0;
773 }
774 #endif
775
776 static struct mgcp_endpoint *find_endpoint(char *name, int msgid, struct sockaddr_in *sin)
777 {
778         struct mgcp_endpoint *p = NULL;
779         struct mgcp_gateway *g;
780         char tmp[256] = "";
781         char *at = NULL;
782         if (name) {
783                 strncpy(tmp, name, sizeof(tmp) - 1);
784                 at = strchr(tmp, '@');
785                 if (!at) {
786                         ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name);
787                         return NULL;
788                 }
789                 *at = '\0';
790                 at++;
791         }
792         ast_pthread_mutex_lock(&gatelock);
793         g = gateways;
794         while(g) {
795                 if ((!name || !strcasecmp(g->name, at)) && 
796                     (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) {
797                         /* Found the gateway.  If it's dynamic, save it's address -- now for the endpoint */
798                         if (sin && g->dynamic) {
799                                 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
800                                         (g->addr.sin_port != sin->sin_port)) {
801                                         memcpy(&g->addr, sin, sizeof(g->addr));
802                                         memcpy(&g->ourip, myaddrfor(&g->addr.sin_addr), sizeof(g->ourip));
803                                         if (option_verbose > 2)
804                                                 ast_verbose(VERBOSE_PREFIX_3 "Registered MGCP gateway '%s' at %s port %d\n", g->name, inet_ntoa(g->addr.sin_addr), ntohs(g->addr.sin_port));
805                                 }
806                         }
807                         p = g->endpoints;
808                         while(p) {
809                                 if ((name && !strcasecmp(p->name, tmp)) ||
810                                     (msgid && (p->lastout == msgid)))
811                                         break;
812                                 p = p->next;
813                         }
814                         if (name || p)
815                                 break;
816                 }
817                 g = g->next;
818         }
819         ast_pthread_mutex_unlock(&gatelock);
820         if (!p) {
821                 if (name) {
822                         if (g)
823                                 ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp,at);
824                         else
825                                 ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
826                 } 
827         }
828         return p;
829 }
830
831 static void parse(struct mgcp_request *req)
832 {
833         /* Divide fields by NULL's */
834         char *c;
835         int f = 0;
836         c = req->data;
837
838         /* First header starts immediately */
839         req->header[f] = c;
840         while(*c) {
841                 if (*c == '\n') {
842                         /* We've got a new header */
843                         *c = 0;
844
845 #if 0
846                         printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f]));
847 #endif                  
848                         if (!strlen(req->header[f])) {
849                                 /* Line by itself means we're now in content */
850                                 c++;
851                                 break;
852                         }
853                         if (f >= MGCP_MAX_HEADERS - 1) {
854                                 ast_log(LOG_WARNING, "Too many MGCP headers...\n");
855                         } else
856                                 f++;
857                         req->header[f] = c + 1;
858                 } else if (*c == '\r') {
859                         /* Ignore but eliminate \r's */
860                         *c = 0;
861                 }
862                 c++;
863         }
864         /* Check for last header */
865         if (strlen(req->header[f])) 
866                 f++;
867         req->headers = f;
868         /* Now we process any mime content */
869         f = 0;
870         req->line[f] = c;
871         while(*c) {
872                 if (*c == '\n') {
873                         /* We've got a new line */
874                         *c = 0;
875 #if 0
876                         printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f]));
877 #endif                  
878                         if (f >= MGCP_MAX_LINES - 1) {
879                                 ast_log(LOG_WARNING, "Too many SDP lines...\n");
880                         } else
881                                 f++;
882                         req->line[f] = c + 1;
883                 } else if (*c == '\r') {
884                         /* Ignore and eliminate \r's */
885                         *c = 0;
886                 }
887                 c++;
888         }
889         /* Check for last line */
890         if (strlen(req->line[f])) 
891                 f++;
892         req->lines = f;
893         /* Parse up the initial header */
894         c = req->header[0];
895         while(*c && *c < 33) c++;
896         /* First the verb */
897         req->verb = c;
898         while(*c && (*c > 32)) c++;
899         if (*c) {
900                 *c = '\0';
901                 c++;
902                 while(*c && (*c < 33)) c++;
903                 req->identifier = c;
904                 while(*c && (*c > 32)) c++;
905                 if (*c) {
906                         *c = '\0';
907                         c++;
908                         while(*c && (*c < 33)) c++;
909                         req->endpoint = c;
910                         while(*c && (*c > 32)) c++;
911                         if (*c) {
912                                 *c = '\0';
913                                 c++;
914                                 while(*c && (*c < 33)) c++;
915                                 req->version = c;
916                                 while(*c && (*c > 32)) c++;
917                                 while(*c && (*c < 33)) c++;
918                                 while(*c && (*c > 32)) c++;
919                                 *c = '\0';
920                         }
921                 }
922         }
923                 
924         if (mgcpdebug) {
925                 ast_verbose("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
926                 req->verb, req->identifier, req->endpoint, req->version);
927                 ast_verbose("%d headers, %d lines\n", req->headers, req->lines);
928         }
929         if (*c) 
930                 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
931 }
932
933 static int process_sdp(struct mgcp_endpoint *p, struct mgcp_request *req)
934 {
935         char *m;
936         char *c;
937         char *a;
938         char host[258];
939         int len;
940         int portno;
941         int peercapability, peerNonCodecCapability;
942         struct sockaddr_in sin;
943         char *codecs;
944         struct hostent *hp;
945         int codec;
946         int iterator;
947
948         /* Get codec and RTP info from SDP */
949         m = get_sdp(req, "m");
950         c = get_sdp(req, "c");
951         if (!strlen(m) || !strlen(c)) {
952                 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
953                 return -1;
954         }
955         if (sscanf(c, "IN IP4 %256s", host) != 1) {
956                 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
957                 return -1;
958         }
959         /* XXX This could block for a long time, and block the main thread! XXX */
960         hp = gethostbyname(host);
961         if (!hp) {
962                 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
963                 return -1;
964         }
965         if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) {
966                 ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m); 
967                 return -1;
968         }
969         sin.sin_family = AF_INET;
970         memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
971         sin.sin_port = htons(portno);
972         ast_rtp_set_peer(p->rtp, &sin);
973 #if 0
974         printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
975 #endif  
976         // Scan through the RTP payload types specified in a "m=" line:
977     ast_rtp_pt_clear(p->rtp);
978         codecs = m + len;
979         while(strlen(codecs)) {
980                 if (sscanf(codecs, "%d %n", &codec, &len) != 1) {
981                         ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
982                         return -1;
983                 }
984                 ast_rtp_set_m_type(p->rtp, codec);
985                 codecs += len;
986         }
987
988         // Next, scan through each "a=rtpmap:" line, noting each
989         // specified RTP payload type (with corresponding MIME subtype):
990         sdpLineNum_iterator_init(&iterator);
991         while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
992           char* mimeSubtype = strdup(a); // ensures we have enough space
993           if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
994           // Note: should really look at the 'freq' and '#chans' params too
995           ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
996           free(mimeSubtype);
997         }
998
999         // Now gather all of the codecs that were asked for:
1000         ast_rtp_get_current_formats(p->rtp,
1001                                 &peercapability, &peerNonCodecCapability);
1002         p->capability = capability & peercapability;
1003         if (mgcpdebug) {
1004                 ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n",
1005                 capability, peercapability, p->capability);
1006                 ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n",
1007                             nonCodecCapability, peerNonCodecCapability,
1008                             p->nonCodecCapability);
1009         }
1010         if (!p->capability) {
1011                 ast_log(LOG_WARNING, "No compatible codecs!\n");
1012                 return -1;
1013         }
1014         return 0;
1015         
1016 }
1017
1018 static int add_header(struct mgcp_request *req, char *var, char *value)
1019 {
1020         if (req->len >= sizeof(req->data) - 4) {
1021                 ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
1022                 return -1;
1023         }
1024         if (req->lines) {
1025                 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
1026                 return -1;
1027         }
1028         req->header[req->headers] = req->data + req->len;
1029         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
1030         req->len += strlen(req->header[req->headers]);
1031         if (req->headers < MGCP_MAX_HEADERS)
1032                 req->headers++;
1033         else {
1034                 ast_log(LOG_WARNING, "Out of header space\n");
1035                 return -1;
1036         }
1037         return 0;       
1038 }
1039
1040 static int add_line(struct mgcp_request *req, char *line)
1041 {
1042         if (req->len >= sizeof(req->data) - 4) {
1043                 ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
1044                 return -1;
1045         }
1046         if (!req->lines) {
1047                 /* Add extra empty return */
1048                 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
1049                 req->len += strlen(req->data + req->len);
1050         }
1051         req->line[req->lines] = req->data + req->len;
1052         snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
1053         req->len += strlen(req->line[req->lines]);
1054         if (req->lines < MGCP_MAX_LINES)
1055                 req->lines++;
1056         else {
1057                 ast_log(LOG_WARNING, "Out of line space\n");
1058                 return -1;
1059         }
1060         return 0;       
1061 }
1062
1063 static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
1064 {
1065         /* Initialize a response */
1066         if (req->headers || req->len) {
1067                 ast_log(LOG_WARNING, "Request already initialized?!?\n");
1068                 return -1;
1069         }
1070         req->header[req->headers] = req->data + req->len;
1071         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
1072         req->len += strlen(req->header[req->headers]);
1073         if (req->headers < MGCP_MAX_HEADERS)
1074                 req->headers++;
1075         else
1076                 ast_log(LOG_WARNING, "Out of header space\n");
1077         return 0;
1078 }
1079
1080 static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb)
1081 {
1082         /* Initialize a response */
1083         if (req->headers || req->len) {
1084                 ast_log(LOG_WARNING, "Request already initialized?!?\n");
1085                 return -1;
1086         }
1087         req->header[req->headers] = req->data + req->len;
1088         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@%s MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name);
1089         req->len += strlen(req->header[req->headers]);
1090         if (req->headers < MGCP_MAX_HEADERS)
1091                 req->headers++;
1092         else
1093                 ast_log(LOG_WARNING, "Out of header space\n");
1094         return 0;
1095 }
1096
1097
1098 static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
1099 {
1100         memset(resp, 0, sizeof(*resp));
1101         init_resp(resp, msg, req, msgrest);
1102         return 0;
1103 }
1104
1105 static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
1106 {
1107         memset(req, 0, sizeof(struct mgcp_request));
1108         oseq++;
1109         init_req(p, req, verb);
1110         return 0;
1111 }
1112
1113 static int transmit_response(struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
1114 {
1115         struct mgcp_request resp;
1116         respprep(&resp, p, msg, req, msgrest);
1117         return send_response(p, &resp);
1118 }
1119
1120
1121 static int add_sdp(struct mgcp_request *resp, struct mgcp_endpoint *p, struct ast_rtp *rtp)
1122 {
1123         int len;
1124         int codec;
1125         char costr[80];
1126         struct sockaddr_in sin;
1127         char v[256];
1128         char s[256];
1129         char o[256];
1130         char c[256];
1131         char t[256];
1132         char m[256];
1133         char a[1024] = "";
1134         int x;
1135         struct sockaddr_in dest;
1136         /* XXX We break with the "recommendation" and send our IP, in order that our
1137                peer doesn't have to gethostbyname() us XXX */
1138         len = 0;
1139         if (!p->rtp) {
1140                 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
1141                 return -1;
1142         }
1143         ast_rtp_get_us(p->rtp, &sin);
1144         if (rtp) {
1145                 ast_rtp_get_peer(rtp, &dest);
1146         } else {
1147                 if (p->tmpdest.sin_addr.s_addr) {
1148                         dest.sin_addr = p->tmpdest.sin_addr;
1149                         dest.sin_port = p->tmpdest.sin_port;
1150                         /* Reset temporary destination */
1151                         memset(&p->tmpdest, 0, sizeof(p->tmpdest));
1152                 } else {
1153                         dest.sin_addr = p->parent->ourip;
1154                         dest.sin_port = sin.sin_port;
1155                 }
1156         }
1157         if (mgcpdebug)
1158                 ast_verbose("We're at %s port %d\n", inet_ntoa(p->parent->ourip), ntohs(sin.sin_port)); 
1159         snprintf(v, sizeof(v), "v=0\r\n");
1160         snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), inet_ntoa(dest.sin_addr));
1161         snprintf(s, sizeof(s), "s=session\r\n");
1162         snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", inet_ntoa(dest.sin_addr));
1163         snprintf(t, sizeof(t), "t=0 0\r\n");
1164         snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
1165         for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) {
1166                 if (p->capability & x) {
1167                         if (mgcpdebug)
1168                                 ast_verbose("Answering with capability %d\n", x);
1169                         codec = ast_rtp_lookup_code(p->rtp, 1, x);
1170                         if (codec > -1) {
1171                                 snprintf(costr, sizeof(costr), " %d", codec);
1172                                 strcat(m, costr);
1173                                 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
1174                                 strcat(a, costr);
1175                         }
1176                 }
1177         }
1178         for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
1179                 if (p->nonCodecCapability & x) {
1180                         if (mgcpdebug)
1181                                 ast_verbose("Answering with non-codec capability %d\n", x);
1182                         codec = ast_rtp_lookup_code(p->rtp, 0, x);
1183                         if (codec > -1) {
1184                                 snprintf(costr, sizeof(costr), " %d", codec);
1185                                 strcat(m, costr);
1186                                 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x));
1187                                 strcat(a, costr);
1188                                 if (x == AST_RTP_DTMF) {
1189                                   /* Indicate we support DTMF...  Not sure about 16, but MSN supports it so dang it, we will too... */
1190                                   snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n",
1191                                            codec);
1192                                   strcat(a, costr);
1193                                 }
1194                         }
1195                 }
1196         }
1197         strcat(m, "\r\n");
1198         len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
1199         snprintf(costr, sizeof(costr), "%d", len);
1200         add_line(resp, v);
1201         add_line(resp, o);
1202         add_line(resp, s);
1203         add_line(resp, c);
1204         add_line(resp, t);
1205         add_line(resp, m);
1206         add_line(resp, a);
1207         return 0;
1208 }
1209
1210 static int transmit_modify_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp)
1211 {
1212         struct mgcp_request resp;
1213         char local[256];
1214         char tmp[80];
1215         int x;
1216         if (!strlen(p->cxident) && rtp) {
1217                 /* We don't have a CXident yet, store the destination and
1218                    wait a bit */
1219                 ast_rtp_get_peer(rtp, &p->tmpdest);
1220                 return 0;
1221         }
1222         snprintf(local, sizeof(local), "p:20");
1223         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
1224                 if (p->capability & x) {
1225                         snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
1226                         strcat(local, tmp);
1227                 }
1228         }
1229         reqprep(&resp, p, "MDCX");
1230         add_header(&resp, "C", p->callid);
1231         add_header(&resp, "L", local);
1232         add_header(&resp, "M", "sendrecv");
1233         add_header(&resp, "X", p->txident);
1234         add_header(&resp, "I", p->cxident);
1235         add_header(&resp, "S", "");
1236         add_sdp(&resp, p, rtp);
1237         return send_request(p, &resp, oseq);
1238 }
1239
1240 static int transmit_connect_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp)
1241 {
1242         struct mgcp_request resp;
1243         char local[256];
1244         char tmp[80];
1245         int x;
1246         snprintf(local, sizeof(local), "p:20");
1247         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
1248                 if (p->capability & x) {
1249                         snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
1250                         strcat(local, tmp);
1251                 }
1252         }
1253         reqprep(&resp, p, "CRCX");
1254         add_header(&resp, "C", p->callid);
1255         add_header(&resp, "L", local);
1256         add_header(&resp, "M", "sendrecv");
1257         add_header(&resp, "X", p->txident);
1258         add_header(&resp, "S", "");
1259         add_sdp(&resp, p, rtp);
1260         return send_request(p, &resp, oseq);
1261 }
1262
1263 static int transmit_notify_request(struct mgcp_endpoint *p, char *tone, int offhook)
1264 {
1265         struct mgcp_request resp;
1266         strncpy(p->curtone, tone, sizeof(p->curtone) - 1);
1267         reqprep(&resp, p, "RQNT");
1268         add_header(&resp, "X", p->txident);
1269         if (offhook)
1270                 add_header(&resp, "R", "hu(N), hf(N), D/[0-9#*](N)");
1271         else
1272                 add_header(&resp, "R", "hd(N)");
1273         add_header(&resp, "S", tone);
1274         return send_request(p, &resp, oseq);
1275 }
1276
1277 static int transmit_notify_request_with_callerid(struct mgcp_endpoint *p, char *tone, int offhook, char *callerid)
1278 {
1279         struct mgcp_request resp;
1280         char cid[256];
1281         char tone2[256];
1282         char *l, *n;
1283         time_t t;
1284         struct tm tm;
1285         
1286         time(&t);
1287         localtime_r(&t,&tm);
1288         if (callerid)
1289                 strncpy(cid, callerid, sizeof(cid) - 1);
1290         else
1291                 strcpy(cid, "");
1292         ast_callerid_parse(cid, &n, &l);
1293         if (l) {
1294                 ast_shrink_phone_number(l);
1295                 if (!ast_isphonenumber(l)) {
1296                         n = l;
1297                         l = "";
1298                 }
1299         } 
1300         if (!n)
1301                 n = "O";
1302         if (!l)
1303                 l = "";
1304         snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 
1305                         tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
1306         strncpy(p->curtone, tone, sizeof(p->curtone) - 1);
1307         reqprep(&resp, p, "RQNT");
1308         add_header(&resp, "X", p->txident);
1309         if (offhook)
1310                 add_header(&resp, "R", "L/hu(N),L/hf(N),D/[0-9#*](N)");
1311         else
1312                 add_header(&resp, "R", "L/hd(N)");
1313         add_header(&resp, "S", tone2);
1314         return send_request(p, &resp, oseq);
1315 }
1316
1317 static int transmit_audit_endpoint(struct mgcp_endpoint *p)
1318 {
1319         struct mgcp_request resp;
1320         reqprep(&resp, p, "AUEP");
1321         add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,VS,E,MD");
1322         return send_request(p, &resp, oseq);
1323 }
1324
1325 static int transmit_connection_del(struct mgcp_endpoint *p)
1326 {
1327         struct mgcp_request resp;
1328         reqprep(&resp, p, "DLCX");
1329         add_header(&resp, "C", p->callid);
1330         add_header(&resp, "I", p->cxident);
1331         return send_request(p, &resp, oseq);
1332 }
1333
1334 static void handle_response(struct mgcp_endpoint *p, int result, int ident)
1335 {
1336         struct mgcp_message *cur;
1337         if (p->msgs && (p->msgs->seqno == ident)) {
1338                 ast_log(LOG_DEBUG, "Got response back on tansaction %d\n", ident);
1339                 cur = p->msgs;
1340                 p->msgs = p->msgs->next;
1341                 free(cur);
1342                 if (p->msgs) {
1343                         /* Send next pending message if appropriate */
1344                         p->messagepending = 1;
1345                         p->lastout = p->msgs->seqno;
1346                         __mgcp_xmit(p, p->msgs->buf, p->msgs->len);
1347                         /* XXX Should schedule retransmission XXX */
1348                 } else
1349                         p->messagepending = 0;
1350         } else {
1351                 ast_log(LOG_NOTICE, "Got response back on transaction %d we aren't sending? (current = %d)\n", ident, p->msgs ? p->msgs->seqno : -1);
1352         }
1353         if ((result >= 400) && (result <= 499)) {
1354                 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s\n", result, p->name, p->parent->name);
1355                 if (p->owner)
1356                         ast_softhangup(p->owner, AST_SOFTHANGUP_DEV);
1357         }
1358 }
1359
1360 static void start_rtp(struct mgcp_endpoint *p)
1361 {
1362                 ast_pthread_mutex_lock(&p->lock);
1363                 /* Allocate the RTP now */
1364                 p->rtp = ast_rtp_new(NULL, NULL);
1365                 if (p->rtp && p->owner)
1366                         p->owner->fds[0] = ast_rtp_fd(p->rtp);
1367                 if (p->rtp)
1368                         ast_rtp_setnat(p->rtp, p->nat);
1369 #if 0
1370                 ast_rtp_set_callback(p->rtp, rtpready);
1371                 ast_rtp_set_data(p->rtp, p);
1372 #endif          
1373                 /* Make a call*ID */
1374                 snprintf(p->callid, sizeof(p->callid), "%08x%s", rand(), p->txident);
1375                 /* Transmit the connection create */
1376                 transmit_connect_with_sdp(p, NULL);
1377                 ast_pthread_mutex_unlock(&p->lock);
1378 }
1379
1380 static void *mgcp_ss(void *data)
1381 {
1382         struct ast_channel *chan = data;
1383         struct mgcp_endpoint *p = chan->pvt->pvt;
1384         char exten[AST_MAX_EXTENSION] = "";
1385         int pos = 0;
1386         int to = 16000;
1387         int res;
1388         for (;;) {
1389                 res = ast_waitfordigit(chan, to);
1390                 if (!res) {
1391                         ast_log(LOG_DEBUG, "Timeout...\n");
1392                         break;
1393                 }
1394                 if (res < 0) {
1395                         ast_log(LOG_DEBUG, "Got hangup...\n");
1396                         break;
1397                 }
1398                 exten[pos++] = res;
1399                 if (!ast_ignore_pattern(chan->context, exten))
1400                         ast_indicate(chan, -1);
1401                 if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
1402                         if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) 
1403                                 to = 3000;
1404                         else
1405                                 to = 8000;
1406                 } else
1407                         break;
1408         }
1409         if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
1410                 strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
1411                 start_rtp(p);
1412                 ast_setstate(chan, AST_STATE_RING);
1413                 chan->rings = 1;
1414                 if (ast_pbx_run(chan)) {
1415                         ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
1416                 } else
1417                         return NULL;
1418         }
1419         ast_hangup(chan);
1420         return NULL;
1421 }
1422
1423 static int handle_request(struct mgcp_endpoint *p, struct mgcp_request *req, struct sockaddr_in *sin)
1424 {
1425         char *ev, *s;
1426         struct ast_channel *c;
1427         pthread_t t;
1428         struct ast_frame f = { 0, };
1429         if (mgcpdebug)
1430                 ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
1431         /* Clear out potential response */
1432         if (!strcasecmp(req->verb, "RSIP")) {
1433                 dump_queue(p);
1434                 if (option_verbose > 2)
1435                         ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name);
1436                 if (p->owner)
1437                         ast_softhangup(p->owner, AST_SOFTHANGUP_DEV);
1438                 transmit_response(p, "200", req, "OK");
1439                 transmit_notify_request(p, "", 0);
1440         } else if (!strcasecmp(req->verb, "NTFY")) {
1441                 /* Acknowledge and be sure we keep looking for the same things */
1442                 transmit_response(p, "200", req, "OK");
1443                 /* Notified of an event */
1444                 ev = get_header(req, "O");
1445                 s = strchr(ev, '/');
1446                 if (s) ev = s + 1;
1447                 ast_log(LOG_DEBUG, "Endpoint '%s@%s' observed '%s'\n", p->name, p->parent->name, ev);
1448                 /* Keep looking for events unless this was a hangup */
1449                 if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd"))
1450                         transmit_notify_request(p, p->curtone, 1);
1451                 if (!strcasecmp(ev, "hd")) {
1452                         /* Off hook / answer */
1453                         if (p->outgoing) {
1454                                 /* Answered */
1455                                 if (p->owner) {
1456                                         start_rtp(p);
1457                                         ast_queue_control(p->owner, AST_CONTROL_ANSWER, 1);
1458                                 }
1459                         } else {
1460                                 /* Start switch */
1461                                 if (!p->owner) {
1462                                         transmit_notify_request(p, "dl", 1);
1463                                         c = mgcp_new(p, AST_STATE_DOWN);
1464                                         if (c) {
1465                                                 if (pthread_create(&t, NULL, mgcp_ss, c)) {
1466                                                         ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
1467                                                         ast_hangup(c);
1468                                                 }
1469                                         } else
1470                                                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
1471                                 } else {
1472                                         ast_log(LOG_WARNING, "Off hook, but alreaedy have owner on %s@%s\n", p->name, p->parent->name);
1473                                 }
1474                         }
1475                 } else if (!strcasecmp(ev, "hu")) {
1476                         ast_log(LOG_DEBUG, "Went on hook\n");
1477                         if (p->owner) {
1478                                 p->alreadygone = 1;
1479                                 ast_queue_hangup(p->owner, 1);
1480                         }
1481                         transmit_notify_request(p, "", 0);
1482                 } else if ((strlen(ev) == 1) && 
1483                                         (((ev[0] >= '0') && (ev[0] <= '9')) ||
1484                                          ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
1485                                          (ev[0] == '*') || (ev[0] == '#'))) {
1486                         f.frametype = AST_FRAME_DTMF;
1487                         f.subclass = ev[0];
1488                         f.src = "mgcp";
1489                         if (p->owner)
1490                                 ast_queue_frame(p->owner, &f, 1);
1491                 } else if (!strcasecmp(ev, "T")) {
1492                         /* Digit timeout -- unimportant */
1493                 } else {
1494                         ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
1495                 }
1496         } else {
1497                 ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, inet_ntoa(sin->sin_addr));
1498                 transmit_response(p, "510", req, "Unknown verb");
1499         }
1500         return 0;
1501 }
1502
1503 static int mgcpsock_read(int *id, int fd, short events, void *ignore)
1504 {
1505         struct mgcp_request req;
1506         struct sockaddr_in sin;
1507         struct mgcp_endpoint *p;
1508         char *c;
1509         int res;
1510         int len;
1511         int result;
1512         int ident;
1513         len = sizeof(sin);
1514         memset(&req, 0, sizeof(req));
1515         res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
1516         if (res < 0) {
1517                 if (errno != ECONNREFUSED)
1518                         ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
1519                 return 1;
1520         }
1521         req.data[res] = '\0';
1522         req.len = res;
1523         if (mgcpdebug)
1524                 ast_verbose("MGCP read: \n%s\nfrom %s:%d", req.data, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1525         parse(&req);
1526         if (req.headers < 1) {
1527                 /* Must have at least one header */
1528                 return 1;
1529         }
1530         if (!req.identifier || !strlen(req.identifier)) {
1531                 ast_log(LOG_NOTICE, "Message from %s missing identifier\n", inet_ntoa(sin.sin_addr));
1532                 return 1;
1533         }
1534
1535         if (sscanf(req.verb, "%d", &result) &&
1536                 sscanf(req.identifier, "%d", &ident)) {
1537                 /* Try to find who this message is for, if it's important */
1538                 p = find_endpoint(NULL, ident, &sin);
1539                 if (p) {
1540                         handle_response(p, result, ident);
1541                         if ((c = get_header(&req, "I"))) {
1542                                 if (strlen(c)) {
1543                                         strncpy(p->cxident, c, sizeof(p->cxident) - 1);
1544                                         if (p->tmpdest.sin_addr.s_addr) {
1545                                                 transmit_modify_with_sdp(p, NULL);
1546                                         }
1547                                 }
1548                         }
1549                         if (req.lines) {
1550                                 if (!p->rtp) 
1551                                         start_rtp(p);
1552                                 if (p->rtp)
1553                                         process_sdp(p, &req);
1554                         }
1555                 }
1556         } else {
1557                 if (!req.endpoint || !strlen(req.endpoint) || 
1558                     !req.version || !strlen(req.version) || 
1559                         !req.verb || !strlen(req.verb)) {
1560                         ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
1561                         return 1;
1562                 }
1563                 /* Process request, with iflock held */
1564                 p = find_endpoint(req.endpoint, 0, &sin);
1565                 if (p) {
1566                         handle_request(p, &req, &sin);
1567                 }
1568         }
1569         return 1;
1570 }
1571
1572 static void *do_monitor(void *data)
1573 {
1574         int res;
1575         struct mgcp_pkt *p;
1576         sched = sched_context_create();
1577         if (!sched) {
1578                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
1579                 return NULL;
1580         }
1581         io = io_context_create();
1582         if (!io) {
1583                 ast_log(LOG_WARNING, "Unable to create I/O context\n");
1584                 return NULL;
1585         }
1586         
1587         /* Add an I/O event to our UDP socket */
1588         if (mgcpsock > -1) 
1589                 ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL);
1590         
1591         /* This thread monitors all the frame relay interfaces which are not yet in use
1592            (and thus do not have a separate thread) indefinitely */
1593         /* From here on out, we die whenever asked */
1594         for(;;) {
1595                 /* Check for interfaces needing to be killed */
1596                 /* Don't let anybody kill us right away.  Nobody should lock the interface list
1597                    and wait for the monitor list, but the other way around is okay. */
1598                 ast_pthread_mutex_lock(&monlock);
1599                 /* Lock the network interface */
1600                 ast_pthread_mutex_lock(&netlock);
1601                 p = packets;
1602                 while(p) {
1603                         /* Handle any retransmissions */
1604                         p = p->next;
1605                 }
1606                 /* Okay, now that we know what to do, release the network lock */
1607                 ast_pthread_mutex_unlock(&netlock);
1608                 /* And from now on, we're okay to be killed, so release the monitor lock as well */
1609                 ast_pthread_mutex_unlock(&monlock);
1610                 pthread_testcancel();
1611                 /* Wait for sched or io */
1612                 res = ast_sched_wait(sched);
1613                 res = ast_io_wait(io, res);
1614                 ast_pthread_mutex_lock(&monlock);
1615                 if (res >= 0) 
1616                         ast_sched_runq(sched);
1617                 ast_pthread_mutex_unlock(&monlock);
1618         }
1619         /* Never reached */
1620         return NULL;
1621         
1622 }
1623
1624 static int restart_monitor(void)
1625 {
1626         /* If we're supposed to be stopped -- stay stopped */
1627         if (monitor_thread == -2)
1628                 return 0;
1629         if (ast_pthread_mutex_lock(&monlock)) {
1630                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
1631                 return -1;
1632         }
1633         if (monitor_thread == pthread_self()) {
1634                 ast_pthread_mutex_unlock(&monlock);
1635                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1636                 return -1;
1637         }
1638         if (monitor_thread) {
1639                 /* Wake up the thread */
1640                 pthread_kill(monitor_thread, SIGURG);
1641         } else {
1642                 /* Start a new monitor */
1643                 if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
1644                         ast_pthread_mutex_unlock(&monlock);
1645                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1646                         return -1;
1647                 }
1648         }
1649         ast_pthread_mutex_unlock(&monlock);
1650         return 0;
1651 }
1652
1653 static struct ast_channel *mgcp_request(char *type, int format, void *data)
1654 {
1655         int oldformat;
1656         struct mgcp_endpoint *p;
1657         struct ast_channel *tmpc = NULL;
1658         char tmp[256];
1659         char *dest = data;
1660
1661         oldformat = format;
1662         format &= capability;
1663         if (!format) {
1664                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
1665                 return NULL;
1666         }
1667         strncpy(tmp, dest, sizeof(tmp) - 1);
1668         if (!strlen(tmp)) {
1669                 ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n");
1670                 return NULL;
1671         }
1672         p = find_endpoint(tmp, 0, NULL);
1673         if (!p) {
1674                 ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
1675                 return NULL;
1676         }
1677         
1678         /* Must be busy */
1679         if (p->owner)
1680                 return NULL;
1681         tmpc = mgcp_new(p, AST_STATE_DOWN);
1682         if (!tmpc)
1683                 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
1684         restart_monitor();
1685         return tmpc;
1686 }
1687
1688 struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
1689 {
1690         struct mgcp_gateway *gw;
1691         struct mgcp_endpoint *e;
1692         char context[AST_MAX_EXTENSION] = "default";
1693         char language[80] = "";
1694         char callerid[AST_MAX_EXTENSION] = "";
1695         int inbanddtmf = 0;
1696         int nat = 0;
1697
1698         gw = malloc(sizeof(struct mgcp_gateway));
1699         if (gw) {
1700                 memset(gw, 0, sizeof(struct mgcp_gateway));
1701                 gw->expire = -1;
1702                 strncpy(gw->name, cat, sizeof(gw->name) - 1);
1703                 while(v) {
1704                         if (!strcasecmp(v->name, "host")) {
1705                                 if (!strcasecmp(v->value, "dynamic")) {
1706                                         /* They'll register with us */
1707                                         gw->dynamic = 1;
1708                                         memset(&gw->addr.sin_addr, 0, 4);
1709                                         if (gw->addr.sin_port) {
1710                                                 /* If we've already got a port, make it the default rather than absolute */
1711                                                 gw->defaddr.sin_port = gw->addr.sin_port;
1712                                                 gw->addr.sin_port = 0;
1713                                         }
1714                                 } else {
1715                                         /* Non-dynamic.  Make sure we become that way if we're not */
1716                                         if (gw->expire > -1)
1717                                                 ast_sched_del(sched, gw->expire);
1718                                         gw->expire = -1;
1719                                         gw->dynamic = 0;
1720                                         if (ast_get_ip(&gw->addr, v->value)) {
1721                                                 free(gw);
1722                                                 return NULL;
1723                                         }
1724                                 }
1725                         } else if (!strcasecmp(v->name, "defaultip")) {
1726                                 if (ast_get_ip(&gw->defaddr, v->value)) {
1727                                         free(gw);
1728                                         return NULL;
1729                                 }
1730                         } else if (!strcasecmp(v->name, "permit") ||
1731                                            !strcasecmp(v->name, "deny")) {
1732                                 gw->ha = ast_append_ha(v->name, v->value, gw->ha);
1733                         } else if (!strcasecmp(v->name, "port")) {
1734                                 gw->addr.sin_port = htons(atoi(v->value));
1735                         } else if (!strcasecmp(v->name, "context")) {
1736                                 strncpy(context, v->value, sizeof(context) - 1);
1737                         } else if (!strcasecmp(v->name, "inbanddtmf")) {
1738                                 inbanddtmf = atoi(v->value);
1739                         } else if (!strcasecmp(v->name, "nat")) {
1740                                 nat = ast_true(v->value);
1741                         } else if (!strcasecmp(v->name, "callerid")) {
1742                                 if (!strcasecmp(v->value, "asreceived"))
1743                                         strcpy(callerid, "");
1744                                 else
1745                                         strncpy(callerid, v->value, sizeof(callerid) - 1);
1746                         } else if (!strcasecmp(v->name, "language")) {
1747                                 strncpy(language, v->value, sizeof(language)-1);
1748                         } else if (!strcasecmp(v->name, "trunk") ||
1749                                    !strcasecmp(v->name, "line")) {
1750                                 e = malloc(sizeof(struct mgcp_endpoint));
1751                                 if (e) {
1752                                         memset(e, 0, sizeof(struct mgcp_endpoint));
1753                                         /* XXX Should we really check for uniqueness?? XXX */
1754                                         snprintf(e->txident, sizeof(e->txident), "%08x", rand());
1755                                         strncpy(e->context, context, sizeof(e->context) - 1);
1756                                         strncpy(e->callerid, callerid, sizeof(e->callerid) - 1);
1757                                         strncpy(e->language, language, sizeof(e->language) - 1);
1758                                         e->capability = capability;
1759                                         e->parent = gw;
1760                                         e->dtmfinband = inbanddtmf;
1761                                         e->nat = nat;
1762                                         strncpy(e->name, v->value, sizeof(e->name) - 1);
1763                                         if (!strcasecmp(v->name, "trunk"))
1764                                                 e->type = TYPE_TRUNK;
1765                                         else
1766                                                 e->type = TYPE_LINE;
1767                                         e->next = gw->endpoints;
1768                                         gw->endpoints = e;
1769                                 }
1770                         } else
1771                                 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
1772                         v = v->next;
1773                 }
1774                 
1775         }
1776
1777         if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) {
1778                 ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name);
1779                 free(gw);
1780                 return NULL;
1781         }
1782         if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port)) 
1783                 gw->defaddr.sin_port = htons(DEFAULT_MGCP_PORT);
1784         if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port))
1785                 gw->addr.sin_port = htons(DEFAULT_MGCP_PORT);
1786         if (gw->addr.sin_addr.s_addr)
1787                 memcpy(&gw->ourip, myaddrfor(&gw->addr.sin_addr), sizeof(gw->ourip));
1788         return gw;
1789 }
1790
1791 static struct ast_rtp *mgcp_get_rtp_peer(struct ast_channel *chan)
1792 {
1793         struct mgcp_endpoint *p;
1794         p = chan->pvt->pvt;
1795         if (p && p->rtp)
1796                 return p->rtp;
1797         return NULL;
1798 }
1799
1800 static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp)
1801 {
1802         struct mgcp_endpoint *p;
1803         p = chan->pvt->pvt;
1804         if (p) {
1805                 transmit_modify_with_sdp(p, rtp);
1806                 return 0;
1807         }
1808         return -1;
1809 }
1810
1811 static struct ast_rtp_protocol mgcp_rtp = {
1812         get_rtp_info: mgcp_get_rtp_peer,
1813         set_rtp_peer: mgcp_set_rtp_peer,
1814 };
1815
1816 static int mgcp_do_debug(int fd, int argc, char *argv[])
1817 {
1818         if (argc != 2)
1819                 return RESULT_SHOWUSAGE;
1820         mgcpdebug = 1;
1821         ast_cli(fd, "MGCP Debugging Enabled\n");
1822         return RESULT_SUCCESS;
1823 }
1824
1825 static int mgcp_no_debug(int fd, int argc, char *argv[])
1826 {
1827         if (argc != 3)
1828                 return RESULT_SHOWUSAGE;
1829         mgcpdebug = 0;
1830         ast_cli(fd, "MGCP Debugging Disabled\n");
1831         return RESULT_SUCCESS;
1832 }
1833
1834 static char debug_usage[] = 
1835 "Usage: mgcp debug\n"
1836 "       Enables dumping of MGCP packets for debugging purposes\n";
1837
1838 static char no_debug_usage[] = 
1839 "Usage: mgcp no debug\n"
1840 "       Disables dumping of MGCP packets for debugging purposes\n";
1841
1842 static struct ast_cli_entry  cli_debug =
1843         { { "mgcp", "debug", NULL }, mgcp_do_debug, "Enable MGCP debugging", debug_usage };
1844 static struct ast_cli_entry  cli_no_debug =
1845         { { "mgcp", "no", "debug", NULL }, mgcp_no_debug, "Disable MGCP debugging", no_debug_usage };
1846
1847
1848 int load_module()
1849 {
1850         struct ast_config *cfg;
1851         struct ast_variable *v;
1852         struct mgcp_gateway *g;
1853         char *cat;
1854         struct hostent *hp;
1855         int format;
1856         
1857         if (gethostname(ourhost, sizeof(ourhost))) {
1858                 ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n");
1859                 return 0;
1860         }
1861         cfg = ast_load(config);
1862
1863         /* We *must* have a config file otherwise stop immediately */
1864         if (!cfg) {
1865                 ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config);
1866                 return 0;
1867         }
1868         memset(&bindaddr, 0, sizeof(bindaddr));
1869         v = ast_variable_browse(cfg, "general");
1870         while(v) {
1871                 /* Create the interface list */
1872                 if (!strcasecmp(v->name, "bindaddr")) {
1873                         if (!(hp = gethostbyname(v->value))) {
1874                                 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
1875                         } else {
1876                                 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
1877                         }
1878                 } else if (!strcasecmp(v->name, "allow")) {
1879                         format = ast_getformatbyname(v->value);
1880                         if (format < 1) 
1881                                 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
1882                         else
1883                                 capability |= format;
1884                 } else if (!strcasecmp(v->name, "disallow")) {
1885                         format = ast_getformatbyname(v->value);
1886                         if (format < 1) 
1887                                 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
1888                         else
1889                                 capability &= ~format;
1890                 } else if (!strcasecmp(v->name, "port")) {
1891                         if (sscanf(v->value, "%i", &ourport) == 1) {
1892                                 bindaddr.sin_port = htons(ourport);
1893                         } else {
1894                                 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
1895                         }
1896                 }
1897                 v = v->next;
1898         }
1899         
1900         cat = ast_category_browse(cfg, NULL);
1901         while(cat) {
1902                 if (strcasecmp(cat, "general")) {
1903                         g = build_gateway(cat, ast_variable_browse(cfg, cat));
1904                         if (g) {
1905                                 if (option_verbose > 2)
1906                                         ast_verbose(VERBOSE_PREFIX_3 "Added gateway '%s'\n", g->name);
1907                                 ast_pthread_mutex_lock(&gatelock);
1908                                 g->next = gateways;
1909                                 gateways = g;
1910                                 ast_pthread_mutex_unlock(&gatelock);
1911                         }
1912                 }
1913                 cat = ast_category_browse(cfg, cat);
1914         }
1915         
1916         if (ntohl(bindaddr.sin_addr.s_addr)) {
1917                 memcpy(&__ourip, &bindaddr, sizeof(__ourip));
1918         } else {
1919                 hp = gethostbyname(ourhost);
1920                 if (!hp) {
1921                         ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n");
1922                         return 0;
1923                 }
1924                 memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
1925         }
1926         if (!ntohs(bindaddr.sin_port))
1927                 bindaddr.sin_port = ntohs(DEFAULT_MGCP_PORT);
1928         bindaddr.sin_family = AF_INET;
1929         pthread_mutex_lock(&netlock);
1930         if (mgcpsock > -1)
1931                 close(mgcpsock);
1932         mgcpsock = socket(AF_INET, SOCK_DGRAM, 0);
1933         if (mgcpsock < 0) {
1934                 ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno));
1935         } else {
1936                 if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
1937                         ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
1938                                         inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
1939                                                 strerror(errno));
1940                         close(mgcpsock);
1941                         mgcpsock = -1;
1942                 } else if (option_verbose > 1)
1943                         ast_verbose(VERBOSE_PREFIX_2 "MGCP Listening on %s:%d\n", 
1944                                 inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
1945         }
1946         pthread_mutex_unlock(&netlock);
1947         ast_destroy(cfg);
1948
1949         /* Make sure we can register our mgcp channel type */
1950         if (ast_channel_register(type, tdesc, capability, mgcp_request)) {
1951                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
1952                 ast_destroy(cfg);
1953                 return -1;
1954         }
1955         mgcp_rtp.type = type;
1956         ast_rtp_proto_register(&mgcp_rtp);
1957         ast_cli_register(&cli_show_endpoints);
1958         ast_cli_register(&cli_audit_endpoint);
1959         ast_cli_register(&cli_debug);
1960         ast_cli_register(&cli_no_debug);
1961         /* And start the monitor for the first time */
1962         restart_monitor();
1963         return 0;
1964 }
1965
1966 int unload_module()
1967 {
1968 #if 0
1969         struct mgcp_endpoint *p, *pl;
1970         /* First, take us out of the channel loop */
1971         ast_channel_unregister(type);
1972         if (!ast_pthread_mutex_lock(&gatelock)) {
1973                 /* Hangup all interfaces if they have an owner */
1974                 p = iflist;
1975                 while(p) {
1976                         if (p->owner)
1977                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
1978                         p = p->next;
1979                 }
1980                 iflist = NULL;
1981                 ast_pthread_mutex_unlock(&iflock);
1982         } else {
1983                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1984                 return -1;
1985         }
1986         if (!ast_pthread_mutex_lock(&monlock)) {
1987                 if (monitor_thread) {
1988                         pthread_cancel(monitor_thread);
1989                         pthread_kill(monitor_thread, SIGURG);
1990                         pthread_join(monitor_thread, NULL);
1991                 }
1992                 monitor_thread = -2;
1993                 ast_pthread_mutex_unlock(&monlock);
1994         } else {
1995                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1996                 return -1;
1997         }
1998
1999         if (!ast_pthread_mutex_lock(&iflock)) {
2000                 /* Destroy all the interfaces and free their memory */
2001                 p = iflist;
2002                 while(p) {
2003                         pl = p;
2004                         p = p->next;
2005                         /* Free associated memory */
2006                         free(pl);
2007                 }
2008                 iflist = NULL;
2009                 ast_pthread_mutex_unlock(&iflock);
2010         } else {
2011                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
2012                 return -1;
2013         }
2014 #endif          
2015         return -1;
2016 }
2017
2018 int usecount()
2019 {
2020         int res;
2021         ast_pthread_mutex_lock(&usecnt_lock);
2022         res = usecnt;
2023         ast_pthread_mutex_unlock(&usecnt_lock);
2024         return res;
2025 }
2026
2027 char *key()
2028 {
2029         return ASTERISK_GPL_KEY;
2030 }
2031
2032 char *description()
2033 {
2034         return desc;
2035 }
2036