Fix deadlock in IAX2 trunking, small MGCP fix
[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 /* JS: Changes
15    -- add support for the wildcard endpoint
16    -- seteable wildcard with wcardep on mgcp.conf
17    -- added package indicator on RQNT, i.e "dl" --> "L/dl"
18    -- removed MDCX just before DLCX, do we need this ?
19 */
20
21 /* JS: TODO
22    -- reload for wildcard endpoint probably buggy
23    -- when hf is notified we're sending CRCX after MDCX, without waiting for
24       OK on the MDCX which fails on Cisco IAD 24XX
25    -- honour codec order, by now the lowest codec number in "allow" is the prefered
26 */
27
28 /* SC: Changes
29    -- packet retransmit mechanism (simplistic)
30    -- per endpoint/subchannel mgcp command sequencing. 
31    -- better transaction handling
32    -- fixed some mem leaks
33    -- run-time configuration reload 
34    -- distinguish CA and GW default MGCP ports
35    -- prevent clipping of DTMF tones in an established call
36    -- fixed a few crash scenarios in 3-way
37    -- fix for a few cases where asterisk and MGW end-up in conflicting ep states 
38    -- enclose numeric IP in [] for outgoing requests
39 */
40
41 /* SC: TODO
42    -- piggyback support
43    -- responseAck support
44    -- enhance retransmit mechanism (RTO calc. etc.)
45    -- embedded command support
46 */
47 /* FS: Changes
48  * -- fixed reload_config() / do_monitor to stay responsive during reloads
49  */
50
51 #include <stdio.h>
52 #include <pthread.h>
53 #include <string.h>
54 #include <asterisk/lock.h>
55 #include <asterisk/channel.h>
56 #include <asterisk/channel_pvt.h>
57 #include <asterisk/config.h>
58 #include <asterisk/logger.h>
59 #include <asterisk/module.h>
60 #include <asterisk/pbx.h>
61 #include <asterisk/options.h>
62 #include <asterisk/lock.h>
63 #include <asterisk/sched.h>
64 #include <asterisk/io.h>
65 #include <asterisk/rtp.h>
66 #include <asterisk/acl.h>
67 #include <asterisk/callerid.h>
68 #include <asterisk/cli.h>
69 #include <asterisk/say.h>
70 #include <asterisk/cdr.h>
71 #include <asterisk/astdb.h>
72 #include <asterisk/parking.h>
73 #include <asterisk/app.h>
74 #include <asterisk/musiconhold.h>
75 #include <sys/socket.h>
76 #include <sys/ioctl.h>
77 #include <net/if.h>
78 #include <errno.h>
79 #include <unistd.h>
80 #include <stdlib.h>
81 #include <fcntl.h>
82 #include <netdb.h>
83 #include <arpa/inet.h>
84 #include <sys/signal.h>
85 #include <signal.h>
86 #include <pthread.h>
87 #include <netinet/in_systm.h>
88 #include <netinet/ip.h>
89
90 #include <asterisk/dsp.h>
91 #include <ctype.h>
92
93 #ifndef IPTOS_MINCOST
94 #define IPTOS_MINCOST 0x02
95 #endif
96
97 #define MGCPDUMPER
98 #define DEFAULT_EXPIREY 120
99 #define MAX_EXPIREY     3600
100 #define CANREINVITE     1
101
102 static char *desc = "Media Gateway Control Protocol (MGCP)";
103 static char *type = "MGCP";
104 static char *tdesc = "Media Gateway Control Protocol (MGCP)";
105 static char *config = "mgcp.conf";
106
107 #define DEFAULT_MGCP_GW_PORT    2427/* From RFC 2705 */
108 #define DEFAULT_MGCP_CA_PORT    2727/* From RFC 2705 */
109 #define MGCP_MAX_PACKET 1500            /* Also from RFC 2543, should sub headers tho */
110 #define DEFAULT_RETRANS         1000   /* How frequently to retransmit */
111 #define MAX_RETRANS             5   /* Try only 5 times for retransmissions */
112
113 /* MGCP rtp stream modes */
114 #define MGCP_CX_SENDONLY 0
115 #define MGCP_CX_RECVONLY 1
116 #define MGCP_CX_SENDRECV 2
117 #define MGCP_CX_CONF     3
118 #define MGCP_CX_CONFERENCE 3
119 #define MGCP_CX_MUTE     4
120 #define MGCP_CX_INACTIVE 4
121
122 static char *mgcp_cxmodes[] = {
123     "sendonly",
124     "recvonly",
125     "sendrecv",
126     "confrnce",
127     "inactive"
128 };
129
130 /* SC: MGCP commands */
131 #define MGCP_CMD_EPCF 0
132 #define MGCP_CMD_CRCX 1
133 #define MGCP_CMD_MDCX 2
134 #define MGCP_CMD_DLCX 3
135 #define MGCP_CMD_RQNT 4
136 #define MGCP_CMD_NTFY 5
137 #define MGCP_CMD_AUEP 6
138 #define MGCP_CMD_AUCX 7
139 #define MGCP_CMD_RSIP 8
140
141 static char context[AST_MAX_EXTENSION] = "default";
142
143 static char language[MAX_LANGUAGE] = "";
144 static char musicclass[MAX_LANGUAGE] = "";
145 static char callerid[AST_MAX_EXTENSION] = "";
146
147 static int inbanddtmf = 0;
148 static int nat = 0;
149
150 /* Not used. Dosn't hurt for us to always send cid  */
151 /* to the mgcp box. */
152 /* static int use_callerid = 1;*/
153 /*static int cur_signalling = -1;*/
154
155 /*static unsigned int cur_group = 0;*/
156 static unsigned int cur_callergroup = 0;
157 static unsigned int cur_pickupgroup = 0;
158
159 /* XXX Is this needed? */
160 /*     Doesn't look like the dsp stuff for */
161 /*     inbanddtmf is actually hooked up.   */
162 /* static int relaxdtmf = 0; */
163
164 static int tos = 0;
165
166 static int immediate = 0;
167
168 static int callwaiting = 0;
169
170 /* Not used. Dosn't hurt for us to always send cid  */
171 /* to the mgcp box. */
172 /*static int callwaitingcallerid = 0;*/
173
174 /*static int hidecallerid = 0;*/
175
176 static int callreturn = 0;
177
178 static int threewaycalling = 0;
179
180 /* This is for flashhook transfers */
181 static int transfer = 0;
182
183 static int cancallforward = 0;
184
185 static int canreinvite = CANREINVITE;
186
187 /*static int busycount = 3;*/
188
189 /*static int callprogress = 0;*/
190
191 static char accountcode[20] = "";
192
193 static char mailbox[AST_MAX_EXTENSION];
194
195 static int amaflags = 0;
196
197 static int adsi = 0;
198
199
200 static int usecnt =0;
201 static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
202 /* SC: transaction id should always be positive */
203 static unsigned int oseq;
204
205 /* Wait up to 16 seconds for first digit (FXO logic) */
206 static int firstdigittimeout = 16000;
207
208 /* How long to wait for following digits (FXO logic) */
209 static int gendigittimeout = 8000;
210
211 /* How long to wait for an extra digit, if there is an ambiguous match */
212 static int matchdigittimeout = 3000;
213
214 /* Protect the monitoring thread, so only one process can kill or start it, and not
215    when it's doing something critical. */
216 static ast_mutex_t netlock = AST_MUTEX_INITIALIZER;
217
218 static ast_mutex_t monlock = AST_MUTEX_INITIALIZER;
219
220 /* This is the thread for the monitor which checks for input on the channels
221    which are not currently in use.  */
222 static pthread_t monitor_thread = AST_PTHREADT_NULL;
223
224 static int restart_monitor(void);
225
226 /* Just about everybody seems to support ulaw, so make it a nice default */
227 static int capability = AST_FORMAT_ULAW;
228 static int nonCodecCapability = AST_RTP_DTMF;
229
230 static char ourhost[256];
231 static struct in_addr __ourip;
232 static int ourport;
233
234 static int mgcpdebug = 0;
235
236 static struct sched_context *sched;
237 static struct io_context *io;
238 /* The private structures of the  mgcp channels are linked for
239    selecting outgoing channels */
240    
241 #define MGCP_MAX_HEADERS                64
242 #define MGCP_MAX_LINES          64
243
244 struct mgcp_request {
245         int len;
246         char *verb;
247         char *identifier;
248         char *endpoint;
249         char *version;
250         int headers;                                    /* MGCP Headers */
251         char *header[MGCP_MAX_HEADERS];
252         int lines;                                              /* SDP Content */
253         char *line[MGCP_MAX_LINES];
254         char data[MGCP_MAX_PACKET];
255     int cmd;                        /* SC: int version of verb = command */
256     unsigned int trid;              /* SC: int version of identifier = transaction id */
257     struct mgcp_request *next;      /* SC: next in the queue */
258 };
259
260 /* SC: obsolete
261 static struct mgcp_pkt {
262         int retrans;
263         struct mgcp_endpoint *owner;
264         int packetlen;
265         char data[MGCP_MAX_PACKET];
266         struct mgcp_pkt *next;
267 } *packets = NULL;      
268 */
269
270 /* MGCP message for queuing up */
271 struct mgcp_message {
272     struct mgcp_endpoint *owner_ep;
273     struct mgcp_subchannel *owner_sub;
274     int retrans;
275     unsigned long expire;
276         unsigned int seqno;
277         int len;
278         struct mgcp_message *next;
279         unsigned char buf[0];
280 };
281
282 #define MAX_SUBS 2
283
284 #define SUB_REAL 0
285 #define SUB_ALT  1
286
287 struct mgcp_subchannel {
288     /* SC: subchannel magic string. 
289        Needed to prove that any subchannel pointer passed by asterisk 
290        really points to a valid subchannel memory area.
291        Ugly.. But serves the purpose for the time being.
292      */
293 #define MGCP_SUBCHANNEL_MAGIC "!978!"
294     char magic[6]; 
295         ast_mutex_t lock;
296     int id;
297     struct ast_channel *owner;
298     struct mgcp_endpoint *parent;
299     struct ast_rtp *rtp;
300         struct sockaddr_in tmpdest;
301         char txident[80];              /* FIXME SC: txident is replaced by rqnt_ident in endpoint. 
302                                       This should be obsoleted */
303     char cxident[80];
304     char callid[80];
305 /* SC: obsolete
306     time_t lastouttime;
307     int lastout;
308 */
309     int cxmode;
310     struct mgcp_request *cx_queue; /* SC: pending CX commands */
311         ast_mutex_t cx_queue_lock;     /* SC: CX queue lock */
312         int nat;
313         int iseq; /* Not used? RTP? */
314         int outgoing;
315         int alreadygone;
316 /* SC: obsolete
317         int messagepending;
318         struct mgcp_message *msgs;
319 */
320     struct mgcp_subchannel *next; /* for out circular linked list */
321 };
322
323 #define MGCP_ONHOOK 1
324 #define MGCP_OFFHOOK 2
325
326 #define TYPE_TRUNK              1
327 #define TYPE_LINE               2
328
329 struct mgcp_endpoint {
330         ast_mutex_t lock;
331         char name[80];
332     struct mgcp_subchannel *sub;        /* pointer to our current connection, channel and stuff */
333         char accountcode[80];
334         char exten[AST_MAX_EXTENSION];          /* Extention where to start */
335         char context[AST_MAX_EXTENSION];
336         char language[MAX_LANGUAGE];
337         char callerid[AST_MAX_EXTENSION];       /* Caller*ID */
338         char lastcallerid[AST_MAX_EXTENSION];   /* Last Caller*ID */
339         char call_forward[AST_MAX_EXTENSION];   /* Last Caller*ID */
340     char mailbox[AST_MAX_EXTENSION];
341     char musicclass[MAX_LANGUAGE];
342         char curtone[80];                                       /* Current tone */
343     unsigned int callgroup;
344     unsigned int pickupgroup;
345         int callwaiting;
346     int transfer;
347     int threewaycalling;
348         int cancallforward;
349         int canreinvite;
350         int callreturn;
351         int dnd; /* How does this affect callwait?  Do we just deny a mgcp_request if we're dnd? */
352         int hascallerid;
353         int hidecallerid;
354         int dtmfinband;
355         int amaflags;
356         int type;
357         int group;
358         int iseq; /* Not used? */
359         int lastout; /* tracking this on the subchannels.  Is it needed here? */
360         int needdestroy; /* Not used? */
361         int capability;
362         int nonCodecCapability;
363     int onhooktime;
364     int msgstate; /* voicemail message state */
365     int immediate;
366     int hookstate;
367     int adsi;
368         char rqnt_ident[80];             /* SC: request identifier */
369     struct mgcp_request *rqnt_queue; /* SC: pending RQNT commands */
370         ast_mutex_t rqnt_queue_lock;
371     struct mgcp_request *cmd_queue;  /* SC: pending commands other than RQNT */
372         ast_mutex_t cmd_queue_lock;
373     int delme;                       /* SC: needed for reload */
374     int needaudit;                   /* SC: needed for reload */
375         struct ast_dsp *dsp; /* XXX Should there be a dsp/subchannel? XXX */
376     /* owner is tracked on the subchannels, and the *sub indicates whos in charge */
377         /* struct ast_channel *owner; */
378         /* struct ast_rtp *rtp; */
379         /* struct sockaddr_in tmpdest; */
380     /* message go the the endpoint and not the channel so they stay here */
381         struct mgcp_endpoint *next;
382         struct mgcp_gateway *parent;
383 };
384
385 static struct mgcp_gateway {
386         /* A gateway containing one or more endpoints */
387         char name[80];
388     int isnamedottedip; /* SC: is the name FQDN or dotted ip */
389         struct sockaddr_in addr;
390         struct sockaddr_in defaddr;
391         struct in_addr ourip;
392         int dynamic;
393         int expire;             /* XXX Should we ever expire dynamic registrations? XXX */
394         struct mgcp_endpoint *endpoints;
395         struct ast_ha *ha;
396 /* SC: obsolete
397     time_t lastouttime;
398     int lastout;
399         int messagepending;
400 */
401 /* JS: Wildcard endpoint name */
402         char wcardep[30];
403         struct mgcp_message *msgs; /* SC: gw msg queue */
404         ast_mutex_t msgs_lock;     /* SC: queue lock */  
405     int retransid;             /* SC: retrans timer id */
406     int delme;                 /* SC: needed for reload */
407         struct mgcp_gateway *next;
408 } *gateways;
409
410 static ast_mutex_t mgcp_reload_lock = AST_MUTEX_INITIALIZER;
411 static int mgcp_reloading = 0;
412
413 static ast_mutex_t gatelock  = AST_MUTEX_INITIALIZER;
414
415 static int mgcpsock  = -1;
416
417 static struct sockaddr_in bindaddr;
418
419 static struct ast_frame  *mgcp_read(struct ast_channel *ast);
420 static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest);
421 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);
422 static int transmit_modify_request(struct mgcp_subchannel *sub);
423 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callerid);
424 static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp);
425 static int transmit_connection_del(struct mgcp_subchannel *sub);
426 static int transmit_audit_endpoint(struct mgcp_endpoint *p);
427 static void start_rtp(struct mgcp_subchannel *sub);
428 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,  
429                             int result, unsigned int ident, struct mgcp_request *resp);
430 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);
431 static int mgcp_do_reload(void);
432 static int mgcp_reload(int fd, int argc, char *argv[]);
433
434 static int has_voicemail(struct mgcp_endpoint *p)
435 {
436         return ast_app_has_voicemail(p->mailbox);
437 }
438
439 static int unalloc_sub(struct mgcp_subchannel *sub)
440 {
441     struct mgcp_endpoint *p = sub->parent;
442         if (p->sub == sub) {
443                 ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, p->parent->name);
444                 return -1;
445         }
446         ast_log(LOG_DEBUG, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name);
447
448         sub->owner = NULL;
449         if (strlen(sub->cxident)) {
450                 transmit_connection_del(sub);
451     }
452     sub->cxident[0] = '\0';
453     sub->callid[0] = '\0';
454     sub->cxmode = MGCP_CX_INACTIVE;
455         sub->outgoing = 0;
456         sub->alreadygone = 0;
457         memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
458         if (sub->rtp) {
459                 ast_rtp_destroy(sub->rtp);
460                 sub->rtp = NULL;
461         }
462     dump_cmd_queues(NULL, sub); /* SC */
463         return 0;
464 }
465
466 /* SC: modified for new transport mechanism */
467 static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
468 {
469         int res;
470         if (gw->addr.sin_addr.s_addr)
471             res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in));
472         else 
473             res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in));
474         if (res != len) {
475                 ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
476         }
477         return res;
478 }
479
480 static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req)
481 {
482     struct mgcp_endpoint *p = sub->parent;
483         int res;
484         if (mgcpdebug) {
485                 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));
486     }
487         res = __mgcp_xmit(p->parent, req->data, req->len);
488         if (res > 0)
489                 res = 0;
490         return res;
491 }
492
493 /* SC: modified for new transport framework */
494 static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
495 {
496         struct mgcp_message *cur, *q = NULL, *w, *prev;
497
498     ast_mutex_lock(&gw->msgs_lock);
499     prev = NULL, cur = gw->msgs;
500     while (cur) {
501         if (!p || cur->owner_ep == p) {
502             if (prev)
503                 prev->next = cur->next;
504             else
505                 gw->msgs = cur->next;
506
507             ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n", 
508                     gw->name, cur->seqno);
509
510             w = cur;
511             cur = cur->next;
512             if (q) {
513                 w->next = q;
514             }
515             else {
516                 w->next = NULL;
517             }
518             q = w;
519         }
520         else {
521             prev = cur, cur=cur->next;
522         }
523     }
524     ast_mutex_unlock(&gw->msgs_lock);
525
526     while (q) {
527         cur = q;
528         q = q->next;
529         free(cur);
530     }
531 }
532
533 static int retrans_pkt(void *data)
534 {
535     struct mgcp_gateway *gw = (struct mgcp_gateway *)data;
536         struct mgcp_message *cur, *exq = NULL, *w, *prev;
537         struct timeval tv;
538     unsigned long t;
539     int res = 0;
540
541         if (gettimeofday(&tv, NULL) < 0) {
542                 /* This shouldn't ever happen, but let's be sure */
543                 ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
544         return 0;
545         }
546
547     t = tv.tv_sec * 1000 + tv.tv_usec / 1000;
548
549     /* find out expired msgs */
550     ast_mutex_lock(&gw->msgs_lock);
551
552     prev = NULL, cur = gw->msgs;
553     while (cur) {
554         if (cur->retrans < MAX_RETRANS) {
555             cur->retrans++;
556             if (mgcpdebug) {
557                 ast_verbose("Retransmitting #%d transaction %u on [%s]\n", cur->retrans, cur->seqno, gw->name);
558             }
559             __mgcp_xmit(gw, cur->buf, cur->len);
560
561             prev = cur;
562             cur = cur->next;
563         }
564         else {
565             if (prev)
566                 prev->next = cur->next;
567             else
568                 gw->msgs = cur->next;
569
570             ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n", cur->seqno, gw->name);
571
572             w = cur;
573             cur = cur->next;
574
575             if (exq) {
576                 w->next = exq;
577             }
578             else {
579                 w->next = NULL;
580             }
581             exq = w;
582         }
583     }
584
585     if (!gw->msgs) {
586         gw->retransid = -1;
587         res = 0;
588     }
589     else {
590         res = 1;
591     }
592     ast_mutex_unlock(&gw->msgs_lock);
593
594     while (exq) {
595         cur = exq;
596         /* time-out transaction */
597         handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL); 
598         exq = exq->next;
599         free(cur);
600     }
601
602     return res;
603 }
604
605 /* SC: modified for the new transaction mechanism */
606 static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, 
607                             unsigned char *data, int len, unsigned int seqno)
608 {
609         struct mgcp_message *msg = malloc(sizeof(struct mgcp_message) + len);
610         struct mgcp_message *cur;
611         struct mgcp_gateway *gw = ((p && p->parent) ? p->parent : NULL);
612         struct timeval tv;
613
614         if (!msg) {
615                 return -1;
616     }
617     if (!gw) {
618         return -1;
619     }
620 /* SC
621     time(&t);
622     if (gw->messagepending && (gw->lastouttime + 20 < t)) {
623         ast_log(LOG_NOTICE, "Timeout waiting for response to message:%d,  lastouttime: %ld, now: %ld.  Dumping pending queue\n",
624                 gw->msgs ? gw->msgs->seqno : -1, (long) gw->lastouttime, (long) t);
625         dump_queue(sub->parent);
626     }
627 */
628         msg->owner_sub = sub;
629         msg->owner_ep = p;
630         msg->seqno = seqno;
631         msg->next = NULL;
632         msg->len = len;
633         msg->retrans = 0;
634         memcpy(msg->buf, data, msg->len);
635
636     ast_mutex_lock(&gw->msgs_lock);
637         cur = gw->msgs;
638         if (cur) {
639                 while(cur->next)
640                         cur = cur->next;
641                 cur->next = msg;
642         } else {
643                 gw->msgs = msg;
644     }
645
646         if (gettimeofday(&tv, NULL) < 0) {
647                 /* This shouldn't ever happen, but let's be sure */
648                 ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
649         }
650     else {
651         msg->expire = tv.tv_sec * 1000 + tv.tv_usec / 1000 + DEFAULT_RETRANS;
652
653         if (gw->retransid == -1)
654             gw->retransid = ast_sched_add(sched, DEFAULT_RETRANS, retrans_pkt, (void *)gw);
655     }
656     ast_mutex_unlock(&gw->msgs_lock);
657 /* SC
658         if (!gw->messagepending) {
659                 gw->messagepending = 1;
660                 gw->lastout = seqno;
661         gw->lastouttime = t;
662 */
663     __mgcp_xmit(gw, msg->buf, msg->len);
664                 /* XXX Should schedule retransmission XXX */
665 /* SC
666         } else
667                 ast_log(LOG_DEBUG, "Deferring transmission of transaction %d\n", seqno);
668 */
669         return 0;
670 }
671
672 /* SC: modified for new transport */
673 static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, 
674                         struct mgcp_request *req, unsigned int seqno)
675 {
676     int res = 0;
677     struct mgcp_request **queue, *q, *r, *t;
678     ast_mutex_t *l;
679
680     switch (req->cmd) {
681         case MGCP_CMD_DLCX:
682             queue = &sub->cx_queue;
683             l = &sub->cx_queue_lock;
684             ast_mutex_lock(l);
685             q = sub->cx_queue;
686             /* delete pending cx cmds */
687             while (q) {
688                 r = q->next;
689                 free(q);
690                 q = r;
691             }
692             *queue = NULL;
693             break;
694
695         case MGCP_CMD_CRCX:
696         case MGCP_CMD_MDCX:
697             queue = &sub->cx_queue;
698             l = &sub->cx_queue_lock;
699             ast_mutex_lock(l);
700             break;
701
702         case MGCP_CMD_RQNT:
703             queue = &p->rqnt_queue;
704             l = &p->rqnt_queue_lock;
705             ast_mutex_lock(l);
706             break;
707
708         default:
709             queue = &p->cmd_queue;
710             l = &p->cmd_queue_lock;
711             ast_mutex_lock(l);
712             break;
713     }
714
715     r = (struct mgcp_request *) malloc (sizeof(struct mgcp_request));
716     if (!r) {
717         ast_log(LOG_WARNING, "Cannot post MGCP request: insufficient memory\n");
718         ast_mutex_unlock(l);
719         return -1;
720     }
721     memcpy(r, req, sizeof(struct mgcp_request));
722
723     if (!(*queue)) {
724         if (mgcpdebug) {
725             ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, 
726                         inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
727         }
728
729         res = mgcp_postrequest(p, sub, req->data, req->len, seqno);
730     }
731     else {
732         if (mgcpdebug) {
733             ast_verbose("Queueing Request:\n%s to %s:%d\n", req->data, 
734                         inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
735         }
736     }
737
738     /* XXX SC: find tail. We could also keep tail in the data struct for faster access */
739     for (t = *queue; t && t->next; t = t->next);
740
741     r->next = NULL;
742     if (t)
743         t->next = r;
744     else
745         *queue = r;
746
747     ast_mutex_unlock(l);
748
749     return res;
750 }
751
752 static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
753 {
754         int res;
755         struct mgcp_endpoint *p;
756     struct mgcp_subchannel *sub;
757     char *tone;
758
759     if (mgcpdebug) {
760         ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_call(%s)\n", ast->name);
761     }
762         sub = ast->pvt->pvt;
763     p = sub->parent;
764
765     switch (p->hookstate) {
766         case MGCP_OFFHOOK:
767             tone = "L/wt";
768             break;
769         case MGCP_ONHOOK:
770         default:
771             tone = "L/rg";
772             break;
773     }
774
775         if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
776                 ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name);
777                 return -1;
778         }
779
780         res = 0;
781         sub->outgoing = 1;
782     sub->cxmode = MGCP_CX_RECVONLY;
783         if (p->type == TYPE_LINE) {
784         if (!sub->rtp) {
785             start_rtp(sub);
786         } else {
787             transmit_modify_request(sub);
788         }
789
790         if (sub->next->owner && strlen(sub->next->cxident) && strlen(sub->next->callid)) {
791             /* try to prevent a callwait from disturbing the other connection */
792             sub->next->cxmode = MGCP_CX_RECVONLY;
793             transmit_modify_request(sub->next);
794         }
795
796                 transmit_notify_request_with_callerid(sub, tone, ast->callerid);
797                 ast_setstate(ast, AST_STATE_RINGING);
798                 ast_queue_control(ast, AST_CONTROL_RINGING);
799
800         if (sub->next->owner && strlen(sub->next->cxident) && strlen(sub->next->callid)) {
801             /* Put the connection back in sendrecv */
802             sub->next->cxmode = MGCP_CX_SENDRECV;
803             transmit_modify_request(sub->next);
804         }
805
806         } else {
807                 ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n");
808                 res = -1;
809         }
810         return res;
811 }
812
813 static int mgcp_hangup(struct ast_channel *ast)
814 {
815         struct mgcp_subchannel *sub = ast->pvt->pvt;
816         struct mgcp_endpoint *p = sub->parent;
817
818         if (option_debug)
819                 ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name);
820         if (!ast->pvt->pvt) {
821                 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
822                 return 0;
823         }
824     if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) {
825                 ast_log(LOG_DEBUG, "Invalid magic. MGCP subchannel freed up already.\n");
826                 return 0;
827     }
828     if (mgcpdebug) {
829         ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name);
830     }
831
832         if ((p->dtmfinband) && (p->dsp != NULL)){
833         /* SC: check whether other channel is active. */
834         if (!sub->next->owner)
835         {
836             if (mgcpdebug) {
837                 ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name);
838             }
839             ast_dsp_free(p->dsp);
840             p->dsp = NULL;
841         }
842     }
843         ast_mutex_lock(&sub->lock);
844
845         sub->owner = NULL;
846         if (strlen(sub->cxident)) {
847                 transmit_connection_del(sub);
848     }
849         strcpy(sub->cxident, "");
850     if ((sub == p->sub) && sub->next->owner) {
851         if (p->hookstate == MGCP_OFFHOOK) {
852             if (sub->next->owner && sub->next->owner->bridge) {
853                 transmit_notify_request_with_callerid(p->sub, "L/wt", sub->next->owner->bridge->callerid);
854             }
855         } else {
856             /* set our other connection as the primary and swith over to it */
857             p->sub = sub->next;
858             p->sub->cxmode = MGCP_CX_RECVONLY;
859             transmit_modify_request(p->sub);
860             if (sub->next->owner && sub->next->owner->bridge) {
861                 transmit_notify_request_with_callerid(p->sub, "L/rg", sub->next->owner->callerid);
862             }
863         }
864
865     } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) {
866         transmit_notify_request(sub, "L/v");
867     } else if (p->hookstate == MGCP_OFFHOOK) {
868         transmit_notify_request(sub, "L/ro");
869     } else {
870         transmit_notify_request(sub, "");
871     }
872
873         ast->pvt->pvt = NULL;
874         sub->alreadygone = 0;
875         sub->outgoing = 0;
876         sub->cxmode = MGCP_CX_INACTIVE;
877         strcpy(sub->callid, "");
878         /* Reset temporary destination */
879         memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
880         if (sub->rtp) {
881                 ast_rtp_destroy(sub->rtp);
882                 sub->rtp = NULL;
883         }
884
885         /* SC: Decrement use count */
886     ast_mutex_lock(&usecnt_lock);
887         usecnt--;
888         ast_mutex_unlock(&usecnt_lock);
889         ast_update_use_count();
890     /* SC: Decrement use count */
891
892     if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) {
893         if (has_voicemail(p)) {
894             if (mgcpdebug) {
895                 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n", ast->name, p->name, p->parent->name);
896             }
897             transmit_notify_request(sub, "L/vmwi(+)");
898         } else {
899             if (mgcpdebug) {
900                 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n", ast->name, p->name, p->parent->name);
901             }
902             transmit_notify_request(sub, "L/vmwi(-)");
903         }
904     }
905         ast_mutex_unlock(&sub->lock);
906         return 0;
907 }
908
909 static int mgcp_show_endpoints(int fd, int argc, char *argv[])
910 {
911         struct mgcp_gateway  *g;
912         struct mgcp_endpoint *e;
913         int hasendpoints = 0;
914         if (argc != 3) 
915                 return RESULT_SHOWUSAGE;
916         ast_mutex_lock(&gatelock);
917         g = gateways;
918         while(g) {
919                 e = g->endpoints;
920                 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");
921                 while(e) {
922                         // JS: Don't show wilcard endpoint
923                         if (strcmp(e->name, g->wcardep) !=0)
924                                 ast_cli(fd, "   -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle");
925                         hasendpoints = 1;
926                         e = e->next;
927                 }
928                 if (!hasendpoints) {
929                         ast_cli(fd, "   << No Endpoints Defined >>     ");
930                 }
931                 g = g->next;
932         }
933         ast_mutex_unlock(&gatelock);
934         return RESULT_SUCCESS;
935 }
936
937 static char show_endpoints_usage[] = 
938 "Usage: mgcp show endpoints\n"
939 "       Lists all endpoints known to the MGCP (Media Gateawy Control Protocol) subsystem.\n";
940
941 static struct ast_cli_entry  cli_show_endpoints = 
942         { { "mgcp", "show", "endpoints", NULL }, mgcp_show_endpoints, "Show defined MGCP endpoints", show_endpoints_usage };
943
944 static int mgcp_audit_endpoint(int fd, int argc, char *argv[])
945 {
946         struct mgcp_gateway  *g;
947         struct mgcp_endpoint *e;
948         int found = 0;
949     char *ename,*gname, *c;
950         if (!mgcpdebug) {
951                 return RESULT_SHOWUSAGE;
952     }
953         if (argc != 4) 
954                 return RESULT_SHOWUSAGE;
955     /* split the name into parts by null */
956     ename = argv[3];
957     gname = ename;
958     while (*gname) {
959         if (*gname == '@') {
960             *gname = 0;
961             gname++;
962             break;
963         }
964         gname++;
965     }
966         if (gname[0] == '[')
967                 gname++;
968         if ((c = strrchr(gname, ']')))
969                 *c = '\0';
970         ast_mutex_lock(&gatelock);
971         g = gateways;
972         while(g) {
973         if (!strcasecmp(g->name, gname)) {
974             e = g->endpoints;
975             while(e) {
976                 if (!strcasecmp(e->name, ename)) {
977                     found = 1;
978                     transmit_audit_endpoint(e);
979                     break;
980                 }
981                 e = e->next;
982             }
983             if (found) {
984                 break;
985             }
986         }
987         g = g->next;
988         }
989     if (!found) {
990         ast_cli(fd, "   << Could not find endpoint >>     ");
991     }
992         ast_mutex_unlock(&gatelock);
993         return RESULT_SUCCESS;
994 }
995
996 static char audit_endpoint_usage[] = 
997 "Usage: mgcp audit endpoint <endpointid>\n"
998 "       List the capabilities of an endpoint in the MGCP (Media Gateawy Control Protocol) subsystem.\n"
999 "       mgcp debug MUST be on to see the results of this command.\n";
1000
1001 static struct ast_cli_entry  cli_audit_endpoint = 
1002         { { "mgcp", "audit", "endpoint", NULL }, mgcp_audit_endpoint, "Audit specified MGCP endpoint", audit_endpoint_usage };
1003
1004 static int mgcp_answer(struct ast_channel *ast)
1005 {
1006         int res = 0;
1007         struct mgcp_subchannel *sub = ast->pvt->pvt;
1008         struct mgcp_endpoint *p = sub->parent;
1009     sub->cxmode = MGCP_CX_SENDRECV;
1010     if (!sub->rtp) {
1011         start_rtp(sub);
1012     } else {
1013         transmit_modify_request(sub);
1014     }
1015     /* SC: verbose level check */
1016     if (option_verbose > 2) {
1017         ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_answer(%s) on %s@%s-%d\n", ast->name, p->name, p->parent->name, sub->id);
1018     }
1019         if (ast->_state != AST_STATE_UP) {
1020                 ast_setstate(ast, AST_STATE_UP);
1021                 if (option_debug)
1022                         ast_log(LOG_DEBUG, "mgcp_answer(%s)\n", ast->name);
1023                 transmit_notify_request(sub, "");
1024                 transmit_modify_request(sub);
1025         }
1026         return res;
1027 }
1028
1029 static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
1030 {
1031         /* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */
1032         struct ast_frame *f;
1033         f = ast_rtp_read(sub->rtp);
1034         if (sub->owner) {
1035                 /* We already hold the channel lock */
1036                 if (f->frametype == AST_FRAME_VOICE) {
1037                         if (f->subclass != sub->owner->nativeformats) {
1038                                 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
1039                                 sub->owner->nativeformats = f->subclass;
1040                                 ast_set_read_format(sub->owner, sub->owner->readformat);
1041                                 ast_set_write_format(sub->owner, sub->owner->writeformat);
1042                         }
1043             /* Courtesy fearnor aka alex@pilosoft.com */
1044             if (sub->parent->dtmfinband) {
1045 #if 0
1046                 ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n");
1047 #endif
1048                 f = ast_dsp_process(sub->owner, sub->parent->dsp, f);
1049             }
1050                 }
1051         }
1052         return f;
1053 }
1054
1055
1056 static struct ast_frame  *mgcp_read(struct ast_channel *ast)
1057 {
1058         struct ast_frame *fr;
1059         struct mgcp_subchannel *sub = ast->pvt->pvt;
1060         ast_mutex_lock(&sub->lock);
1061         fr = mgcp_rtp_read(sub);
1062         ast_mutex_unlock(&sub->lock);
1063         return fr;
1064 }
1065
1066 static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
1067 {
1068         struct mgcp_subchannel *sub = ast->pvt->pvt;
1069         int res = 0;
1070         if (frame->frametype != AST_FRAME_VOICE) {
1071                 if (frame->frametype == AST_FRAME_IMAGE)
1072                         return 0;
1073                 else {
1074                         ast_log(LOG_WARNING, "Can't send %d type frames with MGCP write\n", frame->frametype);
1075                         return 0;
1076                 }
1077         } else {
1078                 if (!(frame->subclass & ast->nativeformats)) {
1079                         ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
1080                                 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
1081                         return -1;
1082                 }
1083         }
1084         if (sub) {
1085                 ast_mutex_lock(&sub->lock);
1086                 if (sub->rtp) {
1087                         res =  ast_rtp_write(sub->rtp, frame);
1088                 }
1089                 ast_mutex_unlock(&sub->lock);
1090         }
1091         return res;
1092 }
1093
1094 static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1095 {
1096         struct mgcp_subchannel *sub = newchan->pvt->pvt;
1097     ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name);
1098         if (sub->owner != oldchan) {
1099                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
1100                 return -1;
1101         }
1102         sub->owner = newchan;
1103         return 0;
1104 }
1105
1106 static int mgcp_senddigit(struct ast_channel *ast, char digit)
1107 {
1108         struct mgcp_subchannel *sub = ast->pvt->pvt;
1109         char tmp[2];
1110         tmp[0] = digit;
1111         tmp[1] = '\0';
1112         transmit_notify_request(sub, tmp);
1113         return -1;
1114 }
1115
1116 static char *control2str(int ind) {
1117     switch (ind) {
1118         case AST_CONTROL_HANGUP:
1119             return "Other end has hungup";
1120         case AST_CONTROL_RING:
1121             return "Local ring";
1122         case AST_CONTROL_RINGING:
1123             return "Remote end is ringing";
1124         case AST_CONTROL_ANSWER:
1125             return "Remote end has answered";
1126         case AST_CONTROL_BUSY:
1127             return "Remote end is busy";
1128         case AST_CONTROL_TAKEOFFHOOK:
1129             return "Make it go off hook";
1130         case AST_CONTROL_OFFHOOK:
1131             return "Line is off hook";
1132         case AST_CONTROL_CONGESTION:
1133             return "Congestion (circuits busy)";
1134         case AST_CONTROL_FLASH:
1135             return "Flash hook";
1136         case AST_CONTROL_WINK:
1137             return "Wink";
1138         case AST_CONTROL_OPTION:
1139             return "Set a low-level option";
1140         case AST_CONTROL_RADIO_KEY:
1141             return "Key Radio";
1142         case AST_CONTROL_RADIO_UNKEY:
1143             return "Un-Key Radio";
1144     }
1145     return "UNKNOWN";
1146 }
1147
1148
1149 static int mgcp_indicate(struct ast_channel *ast, int ind)
1150 {
1151         struct mgcp_subchannel *sub = ast->pvt->pvt;
1152     if (mgcpdebug) {
1153         ast_verbose(VERBOSE_PREFIX_3 "MGCP asked to indicate %d '%s' condition on channel %s\n", ind, control2str(ind), ast->name);
1154     }
1155         switch(ind) {
1156         case AST_CONTROL_RINGING:
1157                 transmit_notify_request(sub, "G/rt");
1158                 break;
1159         case AST_CONTROL_BUSY:
1160                 transmit_notify_request(sub, "L/bz");
1161                 break;
1162         case AST_CONTROL_CONGESTION:
1163                 transmit_notify_request(sub, "G/cg");
1164                 break;
1165         case -1:
1166                 transmit_notify_request(sub, "");
1167                 break;          
1168         default:
1169                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
1170                 return -1;
1171         }
1172         return 0;
1173 }
1174
1175 static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state)
1176 {
1177         struct ast_channel *tmp;
1178     struct mgcp_endpoint *i = sub->parent;
1179         int fmt;
1180     i = sub->parent;
1181         tmp = ast_channel_alloc(1);
1182         if (tmp) {
1183                 tmp->nativeformats = i->capability;
1184                 if (!tmp->nativeformats)
1185                         tmp->nativeformats = capability;
1186                 fmt = ast_best_codec(tmp->nativeformats);
1187                 snprintf(tmp->name, sizeof(tmp->name), "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
1188                 if (sub->rtp)
1189                         tmp->fds[0] = ast_rtp_fd(sub->rtp);
1190                 tmp->type = type;
1191                 if (i->dtmfinband) {
1192                     i->dsp = ast_dsp_new();
1193                     ast_dsp_set_features(i->dsp,DSP_FEATURE_DTMF_DETECT);
1194             /* SC: this is to prevent clipping of dtmf tones during dsp processing */
1195             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_NOQUELCH);
1196                 } else {
1197                     i->dsp = NULL;
1198                 }
1199                 ast_setstate(tmp, state);
1200                 if (state == AST_STATE_RING)
1201                         tmp->rings = 1;
1202                 tmp->writeformat = fmt;
1203                 tmp->pvt->rawwriteformat = fmt;
1204                 tmp->readformat = fmt;
1205                 tmp->pvt->rawreadformat = fmt;
1206                 tmp->pvt->pvt = sub;
1207                 tmp->pvt->call = mgcp_call;
1208                 tmp->pvt->hangup = mgcp_hangup;
1209                 tmp->pvt->answer = mgcp_answer;
1210                 tmp->pvt->read = mgcp_read;
1211                 tmp->pvt->write = mgcp_write;
1212                 tmp->pvt->indicate = mgcp_indicate;
1213                 tmp->pvt->fixup = mgcp_fixup;
1214                 tmp->pvt->send_digit = mgcp_senddigit;
1215                 tmp->pvt->bridge = ast_rtp_bridge;
1216                 if (strlen(i->language))
1217                         strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
1218                 if (strlen(i->accountcode))
1219                         strncpy(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)-1);
1220                 if (i->amaflags)
1221                         tmp->amaflags = i->amaflags;
1222                 sub->owner = tmp;
1223                 ast_mutex_lock(&usecnt_lock);
1224                 usecnt++;
1225                 ast_mutex_unlock(&usecnt_lock);
1226                 ast_update_use_count();
1227                 tmp->callgroup = i->callgroup;
1228                 tmp->pickupgroup = i->pickupgroup;
1229                 strncpy(tmp->call_forward, i->call_forward, sizeof(tmp->call_forward));
1230                 strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
1231                 strncpy(tmp->exten, i->exten, sizeof(tmp->exten)-1);
1232                 if (strlen(i->callerid))
1233                         tmp->callerid = strdup(i->callerid);
1234                 if (!i->adsi)
1235                         tmp->adsicpe = AST_ADSI_UNAVAILABLE;
1236                 tmp->priority = 1;
1237                 if (state != AST_STATE_DOWN) {
1238                         if (ast_pbx_start(tmp)) {
1239                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
1240                                 ast_hangup(tmp);
1241                                 tmp = NULL;
1242                         }
1243                 }
1244         /* SC: verbose level check */
1245         if (option_verbose > 2) {
1246             ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_new(%s) created in state: %s\n", tmp->name, ast_state2str(state));
1247         }
1248         } else {
1249                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
1250     }
1251         return tmp;
1252 }
1253
1254 static char* get_sdp_by_line(char* line, char *name, int nameLen) {
1255   if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
1256     char* r = line + nameLen + 1;
1257     while (*r && (*r < 33)) ++r;
1258     return r;
1259   }
1260
1261   return "";
1262 }
1263
1264 static char *get_sdp(struct mgcp_request *req, char *name) {
1265   int x;
1266   int len = strlen(name);
1267   char *r;
1268
1269   for (x=0; x<req->lines; x++) {
1270     r = get_sdp_by_line(req->line[x], name, len);
1271     if (r[0] != '\0') return r;
1272   }
1273   return "";
1274 }
1275
1276 static void sdpLineNum_iterator_init(int* iterator) {
1277   *iterator = 0;
1278 }
1279
1280 static char* get_sdp_iterate(int* iterator,
1281                              struct mgcp_request *req, char *name) {
1282   int len = strlen(name);
1283   char *r;
1284   while (*iterator < req->lines) {
1285     r = get_sdp_by_line(req->line[(*iterator)++], name, len);
1286     if (r[0] != '\0') return r;
1287   }
1288   return "";
1289 }
1290
1291 static char *__get_header(struct mgcp_request *req, char *name, int *start)
1292 {
1293         int x;
1294         int len = strlen(name);
1295         char *r;
1296         for (x=*start;x<req->headers;x++) {
1297                 if (!strncasecmp(req->header[x], name, len) && 
1298                                 (req->header[x][len] == ':')) {
1299                                         r = req->header[x] + len + 1;
1300                                         while(*r && (*r < 33))
1301                                                         r++;
1302                                         *start = x+1;
1303                                         return r;
1304                 }
1305         }
1306         /* Don't return NULL, so get_header is always a valid pointer */
1307         return "";
1308 }
1309
1310 static char *get_header(struct mgcp_request *req, char *name)
1311 {
1312         int start = 0;
1313         return __get_header(req, name, &start);
1314 }
1315
1316 /* SC: get comma separated value */
1317 static char *get_csv(char *c, int *len, char **next) 
1318 {
1319     char *s;
1320
1321     *next = NULL, *len = 0;
1322     if (!c) return NULL;
1323
1324     while(*c && (*c < 33 || *c == ','))
1325         c++;
1326     
1327     s = c;
1328     while(*c && (*c >= 33 && *c != ','))
1329         c++, (*len)++;
1330     *next = c;
1331     
1332     if (*len == 0)
1333         s = NULL, *next = NULL;
1334     
1335     return s;
1336
1337
1338 #if 0
1339 static int rtpready(struct ast_rtp *rtp, struct ast_frame *f, void *data)
1340 {
1341         /* Just deliver the audio directly */
1342         struct mgcp_endpoint *p = data;
1343         ast_mutex_lock(&p->lock);
1344         if (p->owner) {
1345                 /* Generally, you lock in the order channel lock, followed by private
1346                    lock.  Since here we are doing the reverse, there is the possibility
1347                    of deadlock.  As a result, in the case of a deadlock, we simply fail out
1348                    here. */
1349                 if (!ast_mutex_trylock(&p->owner->lock)) {
1350                         if (f->frametype == AST_FRAME_VOICE) {
1351                                 if (f->subclass != p->owner->nativeformats) {
1352                                         ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
1353                                         p->owner->nativeformats = f->subclass;
1354                                         ast_set_read_format(p->owner, p->owner->readformat);
1355                                         ast_set_write_format(p->owner, p->owner->writeformat);
1356                                 }
1357                                 if (p->dtmfinband) {
1358                                     f = ast_dsp_process(p->owner,p->dsp,f);
1359                                 }
1360                         }
1361                         ast_queue_frame(p->owner, f);
1362                         ast_mutex_unlock(&p->owner->lock);
1363                 }
1364         }
1365         ast_mutex_unlock(&p->lock);
1366         return 0;
1367 }
1368 #endif
1369
1370 static struct mgcp_subchannel *find_subchannel(char *name, int msgid, struct sockaddr_in *sin)
1371 {
1372         struct mgcp_endpoint *p = NULL;
1373         struct mgcp_subchannel *sub = NULL;
1374         struct mgcp_gateway *g;
1375         char tmp[256] = "";
1376         char *at = NULL, *c;
1377     int found = 0;
1378         if (name) {
1379                 strncpy(tmp, name, sizeof(tmp) - 1);
1380                 at = strchr(tmp, '@');
1381                 if (!at) {
1382                         ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name);
1383                         return NULL;
1384                 }
1385                 *at = '\0';
1386                 at++;
1387         }
1388         ast_mutex_lock(&gatelock);
1389         if (at && (at[0] == '[')) {
1390                 at++;
1391                 c = strrchr(at, ']');
1392                 if (c)
1393                         *c = '\0';
1394         }
1395         g = gateways;
1396         while(g) {
1397                 if ((!name || !strcasecmp(g->name, at)) && 
1398                     (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) {
1399                         /* Found the gateway.  If it's dynamic, save it's address -- now for the endpoint */
1400                         if (sin && g->dynamic && name) {
1401                                 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1402                                         (g->addr.sin_port != sin->sin_port)) {
1403                                         memcpy(&g->addr, sin, sizeof(g->addr));
1404                                         if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip))
1405                                                 memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
1406                                         if (option_verbose > 2)
1407                                                 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));
1408                                 }
1409                         }
1410             /* SC: not dynamic, check if the name matches */
1411             else if (name) {
1412                 if (strcasecmp(g->name, at)) {
1413                     g = g->next;
1414                     continue;
1415                 }
1416             }
1417             /* SC: not dynamic, no name, check if the addr matches */
1418             else if (!name && sin) {
1419                                 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1420                                         (g->addr.sin_port != sin->sin_port)) {
1421                     g = g->next;
1422                     continue;
1423                 }
1424             }
1425             else  {
1426                 g = g->next;
1427                 continue;
1428             }
1429             /* SC */
1430                         p = g->endpoints;
1431                         while(p) {
1432                                 if (option_debug)
1433                         ast_log(LOG_DEBUG, "Searching on %s@%s for subchannel\n", p->name, g->name);
1434                 if (msgid) {
1435 #if 0 /* SC: new transport mech */
1436                     sub = p->sub;
1437                     do {
1438                                                 if (option_debug)
1439                             ast_log(LOG_DEBUG, "Searching on %s@%s-%d for subchannel with lastout: %d\n", p->name, g->name, sub->id, msgid);
1440                         if (sub->lastout == msgid) {
1441                                                         if (option_debug)
1442                                 ast_log(LOG_DEBUG, "Found subchannel sub%d to handle request %d sub->lastout: %d\n", sub->id, msgid, sub->lastout);
1443                             found = 1;
1444                             break;
1445                         }
1446                         sub = sub->next;
1447                     } while (sub != p->sub);
1448                     if (found) {
1449                         break;
1450                     }
1451 #endif
1452                     /* SC */
1453                     sub = p->sub;
1454                     found = 1;
1455                     /* SC */
1456                     break;
1457                 } else if (name && !strcasecmp(p->name, tmp)) {
1458                     ast_log(LOG_DEBUG, "Coundn't determine subchannel, assuming current master %s@%s-%d\n", 
1459                             p->name, g->name, p->sub->id);
1460                     sub = p->sub;
1461                     found = 1;
1462                     break;
1463                 }
1464                 p = p->next;
1465                         }
1466                         if (sub && found) {
1467                                 break;
1468             }
1469                 }
1470                 g = g->next;
1471         }
1472         ast_mutex_unlock(&gatelock);
1473         if (!sub) {
1474                 if (name) {
1475                         if (g)
1476                                 ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp,at);
1477                         else
1478                                 ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
1479                 } 
1480         }
1481         return sub;
1482 }
1483
1484 static void parse(struct mgcp_request *req)
1485 {
1486         /* Divide fields by NULL's */
1487         char *c;
1488         int f = 0;
1489         c = req->data;
1490
1491         /* First header starts immediately */
1492         req->header[f] = c;
1493         while(*c) {
1494                 if (*c == '\n') {
1495                         /* We've got a new header */
1496                         *c = 0;
1497
1498 #if 0
1499                         printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f]));
1500 #endif                  
1501                         if (!strlen(req->header[f])) {
1502                                 /* Line by itself means we're now in content */
1503                                 c++;
1504                                 break;
1505                         }
1506                         if (f >= MGCP_MAX_HEADERS - 1) {
1507                                 ast_log(LOG_WARNING, "Too many MGCP headers...\n");
1508                         } else
1509                                 f++;
1510                         req->header[f] = c + 1;
1511                 } else if (*c == '\r') {
1512                         /* Ignore but eliminate \r's */
1513                         *c = 0;
1514                 }
1515                 c++;
1516         }
1517         /* Check for last header */
1518         if (strlen(req->header[f])) 
1519                 f++;
1520         req->headers = f;
1521         /* Now we process any mime content */
1522         f = 0;
1523         req->line[f] = c;
1524         while(*c) {
1525                 if (*c == '\n') {
1526                         /* We've got a new line */
1527                         *c = 0;
1528 #if 0
1529                         printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f]));
1530 #endif                  
1531                         if (f >= MGCP_MAX_LINES - 1) {
1532                                 ast_log(LOG_WARNING, "Too many SDP lines...\n");
1533                         } else
1534                                 f++;
1535                         req->line[f] = c + 1;
1536                 } else if (*c == '\r') {
1537                         /* Ignore and eliminate \r's */
1538                         *c = 0;
1539                 }
1540                 c++;
1541         }
1542         /* Check for last line */
1543         if (strlen(req->line[f])) 
1544                 f++;
1545         req->lines = f;
1546         /* Parse up the initial header */
1547         c = req->header[0];
1548         while(*c && *c < 33) c++;
1549         /* First the verb */
1550         req->verb = c;
1551         while(*c && (*c > 32)) c++;
1552         if (*c) {
1553                 *c = '\0';
1554                 c++;
1555                 while(*c && (*c < 33)) c++;
1556                 req->identifier = c;
1557                 while(*c && (*c > 32)) c++;
1558                 if (*c) {
1559                         *c = '\0';
1560                         c++;
1561                         while(*c && (*c < 33)) c++;
1562                         req->endpoint = c;
1563                         while(*c && (*c > 32)) c++;
1564                         if (*c) {
1565                                 *c = '\0';
1566                                 c++;
1567                                 while(*c && (*c < 33)) c++;
1568                                 req->version = c;
1569                                 while(*c && (*c > 32)) c++;
1570                                 while(*c && (*c < 33)) c++;
1571                                 while(*c && (*c > 32)) c++;
1572                                 *c = '\0';
1573                         }
1574                 }
1575         }
1576                 
1577         if (mgcpdebug) {
1578                 ast_verbose("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
1579                     req->verb, req->identifier, req->endpoint, req->version);
1580                 ast_verbose("%d headers, %d lines\n", req->headers, req->lines);
1581         }
1582         if (*c) 
1583                 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
1584 }
1585
1586 static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
1587 {
1588         char *m;
1589         char *c;
1590         char *a;
1591         char host[258];
1592         int len;
1593         int portno;
1594         int peercapability, peerNonCodecCapability;
1595         struct sockaddr_in sin;
1596         char *codecs;
1597         struct ast_hostent ahp; struct hostent *hp;
1598         int codec;
1599         int iterator;
1600     struct mgcp_endpoint *p = sub->parent;
1601
1602         /* Get codec and RTP info from SDP */
1603         m = get_sdp(req, "m");
1604         c = get_sdp(req, "c");
1605         if (!strlen(m) || !strlen(c)) {
1606                 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
1607                 return -1;
1608         }
1609         if (sscanf(c, "IN IP4 %256s", host) != 1) {
1610                 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
1611                 return -1;
1612         }
1613         /* XXX This could block for a long time, and block the main thread! XXX */
1614         hp = ast_gethostbyname(host, &ahp);
1615         if (!hp) {
1616                 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
1617                 return -1;
1618         }
1619         if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) {
1620                 ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m); 
1621                 return -1;
1622         }
1623         sin.sin_family = AF_INET;
1624         memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
1625         sin.sin_port = htons(portno);
1626         ast_rtp_set_peer(sub->rtp, &sin);
1627 #if 0
1628         printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1629 #endif  
1630         // Scan through the RTP payload types specified in a "m=" line:
1631     ast_rtp_pt_clear(sub->rtp);
1632         codecs = m + len;
1633         while(strlen(codecs)) {
1634                 if (sscanf(codecs, "%d %n", &codec, &len) != 1) {
1635                         ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
1636                         return -1;
1637                 }
1638                 ast_rtp_set_m_type(sub->rtp, codec);
1639                 codecs += len;
1640         }
1641
1642         // Next, scan through each "a=rtpmap:" line, noting each
1643         // specified RTP payload type (with corresponding MIME subtype):
1644         sdpLineNum_iterator_init(&iterator);
1645         while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
1646           char* mimeSubtype = strdup(a); // ensures we have enough space
1647           if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
1648           // Note: should really look at the 'freq' and '#chans' params too
1649           ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype);
1650           free(mimeSubtype);
1651         }
1652
1653         // Now gather all of the codecs that were asked for:
1654         ast_rtp_get_current_formats(sub->rtp,
1655                                 &peercapability, &peerNonCodecCapability);
1656         p->capability = capability & peercapability;
1657         if (mgcpdebug) {
1658                 ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n",
1659                     capability, peercapability, p->capability);
1660                 ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n",
1661                     nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
1662         }
1663         if (!p->capability) {
1664                 ast_log(LOG_WARNING, "No compatible codecs!\n");
1665                 return -1;
1666         }
1667         return 0;
1668         
1669 }
1670
1671 static int add_header(struct mgcp_request *req, char *var, char *value)
1672 {
1673         if (req->len >= sizeof(req->data) - 4) {
1674                 ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
1675                 return -1;
1676         }
1677         if (req->lines) {
1678                 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
1679                 return -1;
1680         }
1681         req->header[req->headers] = req->data + req->len;
1682         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
1683         req->len += strlen(req->header[req->headers]);
1684         if (req->headers < MGCP_MAX_HEADERS)
1685                 req->headers++;
1686         else {
1687                 ast_log(LOG_WARNING, "Out of header space\n");
1688                 return -1;
1689         }
1690         return 0;       
1691 }
1692
1693 static int add_line(struct mgcp_request *req, char *line)
1694 {
1695         if (req->len >= sizeof(req->data) - 4) {
1696                 ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
1697                 return -1;
1698         }
1699         if (!req->lines) {
1700                 /* Add extra empty return */
1701                 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
1702                 req->len += strlen(req->data + req->len);
1703         }
1704         req->line[req->lines] = req->data + req->len;
1705         snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
1706         req->len += strlen(req->line[req->lines]);
1707         if (req->lines < MGCP_MAX_LINES)
1708                 req->lines++;
1709         else {
1710                 ast_log(LOG_WARNING, "Out of line space\n");
1711                 return -1;
1712         }
1713         return 0;       
1714 }
1715
1716 static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
1717 {
1718         /* Initialize a response */
1719         if (req->headers || req->len) {
1720                 ast_log(LOG_WARNING, "Request already initialized?!?\n");
1721                 return -1;
1722         }
1723         req->header[req->headers] = req->data + req->len;
1724         snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
1725         req->len += strlen(req->header[req->headers]);
1726         if (req->headers < MGCP_MAX_HEADERS)
1727                 req->headers++;
1728         else
1729                 ast_log(LOG_WARNING, "Out of header space\n");
1730         return 0;
1731 }
1732
1733 static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb)
1734 {
1735         /* Initialize a response */
1736         if (req->headers || req->len) {
1737                 ast_log(LOG_WARNING, "Request already initialized?!?\n");
1738                 return -1;
1739         }
1740         req->header[req->headers] = req->data + req->len;
1741     /* SC: check if we need brackets around the gw name */
1742     if (p->parent->isnamedottedip)
1743         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);
1744     else
1745         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);
1746         req->len += strlen(req->header[req->headers]);
1747         if (req->headers < MGCP_MAX_HEADERS)
1748                 req->headers++;
1749         else
1750                 ast_log(LOG_WARNING, "Out of header space\n");
1751         return 0;
1752 }
1753
1754
1755 static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
1756 {
1757         memset(resp, 0, sizeof(*resp));
1758         init_resp(resp, msg, req, msgrest);
1759         return 0;
1760 }
1761
1762 static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
1763 {
1764         memset(req, 0, sizeof(struct mgcp_request));
1765         oseq++;
1766         init_req(p, req, verb);
1767         return 0;
1768 }
1769
1770 static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
1771 {
1772         struct mgcp_request resp;
1773     struct mgcp_endpoint *p = sub->parent;
1774         respprep(&resp, p, msg, req, msgrest);
1775         return send_response(sub, &resp);
1776 }
1777
1778
1779 static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp *rtp)
1780 {
1781         int len;
1782         int codec;
1783         char costr[80];
1784         struct sockaddr_in sin;
1785         char v[256];
1786         char s[256];
1787         char o[256];
1788         char c[256];
1789         char t[256];
1790         char m[256];
1791         char a[1024] = "";
1792         int x;
1793         struct sockaddr_in dest;
1794     struct mgcp_endpoint *p = sub->parent;
1795         /* XXX We break with the "recommendation" and send our IP, in order that our
1796                peer doesn't have to ast_gethostbyname() us XXX */
1797         len = 0;
1798         if (!sub->rtp) {
1799                 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
1800                 return -1;
1801         }
1802         ast_rtp_get_us(sub->rtp, &sin);
1803         if (rtp) {
1804                 ast_rtp_get_peer(rtp, &dest);
1805         } else {
1806                 if (sub->tmpdest.sin_addr.s_addr) {
1807                         dest.sin_addr = sub->tmpdest.sin_addr;
1808                         dest.sin_port = sub->tmpdest.sin_port;
1809                         /* Reset temporary destination */
1810                         memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
1811                 } else {
1812                         dest.sin_addr = p->parent->ourip;
1813                         dest.sin_port = sin.sin_port;
1814                 }
1815         }
1816         if (mgcpdebug) {
1817                 ast_verbose("We're at %s port %d\n", inet_ntoa(p->parent->ourip), ntohs(sin.sin_port)); 
1818     }
1819         snprintf(v, sizeof(v), "v=0\r\n");
1820         snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), inet_ntoa(dest.sin_addr));
1821         snprintf(s, sizeof(s), "s=session\r\n");
1822         snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", inet_ntoa(dest.sin_addr));
1823         snprintf(t, sizeof(t), "t=0 0\r\n");
1824         snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
1825         for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) {
1826                 if (p->capability & x) {
1827                         if (mgcpdebug) {
1828                                 ast_verbose("Answering with capability %d\n", x);
1829             }
1830                         codec = ast_rtp_lookup_code(sub->rtp, 1, x);
1831             if (codec > -1) {
1832                                 snprintf(costr, sizeof(costr), " %d", codec);
1833                                 strcat(m, costr);
1834                                 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
1835                                 strcat(a, costr);
1836                         }
1837                 }
1838         }
1839         for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
1840         if (p->nonCodecCapability & x) {
1841             if (mgcpdebug) {
1842                 ast_verbose("Answering with non-codec capability %d\n", x);
1843             }
1844             codec = ast_rtp_lookup_code(sub->rtp, 0, x);
1845             if (codec > -1) {
1846                 snprintf(costr, sizeof(costr), " %d", codec);
1847                 strcat(m, costr);
1848                 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x));
1849                 strcat(a, costr);
1850                 if (x == AST_RTP_DTMF) {
1851                   /* Indicate we support DTMF...  Not sure about 16, but MSN supports it so dang it, we will too... */
1852                   snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec);
1853                   strcat(a, costr);
1854                 }
1855             }
1856         }
1857     }
1858         strcat(m, "\r\n");
1859         len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
1860         snprintf(costr, sizeof(costr), "%d", len);
1861         add_line(resp, v);
1862         add_line(resp, o);
1863         add_line(resp, s);
1864         add_line(resp, c);
1865         add_line(resp, t);
1866         add_line(resp, m);
1867         add_line(resp, a);
1868         return 0;
1869 }
1870
1871 static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp)
1872 {
1873         struct mgcp_request resp;
1874         char local[256];
1875         char tmp[80];
1876         int x;
1877     struct mgcp_endpoint *p = sub->parent;
1878         if (!strlen(sub->cxident) && rtp) {
1879                 /* We don't have a CXident yet, store the destination and
1880                    wait a bit */
1881                 ast_rtp_get_peer(rtp, &sub->tmpdest);
1882                 return 0;
1883         }
1884         snprintf(local, sizeof(local), "p:20");
1885         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
1886                 if (p->capability & x) {
1887                         snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
1888                         strcat(local, tmp);
1889                 }
1890         }
1891         reqprep(&resp, p, "MDCX");
1892         add_header(&resp, "C", sub->callid);
1893         add_header(&resp, "L", local);
1894         add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
1895     /* SC: X header should not be sent. kept for compatibility */
1896         add_header(&resp, "X", sub->txident);
1897         add_header(&resp, "I", sub->cxident);
1898         /*add_header(&resp, "S", "");*/
1899         add_sdp(&resp, sub, rtp);
1900     /* SC: fill in new fields */
1901     resp.cmd = MGCP_CMD_MDCX;
1902     resp.trid = oseq;
1903         return send_request(p, sub, &resp, oseq); /* SC */
1904 }
1905
1906 static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp)
1907 {
1908         struct mgcp_request resp;
1909         char local[256];
1910         char tmp[80];
1911         int x;
1912     struct mgcp_endpoint *p = sub->parent;
1913
1914         snprintf(local, sizeof(local), "p:20");
1915         for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
1916                 if (p->capability & x) {
1917                         snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
1918                         strcat(local, tmp);
1919                 }
1920         }
1921     if (mgcpdebug) {
1922         ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", 
1923                     p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
1924     }
1925         reqprep(&resp, p, "CRCX");
1926         add_header(&resp, "C", sub->callid);
1927         add_header(&resp, "L", local);
1928         add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
1929     /* SC: X header should not be sent. kept for compatibility */
1930         add_header(&resp, "X", sub->txident);
1931         /*add_header(&resp, "S", "");*/
1932         add_sdp(&resp, sub, rtp);
1933     /* SC: fill in new fields */
1934     resp.cmd = MGCP_CMD_CRCX;
1935     resp.trid = oseq;
1936         return send_request(p, sub, &resp, oseq);  /* SC */
1937 }
1938
1939 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
1940 {
1941         struct mgcp_request resp;
1942     struct mgcp_endpoint *p = sub->parent;
1943
1944     if (mgcpdebug) {
1945         ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on  %s@%s-%d in cxmode: %s\n", 
1946                     tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
1947     }
1948         strncpy(p->curtone, tone, sizeof(p->curtone) - 1);
1949         reqprep(&resp, p, "RQNT");
1950         add_header(&resp, "X", p->rqnt_ident); /* SC */
1951     switch (p->hookstate) {
1952             case MGCP_ONHOOK:
1953             add_header(&resp, "R", "L/hd(N)");
1954             break;
1955         case MGCP_OFFHOOK:
1956             add_header(&resp, "R", "L/hu(N), L/hf(N), D/[0-9#*](N)");
1957             break;
1958     }
1959     if (strlen(tone)) {
1960         add_header(&resp, "S", tone);
1961     }
1962     /* SC: fill in new fields */
1963     resp.cmd = MGCP_CMD_RQNT;
1964     resp.trid = oseq;
1965         return send_request(p, NULL, &resp, oseq); /* SC */
1966 }
1967
1968 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callerid)
1969 {
1970         struct mgcp_request resp;
1971         char cid[256];
1972         char tone2[256];
1973         char *l, *n;
1974         time_t t;
1975         struct tm tm;
1976     struct mgcp_endpoint *p = sub->parent;
1977         
1978         time(&t);
1979         localtime_r(&t,&tm);
1980         if (callerid)
1981                 strncpy(cid, callerid, sizeof(cid) - 1);
1982         else
1983                 strcpy(cid, "");
1984         ast_callerid_parse(cid, &n, &l);
1985         if (l) {
1986                 ast_shrink_phone_number(l);
1987                 if (!ast_isphonenumber(l)) {
1988                         n = l;
1989                         l = "";
1990                 }
1991         } 
1992         if (!n)
1993                 n = "";
1994         if (!l)
1995                 l = "";
1996
1997     /* Keep track of last callerid for blacklist and callreturn */
1998     strncpy(p->lastcallerid, l, sizeof(p->lastcallerid) - 1);
1999
2000         snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 
2001                         tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
2002         strncpy(p->curtone, tone, sizeof(p->curtone) - 1);
2003         reqprep(&resp, p, "RQNT");
2004         add_header(&resp, "X", p->rqnt_ident); /* SC */
2005     switch (p->hookstate) {
2006             case MGCP_ONHOOK:
2007             add_header(&resp, "R", "L/hd(N)");
2008             break;
2009         case MGCP_OFFHOOK:
2010             add_header(&resp, "R", "L/hu(N),L/hf(N),D/[0-9#*](N)");
2011             break;
2012     }
2013     if (strlen(tone2)) {
2014         add_header(&resp, "S", tone2);
2015     }
2016     if (mgcpdebug) {
2017         ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on  %s@%s-%d in cxmode: %s\n", 
2018                     tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2019     }
2020     /* SC: fill in new fields */
2021     resp.cmd = MGCP_CMD_RQNT;
2022     resp.trid = oseq;
2023         return send_request(p, NULL, &resp, oseq);  /* SC */
2024 }
2025
2026 static int transmit_modify_request(struct mgcp_subchannel *sub)
2027 {
2028         struct mgcp_request resp;
2029     struct mgcp_endpoint *p = sub->parent;
2030         if (!strlen(sub->cxident)) {
2031                 /* We don't have a CXident yet, store the destination and
2032                    wait a bit */
2033                 return 0;
2034         }
2035     if (mgcpdebug) {
2036         ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", 
2037                     p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2038     }
2039         reqprep(&resp, p, "MDCX");
2040         add_header(&resp, "C", sub->callid);
2041         add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2042     /* SC: X header should not be sent. kept for compatibility */
2043         add_header(&resp, "X", sub->txident);
2044         add_header(&resp, "I", sub->cxident);
2045     switch (sub->parent->hookstate) {
2046             case MGCP_ONHOOK:
2047             add_header(&resp, "R", "L/hd(N)");
2048             break;
2049         case MGCP_OFFHOOK:
2050             add_header(&resp, "R", "L/hu(N),L/hf(N),D/[0-9#*](N)");
2051             break;
2052     }
2053     /* SC: fill in new fields */
2054     resp.cmd = MGCP_CMD_MDCX;
2055     resp.trid = oseq;
2056         return send_request(p, sub, &resp, oseq); /* SC */
2057 }
2058
2059
2060 static int transmit_audit_endpoint(struct mgcp_endpoint *p)
2061 {
2062         struct mgcp_request resp;
2063         reqprep(&resp, p, "AUEP");
2064     /* SC: removed unknown param VS */
2065         //add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");
2066         add_header(&resp, "F", "A");
2067     /* SC: fill in new fields */
2068     resp.cmd = MGCP_CMD_AUEP;
2069     resp.trid = oseq;
2070         return send_request(p, NULL, &resp, oseq);  /* SC */
2071 }
2072
2073 static int transmit_connection_del(struct mgcp_subchannel *sub)
2074 {
2075     struct mgcp_endpoint *p = sub->parent;
2076         struct mgcp_request resp;
2077     if (mgcpdebug) {
2078         ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", 
2079                     sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2080     }
2081         reqprep(&resp, p, "DLCX");
2082     /* SC: check if call id is avail */
2083     if (sub->callid[0])
2084         add_header(&resp, "C", sub->callid);
2085     /* SC: X header should not be sent. kept for compatibility */
2086         add_header(&resp, "X", sub->txident);
2087     /* SC: check if cxident is avail */
2088     if (sub->cxident[0])
2089         add_header(&resp, "I", sub->cxident);
2090     /* SC: fill in new fields */
2091     resp.cmd = MGCP_CMD_DLCX;
2092     resp.trid = oseq;
2093         return send_request(p, sub, &resp, oseq);  /* SC */
2094 }
2095
2096 static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
2097 {
2098         struct mgcp_request resp;
2099     if (mgcpdebug) {
2100         ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", 
2101                     cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
2102     }
2103         reqprep(&resp, p, "DLCX");
2104     /* SC: check if call id is avail */
2105     if (callid && *callid)
2106         add_header(&resp, "C", callid);
2107     /* SC: check if cxident is avail */
2108     if (cxident && *cxident)
2109         add_header(&resp, "I", cxident);
2110     /* SC: fill in new fields */
2111     resp.cmd = MGCP_CMD_DLCX;
2112     resp.trid = oseq;
2113         return send_request(p, p->sub, &resp, oseq);
2114 }
2115
2116 /* SC: cleanup pendng commands */
2117 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub) 
2118 {
2119     struct mgcp_request *t, *q;
2120
2121     if (p) {
2122         ast_mutex_lock(&p->rqnt_queue_lock);
2123         for (q = p->rqnt_queue; q; t = q->next, free(q), q=t);
2124         p->rqnt_queue = NULL;
2125         ast_mutex_unlock(&p->rqnt_queue_lock);
2126
2127         ast_mutex_lock(&p->cmd_queue_lock);
2128         for (q = p->cmd_queue; q; t = q->next, free(q), q=t);
2129         p->cmd_queue = NULL;
2130         ast_mutex_unlock(&p->cmd_queue_lock);
2131
2132         ast_mutex_lock(&p->sub->cx_queue_lock);
2133         for (q = p->sub->cx_queue; q; t = q->next, free(q), q=t);
2134         p->sub->cx_queue = NULL;
2135         ast_mutex_unlock(&p->sub->cx_queue_lock);
2136
2137         ast_mutex_lock(&p->sub->next->cx_queue_lock);
2138         for (q = p->sub->next->cx_queue; q; t = q->next, free(q), q=t);
2139         p->sub->next->cx_queue = NULL;
2140         ast_mutex_unlock(&p->sub->next->cx_queue_lock);
2141     }
2142     else if (sub){
2143         ast_mutex_lock(&sub->cx_queue_lock);
2144         for (q = sub->cx_queue; q; t = q->next, free(q), q=t);
2145         sub->cx_queue = NULL;
2146         ast_mutex_unlock(&sub->cx_queue_lock);
2147     }
2148 }
2149
2150
2151 /* SC: remove command transaction from queue */
2152 static struct mgcp_request *find_command(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
2153                                          struct mgcp_request **queue, ast_mutex_t *l, int ident)
2154 {
2155     struct mgcp_request *prev, *req;
2156
2157     ast_mutex_lock(l);
2158     for (prev = NULL, req = *queue; req; prev = req, req = req->next) {
2159         if (req->trid == ident) {
2160             /* remove from queue */
2161             if (!prev)
2162                 *queue = req->next;
2163             else
2164                 prev->next = req->next;
2165
2166             /* send next pending command */
2167             if (*queue) {
2168                 if (mgcpdebug) {
2169                     ast_verbose("Posting Queued Request:\n%s to %s:%d\n", (*queue)->data, 
2170                                 inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
2171                 }
2172
2173                 mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid);
2174             }
2175             break;
2176         }
2177     }
2178     ast_mutex_unlock(l);
2179     return req;
2180 }
2181
2182 /* SC: modified for new transport mechanism */
2183 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,  
2184                             int result, unsigned int ident, struct mgcp_request *resp)
2185 {
2186     char *c;
2187     struct mgcp_request *req;
2188     struct mgcp_gateway *gw = p->parent;
2189
2190     if (result < 200) {
2191         /* provisional response */
2192         return;
2193     }
2194
2195     if (sub)
2196         req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident);
2197     else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident)))
2198         req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2199
2200     if (!req) {
2201         if (option_verbose > 2) {
2202             ast_verbose(VERBOSE_PREFIX_3 "No command found on [%s] for transaction %d. Ignoring...\n", 
2203                         gw->name, ident);
2204         }
2205         return;
2206     }
2207
2208     if (p && (result >= 400) && (result <= 599)) {
2209         switch (result) {
2210             case 401:
2211                 p->hookstate = MGCP_OFFHOOK;
2212                 break;
2213             case 402:
2214                 p->hookstate = MGCP_ONHOOK;
2215                 break;
2216             case 406:
2217                 ast_log(LOG_NOTICE, "Transaction %d timed out\n", ident);
2218                 break;
2219             case 407:
2220                 ast_log(LOG_NOTICE, "Transaction %d aborted\n", ident);
2221                 break;
2222         }
2223         if (sub)
2224         {
2225             if (sub->owner) {
2226                 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 
2227                         result, p->name, p->parent->name, sub ? sub->id:-1);
2228                 ast_softhangup(sub->owner, AST_SOFTHANGUP_DEV);
2229             }
2230         }
2231         else {
2232             if (p->sub->next->owner) {
2233                 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 
2234                         result, p->name, p->parent->name, sub ? sub->id:-1);
2235                 ast_softhangup(p->sub->next->owner, AST_SOFTHANGUP_DEV);
2236             }
2237
2238             if (p->sub->owner) {
2239                 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 
2240                         result, p->name, p->parent->name, sub ? sub->id:-1);
2241                 ast_softhangup(p->sub->owner, AST_SOFTHANGUP_DEV);
2242             }
2243
2244             dump_cmd_queues(p, NULL);
2245         }
2246     }
2247
2248     if (resp) {
2249         if (req->cmd == MGCP_CMD_CRCX) {
2250             if ((c = get_header(resp, "I"))) {
2251                 if (strlen(c)) {
2252                     /* SC: if we are hanging up do not process this conn. */
2253                     if (sub->owner) {
2254                         if (strlen(sub->cxident)) {
2255                             if (strcasecmp(c, sub->cxident)) {
2256                                 ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c);
2257                             }
2258                         }
2259                         strncpy(sub->cxident, c, sizeof(sub->cxident) - 1);
2260                         if (sub->tmpdest.sin_addr.s_addr) {
2261                             transmit_modify_with_sdp(sub, NULL);
2262                         }
2263                     }
2264                     else {
2265                         /* XXX SC: delete this one
2266                            callid and conn id may already be lost. 
2267                            so the following del conn may have a side effect of 
2268                            cleaning up the next subchannel */
2269                         transmit_connection_del(sub);
2270                     }
2271                 }
2272             }
2273         }
2274
2275         if (req->cmd == MGCP_CMD_AUEP) {
2276             /* SC: check stale connection ids */
2277             if ((c = get_header(resp, "I"))) {
2278                 char *v, *n;
2279                 int len;
2280                 while ((v = get_csv(c, &len, &n))) {
2281                     if (len) {
2282                         if(strncasecmp(v, p->sub->cxident, len) &&
2283                            strncasecmp(v, p->sub->next->cxident, len)) {
2284                             /* connection id not found. delete it */
2285                             char cxident[80];
2286                             memcpy(cxident, v, len);
2287                             cxident[len] = '\0';
2288                             if (option_verbose > 2) {
2289                                 ast_verbose(VERBOSE_PREFIX_3 "Non existing connection id %s on %s@%s \n", 
2290                                             cxident, p->name, gw->name);
2291                             }
2292                             transmit_connection_del_w_params(p, NULL, cxident);
2293                         }
2294                     }
2295                     c = n;
2296                 }
2297             }
2298
2299             /* Try to determine the hookstate returned from an audit endpoint command */
2300             if ((c = get_header(resp, "ES"))) {
2301                 if (strlen(c)) {
2302                     if (strstr(c, "hu")) {
2303                         if (p->hookstate != MGCP_ONHOOK) {
2304                             /* SC: XXX cleanup if we think we are offhook XXX */
2305                             if ((p->sub->owner || p->sub->next->owner ) && 
2306                                 p->hookstate == MGCP_OFFHOOK)
2307                                 ast_softhangup(sub->owner, AST_SOFTHANGUP_DEV);
2308                             p->hookstate = MGCP_ONHOOK;
2309
2310                             /* SC: update the requested events according to the new hookstate */
2311                             transmit_notify_request(p->sub, "");
2312
2313                             /* SC: verbose level check */
2314                             if (option_verbose > 2) {
2315                                 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name);
2316                             }
2317                         }
2318                     } else if (strstr(c, "hd")) {
2319                         if (p->hookstate != MGCP_OFFHOOK) {
2320                             p->hookstate = MGCP_OFFHOOK;
2321
2322                             /* SC: update the requested events according to the new hookstate */
2323                             transmit_notify_request(p->sub, "");
2324
2325                             /* SC: verbose level check */
2326                             if (option_verbose > 2) {
2327                                 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name);
2328                             }
2329                         }
2330                     }
2331                 }
2332            }
2333         }
2334
2335         if (resp && resp->lines) {
2336             /* SC: do not process sdp if we are hanging up. this may be a late response */
2337             if (sub && sub->owner) {
2338                 if (!sub->rtp)
2339                     start_rtp(sub);
2340                 if (sub->rtp)
2341                     process_sdp(sub, resp);
2342             }
2343         }
2344     }
2345
2346     free(req);
2347 }
2348
2349 static void start_rtp(struct mgcp_subchannel *sub)
2350 {
2351                 ast_mutex_lock(&sub->lock);
2352         /* SC: check again to be on the safe side */
2353         if (sub->rtp) {
2354             ast_rtp_destroy(sub->rtp);
2355             sub->rtp = NULL;
2356         }
2357                 /* Allocate the RTP now */
2358                 sub->rtp = ast_rtp_new(sched, io, 1, 0);
2359                 if (sub->rtp && sub->owner)
2360                         sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
2361                 if (sub->rtp)
2362                         ast_rtp_setnat(sub->rtp, sub->nat);
2363 #if 0
2364                 ast_rtp_set_callback(p->rtp, rtpready);
2365                 ast_rtp_set_data(p->rtp, p);
2366 #endif          
2367                 /* Make a call*ID */
2368         snprintf(sub->callid, sizeof(sub->callid), "%08x%s", rand(), sub->txident);
2369                 /* Transmit the connection create */
2370                 transmit_connect_with_sdp(sub, NULL);
2371                 ast_mutex_unlock(&sub->lock);
2372 }
2373
2374 static void *mgcp_ss(void *data)
2375 {
2376         struct ast_channel *chan = data;
2377         struct mgcp_subchannel *sub = chan->pvt->pvt;
2378         struct mgcp_endpoint *p = sub->parent;
2379         char exten[AST_MAX_EXTENSION] = "";
2380         int len = 0;
2381         int timeout = firstdigittimeout;
2382         int res;
2383         int getforward=0;
2384     while(len < AST_MAX_EXTENSION-1) {
2385         res = ast_waitfordigit(chan, timeout);
2386         timeout = 0;
2387         if (res < 0) {
2388             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
2389             /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
2390                         ast_indicate(chan, -1);
2391             ast_hangup(chan);
2392             return NULL;
2393         } else if (res)  {
2394             exten[len++]=res;
2395             exten[len] = '\0';
2396         }
2397         if (!ast_ignore_pattern(chan->context, exten)) {
2398             /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
2399                         ast_indicate(chan, -1);
2400         } else {
2401             /* XXX Redundant?  We should already be playing dialtone */
2402             /*tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/
2403             transmit_notify_request(sub, "L/dl");
2404         }
2405         if (ast_exists_extension(chan, chan->context, exten, 1, p->callerid)) {
2406             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->callerid)) {
2407                 if (getforward) {
2408                     /* Record this as the forwarding extension */
2409                     strncpy(p->call_forward, exten, sizeof(p->call_forward)); 
2410                     if (option_verbose > 2) {
2411                         ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n", 
2412                                 p->call_forward, chan->name);
2413                     }
2414                     /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2415                     transmit_notify_request(sub, "L/sl");
2416                     if (res)
2417                         break;
2418                     usleep(500000);
2419                     /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
2420                     ast_indicate(chan, -1);
2421                     sleep(1);
2422                     memset(exten, 0, sizeof(exten));
2423                     /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/
2424                     transmit_notify_request(sub, "L/dl");
2425                     len = 0;
2426                     getforward = 0;
2427                 } else  {
2428                     /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
2429                     ast_indicate(chan, -1);
2430                     strncpy(chan->exten, exten, sizeof(chan->exten)-1);
2431                     if (strlen(p->callerid)) {
2432                         if (!p->hidecallerid) {
2433                             /* SC: free existing chan->callerid */
2434                             if (chan->callerid)
2435                                 free(chan->callerid);
2436                             chan->callerid = strdup(p->callerid);
2437                         }
2438                         if (chan->ani)
2439                             free(chan->ani);
2440                         chan->ani = strdup(p->callerid);
2441                     }
2442                     ast_setstate(chan, AST_STATE_RING);
2443                     /*zt_enable_ec(p);*/
2444                     res = ast_pbx_run(chan);
2445                     if (res) {
2446                         ast_log(LOG_WARNING, "PBX exited non-zero\n");
2447                         /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/
2448                         /*transmit_notify_request(p, "nbz", 1);*/
2449                         transmit_notify_request(sub, "G/cg");
2450                     }
2451                     return NULL;
2452                 }
2453             } else {
2454                 /* It's a match, but they just typed a digit, and there is an ambiguous match,
2455                    so just set the timeout to matchdigittimeout and wait some more */
2456                 timeout = matchdigittimeout;
2457             }
2458         } else if (res == 0) {
2459             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
2460             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/
2461             transmit_notify_request(sub, "G/cg");
2462             /*zt_wait_event(p->subs[index].zfd);*/
2463             ast_hangup(chan);
2464             return NULL;
2465         } else if (p->callwaiting && !strcmp(exten, "*70")) {
2466             if (option_verbose > 2) {
2467                 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
2468             }
2469             /* Disable call waiting if enabled */
2470             p->callwaiting = 0;
2471             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2472             transmit_notify_request(sub, "L/sl");
2473             len = 0;
2474             memset(exten, 0, sizeof(exten));
2475             timeout = firstdigittimeout;
2476                 
2477         } else if (!strcmp(exten,ast_pickup_ext())) {
2478             /* Scan all channels and see if any there
2479              * ringing channqels with that have call groups
2480              * that equal this channels pickup group  
2481              */
2482             if (ast_pickup_call(chan)) {
2483                 ast_log(LOG_WARNING, "No call pickup possible...\n");
2484                 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/
2485                 transmit_notify_request(sub, "G/cg");
2486             }
2487             ast_hangup(chan);
2488             return NULL;
2489             
2490         } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
2491             if (option_verbose > 2) {
2492                 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
2493             }
2494             /* Disable Caller*ID if enabled */
2495             p->hidecallerid = 1;
2496             if (chan->callerid)
2497                 free(chan->callerid);
2498             chan->callerid = NULL;
2499             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2500             transmit_notify_request(sub, "L/sl");
2501             len = 0;
2502             memset(exten, 0, sizeof(exten));
2503             timeout = firstdigittimeout;
2504         } else if (p->callreturn && !strcmp(exten, "*69")) {
2505             res = 0;
2506             if (strlen(p->lastcallerid)) {
2507                 res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language);
2508             }
2509             if (!res)
2510                 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2511                 transmit_notify_request(sub, "L/sl");
2512             break;
2513         } else if (!strcmp(exten, "*78")) {
2514             /* Do not disturb */
2515             if (option_verbose > 2) {
2516                 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name);
2517             }
2518             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2519             transmit_notify_request(sub, "L/sl");
2520             p->dnd = 1;
2521             getforward = 0;
2522             memset(exten, 0, sizeof(exten));
2523             len = 0;
2524         } else if (!strcmp(exten, "*79")) {
2525             /* Do not disturb */
2526             if (option_verbose > 2) {
2527                 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name);
2528             }
2529             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2530             transmit_notify_request(sub, "L/sl");
2531             p->dnd = 0;
2532             getforward = 0;
2533             memset(exten, 0, sizeof(exten));
2534             len = 0;
2535         } else if (p->cancallforward && !strcmp(exten, "*72")) {
2536             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2537             transmit_notify_request(sub, "L/sl");
2538             getforward = 1;
2539             memset(exten, 0, sizeof(exten));
2540             len = 0;
2541         } else if (p->cancallforward && !strcmp(exten, "*73")) {
2542             if (option_verbose > 2) {
2543                 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name);
2544             }
2545             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2546             transmit_notify_request(sub, "L/sl");
2547             memset(p->call_forward, 0, sizeof(p->call_forward));
2548             getforward = 0;
2549             memset(exten, 0, sizeof(exten));
2550             len = 0;
2551         } else if (!strcmp(exten, ast_parking_ext()) && 
2552                     sub->next->owner &&
2553                     sub->next->owner->bridge) {
2554             /* This is a three way call, the main call being a real channel, 
2555                 and we're parking the first call. */
2556             ast_masq_park_call(sub->next->owner->bridge, chan, 0, NULL);
2557             if (option_verbose > 2) {
2558                 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
2559             }
2560             break;
2561         } else if (strlen(p->lastcallerid) && !strcmp(exten, "*80")) {
2562             if (option_verbose > 2) {
2563                 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcallerid);
2564             }
2565             res = ast_db_put("blacklist", p->lastcallerid, "1");
2566             if (!res) {
2567                 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2568                 transmit_notify_request(sub, "L/sl");
2569                 memset(exten, 0, sizeof(exten));
2570                 len = 0;
2571             }
2572         } else if (p->hidecallerid && !strcmp(exten, "*82")) {
2573             if (option_verbose > 2) {
2574                 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
2575             }
2576             /* Enable Caller*ID if enabled */
2577             p->hidecallerid = 0;
2578             if (chan->callerid)
2579                 free(chan->callerid);
2580             if (strlen(p->callerid))
2581                 chan->callerid = strdup(p->callerid);
2582             /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
2583             transmit_notify_request(sub, "L/sl");
2584             len = 0;
2585             memset(exten, 0, sizeof(exten));
2586             timeout = firstdigittimeout;
2587         } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->callerid) &&
2588                         ((exten[0] != '*') || (strlen(exten) > 2))) {
2589             if (option_debug)
2590                 ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->callerid ? chan->callerid : "<Unknown Caller>", chan->context);
2591             break;
2592         }
2593         if (!timeout)
2594             timeout = gendigittimeout;
2595         if (len && !ast_ignore_pattern(chan->context, exten))
2596             /*tone_zone_play_tone(p->subs[index].zfd, -1);*/
2597                         ast_indicate(chan, -1);
2598     }
2599 #if 0
2600         for (;;) {
2601                 res = ast_waitfordigit(chan, to);
2602                 if (!res) {
2603                         ast_log(LOG_DEBUG, "Timeout...\n");
2604                         break;
2605                 }
2606                 if (res < 0) {
2607                         ast_log(LOG_DEBUG, "Got hangup...\n");
2608             ast_hangup(chan);
2609                         break;
2610                 }
2611                 exten[pos++] = res;
2612                 if (!ast_ignore_pattern(chan->context, exten))
2613                         ast_indicate(chan, -1);
2614                 if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
2615                         if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) 
2616                                 to = 3000;
2617                         else
2618                                 to = 8000;
2619                 } else
2620                         break;
2621         }
2622         if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
2623                 strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
2624         if (!p->rtp) {
2625             start_rtp(p);
2626         }
2627                 ast_setstate(chan, AST_STATE_RING);
2628                 chan->rings = 1;
2629                 if (ast_pbx_run(chan)) {
2630                         ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
2631                 } else
2632                         return NULL;
2633         }
2634 #endif
2635         ast_hangup(chan);
2636         return NULL;
2637 }
2638
2639 static int attempt_transfer(struct mgcp_endpoint *p)
2640 {
2641     /* *************************
2642      * I hope this works.
2643      * Copied out of chan_zap
2644      * Cross your fingers
2645      * *************************/
2646
2647         /* In order to transfer, we need at least one of the channels to
2648            actually be in a call bridge.  We can't conference two applications
2649            together (but then, why would we want to?) */
2650         if (p->sub->owner->bridge) {
2651                 /* The three-way person we're about to transfer to could still be in MOH, so
2652                    stop if now if appropriate */
2653                 if (p->sub->next->owner->bridge)
2654                         ast_moh_stop(p->sub->next->owner->bridge);
2655                 if (p->sub->owner->_state == AST_STATE_RINGING) {
2656                         ast_indicate(p->sub->next->owner->bridge, AST_CONTROL_RINGING);
2657                 }
2658                 if (ast_channel_masquerade(p->sub->next->owner, p->sub->owner->bridge)) {
2659                         ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
2660                                         p->sub->owner->bridge->name, p->sub->next->owner->name);
2661                         return -1;
2662                 }
2663                 /* Orphan the channel */
2664                 unalloc_sub(p->sub->next);
2665         } else if (p->sub->next->owner->bridge) {
2666                 if (p->sub->owner->_state == AST_STATE_RINGING) {
2667                         ast_indicate(p->sub->next->owner->bridge, AST_CONTROL_RINGING);
2668                 }
2669                 ast_moh_stop(p->sub->next->owner->bridge);
2670                 if (ast_channel_masquerade(p->sub->owner, p->sub->next->owner->bridge)) {
2671                         ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
2672                                         p->sub->next->owner->bridge->name, p->sub->owner->name);
2673                         return -1;
2674                 }
2675                 /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/
2676         if (option_verbose > 2) {
2677             ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
2678         }
2679         p->sub = p->sub->next;
2680                 unalloc_sub(p->sub->next);
2681                 /* Tell the caller not to hangup */
2682                 return 1;
2683         } else {
2684                 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
2685                                         p->sub->owner->name, p->sub->next->owner->name);
2686                 p->sub->next->owner->_softhangup |= AST_SOFTHANGUP_DEV;
2687         if (p->sub->next->owner) {
2688             p->sub->next->alreadygone = 1;
2689             ast_queue_hangup(p->sub->next->owner);
2690         }
2691         }
2692         return 0;
2693 }
2694
2695 static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev) 
2696 {
2697     struct mgcp_endpoint *p = sub->parent;
2698     struct ast_channel *c;
2699         pthread_t t;
2700         pthread_attr_t attr;
2701         pthread_attr_init(&attr);
2702         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);    
2703
2704     /* Off hook / answer */
2705     if (sub->outgoing) {
2706         /* Answered */
2707         if (sub->owner) {
2708             if (sub->owner->bridge) {
2709                 ast_moh_stop(sub->owner->bridge);
2710             }
2711             sub->cxmode = MGCP_CX_SENDRECV;
2712             if (!sub->rtp) {
2713                 start_rtp(sub);
2714             } else {
2715                 transmit_modify_request(sub);
2716             }
2717             /*transmit_notify_request(sub, "aw");*/
2718             transmit_notify_request(sub, "");
2719             ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
2720         }
2721     } else {
2722         /* Start switch */
2723         /*sub->cxmode = MGCP_CX_SENDRECV;*/
2724         if (!sub->owner) {
2725             if (!sub->rtp) {
2726                 start_rtp(sub);
2727             } else {
2728                 transmit_modify_request(sub);
2729             }
2730             if (p->immediate) {
2731                 /* The channel is immediately up.  Start right away */
2732                 transmit_notify_request(sub, "G/rt");
2733                 c = mgcp_new(sub, AST_STATE_RING);
2734                 if (!c) {
2735                     ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
2736                     transmit_notify_request(sub, "G/cg");
2737                     ast_hangup(c);
2738                 }
2739             } else {
2740                 if (has_voicemail(p)) {
2741                     transmit_notify_request(sub, "L/sl");
2742                 } else {
2743                     transmit_notify_request(sub, "L/dl");
2744                 }
2745                 c = mgcp_new(sub, AST_STATE_DOWN);
2746                 if (c) {
2747                     if (pthread_create(&t, &attr, mgcp_ss, c)) {
2748                         ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
2749                         ast_hangup(c);
2750                     }
2751                 } else {
2752                     ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
2753                 }
2754             }
2755         } else {
2756             if (p->hookstate == MGCP_OFFHOOK) {
2757                 ast_log(LOG_WARNING, "Off hook, but alreaedy have owner on %s@%s\n", p->name, p->parent->name);
2758             } else {
2759                 ast_log(LOG_WARNING, "On hook, but alreaedy have owner on %s@%s\n", p->name, p->parent->name);
2760                 ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?");
2761             }
2762             if (sub->owner->bridge) {
2763                 ast_moh_stop(sub->owner->bridge);
2764             }
2765             sub->cxmode = MGCP_CX_SENDRECV;
2766             if (!sub->rtp) {
2767                 start_rtp(sub);
2768             } else {
2769                 transmit_modify_request(sub);
2770             }
2771             /*transmit_notify_request(sub, "aw");*/
2772             transmit_notify_request(sub, "");
2773             /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/
2774         }
2775     }
2776 }
2777
2778 static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
2779 {
2780         char *ev, *s;
2781         struct ast_frame f = { 0, };
2782     struct mgcp_endpoint *p = sub->parent;
2783     struct mgcp_gateway *g = NULL;
2784     int res;
2785         if (mgcpdebug) {
2786                 ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
2787     }
2788         /* Clear out potential response */
2789         if (!strcasecmp(req->verb, "RSIP")) {
2790                 /* Test if this RSIP request is just a keepalive */
2791                 if(!strcasecmp( get_header(req, "RM"), "X-keepalive")) {
2792                         if (option_verbose > 2)
2793                                 ast_verbose(VERBOSE_PREFIX_3 "Received keepalive request from %s@%s\n", p->name, p->parent->name);
2794                         transmit_response(sub, "200", req, "OK");
2795                 } else {
2796                         dump_queue(p->parent, p);
2797             dump_cmd_queues(p, NULL);
2798                         
2799                         if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) {
2800                                         ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name);
2801                         }
2802                         // JS: For RSIP on wildcard we reset all endpoints
2803                         if (!strcmp(p->name, p->parent->wcardep)) {
2804                                 /* Reset all endpoints */
2805                                 struct mgcp_endpoint *tmp_ep;
2806                                                 
2807                                 g = p->parent;
2808                                 tmp_ep = g->endpoints;
2809                                 while (tmp_ep) {
2810                                         //if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/*") != 0)) {
2811                                         if (strcmp(tmp_ep->name, g->wcardep) != 0) {
2812                                                 struct mgcp_subchannel *tmp_sub, *first_sub;
2813                                                 if (option_verbose > 2) {
2814                                                         ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name);
2815                                                 }
2816                                                 
2817                                                 first_sub = tmp_ep->sub;
2818                                                 tmp_sub = tmp_ep->sub;
2819                                                 while (tmp_sub) {
2820                                                         if (tmp_sub->owner)
2821                                                                 ast_softhangup(sub->owner, AST_SOFTHANGUP_DEV);
2822                                                         tmp_sub = tmp_sub->next;
2823                                                         if (tmp_sub == first_sub)
2824                                                                 break;
2825                                                 } 
2826                                         }
2827                                         tmp_ep = tmp_ep->next;
2828                                 }
2829                         } else if (sub->owner) {
2830                                 ast_softhangup(sub->owner, AST_SOFTHANGUP_DEV);
2831                         }
2832                         transmit_response(sub, "200", req, "OK");
2833                         /* JS: We dont send NTFY or AUEP to wildcard ep */
2834                         if (strcmp(p->name, p->parent->wcardep) != 0) {
2835                                 transmit_notify_request(sub, "");
2836                 /* SC: Audit endpoint. 
2837                                  Idea is to prevent lost lines due to race conditions 
2838                                 */
2839                                 transmit_audit_endpoint(p);
2840                         }
2841                 }
2842         } else if (!strcasecmp(req->verb, "NTFY")) {
2843                 /* Acknowledge and be sure we keep looking for the same things */
2844                 transmit_response(sub, "200", req, "OK");
2845                 /* Notified of an event */
2846                 ev = get_header(req, "O");
2847                 s = strchr(ev, '/');
2848                 if (s) ev = s + 1;
2849         if (option_verbose > 2) {
2850             ast_verbose(VERBOSE_PREFIX_3 "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev);
2851         }
2852                 /* Keep looking for events unless this was a hangup */
2853                 if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd")) {
2854                         transmit_notify_request(sub, p->curtone);
2855         }
2856                 if (!strcasecmp(ev, "hd")) {
2857             p->hookstate = MGCP_OFFHOOK;
2858             sub->cxmode = MGCP_CX_SENDRECV;
2859             handle_hd_hf(sub, ev);
2860                 } else if (!strcasecmp(ev, "hf")) {
2861             /* We can assume we are offhook if we received a hookflash */
2862             /* First let's just do call wait and ignore threeway */
2863             /* We're currently in charge */
2864             if (p->hookstate != MGCP_OFFHOOK) {
2865                 /* Cisco c7940 sends hf even if the phone is onhook */
2866                 /* Thanks to point on IRC for pointing this out */
2867                 return -1;
2868             }
2869             /* do not let * confrnce two down channels */  
2870             if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) return -1;
2871
2872             if (p->callwaiting || p->transfer || p->threewaycalling) {
2873                 if (option_verbose > 2) {
2874                     ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
2875                 }
2876                 p->sub = p->sub->next;
2877
2878                 /* transfer control to our next subchannel */
2879                 if (!sub->next->owner) {
2880                     /* plave the first call on hold and start up a new call */
2881                     sub->cxmode = MGCP_CX_MUTE;
2882                     if (option_verbose > 2) {
2883                         ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
2884                     }
2885                     transmit_modify_request(sub);
2886                     if (sub->owner && sub->owner->bridge) {
2887                         ast_moh_start(sub->owner->bridge, NULL);
2888                     }
2889                     sub->next->cxmode = MGCP_CX_RECVONLY;
2890                     handle_hd_hf(sub->next, ev);
2891                 } else if (sub->owner && sub->next->owner) {
2892                     /* We've got two active calls lets decide whether or not to conference or just flip flop */
2893                     if ((!sub->outgoing) && (!sub->next->outgoing)) {
2894                         /* We made both calls lets conferenct */
2895                         if (option_verbose > 2) {
2896                             ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n", 
2897                                         sub->id, sub->next->id, p->name, p->parent->name);
2898                         }
2899                         sub->cxmode = MGCP_CX_CONF;
2900                         sub->next->cxmode = MGCP_CX_CONF;
2901                         if (sub->next->owner->bridge) {
2902                             ast_moh_stop(sub->next->owner->bridge);
2903                         }
2904                         transmit_modify_request(sub);
2905                         transmit_modify_request(sub->next);
2906                     } else {
2907                         /* Let's flipflop between calls */
2908                         /* XXX Need to check for state up ??? */
2909                         /* XXX Need a way to indicate the current call, or maybe the call that's waiting */
2910                         if (option_verbose > 2) {
2911                             ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n", 
2912                                         sub->id, sub->next->id, p->name, p->parent->name);
2913                         }
2914                         sub->cxmode = MGCP_CX_MUTE;
2915                         if (option_verbose > 2) {
2916                             ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
2917                         }
2918                         transmit_modify_request(sub);
2919                         if (sub->owner->bridge) {
2920                             ast_moh_start(sub->owner->bridge, NULL);
2921                         }
2922                         if (sub->next->owner->bridge) {
2923                             ast_moh_stop(sub->next->owner->bridge);
2924                         }
2925                         handle_hd_hf(sub->next, ev);
2926 #if 0
2927                         if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) {
2928                             handle_hd_hf(sub->next, ev);
2929                         } else {
2930                             ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name);
2931                             sub->next->cxmode = MGCP_CX_SENDRECV;
2932                             transmit_modify_request(sub->next);
2933                         }
2934 #endif
2935                     }
2936                 } else {
2937                     /* We've most likely lost one of our calls find an active call and bring it up */
2938                     if (sub->owner) {
2939                         p->sub = sub;
2940                     } else if (sub->next->owner) {
2941                         p->sub = sub->next;
2942                     } else {
2943                         /* We seem to have lost both our calls */
2944                         /* XXX - What do we do now? */
2945                         return -1;
2946                     }
2947                     if (p->sub->owner->bridge) {
2948                         ast_moh_stop(p->sub->owner->bridge);
2949                     }
2950                     p->sub->cxmode = MGCP_CX_SENDRECV;
2951                     transmit_modify_request(p->sub);
2952                 }
2953             } else {
2954                 ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", 
2955                         p->name, p->parent->name);
2956             }
2957             /* ast_moh_stop(sub->owner->bridge); */
2958                 } else if (!strcasecmp(ev, "hu")) {
2959             p->hookstate = MGCP_ONHOOK;
2960             sub->cxmode = MGCP_CX_RECVONLY;
2961             ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name);
2962             /* JS: Do we need to send MDCX before a DLCX ?
2963             if (sub->rtp) {
2964                 transmit_modify_request(sub);
2965             }
2966             */
2967             if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) {
2968                 /* We're allowed to transfer, we have two avtive calls and */
2969                 /* we made at least one of the calls.  Let's try and transfer */
2970                 if ((res = attempt_transfer(p)) < 0) {
2971                     if (p->sub->next->owner) {
2972                         sub->next->alreadygone = 1;
2973                         ast_queue_hangup(sub->next->owner);
2974                     }
2975                 } else if (res) {
2976                     ast_log(LOG_WARNING, "Transfer attempt failed\n");
2977                     return -1;
2978                 }
2979             } else {
2980                 /* Hangup the current call */
2981                 /* If there is another active call, mgcp_hangup will ring the phone with the other call */
2982                 if (sub->owner) {
2983                     sub->alreadygone = 1;
2984                     ast_queue_hangup(sub->owner);
2985                 } else {
2986                     /* SC: verbose level check */
2987                     if (option_verbose > 2) {
2988                         ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed\n", 
2989                                     p->name, p->parent->name, sub->id);
2990                     }
2991                 }
2992             }
2993             if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) {
2994                 if (has_voicemail(p)) {
2995                     if (option_verbose > 2) {
2996                         ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name);
2997                     }
2998                     transmit_notify_request(sub, "L/vmwi(+)");
2999                 } else {
3000                     if (option_verbose > 2) {
3001                         ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name);
3002                     }
3003                     transmit_notify_request(sub, "L/vmwi(-)");
3004                 }
3005             }
3006                 } else if ((strlen(ev) == 1) && 
3007                                         (((ev[0] >= '0') && (ev[0] <= '9')) ||
3008                                          ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
3009                                          (ev[0] == '*') || (ev[0] == '#'))) {
3010                         f.frametype = AST_FRAME_DTMF;
3011                         f.subclass = ev[0];
3012                         f.src = "mgcp";
3013                         if (sub->owner) {
3014                 /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */
3015                                 ast_queue_frame(sub->owner, &f);
3016                 if (sub->next->owner) {
3017                     ast_queue_frame(sub->next->owner, &f);
3018                 }
3019             }
3020             if (strstr(p->curtone, "wt") && (ev[0] == 'A')) {
3021                 memset(p->curtone, 0, sizeof(p->curtone));
3022             }
3023                 } 
3024         else if (!strcasecmp(ev, "T")) {
3025                         /* Digit timeout -- unimportant */
3026                 } else {
3027                         ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
3028                 }
3029         } else {
3030                 ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, inet_ntoa(sin->sin_addr));
3031                 transmit_response(sub, "510", req, "Unknown verb");
3032         }
3033         return 0;
3034 }
3035
3036 static int mgcpsock_read(int *id, int fd, short events, void *ignore)
3037 {
3038         struct mgcp_request req;
3039         struct sockaddr_in sin;
3040         struct mgcp_subchannel *sub;
3041         int res;
3042         int len;
3043         int result;
3044         int ident;
3045         len = sizeof(sin);
3046         memset(&req, 0, sizeof(req));
3047         res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
3048         if (res < 0) {
3049                 if (errno != ECONNREFUSED)
3050                         ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
3051                 return 1;
3052         }
3053         req.data[res] = '\0';
3054         req.len = res;
3055         if (mgcpdebug) {
3056                 ast_verbose("MGCP read: \n%s\nfrom %s:%d", req.data, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
3057     }
3058         parse(&req);
3059         if (req.headers < 1) {
3060                 /* Must have at least one header */
3061                 return 1;
3062         }
3063         if (!req.identifier || !strlen(req.identifier)) {
3064                 ast_log(LOG_NOTICE, "Message from %s missing identifier\n", inet_ntoa(sin.sin_addr));
3065                 return 1;
3066         }
3067
3068         if (sscanf(req.verb, "%d", &result) &&
3069                 sscanf(req.identifier, "%d", &ident)) {
3070                 /* Try to find who this message is for, if it's important */
3071                 sub = find_subchannel(NULL, ident, &sin);
3072                 if (sub) {
3073             struct mgcp_gateway *gw = sub->parent->parent;
3074             struct mgcp_message *cur, *prev;
3075
3076             ast_mutex_lock(&gw->msgs_lock);
3077             for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
3078                 if (cur->seqno == ident) {
3079                     ast_log(LOG_DEBUG, "Got response back on tansaction %d\n", ident);
3080                     if (prev)
3081                         prev->next = cur->next;
3082                     else 
3083                         gw->msgs = cur->next;
3084                     break;
3085                 }
3086             }
3087
3088             /* stop retrans timer if the queue is empty */
3089             if (!gw->msgs && (gw->retransid != -1)) {
3090                 ast_sched_del(sched, gw->retransid);
3091                 gw->retransid = -1;
3092             }
3093
3094             ast_mutex_unlock(&gw->msgs_lock);
3095
3096             if (cur) {
3097                 handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req);
3098                 free(cur);
3099                 return 1;
3100             }
3101
3102             ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n", 
3103                     gw->name, ident);
3104                 }
3105         } else {
3106                 if (!req.endpoint || !strlen(req.endpoint) || 
3107                     !req.version || !strlen(req.version) || 
3108                         !req.verb || !strlen(req.verb)) {
3109                         ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
3110                         return 1;
3111                 }
3112                 /* Process request, with iflock held */
3113                 sub = find_subchannel(req.endpoint, 0, &sin);
3114                 if (sub) {
3115             /* pass the request off to the currently mastering subchannel */
3116                         handle_request(sub, &req, &sin);
3117                 }
3118         }
3119         return 1;
3120 }
3121
3122 static int *mgcpsock_read_id = NULL;
3123
3124 static void *do_monitor(void *data)
3125 {
3126         int res;
3127         int reloading;
3128     /* struct mgcp_gateway *g; */
3129     /* struct mgcp_endpoint *e; */
3130         /*time_t thispass = 0, lastpass = 0;*/
3131
3132         /* Add an I/O event to our UDP socket */
3133         if (mgcpsock > -1) 
3134                 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL);
3135         
3136         /* This thread monitors all the frame relay interfaces which are not yet in use
3137            (and thus do not have a separate thread) indefinitely */
3138         /* From here on out, we die whenever asked */
3139         for(;;) {
3140         /* Check for a reload request */
3141                 ast_mutex_lock(&mgcp_reload_lock);
3142                 reloading = mgcp_reloading;
3143                 mgcp_reloading = 0;
3144                 ast_mutex_unlock(&mgcp_reload_lock);
3145                 if (reloading) {
3146                         if (option_verbose > 0)
3147                                 ast_verbose(VERBOSE_PREFIX_1 "Reloading MGCP\n");
3148                         mgcp_do_reload();
3149                 }
3150
3151         /* Check for interfaces needing to be killed */
3152                &n