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