Version 0.3.0 from FTP
[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
43 #define MGCPDUMPER
44 #define DEFAULT_EXPIREY 120
45 #define MAX_EXPIREY     3600
46
47 static char *desc = "Media Gateway Control Protocol (MGCP)";
48 static char *type = "MGCP";
49 static char *tdesc = "Media Gateway Control Protocol (MGCP)";
50 static char *config = "mgcp.conf";
51
52 #define DEFAULT_MGCP_PORT       2427/* From RFC 2705 */
53 #define MGCP_MAX_PACKET 1500            /* Also from RFC 2543, should sub headers tho */
54
55 static int usecnt =0;
56 static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
57 static int oseq;
58
59 /* Protect the monitoring thread, so only one process can kill or start it, and not
60    when it's doing something critical. */
61 static pthread_mutex_t netlock = AST_MUTEX_INITIALIZER;
62
63 static pthread_mutex_t monlock = AST_MUTEX_INITIALIZER;
64
65 /* This is the thread for the monitor which checks for input on the channels
66    which are not currently in use.  */
67 static pthread_t monitor_thread = 0;
68
69 static int restart_monitor(void);
70
71 /* Just about everybody seems to support ulaw, so make it a nice default */
72 static int capability = AST_FORMAT_ULAW;
73
74 static char ourhost[256];
75 static struct in_addr __ourip;
76 static int ourport;
77
78 static struct sched_context *sched;
79 static struct io_context *io;
80 /* The private structures of the  mgcp channels are linked for
81    selecting outgoing channels */
82    
83 #define MGCP_MAX_HEADERS                64
84 #define MGCP_MAX_LINES          64
85
86 struct mgcp_request {
87         int len;
88         char *verb;
89         char *identifier;
90         char *endpoint;
91         char *version;
92         int headers;                                    /* MGCP Headers */
93         char *header[MGCP_MAX_HEADERS];
94         int lines;                                              /* SDP Content */
95         char *line[MGCP_MAX_LINES];
96         char data[MGCP_MAX_PACKET];
97 };
98
99 static struct mgcp_pkt {
100         int retrans;
101         struct mgcp_endpoint *owner;
102         int packetlen;
103         char data[MGCP_MAX_PACKET];
104         struct mgcp_pkt *next;
105 } *packets = NULL;      
106
107 #define TYPE_TRUNK              1
108 #define TYPE_LINE               2
109
110 struct mgcp_endpoint {
111         pthread_mutex_t lock;
112         char name[80];
113         char accountcode[80];
114         char exten[AST_MAX_EXTENSION];          /* Extention where to start */
115         char context[AST_MAX_EXTENSION];
116         char language[MAX_LANGUAGE];
117         char callerid[256];                                     /* Caller*ID */
118         char curtone[80];                                       /* Current tone */
119         char txident[80];
120         char cxident[80];
121         char callid[80];
122         int hascallerid;
123         int amaflags;
124         int type;
125         int group;
126         int iseq;
127         int lastout;
128         int alreadygone;
129         int needdestroy;
130         int capability;
131         int outgoing;
132         struct ast_channel *owner;
133         struct ast_rtp *rtp;
134         struct mgcp_endpoint *next;
135         struct mgcp_gateway *parent;
136 };
137
138 struct mgcp_gateway {
139         /* A gateway containing one or more endpoints */
140         char name[80];
141         struct sockaddr_in addr;
142         struct in_addr ourip;
143         struct mgcp_endpoint *endpoints;
144         struct ast_ha *ha;
145         struct mgcp_gateway *next;
146 } *gateways;
147
148 static pthread_mutex_t gatelock  = AST_MUTEX_INITIALIZER;
149
150 static int mgcpsock  = -1;
151
152 static struct sockaddr_in bindaddr;
153
154 static struct ast_frame  *mgcp_read(struct ast_channel *ast);
155 static int transmit_response(struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest);
156 static int transmit_notify_request(struct mgcp_endpoint *p, char *tone, int offhook);
157 static int transmit_connection_del(struct mgcp_endpoint *p);
158 static int transmit_notify_request_with_callerid(struct mgcp_endpoint *p, char *tone, int offhook, char *callerid);
159
160 static int __mgcp_xmit(struct mgcp_endpoint *p, char *data, int len)
161 {
162         int res;
163     res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&p->parent->addr, sizeof(struct sockaddr_in));
164         if (res != len) {
165                 ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
166         }
167         return res;
168 }
169
170 static int send_response(struct mgcp_endpoint *p, struct mgcp_request *req)
171 {
172         int res;
173         printf("Transmitting:\n%s\n to %s:%d\n", req->data, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
174         res = __mgcp_xmit(p, req->data, req->len);
175         if (res > 0)
176                 res = 0;
177         return res;
178 }
179
180 static int send_request(struct mgcp_endpoint *p, struct mgcp_request *req)
181 {
182         int res;
183         printf("XXX Need to handle Retransmitting XXX:\n%s to %s:%d\n", req->data, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
184         res = __mgcp_xmit(p, req->data, req->len);
185         return res;
186 }
187
188 static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
189 {
190         int res;
191         struct mgcp_endpoint *p;
192         
193         p = ast->pvt->pvt;
194         if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
195                 ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name);
196                 return -1;
197         }
198
199         res = 0;
200         p->outgoing = 1;
201         if (p->type == TYPE_LINE) {
202                 transmit_notify_request_with_callerid(p, "rg", 0, ast->callerid);
203                 ast_setstate(ast, AST_STATE_RINGING);
204                 ast_queue_control(ast, AST_CONTROL_RINGING, 0);
205         } else {
206                 ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n");
207                 res = -1;
208         }
209         return res;
210 }
211
212 /* Interface lookup code courtesy Tilghman of DrunkCoder.com.  Thanks! */
213
214 struct my_ifreq {
215     union
216       {
217         char ifrn_name[IFNAMSIZ];       /* Interface name, e.g. "en0".  */
218       } ifr_ifrn;
219
220     union
221       {
222         struct sockaddr_in ifru_addr;
223         char ifru_data[512];
224       } ifr_ifru;
225 };
226
227 struct in_addr *lookup_iface(char *iface) {
228         int mysock;
229         int res;
230         static struct  my_ifreq ifreq;
231         strncpy(ifreq.ifr_ifrn.ifrn_name,iface,sizeof(ifreq.ifr_ifrn.ifrn_name));
232
233         mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
234         res = ioctl(mysock,SIOCGIFADDR,&ifreq);
235         
236         close(mysock);
237         if (res < 0) {
238                 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
239                 return &__ourip;
240         }
241         return( (struct in_addr *) &ifreq.ifr_ifru.ifru_addr.sin_addr );
242 }
243
244 static struct in_addr *myaddrfor(struct in_addr *them)
245 {
246         FILE *PROC;
247         struct in_addr *temp = NULL;
248         unsigned int remote_ip;
249         char line[256];
250         remote_ip = them->s_addr;
251         
252         PROC = fopen("/proc/net/route","r");
253         if (!PROC) {
254                 /* If /proc/net/route doesn't exist, fall back to the old method */
255                 return &__ourip;
256         }
257         /* First line contains headers */
258         fgets(line,sizeof(line),PROC);
259
260         while (!feof(PROC)) {
261                 char iface[8];
262                 unsigned int dest, gateway, mask;
263                 int i,aoffset;
264                 char *fields[40];
265
266                 fgets(line,sizeof(line),PROC);
267
268                 aoffset = 0;
269                 for (i=0;i<sizeof(line);i++) {
270                         char *boffset;
271
272                         fields[aoffset++] = line + i;
273                         boffset = strchr(line + i,'\t');
274                         if (boffset == NULL) {
275                                 /* Exit loop */
276                                 break;
277                         } else {
278                                 *boffset = '\0';
279                                 i = boffset - line;
280                         }
281                 }
282
283                 sscanf(fields[0],"%s",iface);
284                 sscanf(fields[1],"%x",&dest);
285                 sscanf(fields[2],"%x",&gateway);
286                 sscanf(fields[7],"%x",&mask);
287 #if 0
288                 printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
289 #endif          
290                 if (((remote_ip & mask) ^ dest) == 0) {
291
292                         printf("Interface is %s\n",iface);
293                         temp = lookup_iface(iface);
294                         printf("IP Address is %s\n",inet_ntoa(*temp));
295                         break;
296                 }
297         }
298         fclose(PROC);
299         if (!temp) {
300                 ast_log(LOG_WARNING, "Couldn't figure out how to get to %s.  Using default\n", inet_ntoa(*them));
301                 temp = &__ourip;
302         }
303         return temp;
304 }
305
306
307 static int mgcp_hangup(struct ast_channel *ast)
308 {
309         struct mgcp_endpoint *p = ast->pvt->pvt;
310         if (option_debug)
311                 ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name);
312         if (!ast->pvt->pvt) {
313                 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
314                 return 0;
315         }
316         ast_pthread_mutex_lock(&p->lock);
317         p->owner = NULL;
318         if (strlen(p->cxident))
319                 transmit_connection_del(p);
320         if (!p->alreadygone && (!p->outgoing || (ast->_state == AST_STATE_UP)))
321                 transmit_notify_request(p, "ro", 1);
322         else
323                 transmit_notify_request(p, "", 0);
324         ast->pvt->pvt = NULL;
325         p->alreadygone = 0;
326         p->outgoing = 0;
327         strcpy(p->cxident, "");
328         strcpy(p->callid, "");
329         if (p->rtp) {
330                 ast_rtp_destroy(p->rtp);
331                 p->rtp = NULL;
332         }
333         ast_pthread_mutex_unlock(&p->lock);
334         return 0;
335 }
336
337 static int mgcp_show_endpoints(int fd, int argc, char *argv[])
338 {
339         struct mgcp_gateway  *g;
340         struct mgcp_endpoint *e;
341         int hasendpoints = 0;
342         if (argc != 3) 
343                 return RESULT_SHOWUSAGE;
344         ast_pthread_mutex_lock(&gatelock);
345         g = gateways;
346         while(g) {
347                 e = g->endpoints;
348                 ast_cli(fd, "Gateway '%s' at %s\n", g->name, inet_ntoa(g->addr.sin_addr));
349                 while(e) {
350                         ast_cli(fd, "   -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->owner ? "active" : "idle");
351                         hasendpoints = 1;
352                         e = e->next;
353                 }
354                 if (!hasendpoints) {
355                         ast_cli(fd, "   << No Endpoints Defined >>     ");
356                 }
357                 g = g->next;
358         }
359         ast_pthread_mutex_unlock(&gatelock);
360         return RESULT_SUCCESS;
361 }
362
363 static char show_endpoints_usage[] = 
364 "Usage: mgcp show endpoints\n"
365 "       Lists all endpoints known to the MGCP (Media Gateawy Control Protocol) subsystem.\n";
366
367 static struct ast_cli_entry  cli_show_endpoints = 
368         { { "mgcp", "show", "endpoints", NULL }, mgcp_show_endpoints, "Show defined MGCP endpoints", show_endpoints_usage };
369
370 static int mgcp_answer(struct ast_channel *ast)
371 {
372         int res = 0;
373         struct mgcp_endpoint *p = ast->pvt->pvt;
374         if (ast->_state != AST_STATE_UP) {
375                 ast_setstate(ast, AST_STATE_UP);
376                 if (option_debug)
377                         ast_log(LOG_DEBUG, "mgcp_answer(%s)\n", ast->name);
378                 transmit_notify_request(p, "", 1);
379         }
380         return res;
381 }
382
383 static struct ast_frame  *mgcp_read(struct ast_channel *ast)
384 {
385         static struct ast_frame f = { AST_FRAME_NULL, };
386         ast_log(LOG_DEBUG, "I should never get called but am on %s!\n", ast->name);
387         return &f;
388 }
389
390 static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
391 {
392         struct mgcp_endpoint *p = ast->pvt->pvt;
393         int res = 0;
394         if (frame->frametype != AST_FRAME_VOICE) {
395                 if (frame->frametype == AST_FRAME_IMAGE)
396                         return 0;
397                 else {
398                         ast_log(LOG_WARNING, "Can't send %d type frames with MGCP write\n", frame->frametype);
399                         return 0;
400                 }
401         } else {
402                 if (!(frame->subclass & ast->nativeformats)) {
403                         ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
404                                 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
405                         return -1;
406                 }
407         }
408         if (p) {
409                 ast_pthread_mutex_lock(&p->lock);
410                 if (p->rtp) {
411                         res =  ast_rtp_write(p->rtp, frame);
412                 }
413                 ast_pthread_mutex_unlock(&p->lock);
414         }
415         return res;
416 }
417
418 static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
419 {
420         struct mgcp_endpoint *p = newchan->pvt->pvt;
421         ast_pthread_mutex_lock(&p->lock);
422         if (p->owner != oldchan) {
423                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
424                 return -1;
425         }
426         p->owner = newchan;
427         ast_pthread_mutex_unlock(&p->lock);
428         return 0;
429 }
430
431 static int mgcp_senddigit(struct ast_channel *ast, char digit)
432 {
433         struct mgcp_endpoint *p = ast->pvt->pvt;
434         char tmp[2];
435         tmp[0] = digit;
436         tmp[1] = '\0';
437         transmit_notify_request(p, tmp, 1);
438         return -1;
439 }
440
441
442 static int mgcp_indicate(struct ast_channel *ast, int ind)
443 {
444         struct mgcp_endpoint *p = ast->pvt->pvt;
445         switch(ind) {
446         case AST_CONTROL_RINGING:
447                 transmit_notify_request(p, "rt", 1);
448                 break;
449         case AST_CONTROL_BUSY:
450                 transmit_notify_request(p, "bz", 1);
451                 break;
452         case AST_CONTROL_CONGESTION:
453                 transmit_notify_request(p, "nbz", 1);
454                 break;
455         case -1:
456                 transmit_notify_request(p, "", 1);
457                 break;          
458         default:
459                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
460                 return -1;
461         }
462         return 0;
463 }
464
465 static struct ast_channel *mgcp_new(struct mgcp_endpoint *i, int state)
466 {
467         struct ast_channel *tmp;
468         int fmt;
469         tmp = ast_channel_alloc(1);
470         if (tmp) {
471                 tmp->nativeformats = i->capability;
472                 if (!tmp->nativeformats)
473                         tmp->nativeformats = capability;
474                 fmt = ast_best_codec(tmp->nativeformats);
475                 snprintf(tmp->name, sizeof(tmp->name), "MGCP/%s@%s", i->name, i->parent->name);
476                 tmp->type = type;
477                 ast_setstate(tmp, state);
478                 if (state == AST_STATE_RING)
479                         tmp->rings = 1;
480                 tmp->writeformat = fmt;
481                 tmp->pvt->rawwriteformat = fmt;
482                 tmp->readformat = fmt;
483                 tmp->pvt->rawreadformat = fmt;
484                 tmp->pvt->pvt = i;
485                 tmp->pvt->call = mgcp_call;
486                 tmp->pvt->hangup = mgcp_hangup;
487                 tmp->pvt->answer = mgcp_answer;
488                 tmp->pvt->read = mgcp_read;
489                 tmp->pvt->write = mgcp_write;
490                 tmp->pvt->indicate = mgcp_indicate;
491                 tmp->pvt->fixup = mgcp_fixup;
492                 tmp->pvt->send_digit = mgcp_senddigit;
493                 if (strlen(i->language))
494                         strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
495                 i->owner = tmp;
496                 ast_pthread_mutex_lock(&usecnt_lock);
497                 usecnt++;
498                 ast_pthread_mutex_unlock(&usecnt_lock);
499                 ast_update_use_count();
500                 strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
501                 strncpy(tmp->exten, i->exten, sizeof(tmp->exten)-1);
502                 if (strlen(i->callerid))
503                         tmp->callerid = strdup(i->callerid);
504                 tmp->priority = 1;
505                 if (state != AST_STATE_DOWN) {
506                         if (ast_pbx_start(tmp)) {
507                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
508                                 ast_hangup(tmp);
509                                 tmp = NULL;
510                         }
511                 }
512         } else
513                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
514         return tmp;
515 }
516
517 static char *get_sdp(struct mgcp_request *req, char *name)
518 {
519         int x;
520         int len = strlen(name);
521         char *r;
522         for (x=0;x<req->lines;x++) {
523                 if (!strncasecmp(req->line[x], name, len) && 
524                                 (req->line[x][len] == '=')) {
525                                         r = req->line[x] + len + 1;
526                                         while(*r && (*r < 33))
527                                                         r++;
528                                         return r;
529                 }
530         }
531         return "";
532 }
533
534 static char *__get_header(struct mgcp_request *req, char *name, int *start)
535 {
536         int x;
537         int len = strlen(name);
538         char *r;
539         for (x=*start;x<req->headers;x++) {
540                 if (!strncasecmp(req->header[x], name, len) && 
541                                 (req->header[x][len] == ':')) {
542                                         r = req->header[x] + len + 1;
543                                         while(*r && (*r < 33))
544                                                         r++;
545                                         *start = x+1;
546                                         return r;
547                 }
548         }
549         /* Don't return NULL, so get_header is always a valid pointer */
550         return "";
551 }
552
553 static char *get_header(struct mgcp_request *req, char *name)
554 {
555         int start = 0;
556         return __get_header(req, name, &start);
557 }
558
559 static int rtpready(struct ast_rtp *rtp, struct ast_frame *f, void *data)
560 {
561         /* Just deliver the audio directly */
562         struct mgcp_endpoint *p = data;
563         ast_pthread_mutex_lock(&p->lock);
564         if (p->owner) {
565                 /* Generally, you lock in the order channel lock, followed by private
566                    lock.  Since here we are doing the reverse, there is the possibility
567                    of deadlock.  As a result, in the case of a deadlock, we simply fail out
568                    here. */
569                 if (!pthread_mutex_trylock(&p->owner->lock)) {
570                         if (f->frametype == AST_FRAME_VOICE) {
571                                 if (f->subclass != p->owner->nativeformats) {
572                                         ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
573                                         p->owner->nativeformats = f->subclass;
574                                         ast_set_read_format(p->owner, p->owner->readformat);
575                                         ast_set_write_format(p->owner, p->owner->writeformat);
576                                 }
577                         }
578                         ast_queue_frame(p->owner, f, 0);
579                         pthread_mutex_unlock(&p->owner->lock);
580                 }
581         }
582         ast_pthread_mutex_unlock(&p->lock);
583         return 0;
584 }
585
586 static struct mgcp_endpoint *find_endpoint(char *name, int msgid, struct sockaddr_in *sin)
587 {
588         struct mgcp_endpoint *p = NULL;
589         struct mgcp_gateway *g;
590         char tmp[256] = "";
591         char *at = NULL;
592         if (name) {
593                 strncpy(tmp, name, sizeof(tmp) - 1);
594                 at = strchr(tmp, '@');
595                 if (!at) {
596                         ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name);
597                         return NULL;
598                 }
599                 *at = '\0';
600                 at++;
601         }
602         ast_pthread_mutex_lock(&gatelock);
603         g = gateways;
604         while(g) {
605                 if (!name || !strcasecmp(g->name, at)) {
606                         /* Found the gateway -- now for the endpoint */
607                         p = g->endpoints;
608                         while(p) {
609                                 if ((name && !strcasecmp(p->name, tmp)) ||
610                                     (msgid && (p->lastout == msgid)))
611                                         break;
612                                 p = p->next;
613                         }
614                         if (name || p)
615                                 break;
616                 }
617                 g = g->next;
618         }
619         ast_pthread_mutex_unlock(&gatelock);
620         if (!p) {
621                 if (name) {
622                         if (g)
623                                 ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp,at);
624                         else
625                                 ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
626                 } 
627         }
628         return p;
629 }
630
631 static void parse(struct mgcp_request *req)
632 {
633         /* Divide fields by NULL's */
634         char *c;
635         int f = 0;
636         c = req->data;
637
638         /* First header starts immediately */
639         req->header[f] = c;
640         while(*c) {
641                 if (*c == '\n') {
642                         /* We've got a new header */
643                         *c = 0;
644
645 #if 0
646                         printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f]));
647 #endif                  
648                         if (!strlen(req->header[f])) {
649                                 /* Line by itself means we're now in content */
650                                 c++;
651                                 break;
652                         }
653                         if (f >= MGCP_MAX_HEADERS - 1) {
654                                 ast_log(LOG_WARNING, "Too many MGCP headers...\n");
655                         } else
656                                 f++;
657                         req->header[f] = c + 1;
658                 } else if (*c == '\r') {
659                         /* Ignore but eliminate \r's */
660                         *c = 0;
661                 }
662                 c++;
663         }
664         /* Check for last header */
665         if (strlen(req->header[f])) 
666                 f++;
667         req->headers = f;
668         /* Now we process any mime content */
669         f = 0;
670         req->line[f] = c;
671         while(*c) {
672                 if (*c == '\n') {
673                         /* We've got a new line */
674                         *c = 0;
675 #if 0
676                         printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f]));
677 #endif                  
678                         if (f >= MGCP_MAX_LINES - 1) {
679                                 ast_log(LOG_WARNING, "Too many SDP lines...\n");
680                         } else
681                                 f++;
682                         req->line[f] = c + 1;
683                 } else if (*c == '\r') {
684                         /* Ignore and eliminate \r's */
685                         *c = 0;
686                 }
687                 c++;
688         }
689         /* Check for last line */
690         if (strlen(req->line[f])) 
691                 f++;
692         req->lines = f;
693         /* Parse up the initial header */
694         c = req->header[0];
695         while(*c && *c < 33) c++;
696         /* First the verb */
697         req->verb = c;
698         while(*c && (*c > 32)) c++;
699         if (*c) {
700                 *c = '\0';
701                 c++;
702                 while(*c && (*c < 33)) c++;
703                 req->identifier = c;
704                 while(*c && (*c > 32)) c++;
705                 if (*c) {
706                         *c = '\0';
707                         c++;
708                         while(*c && (*c < 33)) c++;
709                         req->endpoint = c;
710                         while(*c && (*c > 32)) c++;
711                         if (*c) {
712                                 *c = '\0';
713                                 c++;
714                                 while(*c && (*c < 33)) c++;
715                                 req->version = c;
716                                 while(*c && (*c > 32)) c++;
717                                 while(*c && (*c < 33)) c++;
718                                 while(*c && (*c > 32)) c++;
719                                 *c = '\0';
720                         }
721                 }
722         }
723                 
724         printf("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
725                 req->verb, req->identifier, req->endpoint, req->version);
726         printf("%d headers, %d lines\n", req->headers, req->lines);
727         if (*c) 
728                 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
729 }
730
731 static int process_sdp(struct mgcp_endpoint *p, struct mgcp_request *req)
732 {
733         char *m;
734         char *c;
735         char host[258];
736         int len;
737         int portno;
738         int peercapability;
739         struct sockaddr_in sin;
740         char *codecs;
741         struct hostent *hp;
742         int codec;
743         /* Get codec and RTP info from SDP */
744         m = get_sdp(req, "m");
745         c = get_sdp(req, "c");
746         if (!strlen(m) || !strlen(c)) {
747                 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
748                 return -1;
749         }
750         if (sscanf(c, "IN IP4 %256s", host) != 1) {
751                 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
752                 return -1;
753         }
754         /* XXX This could block for a long time, and block the main thread! XXX */
755         hp = gethostbyname(host);
756         if (!hp) {
757                 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
758                 return -1;
759         }
760         if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) {
761                 ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m); 
762                 return -1;
763         }
764         sin.sin_family = AF_INET;
765         memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
766         sin.sin_port = htons(portno);
767         if (p->rtp)
768                 ast_rtp_set_peer(p->rtp, &sin);
769 #if 0
770         printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
771 #endif  
772         peercapability = 0;
773         codecs = m + len;
774         while(strlen(codecs)) {
775                 if (sscanf(codecs, "%d %n", &codec, &len) != 1) {
776                         ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
777                         return -1;
778                 }
779 #if 0
780                 printf("Codec: %d\n", codec);
781 #endif          
782                 codec = rtp2ast(codec);
783                 if (codec  > -1)
784                         peercapability |= codec;
785                 codecs += len;
786         }
787         p->capability = capability & peercapability;
788         printf("Capabilities: us - %d, them - %d, combined - %d\n",
789                 capability, peercapability, p->capability);
790         if (!p->capability) {
791                 ast_log(LOG_WARNING, "No compatible codecs!\n");
792                 return -1;
793         }
794         return 0;
795         
796 }
797
798 static int add_header(struct mgcp_request *req, char *var, char *value)
799 {
800         if (req->len >= sizeof(req->data) - 4) {
801                 ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
802                 return -1;
803         }
804         if (req->lines) {
805                 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
806                 return -1;
807         }
808         req->header[req->headers] = req->data + req->len;
809         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
810         req->len += strlen(req->header[req->headers]);
811         if (req->headers < MGCP_MAX_HEADERS)
812                 req->headers++;
813         else {
814                 ast_log(LOG_WARNING, "Out of header space\n");
815                 return -1;
816         }
817         return 0;       
818 }
819
820 static int add_line(struct mgcp_request *req, char *line)
821 {
822         if (req->len >= sizeof(req->data) - 4) {
823                 ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
824                 return -1;
825         }
826         if (!req->lines) {
827                 /* Add extra empty return */
828                 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
829                 req->len += strlen(req->data + req->len);
830         }
831         req->line[req->lines] = req->data + req->len;
832         snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
833         req->len += strlen(req->line[req->lines]);
834         if (req->lines < MGCP_MAX_LINES)
835                 req->lines++;
836         else {
837                 ast_log(LOG_WARNING, "Out of line space\n");
838                 return -1;
839         }
840         return 0;       
841 }
842
843 static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
844 {
845         /* Initialize a response */
846         if (req->headers || req->len) {
847                 ast_log(LOG_WARNING, "Request already initialized?!?\n");
848                 return -1;
849         }
850         req->header[req->headers] = req->data + req->len;
851         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
852         req->len += strlen(req->header[req->headers]);
853         if (req->headers < MGCP_MAX_HEADERS)
854                 req->headers++;
855         else
856                 ast_log(LOG_WARNING, "Out of header space\n");
857         return 0;
858 }
859
860 static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb)
861 {
862         /* Initialize a response */
863         if (req->headers || req->len) {
864                 ast_log(LOG_WARNING, "Request already initialized?!?\n");
865                 return -1;
866         }
867         req->header[req->headers] = req->data + req->len;
868         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);
869         req->len += strlen(req->header[req->headers]);
870         if (req->headers < MGCP_MAX_HEADERS)
871                 req->headers++;
872         else
873                 ast_log(LOG_WARNING, "Out of header space\n");
874         return 0;
875 }
876
877
878 static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
879 {
880         memset(resp, 0, sizeof(*resp));
881         init_resp(resp, msg, req, msgrest);
882         return 0;
883 }
884
885 static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
886 {
887         memset(req, 0, sizeof(struct mgcp_request));
888         oseq++;
889         init_req(p, req, verb);
890         return 0;
891 }
892
893 static int transmit_response(struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
894 {
895         struct mgcp_request resp;
896         respprep(&resp, p, msg, req, msgrest);
897         return send_response(p, &resp);
898 }
899
900
901 static int add_sdp(struct mgcp_request *resp, struct mgcp_endpoint *p, struct ast_rtp *rtp)
902 {
903         int len;
904         int codec;
905         char costr[80];
906         struct sockaddr_in sin;
907         char v[256];
908         char s[256];
909         char o[256];
910         char c[256];
911         char t[256];
912         char m[256];
913         char a[1024] = "";
914         int x;
915         struct sockaddr_in dest;
916         /* XXX We break with the "recommendation" and send our IP, in order that our
917                peer doesn't have to gethostbyname() us XXX */
918         len = 0;
919         if (!p->rtp) {
920                 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
921                 return -1;
922         }
923         ast_rtp_get_us(p->rtp, &sin);
924         if (rtp) {
925                 ast_rtp_get_peer(rtp, &dest);
926         } else {
927                 dest.sin_addr = p->parent->ourip;
928                 dest.sin_port = sin.sin_port;
929         }
930         printf("We're at %s port %d\n", inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));      
931         snprintf(v, sizeof(v), "v=0\r\n");
932         snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), inet_ntoa(dest.sin_addr));
933         snprintf(s, sizeof(s), "s=session\r\n");
934         snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", inet_ntoa(dest.sin_addr));
935         snprintf(t, sizeof(t), "t=0 0\r\n");
936         snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
937         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
938                 if (p->capability & x) {
939                         printf("Answering with capability %d\n", x);
940                         if ((codec = ast2rtp(x)) > -1) {
941                                 snprintf(costr, sizeof(costr), " %d", codec);
942                                 strcat(m, costr);
943                                 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast2rtpn(x));
944                                 strcat(a, costr);
945                         }
946                 }
947         }
948         strcat(m, "\r\n");
949         len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
950         snprintf(costr, sizeof(costr), "%d", len);
951         add_line(resp, v);
952         add_line(resp, o);
953         add_line(resp, s);
954         add_line(resp, c);
955         add_line(resp, t);
956         add_line(resp, m);
957         add_line(resp, a);
958         return 0;
959 }
960
961 static int transmit_modify_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp)
962 {
963         struct mgcp_request resp;
964         char local[256];
965         char tmp[80];
966         int x;
967         snprintf(local, sizeof(local), "p:20");
968         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
969                 if (p->capability & x) {
970                         snprintf(tmp, sizeof(tmp), ", a:%s", ast2rtpn(x));
971                         strcat(local, tmp);
972                 }
973         }
974         reqprep(&resp, p, "MDCX");
975         add_header(&resp, "C", p->callid);
976         add_header(&resp, "L", local);
977         add_header(&resp, "M", "sendrecv");
978         add_header(&resp, "X", p->txident);
979         add_header(&resp, "S", "");
980         add_sdp(&resp, p, rtp);
981         p->lastout = oseq;
982         return send_request(p, &resp);
983 }
984
985 static int transmit_connect_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp)
986 {
987         struct mgcp_request resp;
988         char local[256];
989         char tmp[80];
990         int x;
991         snprintf(local, sizeof(local), "p:20");
992         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
993                 if (p->capability & x) {
994                         snprintf(tmp, sizeof(tmp), ", a:%s", ast2rtpn(x));
995                         strcat(local, tmp);
996                 }
997         }
998         reqprep(&resp, p, "CRCX");
999         add_header(&resp, "C", p->callid);
1000         add_header(&resp, "L", local);
1001         add_header(&resp, "M", "sendrecv");
1002         add_header(&resp, "X", p->txident);
1003         add_header(&resp, "S", "");
1004         add_sdp(&resp, p, rtp);
1005         p->lastout = oseq;
1006         return send_request(p, &resp);
1007 }
1008
1009 static int transmit_notify_request(struct mgcp_endpoint *p, char *tone, int offhook)
1010 {
1011         struct mgcp_request resp;
1012         strncpy(p->curtone, tone, sizeof(p->curtone) - 1);
1013         reqprep(&resp, p, "RQNT");
1014         add_header(&resp, "X", p->txident);
1015         if (offhook)
1016                 add_header(&resp, "R", "hu(N), hf(N), D/[0-9#*](N)");
1017         else
1018                 add_header(&resp, "R", "hd(N)");
1019         add_header(&resp, "S", tone);
1020         return send_request(p, &resp);
1021 }
1022
1023 static int transmit_notify_request_with_callerid(struct mgcp_endpoint *p, char *tone, int offhook, char *callerid)
1024 {
1025         struct mgcp_request resp;
1026         char cid[256];
1027         char tone2[256];
1028         char *l, *n;
1029         time_t t;
1030         struct tm *tm;
1031         
1032         time(&t);
1033         tm = localtime(&t);
1034         if (callerid)
1035                 strncpy(cid, callerid, sizeof(cid) - 1);
1036         else
1037                 strcpy(cid, "");
1038         ast_callerid_parse(cid, &n, &l);
1039         if (l) {
1040                 ast_shrink_phone_number(l);
1041                 if (!ast_isphonenumber(l)) {
1042                         n = l;
1043                         l = "";
1044                 }
1045         } 
1046         if (!n)
1047                 n = "O";
1048         if (!l)
1049                 l = "";
1050         snprintf(tone2, sizeof(tone2), "%s, ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 
1051                         tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, l, n);
1052         strncpy(p->curtone, tone, sizeof(p->curtone) - 1);
1053         reqprep(&resp, p, "RQNT");
1054         add_header(&resp, "X", p->txident);
1055         if (offhook)
1056                 add_header(&resp, "R", "hu(N), hf(N), D/[0-9#*](N)");
1057         else
1058                 add_header(&resp, "R", "hd(N)");
1059         add_header(&resp, "S", tone2);
1060         return send_request(p, &resp);
1061 }
1062 static int transmit_connection_del(struct mgcp_endpoint *p)
1063 {
1064         struct mgcp_request resp;
1065         reqprep(&resp, p, "DLCX");
1066         add_header(&resp, "C", p->callid);
1067         add_header(&resp, "I", p->cxident);
1068         return send_request(p, &resp);
1069 }
1070
1071 static void handle_response(struct mgcp_endpoint *p, int result, int ident)
1072 {
1073         if ((result >= 400) && (result <= 499)) {
1074                 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s\n", result, p->name, p->parent->name);
1075                 if (p->owner)
1076                         ast_softhangup(p->owner, AST_SOFTHANGUP_DEV);
1077         }
1078 }
1079
1080 static void start_rtp(struct mgcp_endpoint *p)
1081 {
1082                 ast_pthread_mutex_lock(&p->lock);
1083                 /* Allocate the RTP now */
1084                 p->rtp = ast_rtp_new(sched, io);
1085                 ast_rtp_set_callback(p->rtp, rtpready);
1086                 ast_rtp_set_data(p->rtp, p);
1087                 /* Make a call*ID */
1088                 snprintf(p->callid, sizeof(p->callid), "%08x%s", rand(), p->txident);
1089                 /* Transmit the connection create */
1090                 transmit_connect_with_sdp(p, NULL);
1091                 ast_pthread_mutex_unlock(&p->lock);
1092 }
1093
1094 static void *mgcp_ss(void *data)
1095 {
1096         struct ast_channel *chan = data;
1097         struct mgcp_endpoint *p = chan->pvt->pvt;
1098         char exten[AST_MAX_EXTENSION] = "";
1099         int pos = 0;
1100         int to = 16000;
1101         int res;
1102         for (;;) {
1103                 res = ast_waitfordigit(chan, to);
1104                 if (!res) {
1105                         ast_log(LOG_DEBUG, "Timeout...\n");
1106                         break;
1107                 }
1108                 if (res < 0) {
1109                         ast_log(LOG_DEBUG, "Got hangup...\n");
1110                         break;
1111                 }
1112                 exten[pos++] = res;
1113                 if (!ast_ignore_pattern(chan->context, exten))
1114                         ast_indicate(chan, -1);
1115                 if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
1116                         if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) 
1117                                 to = 3000;
1118                         else
1119                                 to = 8000;
1120                 } else
1121                         break;
1122         }
1123         if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
1124                 strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
1125                 start_rtp(p);
1126                 ast_setstate(chan, AST_STATE_RING);
1127                 chan->rings = 1;
1128                 if (ast_pbx_run(chan)) {
1129                         ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
1130                 } else
1131                         return NULL;
1132         }
1133         ast_hangup(chan);
1134         return NULL;
1135 }
1136
1137 static int handle_request(struct mgcp_endpoint *p, struct mgcp_request *req, struct sockaddr_in *sin)
1138 {
1139         char *ev, *s;
1140         struct ast_channel *c;
1141         pthread_t t;
1142         struct ast_frame f = { 0, };
1143         printf("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
1144         /* Clear out potential response */
1145         if (!strcasecmp(req->verb, "RSIP")) {
1146                 if (option_verbose > 2)
1147                         ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name);
1148                 if (p->owner)
1149                         ast_softhangup(p->owner, AST_SOFTHANGUP_DEV);
1150                 transmit_response(p, "200", req, "OK");
1151         } else if (!strcasecmp(req->verb, "NTFY")) {
1152                 /* Acknowledge and be sure we keep looking for the same things */
1153                 transmit_response(p, "200", req, "OK");
1154                 /* Notified of an event */
1155                 ev = get_header(req, "O");
1156                 s = strchr(ev, '/');
1157                 if (s) ev = s + 1;
1158                 ast_log(LOG_DEBUG, "Endpoint '%s@%s' observed '%s'\n", p->name, p->parent->name, ev);
1159                 /* Keep looking for events unless this was a hangup */
1160                 if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd"))
1161                         transmit_notify_request(p, p->curtone, 1);
1162                 if (!strcasecmp(ev, "hd")) {
1163                         /* Off hook / answer */
1164                         if (p->outgoing) {
1165                                 /* Answered */
1166                                 if (p->owner) {
1167                                         start_rtp(p);
1168                                         ast_queue_control(p->owner, AST_CONTROL_ANSWER, 1);
1169                                 }
1170                         } else {
1171                                 /* Start switch */
1172                                 if (!p->owner) {
1173                                         transmit_notify_request(p, "dl", 1);
1174                                         c = mgcp_new(p, AST_STATE_DOWN);
1175                                         if (c) {
1176                                                 if (pthread_create(&t, NULL, mgcp_ss, c)) {
1177                                                         ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
1178                                                         ast_hangup(c);
1179                                                 }
1180                                         } else
1181                                                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
1182                                 } else {
1183                                         ast_log(LOG_WARNING, "Off hook, but alreaedy have owner on %s@%s\n", p->name, p->parent->name);
1184                                 }
1185                         }
1186                 } else if (!strcasecmp(ev, "hu")) {
1187                         ast_log(LOG_DEBUG, "Went on hook\n");
1188                         if (p->owner) {
1189                                 p->alreadygone = 1;
1190                                 ast_queue_hangup(p->owner, 1);
1191                         }
1192                 } else if ((strlen(ev) == 1) && 
1193                                         (((ev[0] >= '0') && (ev[0] <= '9')) ||
1194                                          ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
1195                                          (ev[0] == '*') || (ev[0] == '#'))) {
1196                         f.frametype = AST_FRAME_DTMF;
1197                         f.subclass = ev[0];
1198                         f.src = "mgcp";
1199                         if (p->owner)
1200                                 ast_queue_frame(p->owner, &f, 1);
1201                 } else if (!strcasecmp(ev, "T")) {
1202                         /* Digit timeout -- unimportant */
1203                 } else {
1204                         ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
1205                 }
1206         } else {
1207                 ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, inet_ntoa(sin->sin_addr));
1208                 transmit_response(p, "510", req, "Unknown verb");
1209         }
1210         return 0;
1211 }
1212
1213 static int mgcpsock_read(int *id, int fd, short events, void *ignore)
1214 {
1215         struct mgcp_request req;
1216         struct sockaddr_in sin;
1217         struct mgcp_endpoint *p;
1218         char *c;
1219         int res;
1220         int len;
1221         int result;
1222         int ident;
1223         len = sizeof(sin);
1224         memset(&req, 0, sizeof(req));
1225         res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
1226         if (res < 0) {
1227                 if (errno != ECONNREFUSED)
1228                         ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
1229                 return 1;
1230         }
1231         req.data[res] = '\0';
1232         req.len = res;
1233         printf("MGCP read: \n%s\n", req.data);
1234         parse(&req);
1235         if (req.headers < 1) {
1236                 /* Must have at least one header */
1237                 return 1;
1238         }
1239         if (!req.identifier || !strlen(req.identifier)) {
1240                 ast_log(LOG_NOTICE, "Message from %s missing identifier\n", inet_ntoa(sin.sin_addr));
1241                 return 1;
1242         }
1243
1244         if (sscanf(req.verb, "%d", &result) &&
1245                 sscanf(req.identifier, "%d", &ident)) {
1246                 /* Try to find who this message is for, if it's important */
1247                 p = find_endpoint(NULL, ident, &sin);
1248                 if (p) {
1249                         handle_response(p, result, ident);
1250                         if ((c = get_header(&req, "I")))
1251                                 strncpy(p->cxident, c, sizeof(p->cxident) - 1);
1252                         if (req.lines)
1253                                 process_sdp(p, &req);
1254                 }
1255         } else {
1256                 if (!req.endpoint || !strlen(req.endpoint) || 
1257                     !req.version || !strlen(req.version) || 
1258                         !req.verb || !strlen(req.verb)) {
1259                         ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
1260                         return 1;
1261                 }
1262                 /* Process request, with iflock held */
1263                 p = find_endpoint(req.endpoint, 0, &sin);
1264                 if (p) {
1265                         handle_request(p, &req, &sin);
1266                 }
1267         }
1268         return 1;
1269 }
1270
1271 static void *do_monitor(void *data)
1272 {
1273         int res;
1274         struct mgcp_pkt *p;
1275         sched = sched_context_create();
1276         if (!sched) {
1277                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
1278                 return NULL;
1279         }
1280         io = io_context_create();
1281         if (!io) {
1282                 ast_log(LOG_WARNING, "Unable to create I/O context\n");
1283                 return NULL;
1284         }
1285         
1286         /* Add an I/O event to our UDP socket */
1287         if (mgcpsock > -1) 
1288                 ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL);
1289         
1290         /* This thread monitors all the frame relay interfaces which are not yet in use
1291            (and thus do not have a separate thread) indefinitely */
1292         /* From here on out, we die whenever asked */
1293         for(;;) {
1294                 /* Check for interfaces needing to be killed */
1295                 /* Don't let anybody kill us right away.  Nobody should lock the interface list
1296                    and wait for the monitor list, but the other way around is okay. */
1297                 ast_pthread_mutex_lock(&monlock);
1298                 /* Lock the network interface */
1299                 ast_pthread_mutex_lock(&netlock);
1300                 p = packets;
1301                 while(p) {
1302                         /* Handle any retransmissions */
1303                         p = p->next;
1304                 }
1305                 /* Okay, now that we know what to do, release the network lock */
1306                 ast_pthread_mutex_unlock(&netlock);
1307                 /* And from now on, we're okay to be killed, so release the monitor lock as well */
1308                 ast_pthread_mutex_unlock(&monlock);
1309                 pthread_testcancel();
1310                 /* Wait for sched or io */
1311                 res = ast_sched_wait(sched);
1312                 res = ast_io_wait(io, res);
1313                 ast_pthread_mutex_lock(&monlock);
1314                 if (res >= 0) 
1315                         ast_sched_runq(sched);
1316                 ast_pthread_mutex_unlock(&monlock);
1317         }
1318         /* Never reached */
1319         return NULL;
1320         
1321 }
1322
1323 static int restart_monitor(void)
1324 {
1325         /* If we're supposed to be stopped -- stay stopped */
1326         if (monitor_thread == -2)
1327                 return 0;
1328         if (ast_pthread_mutex_lock(&monlock)) {
1329                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
1330                 return -1;
1331         }
1332         if (monitor_thread == pthread_self()) {
1333                 ast_pthread_mutex_unlock(&monlock);
1334                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1335                 return -1;
1336         }
1337         if (monitor_thread) {
1338                 /* Wake up the thread */
1339                 pthread_kill(monitor_thread, SIGURG);
1340         } else {
1341                 /* Start a new monitor */
1342                 if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
1343                         ast_pthread_mutex_unlock(&monlock);
1344                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1345                         return -1;
1346                 }
1347         }
1348         ast_pthread_mutex_unlock(&monlock);
1349         return 0;
1350 }
1351
1352 static struct ast_channel *mgcp_request(char *type, int format, void *data)
1353 {
1354         int oldformat;
1355         struct mgcp_endpoint *p;
1356         struct ast_channel *tmpc = NULL;
1357         char tmp[256];
1358         char *dest = data;
1359
1360         oldformat = format;
1361         format &= capability;
1362         if (!format) {
1363                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
1364                 return NULL;
1365         }
1366         strncpy(tmp, dest, sizeof(tmp) - 1);
1367         if (!strlen(tmp)) {
1368                 ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n");
1369                 return NULL;
1370         }
1371         p = find_endpoint(tmp, 0, NULL);
1372         if (!p) {
1373                 ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
1374                 return NULL;
1375         }
1376         /* Must be busy */
1377         if (p->owner)
1378                 return NULL;
1379         tmpc = mgcp_new(p, AST_STATE_DOWN);
1380         if (!tmpc)
1381                 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
1382         restart_monitor();
1383         return tmpc;
1384 }
1385
1386 struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
1387 {
1388         struct mgcp_gateway *gw;
1389         struct mgcp_endpoint *e;
1390         char context[AST_MAX_EXTENSION] = "default";
1391         char language[80] = "";
1392         char callerid[AST_MAX_EXTENSION] = "";
1393
1394         gw = malloc(sizeof(struct mgcp_gateway));
1395         if (gw) {
1396                 memset(gw, 0, sizeof(struct mgcp_gateway));
1397                 strncpy(gw->name, cat, sizeof(gw->name) - 1);
1398                 while(v) {
1399                         if (!strcasecmp(v->name, "host")) {
1400                                 if (ast_get_ip(&gw->addr, v->value)) {
1401                                         free(gw);
1402                                         return NULL;
1403                                 }
1404                         } else if (!strcasecmp(v->name, "permit") ||
1405                                            !strcasecmp(v->name, "deny")) {
1406                                 gw->ha = ast_append_ha(v->name, v->value, gw->ha);
1407                         } else if (!strcasecmp(v->name, "port")) {
1408                                 gw->addr.sin_port = htons(atoi(v->value));
1409                         } else if (!strcasecmp(v->name, "context")) {
1410                                 strncpy(context, v->value, sizeof(context) - 1);
1411                         } else if (!strcasecmp(v->name, "callerid")) {
1412                                 if (!strcasecmp(v->value, "asreceived"))
1413                                         strcpy(callerid, "");
1414                                 else
1415                                         strncpy(callerid, v->value, sizeof(callerid) - 1);
1416                         } else if (!strcasecmp(v->name, "language")) {
1417                                 strncpy(language, v->value, sizeof(language)-1);
1418                         } else if (!strcasecmp(v->name, "trunk") ||
1419                                    !strcasecmp(v->name, "line")) {
1420                                 e = malloc(sizeof(struct mgcp_endpoint));
1421                                 if (e) {
1422                                         memset(e, 0, sizeof(struct mgcp_endpoint));
1423                                         /* XXX Should we really check for uniqueness?? XXX */
1424                                         snprintf(e->txident, sizeof(e->txident), "%08x", rand());
1425                                         strncpy(e->context, context, sizeof(e->context) - 1);
1426                                         strncpy(e->callerid, callerid, sizeof(e->callerid) - 1);
1427                                         strncpy(e->language, language, sizeof(e->language) - 1);
1428                                         e->capability = capability;
1429                                         e->parent = gw;
1430                                         strncpy(e->name, v->value, sizeof(e->name) - 1);
1431                                         if (!strcasecmp(v->name, "trunk"))
1432                                                 e->type = TYPE_TRUNK;
1433                                         else
1434                                                 e->type = TYPE_LINE;
1435                                         e->next = gw->endpoints;
1436                                         gw->endpoints = e;
1437                                 }
1438                         } else
1439                                 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
1440                         v = v->next;
1441                 }
1442                 
1443         }
1444         if (!ntohl(gw->addr.sin_addr.s_addr)) {
1445                 ast_log(LOG_WARNING, "Gateway '%s' lacks IP address\n", gw->name);
1446                 free(gw);
1447                 gw = NULL;
1448         } else if (!ntohs(gw->addr.sin_port)) {
1449                 gw->addr.sin_port = htons(DEFAULT_MGCP_PORT);
1450                 memcpy(&gw->ourip, myaddrfor(&gw->addr.sin_addr), sizeof(gw->ourip));
1451         }
1452         return gw;
1453 }
1454
1455 int load_module()
1456 {
1457         struct ast_config *cfg;
1458         struct ast_variable *v;
1459         struct mgcp_gateway *g;
1460         char *cat;
1461         struct hostent *hp;
1462         int format;
1463         
1464         if (gethostname(ourhost, sizeof(ourhost))) {
1465                 ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n");
1466                 return 0;
1467         }
1468         cfg = ast_load(config);
1469
1470         /* We *must* have a config file otherwise stop immediately */
1471         if (!cfg) {
1472                 ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config);
1473                 return 0;
1474         }
1475         memset(&bindaddr, 0, sizeof(bindaddr));
1476         v = ast_variable_browse(cfg, "general");
1477         while(v) {
1478                 /* Create the interface list */
1479                 if (!strcasecmp(v->name, "bindaddr")) {
1480                         if (!(hp = gethostbyname(v->value))) {
1481                                 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
1482                         } else {
1483                                 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
1484                         }
1485                 } else if (!strcasecmp(v->name, "allow")) {
1486                         format = ast_getformatbyname(v->value);
1487                         if (format < 1) 
1488                                 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
1489                         else
1490                                 capability |= format;
1491                 } else if (!strcasecmp(v->name, "disallow")) {
1492                         format = ast_getformatbyname(v->value);
1493                         if (format < 1) 
1494                                 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
1495                         else
1496                                 capability &= ~format;
1497                 } else if (!strcasecmp(v->name, "port")) {
1498                         if (sscanf(v->value, "%i", &ourport) == 1) {
1499                                 bindaddr.sin_port = htons(ourport);
1500                         } else {
1501                                 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
1502                         }
1503                 }
1504                 v = v->next;
1505         }
1506         
1507         cat = ast_category_browse(cfg, NULL);
1508         while(cat) {
1509                 if (strcasecmp(cat, "general")) {
1510                         g = build_gateway(cat, ast_variable_browse(cfg, cat));
1511                         if (g) {
1512                                 if (option_verbose > 2)
1513                                         ast_verbose(VERBOSE_PREFIX_3 "Added gateway '%s'\n", g->name);
1514                                 ast_pthread_mutex_lock(&gatelock);
1515                                 g->next = gateways;
1516                                 gateways = g;
1517                                 ast_pthread_mutex_unlock(&gatelock);
1518                         }
1519                 }
1520                 cat = ast_category_browse(cfg, cat);
1521         }
1522         
1523         if (ntohl(bindaddr.sin_addr.s_addr)) {
1524                 memcpy(&__ourip, &bindaddr, sizeof(__ourip));
1525         } else {
1526                 hp = gethostbyname(ourhost);
1527                 if (!hp) {
1528                         ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n");
1529                         return 0;
1530                 }
1531                 memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
1532         }
1533         if (!ntohs(bindaddr.sin_port))
1534                 bindaddr.sin_port = ntohs(DEFAULT_MGCP_PORT);
1535         bindaddr.sin_family = AF_INET;
1536         pthread_mutex_lock(&netlock);
1537         if (mgcpsock > -1)
1538                 close(mgcpsock);
1539         mgcpsock = socket(AF_INET, SOCK_DGRAM, 0);
1540         if (mgcpsock < 0) {
1541                 ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno));
1542         } else {
1543                 if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
1544                         ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
1545                                         inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
1546                                                 strerror(errno));
1547                         close(mgcpsock);
1548                         mgcpsock = -1;
1549                 } else if (option_verbose > 1)
1550                         ast_verbose(VERBOSE_PREFIX_2 "MGCP Listening on %s:%d\n", 
1551                                 inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
1552         }
1553         pthread_mutex_unlock(&netlock);
1554         ast_destroy(cfg);
1555
1556         /* Make sure we can register our mgcp channel type */
1557         if (ast_channel_register(type, tdesc, capability, mgcp_request)) {
1558                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
1559                 ast_destroy(cfg);
1560                 return -1;
1561         }
1562         ast_cli_register(&cli_show_endpoints);
1563         /* And start the monitor for the first time */
1564         restart_monitor();
1565         return 0;
1566 }
1567
1568 int unload_module()
1569 {
1570         struct mgcp_endpoint *p, *pl;
1571 #if 0
1572         /* First, take us out of the channel loop */
1573         ast_channel_unregister(type);
1574         if (!ast_pthread_mutex_lock(&gatelock)) {
1575                 /* Hangup all interfaces if they have an owner */
1576                 p = iflist;
1577                 while(p) {
1578                         if (p->owner)
1579                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
1580                         p = p->next;
1581                 }
1582                 iflist = NULL;
1583                 ast_pthread_mutex_unlock(&iflock);
1584         } else {
1585                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1586                 return -1;
1587         }
1588         if (!ast_pthread_mutex_lock(&monlock)) {
1589                 if (monitor_thread) {
1590                         pthread_cancel(monitor_thread);
1591                         pthread_kill(monitor_thread, SIGURG);
1592                         pthread_join(monitor_thread, NULL);
1593                 }
1594                 monitor_thread = -2;
1595                 ast_pthread_mutex_unlock(&monlock);
1596         } else {
1597                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1598                 return -1;
1599         }
1600
1601         if (!ast_pthread_mutex_lock(&iflock)) {
1602                 /* Destroy all the interfaces and free their memory */
1603                 p = iflist;
1604                 while(p) {
1605                         pl = p;
1606                         p = p->next;
1607                         /* Free associated memory */
1608                         free(pl);
1609                 }
1610                 iflist = NULL;
1611                 ast_pthread_mutex_unlock(&iflock);
1612         } else {
1613                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1614                 return -1;
1615         }
1616 #endif          
1617         return -1;
1618 }
1619
1620 int usecount()
1621 {
1622         int res;
1623         ast_pthread_mutex_lock(&usecnt_lock);
1624         res = usecnt;
1625         ast_pthread_mutex_unlock(&usecnt_lock);
1626         return res;
1627 }
1628
1629 char *key()
1630 {
1631         return ASTERISK_GPL_KEY;
1632 }
1633
1634 char *description()
1635 {
1636         return desc;
1637 }
1638