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