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