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