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