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