Asterisk - The Open Source Telephony Project  GIT-master-4a4f1a5
chan_mgcp.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Implementation of Media Gateway Control Protocol
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \ingroup channel_drivers
26  */
27 
28 /*! \li \ref chan_mgcp.c uses the configuration file \ref mgcp.conf
29  * \addtogroup configuration_file
30  */
31 
32 /*! \page mgcp.conf mgcp.conf
33  * \verbinclude mgcp.conf.sample
34  */
35 
36 /*** MODULEINFO
37  <use type="module">res_pktccops</use>
38  <defaultenabled>no</defaultenabled>
39  <support_level>deprecated</support_level>
40  <deprecated_in>19</deprecated_in>
41  <removed_in>21</removed_in>
42  ***/
43 
44 #include "asterisk.h"
45 
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <net/if.h>
49 #include <fcntl.h>
50 #include <netdb.h>
51 #include <signal.h>
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/ip.h>
55 #include <arpa/inet.h>
56 #include <ctype.h>
57 
58 #include "asterisk/lock.h"
59 #include "asterisk/channel.h"
60 #include "asterisk/config.h"
61 #include "asterisk/module.h"
62 #include "asterisk/pickup.h"
63 #include "asterisk/pbx.h"
64 #include "asterisk/sched.h"
65 #include "asterisk/io.h"
66 #include "asterisk/rtp_engine.h"
67 #include "asterisk/acl.h"
68 #include "asterisk/callerid.h"
69 #include "asterisk/cli.h"
70 #include "asterisk/say.h"
71 #include "asterisk/astdb.h"
72 #include "asterisk/features.h"
73 #include "asterisk/app.h"
74 #include "asterisk/mwi.h"
75 #include "asterisk/musiconhold.h"
76 #include "asterisk/utils.h"
77 #include "asterisk/netsock2.h"
78 #include "asterisk/causes.h"
79 #include "asterisk/dsp.h"
80 #include "asterisk/devicestate.h"
81 #include "asterisk/stringfields.h"
82 #include "asterisk/abstract_jb.h"
83 #include "asterisk/chanvars.h"
84 #include "asterisk/pktccops.h"
85 #include "asterisk/stasis.h"
86 #include "asterisk/bridge.h"
88 #include "asterisk/parking.h"
90 #include "asterisk/format_cache.h"
91 
92 /*
93  * Define to work around buggy dlink MGCP phone firmware which
94  * appears not to know that "rt" is part of the "G" package.
95  */
96 /* #define DLINK_BUGGY_FIRMWARE */
97 
98 #define MGCPDUMPER
99 #define DEFAULT_EXPIRY 120
100 #define MAX_EXPIRY 3600
101 #define DIRECTMEDIA 1
102 
103 #ifndef INADDR_NONE
104 #define INADDR_NONE (in_addr_t)(-1)
105 #endif
106 
107 /*! Global jitterbuffer configuration - by default, jb is disabled
108  * \note Values shown here match the defaults shown in mgcp.conf.sample */
109 static struct ast_jb_conf default_jbconf =
110 {
111  .flags = 0,
112  .max_size = 200,
113  .resync_threshold = 1000,
114  .impl = "fixed",
115  .target_extra = 40,
116 };
117 static struct ast_jb_conf global_jbconf;
118 
119 static const char tdesc[] = "Media Gateway Control Protocol (MGCP)";
120 static const char config[] = "mgcp.conf";
121 
122 #define MGCP_DTMF_RFC2833 (1 << 0)
123 #define MGCP_DTMF_INBAND (1 << 1)
124 #define MGCP_DTMF_HYBRID (1 << 2)
125 
126 #define DEFAULT_MGCP_GW_PORT 2427 /*!< From RFC 2705 */
127 #define DEFAULT_MGCP_CA_PORT 2727 /*!< From RFC 2705 */
128 #define MGCP_MAX_PACKET 1500 /*!< Also from RFC 2543, should sub headers tho */
129 #define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit */
130 #define MAX_RETRANS 5 /*!< Try only 5 times for retransmissions */
131 
132 /*! MGCP rtp stream modes { */
133 #define MGCP_CX_SENDONLY 0
134 #define MGCP_CX_RECVONLY 1
135 #define MGCP_CX_SENDRECV 2
136 #define MGCP_CX_CONF 3
137 #define MGCP_CX_CONFERENCE 3
138 #define MGCP_CX_MUTE 4
139 #define MGCP_CX_INACTIVE 4
140 /*! } */
141 
142 static const char * const mgcp_cxmodes[] = {
143  "sendonly",
144  "recvonly",
145  "sendrecv",
146  "confrnce",
147  "inactive"
148 };
149 
150 enum {
160 };
161 
162 static char context[AST_MAX_EXTENSION] = "default";
163 
164 static char language[MAX_LANGUAGE] = "";
165 static char musicclass[MAX_MUSICCLASS] = "";
167 static char cid_num[AST_MAX_EXTENSION] = "";
168 static char cid_name[AST_MAX_EXTENSION] = "";
169 
170 static int dtmfmode = 0;
171 static int nat = 0;
172 static int ncs = 0;
173 static int pktcgatealloc = 0;
174 static int hangupongateremove = 0;
175 
178 
179 static struct {
180  unsigned int tos;
181  unsigned int tos_audio;
182  unsigned int cos;
183  unsigned int cos_audio;
184 } qos = { 0, 0, 0, 0 };
185 
186 static int immediate = 0;
187 
188 static int callwaiting = 0;
189 
190 static int callreturn = 0;
191 
192 static int slowsequence = 0;
193 
194 static int threewaycalling = 0;
195 
196 /*! This is for flashhook transfers */
197 static int transfer = 0;
198 
199 static int cancallforward = 0;
200 
201 static int singlepath = 0;
202 
204 
206 
208 
209 static int amaflags = 0;
210 
211 static int adsi = 0;
212 
213 static unsigned int oseq_global = 0;
215 
216 /*! Wait up to 16 seconds for first digit (FXO logic) */
217 static int firstdigittimeout = 16000;
218 
219 /*! How long to wait for following digits (FXO logic) */
220 static int gendigittimeout = 8000;
221 
222 /*! How long to wait for an extra digit, if there is an ambiguous match */
223 static int matchdigittimeout = 3000;
224 
225 /*! Protect the monitoring thread, so only one process can kill or start it, and not
226  when it's doing something critical. */
228 
230 
231 /*! This is the thread for the monitor which checks for input on the channels
232  * which are not currently in use.
233  */
235 
236 static int restart_monitor(void);
237 
240 
241 static char ourhost[MAXHOSTNAMELEN];
242 static struct in_addr __ourip;
243 static int ourport;
244 
245 static struct ast_sched_context *sched;
246 static struct io_context *io;
247 /*! The private structures of the mgcp channels are linked for
248  * selecting outgoing channels
249  */
250 
251 #define MGCP_MAX_HEADERS 64
252 #define MGCP_MAX_LINES 64
253 
254 struct mgcp_request {
255  int len;
256  char *verb;
257  char *identifier;
258  char *endpoint;
259  char *version;
260  int headers; /*!< MGCP Headers */
262  int lines; /*!< SDP Content */
265  int cmd; /*!< int version of verb = command */
266  unsigned int trid; /*!< int version of identifier = transaction id */
267  struct mgcp_request *next; /*!< next in the queue */
268 };
269 
270 /*! \brief mgcp_message: MGCP message for queuing up */
271 struct mgcp_message {
274  int retrans;
275  unsigned long expire;
276  unsigned int seqno;
277  int len;
279  char buf[0];
280 };
281 
282 #define RESPONSE_TIMEOUT 30 /*!< in seconds */
283 
285  time_t whensent;
286  int len;
287  int seqno;
289  char buf[0];
290 };
291 
292 #define MAX_SUBS 2
293 
294 #define SUB_REAL 0
295 #define SUB_ALT 1
296 
298  /*! subchannel magic string.
299  Needed to prove that any subchannel pointer passed by asterisk
300  really points to a valid subchannel memory area.
301  Ugly.. But serves the purpose for the time being.
302  */
303 #define MGCP_SUBCHANNEL_MAGIC "!978!"
304  char magic[6];
306  int id;
310  struct sockaddr_in tmpdest;
311  char txident[80]; /*! \todo FIXME txident is replaced by rqnt_ident in endpoint.
312  This should be obsoleted */
313  char cxident[80];
314  char callid[80];
315  int cxmode;
316  struct mgcp_request *cx_queue; /*!< pending CX commands */
317  ast_mutex_t cx_queue_lock; /*!< CX queue lock */
318  int nat;
319  int iseq; /*!< Not used? RTP? */
320  int outgoing;
322  int sdpsent;
323  struct cops_gate *gate;
324  struct mgcp_subchannel *next; /*!< for out circular linked list */
325 };
326 
327 #define MGCP_ONHOOK 1
328 #define MGCP_OFFHOOK 2
329 
330 #define TYPE_TRUNK 1
331 #define TYPE_LINE 2
332 
335  char name[80];
336  struct mgcp_subchannel *sub; /*!< Pointer to our current connection, channel and stuff */
338  char exten[AST_MAX_EXTENSION]; /*!< Extension where to start */
341  char cid_num[AST_MAX_EXTENSION]; /*!< Caller*ID number */
342  char cid_name[AST_MAX_EXTENSION]; /*!< Caller*ID name */
343  char lastcallerid[AST_MAX_EXTENSION]; /*!< Last Caller*ID */
344  char dtmf_buf[AST_MAX_EXTENSION]; /*!< place to collect digits be */
345  char call_forward[AST_MAX_EXTENSION]; /*!< Last Caller*ID */
347  char curtone[80]; /*!< Current tone */
349  char parkinglot[AST_MAX_CONTEXT]; /*!< Parkinglot */
355  int transfer;
361  int dnd; /* How does this affect callwait? Do we just deny a mgcp_request if we're dnd? */
364  int dtmfmode;
365  int amaflags;
366  int ncs;
369  int type;
370  int slowsequence; /*!< MS: Sequence the endpoint as a whole */
371  int group;
372  int iseq; /*!< Not used? */
373  int lastout; /*!< tracking this on the subchannels. Is it needed here? */
374  int needdestroy; /*!< Not used? */
378  int msgstate; /*!< voicemail message state */
381  int adsi;
382  char rqnt_ident[80]; /*!< request identifier */
383  struct mgcp_request *rqnt_queue; /*!< pending RQNT commands */
385  struct mgcp_request *cmd_queue; /*!< pending commands other than RQNT */
387  int delme; /*!< needed for reload */
388  int needaudit; /*!< needed for reload */
389  struct ast_dsp *dsp; /*!< XXX Should there be a dsp/subchannel? XXX */
390  /* owner is tracked on the subchannels, and the *sub indicates whos in charge */
391  /* struct ast_channel *owner; */
392  /* struct ast_rtp *rtp; */
393  /* struct sockaddr_in tmpdest; */
394  /* message go the endpoint and not the channel so they stay here */
395  struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
398 };
399 
400 static struct mgcp_gateway {
401  /* A gateway containing one or more endpoints */
402  char name[80];
403  int isnamedottedip; /*!< is the name FQDN or dotted ip */
404  struct sockaddr_in addr;
405  struct sockaddr_in defaddr;
406  struct in_addr ourip;
407  int dynamic;
408  int expire; /*!< XXX Should we ever expire dynamic registrations? XXX */
410  struct ast_ha *ha;
411 /* obsolete
412  time_t lastouttime;
413  int lastout;
414  int messagepending;
415 */
416 /* Wildcard endpoint name */
417  char wcardep[30];
418  struct mgcp_message *msgs; /*!< gw msg queue */
419  ast_mutex_t msgs_lock; /*!< queue lock */
420  int retransid; /*!< retrans timer id */
421  int delme; /*!< needed for reload */
422  int realtime;
426 
428 static int mgcp_reloading = 0;
429 
430 /*! \brief gatelock: mutex for gateway/endpoint lists */
432 
433 static int mgcpsock = -1;
434 
435 static struct sockaddr_in bindaddr;
436 
437 static void mgcp_set_owner(struct mgcp_subchannel *sub, struct ast_channel *chan);
438 static struct ast_frame *mgcp_read(struct ast_channel *ast);
439 static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest);
440 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);
441 static int transmit_modify_request(struct mgcp_subchannel *sub);
442 static int transmit_connect(struct mgcp_subchannel *sub);
443 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername);
444 static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, const struct ast_format_cap *codecs);
445 static int transmit_connection_del(struct mgcp_subchannel *sub);
446 static int transmit_audit_endpoint(struct mgcp_endpoint *p);
447 static void start_rtp(struct mgcp_subchannel *sub);
448 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
449  int result, unsigned int ident, struct mgcp_request *resp);
450 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);
451 static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
452 static int reload_config(int reload);
453 
454 static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause);
455 static int mgcp_call(struct ast_channel *ast, const char *dest, int timeout);
456 static int mgcp_hangup(struct ast_channel *ast);
457 static int mgcp_answer(struct ast_channel *ast);
458 static struct ast_frame *mgcp_read(struct ast_channel *ast);
459 static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame);
460 static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);
461 static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
462 static int mgcp_senddigit_begin(struct ast_channel *ast, char digit);
463 static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
464 static int mgcp_devicestate(const char *data);
465 static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone);
466 static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp);
467 static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v);
468 static int mgcp_alloc_pktcgate(struct mgcp_subchannel *sub);
469 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
470 static struct ast_variable *add_var(const char *buf, struct ast_variable *list);
471 static struct ast_variable *copy_vars(struct ast_variable *src);
472 
473 static struct ast_channel_tech mgcp_tech = {
474  .type = "MGCP",
475  .description = tdesc,
477  .requester = mgcp_request,
478  .devicestate = mgcp_devicestate,
479  .call = mgcp_call,
480  .hangup = mgcp_hangup,
481  .answer = mgcp_answer,
482  .read = mgcp_read,
483  .write = mgcp_write,
484  .indicate = mgcp_indicate,
485  .fixup = mgcp_fixup,
486  .send_digit_begin = mgcp_senddigit_begin,
487  .send_digit_end = mgcp_senddigit_end,
488  .func_channel_read = acf_channel_read,
489 };
490 
491 static int has_voicemail(struct mgcp_endpoint *p)
492 {
493  int new_msgs;
494  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
495 
497  if (msg) {
498  struct ast_mwi_state *mwi_state = stasis_message_data(msg);
499  new_msgs = mwi_state->new_msgs;
500  } else {
502  }
503 
504  return new_msgs;
505 }
506 
507 static int unalloc_sub(struct mgcp_subchannel *sub)
508 {
509  struct mgcp_endpoint *p = sub->parent;
510  if (p->sub == sub) {
511  ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, p->parent->name);
512  return -1;
513  }
514  ast_debug(1, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name);
515 
517  if (!ast_strlen_zero(sub->cxident)) {
519  }
520  sub->cxident[0] = '\0';
521  sub->callid[0] = '\0';
522  sub->cxmode = MGCP_CX_INACTIVE;
523  sub->outgoing = 0;
524  sub->alreadygone = 0;
525  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
526  if (sub->rtp) {
528  sub->rtp = NULL;
529  }
531  return 0;
532 }
533 
534 /* modified for new transport mechanism */
535 static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
536 {
537  int res;
538  if (gw->addr.sin_addr.s_addr)
539  res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in));
540  else
541  res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in));
542  if (res != len) {
543  ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
544  }
545  return res;
546 }
547 
548 static int resend_response(struct mgcp_subchannel *sub, struct mgcp_response *resp)
549 {
550  struct mgcp_endpoint *p = sub->parent;
551  int res;
552  ast_debug(1, "Retransmitting:\n%s\n to %s:%d\n", resp->buf, ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
553  res = __mgcp_xmit(p->parent, resp->buf, resp->len);
554  if (res > 0)
555  res = 0;
556  return res;
557 }
558 
559 static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req)
560 {
561  struct mgcp_endpoint *p = sub->parent;
562  int res;
563  ast_debug(1, "Transmitting:\n%s\n to %s:%d\n", req->data, ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
564  res = __mgcp_xmit(p->parent, req->data, req->len);
565  if (res > 0)
566  res = 0;
567  return res;
568 }
569 
570 /* modified for new transport framework */
571 static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
572 {
573  struct mgcp_message *cur, *q = NULL, *w, *prev;
574 
576  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
577  if (!p || cur->owner_ep == p) {
578  if (prev) {
579  prev->next = cur->next;
580  } else {
581  gw->msgs = cur->next;
582  }
583 
584  ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n",
585  gw->name, cur->seqno);
586 
587  w = cur;
588  if (q) {
589  w->next = q;
590  } else {
591  w->next = NULL;
592  }
593  q = w;
594  }
595  }
597 
598  while (q) {
599  cur = q;
600  q = q->next;
601  ast_free(cur);
602  }
603 }
604 
605 static void mgcp_queue_frame(struct mgcp_subchannel *sub, struct ast_frame *f)
606 {
607  for (;;) {
608  if (sub->owner) {
609  if (!ast_channel_trylock(sub->owner)) {
610  ast_queue_frame(sub->owner, f);
611  ast_channel_unlock(sub->owner);
612  break;
613  } else {
614  DEADLOCK_AVOIDANCE(&sub->lock);
615  }
616  } else {
617  break;
618  }
619  }
620 }
621 
623 {
624  for (;;) {
625  if (sub->owner) {
626  if (!ast_channel_trylock(sub->owner)) {
627  ast_queue_hangup(sub->owner);
628  ast_channel_unlock(sub->owner);
629  break;
630  } else {
631  DEADLOCK_AVOIDANCE(&sub->lock);
632  }
633  } else {
634  break;
635  }
636  }
637 }
638 
639 static void mgcp_queue_control(struct mgcp_subchannel *sub, int control)
640 {
641  struct ast_frame f = { AST_FRAME_CONTROL, { control } };
642  return mgcp_queue_frame(sub, &f);
643 }
644 
645 static int retrans_pkt(const void *data)
646 {
647  struct mgcp_gateway *gw = (struct mgcp_gateway *)data;
648  struct mgcp_message *cur, *exq = NULL, *w, *prev;
649  int res = 0;
650 
651  /* find out expired msgs */
653 
654  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
655  if (cur->retrans < MAX_RETRANS) {
656  cur->retrans++;
657  ast_debug(1, "Retransmitting #%d transaction %u on [%s]\n",
658  cur->retrans, cur->seqno, gw->name);
659  __mgcp_xmit(gw, cur->buf, cur->len);
660  } else {
661  if (prev)
662  prev->next = cur->next;
663  else
664  gw->msgs = cur->next;
665 
666  ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n",
667  cur->seqno, gw->name);
668 
669  w = cur;
670 
671  if (exq) {
672  w->next = exq;
673  } else {
674  w->next = NULL;
675  }
676  exq = w;
677  }
678  }
679 
680  if (!gw->msgs) {
681  gw->retransid = -1;
682  res = 0;
683  } else {
684  res = 1;
685  }
687 
688  while (exq) {
689  cur = exq;
690  /* time-out transaction */
691  handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL);
692  exq = exq->next;
693  ast_free(cur);
694  }
695 
696  return res;
697 }
698 
699 /* modified for the new transaction mechanism */
700 static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
701  char *data, int len, unsigned int seqno)
702 {
703  struct mgcp_message *msg;
704  struct mgcp_message *cur;
705  struct mgcp_gateway *gw;
706  struct timeval now;
707 
708  if (!(msg = ast_malloc(sizeof(*msg) + len))) {
709  return -1;
710  }
711  if (!(gw = ((p && p->parent) ? p->parent : NULL))) {
712  ast_free(msg);
713  return -1;
714  }
715 
716  msg->owner_sub = sub;
717  msg->owner_ep = p;
718  msg->seqno = seqno;
719  msg->next = NULL;
720  msg->len = len;
721  msg->retrans = 0;
722  memcpy(msg->buf, data, msg->len);
723 
725  for (cur = gw->msgs; cur && cur->next; cur = cur->next);
726  if (cur) {
727  cur->next = msg;
728  } else {
729  gw->msgs = msg;
730  }
731 
732  now = ast_tvnow();
733  msg->expire = now.tv_sec * 1000 + now.tv_usec / 1000 + DEFAULT_RETRANS;
734 
735  if (gw->retransid == -1)
738  __mgcp_xmit(gw, msg->buf, msg->len);
739  /* XXX Should schedule retransmission XXX */
740  return 0;
741 }
742 
743 /* modified for new transport */
744 static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
745  struct mgcp_request *req, unsigned int seqno)
746 {
747  int res = 0;
748  struct mgcp_request **queue, *q, *r, *t;
749  ast_mutex_t *l;
750 
751  ast_debug(1, "Slow sequence is %d\n", p->slowsequence);
752  if (p->slowsequence) {
753  queue = &p->cmd_queue;
754  l = &p->cmd_queue_lock;
755  ast_mutex_lock(l);
756  } else {
757  switch (req->cmd) {
758  case MGCP_CMD_DLCX:
759  queue = &sub->cx_queue;
760  l = &sub->cx_queue_lock;
761  ast_mutex_lock(l);
762  q = sub->cx_queue;
763  /* delete pending cx cmds */
764  /* buggy sb5120 */
765  if (!sub->parent->ncs) {
766  while (q) {
767  r = q->next;
768  ast_free(q);
769  q = r;
770  }
771  *queue = NULL;
772  }
773  break;
774 
775  case MGCP_CMD_CRCX:
776  case MGCP_CMD_MDCX:
777  queue = &sub->cx_queue;
778  l = &sub->cx_queue_lock;
779  ast_mutex_lock(l);
780  break;
781 
782  case MGCP_CMD_RQNT:
783  queue = &p->rqnt_queue;
784  l = &p->rqnt_queue_lock;
785  ast_mutex_lock(l);
786  break;
787 
788  default:
789  queue = &p->cmd_queue;
790  l = &p->cmd_queue_lock;
791  ast_mutex_lock(l);
792  break;
793  }
794  }
795 
796  if (!(r = ast_malloc(sizeof(*r)))) {
797  ast_log(LOG_WARNING, "Cannot post MGCP request: insufficient memory\n");
798  ast_mutex_unlock(l);
799  return -1;
800  }
801  memcpy(r, req, sizeof(*r));
802 
803  if (!(*queue)) {
804  ast_debug(1, "Posting Request:\n%s to %s:%d\n", req->data,
805  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
806 
807  res = mgcp_postrequest(p, sub, req->data, req->len, seqno);
808  } else {
809  ast_debug(1, "Queueing Request:\n%s to %s:%d\n", req->data,
810  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
811  }
812 
813  /* XXX find tail. We could also keep tail in the data struct for faster access */
814  for (t = *queue; t && t->next; t = t->next);
815 
816  r->next = NULL;
817  if (t)
818  t->next = r;
819  else
820  *queue = r;
821 
822  ast_mutex_unlock(l);
823 
824  return res;
825 }
826 
827 static int mgcp_call(struct ast_channel *ast, const char *dest, int timeout)
828 {
829  int res;
830  struct mgcp_endpoint *p;
831  struct mgcp_subchannel *sub;
832  char tone[50] = "";
833  const char *distinctive_ring = pbx_builtin_getvar_helper(ast, "ALERT_INFO");
834 
835  ast_debug(3, "MGCP mgcp_call(%s)\n", ast_channel_name(ast));
836  sub = ast_channel_tech_pvt(ast);
837  p = sub->parent;
838 
839  ast_mutex_lock(&sub->lock);
840  switch (p->hookstate) {
841  case MGCP_OFFHOOK:
842  if (!ast_strlen_zero(distinctive_ring)) {
843  snprintf(tone, sizeof(tone), "L/wt%s", distinctive_ring);
844  ast_debug(3, "MGCP distinctive callwait %s\n", tone);
845  } else {
846  ast_copy_string(tone, (p->ncs ? "L/wt1" : "L/wt"), sizeof(tone));
847  ast_debug(3, "MGCP normal callwait %s\n", tone);
848  }
849  break;
850  case MGCP_ONHOOK:
851  default:
852  if (!ast_strlen_zero(distinctive_ring)) {
853  snprintf(tone, sizeof(tone), "L/r%s", distinctive_ring);
854  ast_debug(3, "MGCP distinctive ring %s\n", tone);
855  } else {
856  ast_copy_string(tone, "L/rg", sizeof(tone));
857  ast_debug(3, "MGCP default ring\n");
858  }
859  break;
860  }
861 
863  ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
864  ast_mutex_unlock(&sub->lock);
865  return -1;
866  }
867 
868  res = 0;
869  sub->outgoing = 1;
870  sub->cxmode = MGCP_CX_RECVONLY;
872  if (p->type == TYPE_LINE) {
873  if (!sub->rtp) {
874  start_rtp(sub);
875  } else {
877  }
878 
879  if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
880  /* try to prevent a callwait from disturbing the other connection */
881  sub->next->cxmode = MGCP_CX_RECVONLY;
883  }
884 
886  S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""),
887  S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""));
889 
890  if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
891  /* Put the connection back in sendrecv */
892  sub->next->cxmode = MGCP_CX_SENDRECV;
894  }
895  } else {
896  ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n");
897  res = -1;
898  }
899  ast_mutex_unlock(&sub->lock);
900  return res;
901 }
902 
903 static int mgcp_hangup(struct ast_channel *ast)
904 {
906  struct mgcp_endpoint *p = sub->parent;
907 
908  ast_debug(1, "mgcp_hangup(%s)\n", ast_channel_name(ast));
909  if (!ast_channel_tech_pvt(ast)) {
910  ast_debug(1, "Asked to hangup channel not connected\n");
911  return 0;
912  }
913  if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) {
914  ast_debug(1, "Invalid magic. MGCP subchannel freed up already.\n");
915  return 0;
916  }
917  ast_mutex_lock(&sub->lock);
918  ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s\n", ast_channel_name(ast), p->name, p->parent->name);
919 
920  if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) {
921  /* check whether other channel is active. */
922  if (!sub->next->owner) {
923  if (p->dtmfmode & MGCP_DTMF_HYBRID) {
924  p->dtmfmode &= ~MGCP_DTMF_INBAND;
925  }
926  ast_debug(2, "MGCP free dsp on %s@%s\n", p->name, p->parent->name);
927  ast_dsp_free(p->dsp);
928  p->dsp = NULL;
929  }
930  }
931 
933 
934  /* for deleting gate */
935  if (p->pktcgatealloc && sub->gate) {
936  sub->gate->gate_open = NULL;
937  sub->gate->gate_remove = NULL;
938  sub->gate->got_dq_gi = NULL;
939  sub->gate->tech_pvt = NULL;
940  if (sub->gate->state == GATE_ALLOC_PROGRESS || sub->gate->state == GATE_ALLOCATED) {
941  ast_pktccops_gate_alloc(GATE_DEL, sub->gate, 0, 0, 0, 0, 0, 0, NULL, NULL);
942  } else {
943  sub->gate->deltimer = time(NULL) + 5;
944  }
945  sub->gate = NULL;
946  }
947 
948  if (!ast_strlen_zero(sub->cxident)) {
950  }
951  sub->cxident[0] = '\0';
952  if ((sub == p->sub) && sub->next->owner) {
953  RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(sub->next->owner), ast_channel_cleanup);
954 
955  if (p->hookstate == MGCP_OFFHOOK) {
956  if (sub->next->owner && bridged) {
957  /* ncs fix! */
958  transmit_notify_request_with_callerid(p->sub, (p->ncs ? "L/wt1" : "L/wt"),
959  S_COR(ast_channel_caller(bridged)->id.number.valid, ast_channel_caller(bridged)->id.number.str, ""),
960  S_COR(ast_channel_caller(bridged)->id.name.valid, ast_channel_caller(bridged)->id.name.str, ""));
961  }
962  } else {
963  /* set our other connection as the primary and swith over to it */
964  p->sub = sub->next;
967  if (sub->next->owner && bridged) {
969  S_COR(ast_channel_caller(bridged)->id.number.valid, ast_channel_caller(bridged)->id.number.str, ""),
970  S_COR(ast_channel_caller(bridged)->id.name.valid, ast_channel_caller(bridged)->id.name.str, ""));
971  }
972  }
973 
974  } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) {
975  transmit_notify_request(sub, p->ncs ? "" : "L/v");
976  } else if (p->hookstate == MGCP_OFFHOOK) {
977  transmit_notify_request(sub, "L/ro");
978  } else {
980  }
981 
983  sub->alreadygone = 0;
984  sub->outgoing = 0;
985  sub->cxmode = MGCP_CX_INACTIVE;
986  sub->callid[0] = '\0';
987  if (p) {
988  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
989  }
990  /* Reset temporary destination */
991  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
992  if (sub->rtp) {
994  sub->rtp = NULL;
995  }
996 
998 
999  if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) {
1000  p->hidecallerid = 0;
1001  if (p->hascallwaiting && !p->callwaiting) {
1002  ast_verb(3, "Enabling call waiting on %s\n", ast_channel_name(ast));
1003  p->callwaiting = -1;
1004  }
1005  if (has_voicemail(p)) {
1006  ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n",
1007  ast_channel_name(ast), p->name, p->parent->name);
1008  transmit_notify_request(sub, "L/vmwi(+)");
1009  } else {
1010  ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n",
1011  ast_channel_name(ast), p->name, p->parent->name);
1012  transmit_notify_request(sub, "L/vmwi(-)");
1013  }
1014  }
1015  ast_mutex_unlock(&sub->lock);
1016  return 0;
1017 }
1018 
1019 static char *handle_mgcp_show_endpoints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1020 {
1021  struct mgcp_gateway *mg;
1022  struct mgcp_endpoint *me;
1023  int hasendpoints = 0;
1024  struct ast_variable * v = NULL;
1025 
1026  switch (cmd) {
1027  case CLI_INIT:
1028  e->command = "mgcp show endpoints";
1029  e->usage =
1030  "Usage: mgcp show endpoints\n"
1031  " Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";
1032  return NULL;
1033  case CLI_GENERATE:
1034  return NULL;
1035  }
1036 
1037  if (a->argc != 3) {
1038  return CLI_SHOWUSAGE;
1039  }
1041  for (mg = gateways; mg; mg = mg->next) {
1042  ast_cli(a->fd, "Gateway '%s' at %s (%s%s)\n", mg->name, mg->addr.sin_addr.s_addr ? ast_inet_ntoa(mg->addr.sin_addr) : ast_inet_ntoa(mg->defaddr.sin_addr), mg->realtime ? "Realtime, " : "", mg->dynamic ? "Dynamic" : "Static");
1043  for (me = mg->endpoints; me; me = me->next) {
1044  ast_cli(a->fd, " -- '%s@%s in '%s' is %s\n", me->name, mg->name, me->context, me->sub->owner ? "active" : "idle");
1045  if (me->chanvars) {
1046  ast_cli(a->fd, " Variables:\n");
1047  for (v = me->chanvars ; v ; v = v->next) {
1048  ast_cli(a->fd, " %s = '%s'\n", v->name, v->value);
1049  }
1050  }
1051  hasendpoints = 1;
1052  }
1053  if (!hasendpoints) {
1054  ast_cli(a->fd, " << No Endpoints Defined >> ");
1055  }
1056  }
1058  return CLI_SUCCESS;
1059 }
1060 
1061 static char *handle_mgcp_audit_endpoint(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1062 {
1063  struct mgcp_gateway *mg;
1064  struct mgcp_endpoint *me;
1065  int found = 0;
1066  char *ename,*gname, *c;
1067 
1068  switch (cmd) {
1069  case CLI_INIT:
1070  e->command = "mgcp audit endpoint";
1071  e->usage =
1072  "Usage: mgcp audit endpoint <endpointid>\n"
1073  " Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n"
1074  " Debug logging (core set debug on) MUST be on to see the results of this command.\n";
1075  return NULL;
1076  case CLI_GENERATE:
1077  return NULL;
1078  }
1079 
1080  if (!DEBUG_ATLEAST(1)) {
1081  return CLI_SHOWUSAGE;
1082  }
1083  if (a->argc != 4)
1084  return CLI_SHOWUSAGE;
1085  /* split the name into parts by null */
1086  ename = ast_strdupa(a->argv[3]);
1087  for (gname = ename; *gname; gname++) {
1088  if (*gname == '@') {
1089  *gname = 0;
1090  gname++;
1091  break;
1092  }
1093  }
1094  if (gname[0] == '[') {
1095  gname++;
1096  }
1097  if ((c = strrchr(gname, ']'))) {
1098  *c = '\0';
1099  }
1101  for (mg = gateways; mg; mg = mg->next) {
1102  if (!strcasecmp(mg->name, gname)) {
1103  for (me = mg->endpoints; me; me = me->next) {
1104  if (!strcasecmp(me->name, ename)) {
1105  found = 1;
1107  break;
1108  }
1109  }
1110  if (found) {
1111  break;
1112  }
1113  }
1114  }
1115  if (!found) {
1116  ast_cli(a->fd, " << Could not find endpoint >> ");
1117  }
1119  return CLI_SUCCESS;
1120 }
1121 
1122 static struct ast_cli_entry cli_mgcp[] = {
1123  AST_CLI_DEFINE(handle_mgcp_audit_endpoint, "Audit specified MGCP endpoint"),
1124  AST_CLI_DEFINE(handle_mgcp_show_endpoints, "List defined MGCP endpoints"),
1125  AST_CLI_DEFINE(mgcp_reload, "Reload MGCP configuration"),
1126 };
1127 
1128 static int mgcp_answer(struct ast_channel *ast)
1129 {
1130  int res = 0;
1131  struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
1132  struct mgcp_endpoint *p = sub->parent;
1133 
1134  ast_mutex_lock(&sub->lock);
1135  sub->cxmode = MGCP_CX_SENDRECV;
1136  if (!sub->rtp) {
1137  start_rtp(sub);
1138  } else {
1140  }
1141  ast_verb(3, "MGCP mgcp_answer(%s) on %s@%s-%d\n",
1142  ast_channel_name(ast), p->name, p->parent->name, sub->id);
1143  if (ast_channel_state(ast) != AST_STATE_UP) {
1144  ast_setstate(ast, AST_STATE_UP);
1145  ast_debug(1, "mgcp_answer(%s)\n", ast_channel_name(ast));
1148  }
1149  ast_mutex_unlock(&sub->lock);
1150  return res;
1151 }
1152 
1154 {
1155  /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
1156  struct ast_frame *f;
1157 
1158  f = ast_rtp_instance_read(sub->rtp, 0);
1159  /* Don't send RFC2833 if we're not supposed to */
1160  if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833))
1161  return &ast_null_frame;
1162  if (sub->owner) {
1163  /* We already hold the channel lock */
1164  if (f->frametype == AST_FRAME_VOICE) {
1166  struct ast_format_cap *caps;
1167 
1168  ast_debug(1, "Oooh, format changed to %s\n", ast_format_get_name(f->subclass.format));
1169 
1171  if (caps) {
1172  ast_format_cap_append(caps, f->subclass.format, 0);
1173  ast_channel_nativeformats_set(sub->owner, caps);
1174  ao2_ref(caps, -1);
1175  } else {
1176  return &ast_null_frame;
1177  }
1178 
1181  }
1182  /* Courtesy fearnor aka alex@pilosoft.com */
1183  if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
1184 #if 0
1185  ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n");
1186 #endif
1187  f = ast_dsp_process(sub->owner, sub->parent->dsp, f);
1188  }
1189  }
1190  }
1191  return f;
1192 }
1193 
1194 static void mgcp_set_owner(struct mgcp_subchannel *sub, struct ast_channel *chan)
1195 {
1196  sub->owner = chan;
1197  if (sub->rtp) {
1198  ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(chan) : "");
1199  }
1200 }
1201 
1202 static struct ast_frame *mgcp_read(struct ast_channel *ast)
1203 {
1204  struct ast_frame *f;
1205  struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
1206  ast_mutex_lock(&sub->lock);
1207  f = mgcp_rtp_read(sub);
1208  ast_mutex_unlock(&sub->lock);
1209  return f;
1210 }
1211 
1212 static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
1213 {
1214  struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
1215  int res = 0;
1216 
1217  if (frame->frametype != AST_FRAME_VOICE) {
1218  if (frame->frametype == AST_FRAME_IMAGE)
1219  return 0;
1220  else {
1221  ast_log(LOG_WARNING, "Can't send %u type frames with MGCP write\n", frame->frametype);
1222  return 0;
1223  }
1224  } else {
1226  struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1227 
1228  ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1233  /* return -1; */
1234  }
1235  }
1236  if (sub) {
1237  ast_mutex_lock(&sub->lock);
1238  if (!sub->sdpsent && sub->gate) {
1239  if (sub->gate->state == GATE_ALLOCATED) {
1240  ast_debug(1, "GATE ALLOCATED, sending sdp\n");
1242  }
1243  }
1244  if ((sub->parent->sub == sub) || !sub->parent->singlepath) {
1245  if (sub->rtp) {
1246  res = ast_rtp_instance_write(sub->rtp, frame);
1247  }
1248  }
1249  ast_mutex_unlock(&sub->lock);
1250  }
1251  return res;
1252 }
1253 
1254 static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1255 {
1256  struct mgcp_subchannel *sub = ast_channel_tech_pvt(newchan);
1257 
1258  ast_mutex_lock(&sub->lock);
1259  ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", ast_channel_name(oldchan), ast_channel_name(newchan));
1260  if (sub->owner != oldchan) {
1261  ast_mutex_unlock(&sub->lock);
1262  ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
1263  return -1;
1264  }
1265  mgcp_set_owner(sub, newchan);
1266  ast_mutex_unlock(&sub->lock);
1267  return 0;
1268 }
1269 
1270 static int mgcp_senddigit_begin(struct ast_channel *ast, char digit)
1271 {
1272  struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
1273  struct mgcp_endpoint *p = sub->parent;
1274  int res = 0;
1275 
1276  ast_mutex_lock(&sub->lock);
1278  ast_debug(1, "Sending DTMF using inband/hybrid\n");
1279  res = -1; /* Let asterisk play inband indications */
1280  } else if (p->dtmfmode & MGCP_DTMF_RFC2833) {
1281  ast_debug(1, "Sending DTMF using RFC2833\n");
1283  } else {
1284  ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
1285  }
1286  ast_mutex_unlock(&sub->lock);
1287 
1288  return res;
1289 }
1290 
1291 static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
1292 {
1293  struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
1294  struct mgcp_endpoint *p = sub->parent;
1295  int res = 0;
1296  char tmp[4];
1297 
1298  ast_mutex_lock(&sub->lock);
1300  ast_debug(1, "Stopping DTMF using inband/hybrid\n");
1301  res = -1; /* Tell Asterisk to stop inband indications */
1302  } else if (p->dtmfmode & MGCP_DTMF_RFC2833) {
1303  ast_debug(1, "Stopping DTMF using RFC2833\n");
1304  if (sub->parent->ncs) {
1305  tmp[0] = digit;
1306  tmp[1] = '\0';
1307  } else {
1308  tmp[0] = 'D';
1309  tmp[1] = '/';
1310  tmp[2] = digit;
1311  tmp[3] = '\0';
1312  }
1315  } else {
1316  ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
1317  }
1318  ast_mutex_unlock(&sub->lock);
1319 
1320  return res;
1321 }
1322 
1323 /*!
1324  * \brief mgcp_devicestate: channel callback for device status monitoring
1325  * \param data tech/resource name of MGCP device to query
1326  *
1327  * Callback for device state management in channel subsystem
1328  * to obtain device status (up/down) of a specific MGCP endpoint
1329  *
1330  * \return device status result (from devicestate.h) AST_DEVICE_INVALID (not available) or AST_DEVICE_UNKNOWN (available but unknown state)
1331  */
1332 static int mgcp_devicestate(const char *data)
1333 {
1334  struct mgcp_gateway *g;
1335  struct mgcp_endpoint *e = NULL;
1336  char *tmp, *endpt, *gw;
1337  int ret = AST_DEVICE_INVALID;
1338 
1339  endpt = ast_strdupa(data);
1340  if ((tmp = strchr(endpt, '@'))) {
1341  *tmp++ = '\0';
1342  gw = tmp;
1343  } else
1344  goto error;
1345 
1347  for (g = gateways; g; g = g->next) {
1348  if (strcasecmp(g->name, gw) == 0) {
1349  e = g->endpoints;
1350  break;
1351  }
1352  }
1353 
1354  if (!e)
1355  goto error;
1356 
1357  for (; e; e = e->next) {
1358  if (strcasecmp(e->name, endpt) == 0) {
1359  break;
1360  }
1361  }
1362 
1363  if (!e)
1364  goto error;
1365 
1366  /*
1367  * As long as the gateway/endpoint is valid, we'll
1368  * assume that the device is available and its state
1369  * can be tracked.
1370  */
1371  ret = AST_DEVICE_UNKNOWN;
1372 
1373 error:
1375  return ret;
1376 }
1377 
1378 static char *control2str(int ind) {
1379  switch (ind) {
1380  case AST_CONTROL_HANGUP:
1381  return "Other end has hungup";
1382  case AST_CONTROL_RING:
1383  return "Local ring";
1384  case AST_CONTROL_RINGING:
1385  return "Remote end is ringing";
1386  case AST_CONTROL_ANSWER:
1387  return "Remote end has answered";
1388  case AST_CONTROL_BUSY:
1389  return "Remote end is busy";
1391  return "Make it go off hook";
1392  case AST_CONTROL_OFFHOOK:
1393  return "Line is off hook";
1395  return "Congestion (circuits busy)";
1396  case AST_CONTROL_FLASH:
1397  return "Flash hook";
1398  case AST_CONTROL_WINK:
1399  return "Wink";
1400  case AST_CONTROL_OPTION:
1401  return "Set a low-level option";
1402  case AST_CONTROL_RADIO_KEY:
1403  return "Key Radio";
1405  return "Un-Key Radio";
1406  }
1407  return "UNKNOWN";
1408 }
1409 
1410 static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
1411 {
1412  struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
1413  int res = 0;
1414 
1415  ast_debug(3, "MGCP asked to indicate %d '%s' condition on channel %s\n",
1416  ind, control2str(ind), ast_channel_name(ast));
1417  ast_mutex_lock(&sub->lock);
1418  switch(ind) {
1419  case AST_CONTROL_RINGING:
1420 #ifdef DLINK_BUGGY_FIRMWARE
1422 #else
1423  if (!sub->sdpsent) { /* will hide the inband progress!!! */
1424  transmit_notify_request(sub, sub->parent->ncs ? "L/rt" : "G/rt");
1425  }
1426 #endif
1427  break;
1428  case AST_CONTROL_BUSY:
1429  transmit_notify_request(sub, "L/bz");
1430  break;
1432  /* We do not currently support resetting of the Interdigit Timer, so treat
1433  * Incomplete control frames as a congestion response
1434  */
1436  transmit_notify_request(sub, sub->parent->ncs ? "L/cg" : "G/cg");
1437  break;
1438  case AST_CONTROL_HOLD:
1439  ast_moh_start(ast, data, NULL);
1440  break;
1441  case AST_CONTROL_UNHOLD:
1442  ast_moh_stop(ast);
1443  break;
1444  case AST_CONTROL_SRCUPDATE:
1446  break;
1447  case AST_CONTROL_SRCCHANGE:
1449  break;
1450  case AST_CONTROL_PROGRESS:
1453  case -1:
1455  break;
1456  default:
1457  ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
1458  /* fallthrough */
1460  res = -1;
1461  }
1462  ast_mutex_unlock(&sub->lock);
1463  return res;
1464 }
1465 
1466 static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
1467 {
1468  struct ast_format_cap *caps = NULL;
1469  struct ast_channel *tmp;
1470  struct ast_variable *v = NULL;
1471  struct mgcp_endpoint *i = sub->parent;
1472  struct ast_format *tmpfmt;
1473 
1475  if (!caps) {
1476  ast_log(LOG_ERROR, "Format capabilities could not be created\n");
1477  return NULL;
1478  }
1479  tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
1480  if (!tmp) {
1481  ast_log(LOG_WARNING, "Channel could not be created\n");
1482  ao2_ref(caps, -1);
1483  return NULL;
1484  }
1485 
1488  if (ast_format_cap_count(i->cap)) {
1490  } else {
1492  }
1494  ao2_ref(caps, -1);
1495  if (sub->rtp) {
1497  }
1499  i->dsp = ast_dsp_new();
1501  /* this is to prevent clipping of dtmf tones during dsp processing */
1503  } else {
1504  i->dsp = NULL;
1505  }
1506  if (state == AST_STATE_RING) {
1508  }
1509 
1515  ao2_ref(tmpfmt, -1);
1517  if (!ast_strlen_zero(i->language))
1518  ast_channel_language_set(tmp, i->language);
1519  if (!ast_strlen_zero(i->accountcode))
1520  ast_channel_accountcode_set(tmp, i->accountcode);
1521  if (i->amaflags)
1527  ast_channel_call_forward_set(tmp, i->call_forward);
1530  /* Don't use ast_set_callerid() here because it will
1531  * generate a needless NewCallerID event */
1532  if (!ast_strlen_zero(i->cid_num)) {
1535  }
1536 
1537  if (!i->adsi) {
1539  }
1541 
1542  /* Set channel variables for this call from configuration */
1543  for (v = i->chanvars ; v ; v = v->next) {
1544  char valuebuf[1024];
1545  pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
1546  }
1547 
1548  if (sub->rtp) {
1550  }
1551 
1554 
1555  if (state != AST_STATE_DOWN) {
1556  if (ast_pbx_start(tmp)) {
1557  ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
1558  ast_hangup(tmp);
1559  tmp = NULL;
1560  }
1561  }
1562  ast_verb(3, "MGCP mgcp_new(%s) created in state: %s\n",
1564 
1565  return tmp;
1566 }
1567 
1568 static char *get_sdp_by_line(char* line, char *name, int nameLen)
1569 {
1570  if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
1571  char *r = line + nameLen + 1;
1572  while (*r && (*r < 33)) ++r;
1573  return r;
1574  }
1575  return "";
1576 }
1577 
1578 static char *get_sdp(struct mgcp_request *req, char *name)
1579 {
1580  int x;
1581  int len = strlen(name);
1582  char *r;
1583 
1584  for (x = 0; x < req->lines; x++) {
1585  r = get_sdp_by_line(req->line[x], name, len);
1586  if (r[0] != '\0') return r;
1587  }
1588  return "";
1589 }
1590 
1591 static void sdpLineNum_iterator_init(int *iterator)
1592 {
1593  *iterator = 0;
1594 }
1595 
1596 static char *get_sdp_iterate(int* iterator, struct mgcp_request *req, char *name)
1597 {
1598  int len = strlen(name);
1599  char *r;
1600  while (*iterator < req->lines) {
1601  r = get_sdp_by_line(req->line[(*iterator)++], name, len);
1602  if (r[0] != '\0') return r;
1603  }
1604  return "";
1605 }
1606 
1607 static char *__get_header(struct mgcp_request *req, char *name, int *start, char *def)
1608 {
1609  int x;
1610  int len = strlen(name);
1611  char *r;
1612  for (x = *start; x < req->headers; x++) {
1613  if (!strncasecmp(req->header[x], name, len) &&
1614  (req->header[x][len] == ':')) {
1615  r = req->header[x] + len + 1;
1616  while (*r && (*r < 33)) {
1617  r++;
1618  }
1619  *start = x + 1;
1620  return r;
1621  }
1622  }
1623  /* Don't return NULL, so get_header is always a valid pointer */
1624  return def;
1625 }
1626 
1627 static char *get_header(struct mgcp_request *req, char *name)
1628 {
1629  int start = 0;
1630  return __get_header(req, name, &start, "");
1631 }
1632 
1633 /*! \brief get_csv: (SC:) get comma separated value */
1634 static char *get_csv(char *c, int *len, char **next)
1635 {
1636  char *s;
1637 
1638  *next = NULL, *len = 0;
1639  if (!c) return NULL;
1640 
1641  while (*c && (*c < 33 || *c == ',')) {
1642  c++;
1643  }
1644 
1645  s = c;
1646  while (*c && (*c >= 33 && *c != ',')) {
1647  c++, (*len)++;
1648  }
1649  *next = c;
1650 
1651  if (*len == 0) {
1652  s = NULL, *next = NULL;
1653  }
1654 
1655  return s;
1656 }
1657 
1658 static struct mgcp_gateway *find_realtime_gw(char *name, char *at, struct sockaddr_in *sin)
1659 {
1660  struct mgcp_gateway *g = NULL;
1661  struct ast_variable *mgcpgwconfig = NULL;
1662  struct ast_variable *gwv, *epname = NULL;
1663  struct mgcp_endpoint *e;
1664  char lines[256];
1665  int i, j;
1666 
1667  ast_debug(1, "*** find Realtime MGCPGW\n");
1668 
1669  if (!(i = ast_check_realtime("mgcpgw")) || !(j = ast_check_realtime("mgcpep"))) {
1670  return NULL;
1671  }
1672 
1673  if (ast_strlen_zero(at)) {
1674  ast_debug(1, "null gw name\n");
1675  return NULL;
1676  }
1677 
1678  if (!(mgcpgwconfig = ast_load_realtime("mgcpgw", "name", at, NULL))) {
1679  return NULL;
1680  }
1681 
1682  /*!
1683  * \note This is a fairly odd way of instantiating lines. Instead of each
1684  * line created by virtue of being in the database (and loaded via
1685  * ast_load_realtime_multientry), this code forces a specific order with a
1686  * "lines" entry in the "mgcpgw" record. This has benefits, because as with
1687  * chan_dahdi, values are inherited across definitions. The downside is
1688  * that it's not as clear what the values will be simply by looking at a
1689  * single row in the database, and it's probable that the sanest configuration
1690  * should have the first column in the "mgcpep" table be "clearvars", with a
1691  * static value of "all", if any variables are set at all. It may be worth
1692  * making this assumption explicit in the code in the future, and then just
1693  * using ast_load_realtime_multientry for the "mgcpep" records.
1694  */
1695  lines[0] = '\0';
1696  for (gwv = mgcpgwconfig; gwv; gwv = gwv->next) {
1697  if (!strcasecmp(gwv->name, "lines")) {
1698  ast_copy_string(lines, gwv->value, sizeof(lines));
1699  break;
1700  }
1701  }
1702  /* Position gwv at the end of the list */
1703  for (gwv = gwv && gwv->next ? gwv : mgcpgwconfig; gwv->next; gwv = gwv->next);
1704 
1705  if (!ast_strlen_zero(lines)) {
1707  AST_APP_ARG(line)[100];
1708  );
1710  for (i = 0; i < args.argc; i++) {
1711  gwv->next = ast_load_realtime("mgcpep", "name", at, "line", args.line[i], NULL);
1712 
1713  /* Remove "line" AND position gwv at the end of the list. */
1714  for (epname = NULL; gwv->next; gwv = gwv->next) {
1715  if (!strcasecmp(gwv->next->name, "line")) {
1716  /* Remove it from the list */
1717  epname = gwv->next;
1718  gwv->next = gwv->next->next;
1719  }
1720  }
1721  /* Since "line" instantiates the configuration, we have to move it to the end. */
1722  if (epname) {
1723  gwv->next = epname;
1724  epname->next = NULL;
1725  gwv = gwv->next;
1726  }
1727  }
1728  }
1729  for (gwv = mgcpgwconfig; gwv; gwv = gwv->next) {
1730  ast_debug(1, "MGCP Realtime var: %s => %s\n", gwv->name, gwv->value);
1731  }
1732 
1733  if (mgcpgwconfig) {
1734  g = build_gateway(at, mgcpgwconfig);
1735  ast_variables_destroy(mgcpgwconfig);
1736  }
1737  if (g) {
1738  g->next = gateways;
1739  g->realtime = 1;
1740  gateways = g;
1741  for (e = g->endpoints; e; e = e->next) {
1743  e->needaudit = 0;
1744  }
1745  }
1746  return g;
1747 }
1748 
1749 static struct mgcp_subchannel *find_subchannel_and_lock(char *name, int msgid, struct sockaddr_in *sin)
1750 {
1751  struct mgcp_endpoint *p = NULL;
1752  struct mgcp_subchannel *sub = NULL;
1753  struct mgcp_gateway *g;
1754  char tmp[256] = "";
1755  char *at = NULL, *c;
1756  int found = 0;
1757  if (name) {
1758  ast_copy_string(tmp, name, sizeof(tmp));
1759  at = strchr(tmp, '@');
1760  if (!at) {
1761  ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name);
1762  return NULL;
1763  }
1764  *at++ = '\0';
1765  }
1767  if (at && (at[0] == '[')) {
1768  at++;
1769  c = strrchr(at, ']');
1770  if (c) {
1771  *c = '\0';
1772  }
1773  }
1774  for (g = gateways ? gateways : find_realtime_gw(name, at, sin); g; g = g->next ? g->next : find_realtime_gw(name, at, sin)) {
1775  if ((!name || !strcasecmp(g->name, at)) &&
1776  (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) {
1777  /* Found the gateway. If it's dynamic, save it's address -- now for the endpoint */
1778  if (sin && g->dynamic && name) {
1779  if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1780  (g->addr.sin_port != sin->sin_port)) {
1781  memcpy(&g->addr, sin, sizeof(g->addr));
1782  {
1783  struct ast_sockaddr tmp1, tmp2;
1784  struct sockaddr_in tmp3 = {0,};
1785 
1786  tmp3.sin_addr = g->ourip;
1787  ast_sockaddr_from_sin(&tmp1, &g->addr);
1788  ast_sockaddr_from_sin(&tmp2, &tmp3);
1789  if (ast_ouraddrfor(&tmp1, &tmp2)) {
1790  memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
1791  }
1792  ast_sockaddr_to_sin(&tmp2, &tmp3);
1793  g->ourip = tmp3.sin_addr;
1794  }
1795  ast_verb(3, "Registered MGCP gateway '%s' at %s port %d\n", g->name, ast_inet_ntoa(g->addr.sin_addr), ntohs(g->addr.sin_port));
1796  }
1797  /* not dynamic, check if the name matches */
1798  } else if (name) {
1799  if (strcasecmp(g->name, at)) {
1800  continue;
1801  }
1802  /* not dynamic, no name, check if the addr matches */
1803  } else if (!name && sin) {
1804  if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1805  (g->addr.sin_port != sin->sin_port)) {
1806  continue;
1807  }
1808  } else {
1809  continue;
1810  }
1811  for (p = g->endpoints; p; p = p->next) {
1812  ast_debug(1, "Searching on %s@%s for subchannel\n", p->name, g->name);
1813  if (msgid) {
1814  sub = p->sub;
1815  found = 1;
1816  break;
1817  } else if (name && !strcasecmp(p->name, tmp)) {
1818  ast_debug(1, "Coundn't determine subchannel, assuming current master %s@%s-%d\n",
1819  p->name, g->name, p->sub->id);
1820  sub = p->sub;
1821  found = 1;
1822  break;
1823  }
1824  }
1825  if (sub && found) {
1826  ast_mutex_lock(&sub->lock);
1827  break;
1828  }
1829  }
1830  }
1832  if (!sub) {
1833  if (name) {
1834  if (g) {
1835  ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp, at);
1836  } else {
1837  ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
1838  }
1839  }
1840  }
1841  return sub;
1842 }
1843 
1844 static void parse(struct mgcp_request *req)
1845 {
1846  /* Divide fields by NULL's */
1847  char *c;
1848  int f = 0;
1849  c = req->data;
1850 
1851  /* First header starts immediately */
1852  req->header[f] = c;
1853  for (; *c; c++) {
1854  if (*c == '\n') {
1855  /* We've got a new header */
1856  *c = 0;
1857  ast_debug(3, "Header: %s (%d)\n", req->header[f], (int) strlen(req->header[f]));
1858  if (ast_strlen_zero(req->header[f])) {
1859  /* Line by itself means we're now in content */
1860  c++;
1861  break;
1862  }
1863  if (f >= MGCP_MAX_HEADERS - 1) {
1864  ast_log(LOG_WARNING, "Too many MGCP headers...\n");
1865  } else {
1866  f++;
1867  }
1868  req->header[f] = c + 1;
1869  } else if (*c == '\r') {
1870  /* Ignore but eliminate \r's */
1871  *c = 0;
1872  }
1873  }
1874  /* Check for last header */
1875  if (!ast_strlen_zero(req->header[f])) {
1876  f++;
1877  }
1878  req->headers = f;
1879  /* Now we process any mime content */
1880  f = 0;
1881  req->line[f] = c;
1882  for (; *c; c++) {
1883  if (*c == '\n') {
1884  /* We've got a new line */
1885  *c = 0;
1886  ast_debug(3, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
1887  if (f >= MGCP_MAX_LINES - 1) {
1888  ast_log(LOG_WARNING, "Too many SDP lines...\n");
1889  } else {
1890  f++;
1891  }
1892  req->line[f] = c + 1;
1893  } else if (*c == '\r') {
1894  /* Ignore and eliminate \r's */
1895  *c = 0;
1896  }
1897  }
1898  /* Check for last line */
1899  if (!ast_strlen_zero(req->line[f])) {
1900  f++;
1901  }
1902  req->lines = f;
1903  /* Parse up the initial header */
1904  c = req->header[0];
1905  while (*c && *c < 33) c++;
1906  /* First the verb */
1907  req->verb = c;
1908  while (*c && (*c > 32)) c++;
1909  if (*c) {
1910  *c = '\0';
1911  c++;
1912  while (*c && (*c < 33)) c++;
1913  req->identifier = c;
1914  while (*c && (*c > 32)) c++;
1915  if (*c) {
1916  *c = '\0';
1917  c++;
1918  while (*c && (*c < 33)) c++;
1919  req->endpoint = c;
1920  while (*c && (*c > 32)) c++;
1921  if (*c) {
1922  *c = '\0';
1923  c++;
1924  while (*c && (*c < 33)) c++;
1925  req->version = c;
1926  while (*c && (*c > 32)) c++;
1927  while (*c && (*c < 33)) c++;
1928  while (*c && (*c > 32)) c++;
1929  *c = '\0';
1930  }
1931  }
1932  }
1933 
1934  ast_debug(1, "Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
1935  req->verb, req->identifier, req->endpoint, req->version);
1936  ast_debug(1, "%d headers, %d lines\n", req->headers, req->lines);
1937  if (*c) {
1938  ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
1939  }
1940 }
1941 
1942 static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
1943 {
1944  char *m;
1945  char *c;
1946  char *a;
1947  char host[258];
1948  int len = 0;
1949  int portno;
1950  struct ast_format_cap *peercap;
1951  int peerNonCodecCapability;
1952  struct sockaddr_in sin;
1953  struct ast_sockaddr sin_tmp;
1954  char *codecs;
1955  struct ast_hostent ahp; struct hostent *hp;
1956  int codec, codec_count=0;
1957  int iterator;
1958  struct mgcp_endpoint *p = sub->parent;
1959  struct ast_str *global_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1960  struct ast_str *peer_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1961  struct ast_str *pvt_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1962 
1963  /* Get codec and RTP info from SDP */
1964  m = get_sdp(req, "m");
1965  c = get_sdp(req, "c");
1966  if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
1967  ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
1968  return -1;
1969  }
1970  if (sscanf(c, "IN IP4 %256s", host) != 1) {
1971  ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
1972  return -1;
1973  }
1974  /* XXX This could block for a long time, and block the main thread! XXX */
1975  hp = ast_gethostbyname(host, &ahp);
1976  if (!hp) {
1977  ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
1978  return -1;
1979  }
1980  if (sscanf(m, "audio %30d RTP/AVP %n", &portno, &len) != 1 || !len) {
1981  ast_log(LOG_WARNING, "Malformed media stream descriptor: %s\n", m);
1982  return -1;
1983  }
1984  sin.sin_family = AF_INET;
1985  memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
1986  sin.sin_port = htons(portno);
1987  ast_sockaddr_from_sin(&sin_tmp, &sin);
1988  ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
1989  ast_debug(3, "Peer RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1990  /* Scan through the RTP payload types specified in a "m=" line: */
1991  codecs = ast_strdupa(m + len);
1992  while (!ast_strlen_zero(codecs)) {
1993  if (sscanf(codecs, "%30d%n", &codec, &len) != 1) {
1994  if (codec_count) {
1995  break;
1996  }
1997  ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs);
1998  return -1;
1999  }
2001  codec_count++;
2002  codecs += len;
2003  }
2004 
2005  /* Next, scan through each "a=rtpmap:" line, noting each */
2006  /* specified RTP payload type (with corresponding MIME subtype): */
2007  sdpLineNum_iterator_init(&iterator);
2008  while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
2009  char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
2010  if (sscanf(a, "rtpmap: %30d %127[^/]/", &codec, mimeSubtype) != 2)
2011  continue;
2012  /* Note: should really look at the 'freq' and '#chans' params too */
2013  ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, codec, "audio", mimeSubtype, 0);
2014  }
2015 
2016  /* Now gather all of the codecs that were asked for: */
2018  return -1;
2019  }
2020  ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), peercap, &peerNonCodecCapability);
2022  ast_debug(1, "Capabilities: us - %s, them - %s, combined - %s\n",
2024  ast_format_cap_get_names(peercap, &peer_buf),
2025  ast_format_cap_get_names(p->cap, &pvt_buf));
2026  ao2_ref(peercap, -1);
2027 
2028  ast_debug(1, "Non-codec capabilities: us - %d, them - %d, combined - %d\n",
2029  nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
2030  if (!ast_format_cap_count(p->cap)) {
2031  ast_log(LOG_WARNING, "No compatible codecs!\n");
2032  return -1;
2033  }
2034  return 0;
2035 }
2036 
2037 static int add_header(struct mgcp_request *req, const char *var, const char *value)
2038 {
2039  if (req->len >= sizeof(req->data) - 4) {
2040  ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
2041  return -1;
2042  }
2043  if (req->lines) {
2044  ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
2045  return -1;
2046  }
2047  req->header[req->headers] = req->data + req->len;
2048  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
2049  req->len += strlen(req->header[req->headers]);
2050  if (req->headers < MGCP_MAX_HEADERS) {
2051  req->headers++;
2052  } else {
2053  ast_log(LOG_WARNING, "Out of header space\n");
2054  return -1;
2055  }
2056  return 0;
2057 }
2058 
2059 static int add_line(struct mgcp_request *req, char *line)
2060 {
2061  if (req->len >= sizeof(req->data) - 4) {
2062  ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
2063  return -1;
2064  }
2065  if (!req->lines) {
2066  /* Add extra empty return */
2067  ast_copy_string(req->data + req->len, "\r\n", sizeof(req->data) - req->len);
2068  req->len += strlen(req->data + req->len);
2069  }
2070  req->line[req->lines] = req->data + req->len;
2071  snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
2072  req->len += strlen(req->line[req->lines]);
2073  if (req->lines < MGCP_MAX_LINES) {
2074  req->lines++;
2075  } else {
2076  ast_log(LOG_WARNING, "Out of line space\n");
2077  return -1;
2078  }
2079  return 0;
2080 }
2081 
2082 static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
2083 {
2084  /* Initialize a response */
2085  if (req->headers || req->len) {
2086  ast_log(LOG_WARNING, "Request already initialized?!?\n");
2087  return -1;
2088  }
2089  req->header[req->headers] = req->data + req->len;
2090  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
2091  req->len += strlen(req->header[req->headers]);
2092  if (req->headers < MGCP_MAX_HEADERS) {
2093  req->headers++;
2094  } else {
2095  ast_log(LOG_WARNING, "Out of header space\n");
2096  }
2097  return 0;
2098 }
2099 
2100 static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb, unsigned int oseq)
2101 {
2102  /* Initialize a response */
2103  if (req->headers || req->len) {
2104  ast_log(LOG_WARNING, "Request already initialized?!?\n");
2105  return -1;
2106  }
2107  req->header[req->headers] = req->data + req->len;
2108  /* check if we need brackets around the gw name */
2109  if (p->parent->isnamedottedip) {
2110  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %u %s@[%s] MGCP 1.0%s\r\n", verb, oseq, p->name, p->parent->name, p->ncs ? " NCS 1.0" : "");
2111  } else {
2112 + snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %u %s@%s MGCP 1.0%s\r\n", verb, oseq, p->name, p->parent->name, p->ncs ? " NCS 1.0" : "");
2113  }
2114  req->len += strlen(req->header[req->headers]);
2115  if (req->headers < MGCP_MAX_HEADERS) {
2116  req->headers++;
2117  } else {
2118  ast_log(LOG_WARNING, "Out of header space\n");
2119  }
2120  return 0;
2121 }
2122 
2123 
2124 static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
2125 {
2126  memset(resp, 0, sizeof(*resp));
2127  init_resp(resp, msg, req, msgrest);
2128  return 0;
2129 }
2130 
2131 static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
2132 {
2133  unsigned int oseq;
2134  memset(req, 0, sizeof(struct mgcp_request));
2136  oseq_global++;
2137  if (oseq_global > 999999999) {
2138  oseq_global = 1;
2139  }
2140  oseq = oseq_global;
2142  init_req(p, req, verb, oseq);
2143  return oseq;
2144 }
2145 
2146 static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
2147 {
2148  struct mgcp_request resp;
2149  struct mgcp_endpoint *p = sub->parent;
2150  struct mgcp_response *mgr;
2151 
2152  if (!sub) {
2153  return -1;
2154  }
2155 
2156  respprep(&resp, p, msg, req, msgrest);
2157  if (!(mgr = ast_calloc(1, sizeof(*mgr) + resp.len + 1))) {
2158  return send_response(sub, &resp);
2159  }
2160  /* Store MGCP response in case we have to retransmit */
2161  sscanf(req->identifier, "%30d", &mgr->seqno);
2162  time(&mgr->whensent);
2163  mgr->len = resp.len;
2164  memcpy(mgr->buf, resp.data, resp.len);
2165  mgr->buf[resp.len] = '\0';
2166  mgr->next = p->parent->responses;
2167  p->parent->responses = mgr;
2168 
2169  return send_response(sub, &resp);
2170 }
2171 
2172 
2173 static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
2174 {
2175  int len;
2176  int codec;
2177  char costr[80];
2178  struct sockaddr_in sin;
2179  struct ast_sockaddr sin_tmp;
2180  char v[256];
2181  char s[256];
2182  char o[256];
2183  char c[256];
2184  char t[256];
2185  char m[256] = "";
2186  char a[1024] = "";
2187  int x;
2188  struct sockaddr_in dest = { 0, };
2189  struct ast_sockaddr dest_tmp;
2190  struct mgcp_endpoint *p = sub->parent;
2191  /* XXX We break with the "recommendation" and send our IP, in order that our
2192  peer doesn't have to ast_gethostbyname() us XXX */
2193  len = 0;
2194  if (!sub->rtp) {
2195  ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
2196  return -1;
2197  }
2198  ast_rtp_instance_get_local_address(sub->rtp, &sin_tmp);
2199  ast_sockaddr_to_sin(&sin_tmp, &sin);
2200  if (rtp) {
2201  ast_rtp_instance_get_remote_address(sub->rtp, &dest_tmp);
2202  ast_sockaddr_to_sin(&dest_tmp, &dest);
2203  } else {
2204  if (sub->tmpdest.sin_addr.s_addr) {
2205  dest.sin_addr = sub->tmpdest.sin_addr;
2206  dest.sin_port = sub->tmpdest.sin_port;
2207  /* Reset temporary destination */
2208  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
2209  } else {
2210  dest.sin_addr = p->parent->ourip;
2211  dest.sin_port = sin.sin_port;
2212  }
2213  }
2214  ast_debug(1, "We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
2215  ast_copy_string(v, "v=0\r\n", sizeof(v));
2216  snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
2217  ast_copy_string(s, "s=session\r\n", sizeof(s));
2218  snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
2219  ast_copy_string(t, "t=0 0\r\n", sizeof(t));
2220  snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
2221 
2222  for (x = 0; x < ast_format_cap_count(p->cap); x++) {
2224 
2226  ao2_ref(format, -1);
2227  continue;
2228  }
2229 
2230  ast_debug(1, "Answering with capability %s\n", ast_format_get_name(format));
2232  if (codec > -1) {
2233  snprintf(costr, sizeof(costr), " %d", codec);
2234  strncat(m, costr, sizeof(m) - strlen(m) - 1);
2235  snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2236  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2237  }
2238 
2239  ao2_ref(format, -1);
2240  }
2241 
2242  for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
2243  if (p->nonCodecCapability & x) {
2244  ast_debug(1, "Answering with non-codec capability %d\n", (int) x);
2246  if (codec > -1) {
2247  snprintf(costr, sizeof(costr), " %d", codec);
2248  strncat(m, costr, sizeof(m) - strlen(m) - 1);
2249  snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, NULL, x, 0));
2250  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2251  if (x == AST_RTP_DTMF) {
2252  /* Indicate we support DTMF... Not sure about 16,
2253  but MSN supports it so dang it, we will too... */
2254  snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec);
2255  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2256  }
2257  }
2258  }
2259  }
2260  strncat(m, "\r\n", sizeof(m) - strlen(m) - 1);
2261  len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
2262  snprintf(costr, sizeof(costr), "%d", len);
2263  add_line(resp, v);
2264  add_line(resp, o);
2265  add_line(resp, s);
2266  add_line(resp, c);
2267  add_line(resp, t);
2268  add_line(resp, m);
2269  add_line(resp, a);
2270  return 0;
2271 }
2272 
2274 {
2275  struct mgcp_request resp;
2276  char local[256];
2277  char tmp[80];
2278  struct mgcp_endpoint *p = sub->parent;
2279  int i;
2280  struct ast_sockaddr sub_tmpdest_tmp;
2281  unsigned int oseq;
2282 
2283  if (ast_strlen_zero(sub->cxident) && rtp) {
2284  /* We don't have a CXident yet, store the destination and
2285  wait a bit */
2286  ast_rtp_instance_get_remote_address(rtp, &sub_tmpdest_tmp);
2287  ast_sockaddr_to_sin(&sub_tmpdest_tmp, &sub->tmpdest);
2288  return 0;
2289  }
2290  ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
2291 
2292  for (i = 0; i < ast_format_cap_count(p->cap); i++) {
2294 
2296  ao2_ref(format, -1);
2297  continue;
2298  }
2299 
2300  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2301  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2302 
2303  ao2_ref(format, -1);
2304  }
2305 
2306  if (sub->gate) {
2307  if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
2308  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2309  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2310  sub->sdpsent = 1;
2311  } else {
2312  /* oops wait */
2313  ast_debug(1, "Waiting for opened gate...\n");
2314  sub->sdpsent = 0;
2315  return 0;
2316  }
2317  }
2318 
2319 
2320  oseq = reqprep(&resp, p, "MDCX");
2321  add_header(&resp, "C", sub->callid);
2322  add_header(&resp, "L", local);
2323  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2324  /* X header should not be sent. kept for compatibility */
2325  add_header(&resp, "X", sub->txident);
2326  add_header(&resp, "I", sub->cxident);
2327  /*add_header(&resp, "S", "");*/
2328  add_sdp(&resp, sub, rtp);
2329  /* fill in new fields */
2330  resp.cmd = MGCP_CMD_MDCX;
2331  resp.trid = oseq;
2332  return send_request(p, sub, &resp, oseq);
2333 }
2334 
2336 {
2337  struct mgcp_request resp;
2338  char local[256];
2339  char tmp[80];
2340  int i;
2341  struct mgcp_endpoint *p = sub->parent;
2342  unsigned int oseq;
2343 
2344  ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2345  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2346 
2347  ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
2348 
2349  for (i = 0; i < ast_format_cap_count(p->cap); i++) {
2351 
2353  ao2_ref(format, -1);
2354  continue;
2355  }
2356 
2357  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2358  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2359 
2360  ao2_ref(format, -1);
2361  }
2362 
2363  if (sub->gate) {
2364  if(sub->gate->state == GATE_ALLOCATED) {
2365  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2366  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2367  }
2368  }
2369  sub->sdpsent = 1;
2370  oseq = reqprep(&resp, p, "CRCX");
2371  add_header(&resp, "C", sub->callid);
2372  add_header(&resp, "L", local);
2373  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2374  /* X header should not be sent. kept for compatibility */
2375  add_header(&resp, "X", sub->txident);
2376  /*add_header(&resp, "S", "");*/
2377  add_sdp(&resp, sub, rtp);
2378  /* fill in new fields */
2379  resp.cmd = MGCP_CMD_CRCX;
2380  resp.trid = oseq;
2381  return send_request(p, sub, &resp, oseq);
2382 }
2383 
2384 static int mgcp_pktcgate_remove(struct cops_gate *gate)
2385 {
2386  struct mgcp_subchannel *sub = gate->tech_pvt;
2387 
2388  if (!sub) {
2389  return 1;
2390  }
2391 
2392  ast_mutex_lock(&sub->lock);
2393  ast_debug(1, "Pktc: gate 0x%x deleted\n", gate->gateid);
2394  if (sub->gate->state != GATE_CLOSED && sub->parent->hangupongateremove) {
2395  sub->gate = NULL;
2396  if (sub->owner) {
2398  ast_channel_unlock(sub->owner);
2399  }
2400  } else {
2401  sub->gate = NULL;
2402  }
2403  ast_mutex_unlock(&sub->lock);
2404  return 1;
2405 }
2406 
2407 static int mgcp_pktcgate_open(struct cops_gate *gate)
2408 {
2409  struct mgcp_subchannel *sub = gate->tech_pvt;
2410  if (!sub) {
2411  return 1;
2412  }
2413  ast_mutex_lock(&sub->lock);
2414  ast_debug(1, "Pktc: gate 0x%x open\n", gate->gateid);
2415  if (!sub->sdpsent) transmit_modify_with_sdp(sub, NULL, 0);
2416  ast_mutex_unlock(&sub->lock);
2417  return 1;
2418 }
2419 
2421 {
2422  struct mgcp_endpoint *p = sub->parent;
2423  sub->gate = ast_pktccops_gate_alloc(GATE_SET, NULL, ntohl(p->parent->addr.sin_addr.s_addr),
2424  8, 128000, 232, 0, 0, NULL, &mgcp_pktcgate_remove);
2425 
2426  if (!sub->gate) {
2427  return 0;
2428  }
2429  sub->gate->tech_pvt = sub;
2430  sub->gate->gate_open = &mgcp_pktcgate_open;
2431  return 1;
2432 }
2433 
2435 {
2436  struct mgcp_request resp;
2437  int x;
2438  char local[256];
2439  char tmp[80];
2440  struct ast_format *tmpfmt;
2441  struct mgcp_endpoint *p = sub->parent;
2442  unsigned int oseq;
2443 
2444  ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
2445 
2446  for (x = 0; x < ast_format_cap_count(p->cap); x++) {
2447  tmpfmt = ast_format_cap_get_format(p->cap, x);
2448 
2449  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, tmpfmt, 0, 0));
2450  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2451 
2452  ao2_ref(tmpfmt, -1);
2453  }
2454 
2455  ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2456  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2457  sub->sdpsent = 0;
2458  oseq = reqprep(&resp, p, "CRCX");
2459  add_header(&resp, "C", sub->callid);
2460  add_header(&resp, "L", local);
2461  add_header(&resp, "M", "inactive");
2462  /* X header should not be sent. kept for compatibility */
2463  add_header(&resp, "X", sub->txident);
2464  /*add_header(&resp, "S", "");*/
2465  /* fill in new fields */
2466  resp.cmd = MGCP_CMD_CRCX;
2467  resp.trid = oseq;
2468  return send_request(p, sub, &resp, oseq);
2469 }
2470 
2471 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
2472 {
2473  struct mgcp_request resp;
2474  struct mgcp_endpoint *p = sub->parent;
2475  unsigned int oseq;
2476 
2477  ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2478  tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2479  ast_copy_string(p->curtone, tone, sizeof(p->curtone));
2480  oseq = reqprep(&resp, p, "RQNT");
2481  add_header(&resp, "X", p->rqnt_ident);
2482  switch (p->hookstate) {
2483  case MGCP_ONHOOK:
2484  add_header(&resp, "R", "L/hd(N)");
2485  break;
2486  case MGCP_OFFHOOK:
2487  add_header_offhook(sub, &resp, tone);
2488  break;
2489  }
2490  if (!ast_strlen_zero(tone)) {
2491  add_header(&resp, "S", tone);
2492  }
2493  /* fill in new fields */
2494  resp.cmd = MGCP_CMD_RQNT;
2495  resp.trid = oseq;
2496  return send_request(p, NULL, &resp, oseq);
2497 }
2498 
2499 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
2500 {
2501  struct mgcp_request resp;
2502  char tone2[256];
2503  char *l, *n;
2504  struct timeval t = ast_tvnow();
2505  struct ast_tm tm;
2506  struct mgcp_endpoint *p = sub->parent;
2507  unsigned int oseq;
2508 
2509  ast_localtime(&t, &tm, NULL);
2510  n = callername;
2511  l = callernum;
2512  if (!n)
2513  n = "";
2514  if (!l)
2515  l = "";
2516 
2517  /* Keep track of last callerid for blacklist and callreturn */
2518  ast_copy_string(p->lastcallerid, l, sizeof(p->lastcallerid));
2519 
2520  snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone,
2521  tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
2522  ast_copy_string(p->curtone, tone, sizeof(p->curtone));
2523  oseq = reqprep(&resp, p, "RQNT");
2524  add_header(&resp, "X", p->rqnt_ident);
2525  switch (p->hookstate) {
2526  case MGCP_ONHOOK:
2527  add_header(&resp, "R", "L/hd(N)");
2528  break;
2529  case MGCP_OFFHOOK:
2530  add_header_offhook(sub, &resp, tone);
2531  break;
2532  }
2533  if (!ast_strlen_zero(tone2)) {
2534  add_header(&resp, "S", tone2);
2535  }
2536  ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2537  tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2538  /* fill in new fields */
2539  resp.cmd = MGCP_CMD_RQNT;
2540  resp.trid = oseq;
2541  return send_request(p, NULL, &resp, oseq);
2542 }
2543 
2545 {
2546  struct mgcp_request resp;
2547  struct mgcp_endpoint *p = sub->parent;
2548  int i;
2549  int fc = 1;
2550  char local[256];
2551  char tmp[80];
2552  unsigned int oseq;
2553 
2554  if (ast_strlen_zero(sub->cxident)) {
2555  /* We don't have a CXident yet, store the destination and
2556  wait a bit */
2557  return 0;
2558  }
2559  ast_debug(3, "Modified %s@%s-%d with new mode: %s on callid: %s\n",
2560  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2561 
2562  ast_copy_string(local, "", sizeof(local));
2563  for (i = 0; i < ast_format_cap_count(p->cap); i++) {
2565 
2566  if (p->ncs && !fc) {
2568  ast_format_cap_append(p->cap, format, 0); /* sb5120e bug */
2569  ao2_ref(format, -1);
2570  break;
2571  } else {
2572  fc = 0;
2573  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2574  }
2575  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2576 
2577  ao2_ref(format, -1);
2578  }
2579 
2580  if (!sub->sdpsent) {
2581  if (sub->gate) {
2582  if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
2583  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2584  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2585  } else {
2586  /* we still don't have gateid wait */
2587  return 0;
2588  }
2589  }
2590  }
2591 
2592  oseq = reqprep(&resp, p, "MDCX");
2593  add_header(&resp, "C", sub->callid);
2594  if (!sub->sdpsent) {
2595  add_header(&resp, "L", local);
2596  }
2597  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2598  /* X header should not be sent. kept for compatibility */
2599  add_header(&resp, "X", sub->txident);
2600  add_header(&resp, "I", sub->cxident);
2601  switch (sub->parent->hookstate) {
2602  case MGCP_ONHOOK:
2603  add_header(&resp, "R", "L/hd(N)");
2604  break;
2605  case MGCP_OFFHOOK:
2606  add_header_offhook(sub, &resp, "");
2607  break;
2608  }
2609  if (!sub->sdpsent) {
2610  add_sdp(&resp, sub, NULL);
2611  sub->sdpsent = 1;
2612  }
2613  /* fill in new fields */
2614  resp.cmd = MGCP_CMD_MDCX;
2615  resp.trid = oseq;
2616  return send_request(p, sub, &resp, oseq);
2617 }
2618 
2619 
2620 static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
2621 {
2622  struct mgcp_endpoint *p = sub->parent;
2623  char tone_indicate_end = 0;
2624 
2625  /* We also should check the tone to indicate, because it have no sense
2626  to request notify D/[0-9#*] (dtmf keys) if we are sending congestion
2627  tone for example G/cg */
2628  if (p && (!strcasecmp(tone, (p->ncs ? "L/ro" : "G/cg")))) {
2629  tone_indicate_end = 1;
2630  }
2631 
2632  if (p && p->sub && p->sub->owner &&
2635  add_header(resp, "R", "L/hu(N),L/hf(N)");
2636 
2637  } else if (!tone_indicate_end){
2638  add_header(resp, "R", (p->ncs ? "L/hu(N),L/hf(N),L/[0-9#*](N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"));
2639  } else {
2640  ast_debug(1, "We don't want more digits if we will end the call\n");
2641  add_header(resp, "R", "L/hu(N),L/hf(N)");
2642  }
2643 }
2644 
2645 
2646 
2647 
2649 {
2650  struct mgcp_request resp;
2651  unsigned int oseq;
2652  oseq = reqprep(&resp, p, "AUEP");
2653  /* removed unknown param VS */
2654  /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/
2655  add_header(&resp, "F", "A");
2656  /* fill in new fields */
2657  resp.cmd = MGCP_CMD_AUEP;
2658  resp.trid = oseq;
2659  return send_request(p, NULL, &resp, oseq);
2660 }
2661 
2663 {
2664  struct mgcp_endpoint *p = sub->parent;
2665  struct mgcp_request resp;
2666  unsigned int oseq;
2667 
2668  ast_debug(3, "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n",
2669  sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2670  oseq = reqprep(&resp, p, "DLCX");
2671  /* check if call id is avail */
2672  if (sub->callid[0])
2673  add_header(&resp, "C", sub->callid);
2674  /* X header should not be sent. kept for compatibility */
2675  add_header(&resp, "X", sub->txident);
2676  /* check if cxident is avail */
2677  if (sub->cxident[0])
2678  add_header(&resp, "I", sub->cxident);
2679  /* fill in new fields */
2680  resp.cmd = MGCP_CMD_DLCX;
2681  resp.trid = oseq;
2682  return send_request(p, sub, &resp, oseq);
2683 }
2684 
2685 static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
2686 {
2687  struct mgcp_request resp;
2688  unsigned int oseq;
2689 
2690  ast_debug(3, "Delete connection %s %s@%s on callid: %s\n",
2691  cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
2692  oseq = reqprep(&resp, p, "DLCX");
2693  /* check if call id is avail */
2694  if (callid && *callid)
2695  add_header(&resp, "C", callid);
2696  /* check if cxident is avail */
2697  if (cxident && *cxident)
2698  add_header(&resp, "I", cxident);
2699  /* fill in new fields */
2700  resp.cmd = MGCP_CMD_DLCX;
2701  resp.trid = oseq;
2702  return send_request(p, p->sub, &resp, oseq);
2703 }
2704 
2705 /*! \brief dump_cmd_queues: (SC:) cleanup pending commands */
2706 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
2707 {
2708  struct mgcp_request *t, *q;
2709 
2710  if (p) {
2712  for (q = p->rqnt_queue; q; t = q->next, ast_free(q), q=t);
2713  p->rqnt_queue = NULL;
2715 
2717  for (q = p->cmd_queue; q; t = q->next, ast_free(q), q=t);
2718  p->cmd_queue = NULL;
2720 
2722  for (q = p->sub->cx_queue; q; t = q->next, ast_free(q), q=t);
2723  p->sub->cx_queue = NULL;
2725 
2727  for (q = p->sub->next->cx_queue; q; t = q->next, ast_free(q), q=t);
2728  p->sub->next->cx_queue = NULL;
2730  } else if (sub) {
2731  ast_mutex_lock(&sub->cx_queue_lock);
2732  for (q = sub->cx_queue; q; t = q->next, ast_free(q), q=t);
2733  sub->cx_queue = NULL;
2734  ast_mutex_unlock(&sub->cx_queue_lock);
2735  }
2736 }
2737 
2738 
2739 /*! \brief find_command: (SC:) remove command transaction from queue */
2740 static struct mgcp_request *find_command(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
2741  struct mgcp_request **queue, ast_mutex_t *l, int ident)
2742 {
2743  struct mgcp_request *prev, *req;
2744 
2745  ast_mutex_lock(l);
2746  for (prev = NULL, req = *queue; req; prev = req, req = req->next) {
2747  if (req->trid == ident) {
2748  /* remove from queue */
2749  if (!prev)
2750  *queue = req->next;
2751  else
2752  prev->next = req->next;
2753 
2754  /* send next pending command */
2755  if (*queue) {
2756  ast_debug(1, "Posting Queued Request:\n%s to %s:%d\n", (*queue)->data,
2757  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
2758 
2759  mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid);
2760  }
2761  break;
2762  }
2763  }
2764  ast_mutex_unlock(l);
2765  return req;
2766 }
2767 
2768 /* modified for new transport mechanism */
2769 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
2770  int result, unsigned int ident, struct mgcp_request *resp)
2771 {
2772  char *c;
2773  struct mgcp_request *req;
2774  struct mgcp_gateway *gw = p->parent;
2775 
2776  if (result < 200) {
2777  /* provisional response */
2778  return;
2779  }
2780 
2781  if (p->slowsequence)
2782  req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2783  else if (sub)
2784  req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident);
2785  else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident)))
2786  req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2787 
2788  if (!req) {
2789  ast_verb(3, "No command found on [%s] for transaction %u. Ignoring...\n",
2790  gw->name, ident);
2791  return;
2792  }
2793 
2794  if (p && (result >= 400) && (result <= 599)) {
2795  switch (result) {
2796  case 401:
2797  p->hookstate = MGCP_OFFHOOK;
2798  break;
2799  case 402:
2800  p->hookstate = MGCP_ONHOOK;
2801  break;
2802  case 406:
2803  ast_log(LOG_NOTICE, "Transaction %u timed out\n", ident);
2804  break;
2805  case 407:
2806  ast_log(LOG_NOTICE, "Transaction %u aborted\n", ident);
2807  break;
2808  }
2809  if (sub) {
2810  if (!sub->cxident[0] && (req->cmd == MGCP_CMD_CRCX)) {
2811  ast_log(LOG_NOTICE, "DLCX for all connections on %s due to error %d\n", gw->name, result);
2813  }
2814  if (sub->owner) {
2815  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2816  result, p->name, p->parent->name, sub ? sub->id:-1);
2818  }
2819  } else {
2820  if (p->sub->next->owner) {
2821  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2822  result, p->name, p->parent->name, sub ? sub->id:-1);
2823  mgcp_queue_hangup(p->sub);
2824  }
2825 
2826  if (p->sub->owner) {
2827  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2828  result, p->name, p->parent->name, sub ? sub->id:-1);
2829  mgcp_queue_hangup(p->sub);
2830  }
2831 
2832  dump_cmd_queues(p, NULL);
2833  }
2834  }
2835 
2836  if (resp) {
2837  /* responseAck: */
2838  if (result == 200 && (req->cmd == MGCP_CMD_CRCX || req->cmd == MGCP_CMD_MDCX)) {
2839  if (sub) {
2840  transmit_response(sub, "000", resp, "OK");
2841  if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_RINGING) {
2843  }
2844  }
2845  }
2846  if (req->cmd == MGCP_CMD_CRCX) {
2847  if ((c = get_header(resp, "I"))) {
2848  if (!ast_strlen_zero(c) && sub) {
2849  /* if we are hanging up do not process this conn. */
2850  if (sub->owner) {
2851  if (!ast_strlen_zero(sub->cxident)) {
2852  if (strcasecmp(c, sub->cxident)) {
2853  ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c);
2854  }
2855  }
2856  ast_copy_string(sub->cxident, c, sizeof(sub->cxident));
2857  if (sub->tmpdest.sin_addr.s_addr) {
2859  }
2860  } else {
2861  /* XXX delete this one
2862  callid and conn id may already be lost.
2863  so the following del conn may have a side effect of
2864  cleaning up the next subchannel */
2866  }
2867  }
2868  }
2869  }
2870 
2871  if (req->cmd == MGCP_CMD_AUEP) {
2872  /* check stale connection ids */
2873  if ((c = get_header(resp, "I"))) {
2874  char *v, *n;
2875  int len;
2876  while ((v = get_csv(c, &len, &n))) {
2877  if (len) {
2878  if (strncasecmp(v, p->sub->cxident, len) &&
2879  strncasecmp(v, p->sub->next->cxident, len)) {
2880  /* connection id not found. delete it */
2881  char cxident[80] = "";
2882 
2883  if (len > (sizeof(cxident) - 1))
2884  len = sizeof(cxident) - 1;
2885  ast_copy_string(cxident, v, len);
2886  ast_verb(3, "Non existing connection id %s on %s@%s \n",
2887  cxident, p->name, gw->name);
2889  }
2890  }
2891  c = n;
2892  }
2893  }
2894 
2895  /* Try to determine the hookstate returned from an audit endpoint command */
2896  if ((c = get_header(resp, "ES"))) {
2897  if (!ast_strlen_zero(c)) {
2898  if (strstr(c, "hu")) {
2899  if (p->hookstate != MGCP_ONHOOK) {
2900  /* XXX cleanup if we think we are offhook XXX */
2901  if ((p->sub->owner || p->sub->next->owner ) &&
2902  p->hookstate == MGCP_OFFHOOK)
2904  p->hookstate = MGCP_ONHOOK;
2905 
2906  /* update the requested events according to the new hookstate */
2907  transmit_notify_request(p->sub, "");
2908 
2909  ast_verb(3, "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name);
2910  }
2911  } else if (strstr(c, "hd")) {
2912  if (p->hookstate != MGCP_OFFHOOK) {
2913  p->hookstate = MGCP_OFFHOOK;
2914 
2915  /* update the requested events according to the new hookstate */
2916  transmit_notify_request(p->sub, "");
2917 
2918  ast_verb(3, "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name);
2919  }
2920  }
2921  }
2922  }
2923  }
2924 
2925  if (resp && resp->lines) {
2926  /* do not process sdp if we are hanging up. this may be a late response */
2927  if (sub && sub->owner) {
2928  if (!sub->rtp)
2929  start_rtp(sub);
2930  if (sub->rtp)
2931  process_sdp(sub, resp);
2932  }
2933  }
2934  }
2935 
2936  ast_free(req);
2937 }
2938 
2939 static void start_rtp(struct mgcp_subchannel *sub)
2940 {
2941  struct ast_sockaddr bindaddr_tmp;
2942 
2943  ast_mutex_lock(&sub->lock);
2944  /* check again to be on the safe side */
2945  if (sub->rtp) {
2947  sub->rtp = NULL;
2948  }
2949  /* Allocate the RTP now */
2950  ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
2951  sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
2952  if (sub->rtp && sub->owner)
2953  ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
2954  if (sub->rtp) {
2955  ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "MGCP RTP");
2957  }
2958  /* Make a call*ID */
2959  snprintf(sub->callid, sizeof(sub->callid), "%08lx%s", (unsigned long)ast_random(), sub->txident);
2960  /* Transmit the connection create */
2961  if(!sub->parent->pktcgatealloc) {
2963  } else {
2965  sub->gate = NULL;
2966  if(!mgcp_alloc_pktcgate(sub))
2968  }
2969  ast_mutex_unlock(&sub->lock);
2970 }
2971 
2972 static void *mgcp_ss(void *data)
2973 {
2974  struct ast_channel *chan = data;
2975  struct mgcp_subchannel *sub = ast_channel_tech_pvt(chan);
2976  struct mgcp_endpoint *p = sub->parent;
2977  /* char exten[AST_MAX_EXTENSION] = ""; */
2978  int len = 0;
2979  int timeout = firstdigittimeout;
2980  int res= 0;
2981  int getforward = 0;
2982  int loop_pause = 100;
2983  RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
2984  const char *pickupexten;
2985 
2986  len = strlen(p->dtmf_buf);
2987 
2988  ast_channel_lock(chan);
2989  pickup_cfg = ast_get_chan_features_pickup_config(chan);
2990  if (!pickup_cfg) {
2991  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
2992  pickupexten = "";
2993  } else {
2994  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
2995  }
2996  ast_channel_unlock(chan);
2997 
2998  while (len < AST_MAX_EXTENSION - 1) {
2999  ast_debug(1, "Dtmf buffer '%s' for '%s@%s'\n", p->dtmf_buf, p->name, p->parent->name);
3000  res = 1; /* Assume that we will get a digit */
3001  while (strlen(p->dtmf_buf) == len) {
3002  ast_safe_sleep(chan, loop_pause);
3003  timeout -= loop_pause;
3004  if (timeout <= 0){
3005  res = 0;
3006  break;
3007  }
3008  res = 1;
3009  }
3010 
3011  timeout = 0;
3012  len = strlen(p->dtmf_buf);
3013 
3015  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3016  ast_indicate(chan, -1);
3017  } else {
3018  /* XXX Redundant? We should already be playing dialtone */
3019  /*tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
3020  transmit_notify_request(sub, "L/dl");
3021  }
3022  if (ast_exists_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1, p->cid_num)) {
3023  if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1, p->cid_num)) {
3024  if (getforward) {
3025  /* Record this as the forwarding extension */
3026  ast_copy_string(p->call_forward, p->dtmf_buf, sizeof(p->call_forward));
3027  ast_verb(3, "Setting call forward to '%s' on channel %s\n",
3028  p->call_forward, ast_channel_name(chan));
3029  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3030  transmit_notify_request(sub, "L/sl");
3031  if (res)
3032  break;
3033  usleep(500000);
3034  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3035  ast_indicate(chan, -1);
3036  sleep(1);
3037  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3038  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
3039  transmit_notify_request(sub, "L/dl");
3040  len = 0;
3041  getforward = 0;
3042  } else {
3043  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3044  ast_indicate(chan, -1);
3045  ast_channel_lock(chan);
3046  ast_channel_exten_set(chan, p->dtmf_buf);
3048  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3049  ast_set_callerid(chan,
3050  p->hidecallerid ? "" : p->cid_num,
3051  p->hidecallerid ? "" : p->cid_name,
3052  ast_channel_caller(chan)->ani.number.valid ? NULL : p->cid_num);
3054  ast_channel_unlock(chan);
3055  if (p->dtmfmode & MGCP_DTMF_HYBRID) {
3056  p->dtmfmode |= MGCP_DTMF_INBAND;
3057  ast_indicate(chan, -1);
3058  }
3059  res = ast_pbx_run(chan);
3060  if (res) {
3061  ast_log(LOG_WARNING, "PBX exited non-zero\n");
3062  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3063  /*transmit_notify_request(p, "nbz", 1);*/
3064  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3065  }
3066  return NULL;
3067  }
3068  } else {
3069  /* It's a match, but they just typed a digit, and there is an ambiguous match,
3070  so just set the timeout to matchdigittimeout and wait some more */
3071  timeout = matchdigittimeout;
3072  }
3073  } else if (res == 0) {
3074  ast_debug(1, "not enough digits (and no ambiguous match)...\n");
3075  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3076  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3077  /*dahdi_wait_event(p->subs[index].zfd);*/
3078  ast_hangup(chan);
3079  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3080  return NULL;
3081  } else if (p->hascallwaiting && p->callwaiting && !strcmp(p->dtmf_buf, "*70")) {
3082  ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan));
3083  /* Disable call waiting if enabled */
3084  p->callwaiting = 0;
3085  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3086  transmit_notify_request(sub, "L/sl");
3087  len = 0;
3088  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3089  timeout = firstdigittimeout;
3090  } else if (!strcmp(p->dtmf_buf, pickupexten)) {
3091  /* Scan all channels and see if any there
3092  * ringing channels with that have call groups
3093  * that equal this channels pickup group
3094  */
3095  if (ast_pickup_call(chan)) {
3096  ast_log(LOG_WARNING, "No call pickup possible...\n");
3097  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3098  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3099  }
3100  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3101  ast_hangup(chan);
3102  return NULL;
3103  } else if (!p->hidecallerid && !strcmp(p->dtmf_buf, "*67")) {
3104  ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
3105  /* Disable Caller*ID if enabled */
3106  p->hidecallerid = 1;
3107  ast_set_callerid(chan, "", "", NULL);
3108  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3109  transmit_notify_request(sub, "L/sl");
3110  len = 0;
3111  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3112  timeout = firstdigittimeout;
3113  } else if (p->callreturn && !strcmp(p->dtmf_buf, "*69")) {
3114  res = 0;
3115  if (!ast_strlen_zero(p->lastcallerid)) {
3116  res = ast_say_digit_str(chan, p->lastcallerid, "", ast_channel_language(chan));
3117  }
3118  if (!res)
3119  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3120  transmit_notify_request(sub, "L/sl");
3121  break;
3122  } else if (!strcmp(p->dtmf_buf, "*78")) {
3123  /* Do not disturb */
3124  ast_verb(3, "Enabled DND on channel %s\n", ast_channel_name(chan));
3125  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3126  transmit_notify_request(sub, "L/sl");
3127  p->dnd = 1;
3128  getforward = 0;
3129  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3130  len = 0;
3131  } else if (!strcmp(p->dtmf_buf, "*79")) {
3132  /* Do not disturb */
3133  ast_verb(3, "Disabled DND on channel %s\n", ast_channel_name(chan));
3134  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3135  transmit_notify_request(sub, "L/sl");
3136  p->dnd = 0;
3137  getforward = 0;
3138  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3139  len = 0;
3140  } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*72")) {
3141  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3142  transmit_notify_request(sub, "L/sl");
3143  getforward = 1;
3144  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3145  len = 0;
3146  } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*73")) {
3147  ast_verb(3, "Cancelling call forwarding on channel %s\n", ast_channel_name(chan));
3148  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3149  transmit_notify_request(sub, "L/sl");
3150  memset(p->call_forward, 0, sizeof(p->call_forward));
3151  getforward = 0;
3152  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3153  len = 0;
3155  sub->next->owner) {
3156  RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
3157  /* This is a three way call, the main call being a real channel,
3158  and we're parking the first call. */
3159  ast_channel_lock(chan);
3160  bridge_channel = ast_channel_get_bridge_channel(chan);
3161  ast_channel_unlock(chan);
3162  if (bridge_channel && !ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), p->dtmf_buf, NULL, NULL)) {
3163  ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
3164  }
3165  break;
3166  } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(p->dtmf_buf, "*60")) {
3167  ast_verb(3, "Blacklisting number %s\n", p->lastcallerid);
3168  res = ast_db_put("blacklist", p->lastcallerid, "1");
3169  if (!res) {
3170  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3171  transmit_notify_request(sub, "L/sl");
3172  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3173  len = 0;
3174  }
3175  } else if (p->hidecallerid && !strcmp(p->dtmf_buf, "*82")) {
3176  ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
3177  /* Enable Caller*ID if enabled */
3178  p->hidecallerid = 0;
3179  ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
3180  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3181  transmit_notify_request(sub, "L/sl");
3182  len = 0;
3183  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3184  timeout = firstdigittimeout;
3185  } else if (!ast_canmatch_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1,
3186  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
3187  && ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
3188  ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf,
3189  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
3190  ast_channel_context(chan));
3191  break;
3192  }
3193  if (!timeout)
3194  timeout = gendigittimeout;
3196  /*tone_zone_play_tone(p->subs[index].zfd, -1);*/
3197  ast_indicate(chan, -1);
3198  }
3199 #if 0
3200  for (;;) {
3201  res = ast_waitfordigit(chan, to);
3202  if (!res) {
3203  ast_debug(1, "Timeout...\n");
3204  break;
3205  }
3206  if (res < 0) {
3207  ast_debug(1, "Got hangup...\n");
3208  ast_hangup(chan);
3209  break;
3210  }
3211  exten[pos++] = res;
3212  if (!ast_ignore_pattern(chan->context, exten))
3213  ast_indicate(chan, -1);
3214  if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
3215  if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid))
3216  to = 3000;
3217  else
3218  to = 8000;
3219  } else
3220  break;
3221  }
3222  if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
3223  ast_copy_string(chan->exten, exten, sizeof(chan->exten)1);
3224  if (!p->rtp) {
3225  start_rtp(p);
3226  }
3228  chan->rings = 1;
3229  if (ast_pbx_run(chan)) {
3230  ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
3231  } else {
3232  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3233  return NULL;
3234  }
3235  }
3236 #endif
3237  ast_hangup(chan);
3238  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3239  return NULL;
3240 }
3241 
3242 /*! \brief Complete an attended transfer
3243  *
3244  * \param p The endpoint performing the attended transfer
3245  * \param sub The sub-channel completing the attended transfer
3246  *
3247  * \note p->sub is the currently active sub-channel (the channel the phone is using)
3248  * \note p->sub->next is the sub-channel not in use, potentially on hold
3249  *
3250  * \retval 0 when channel should be hung up
3251  * \retval 1 when channel should not be hung up
3252  */
3253 static int attempt_transfer(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
3254 {
3255  enum ast_transfer_result res;
3256 
3257  /* Ensure that the other channel goes off hold and that it is indicating properly */
3258  ast_queue_unhold(sub->next->owner);
3259  if (ast_channel_state(sub->owner) == AST_STATE_RINGING) {
3260  ast_queue_control(sub->next->owner, AST_CONTROL_RINGING);
3261  }
3262 
3263  ast_mutex_unlock(&p->sub->next->lock);
3264  ast_mutex_unlock(&p->sub->lock);
3265  res = ast_bridge_transfer_attended(sub->owner, sub->next->owner);
3266 
3267  /* Subs are only freed when the endpoint itself is destroyed, so they will continue to exist
3268  * after ast_bridge_transfer_attended returns making this safe without reference counting
3269  */
3270  ast_mutex_lock(&p->sub->lock);
3271  ast_mutex_lock(&p->sub->next->lock);
3272 
3273  if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
3274  /* If transferring fails hang up the other channel if present and us */
3275  if (sub->next->owner) {
3277  mgcp_queue_hangup(sub->next);
3278  }
3279  sub->next->alreadygone = 1;
3280  return 0;
3281  }
3282 
3283  unalloc_sub(sub->next);
3284 
3285  /* If the active sub is NOT the one completing the transfer change it to be, and hang up the other sub */
3286  if (p->sub != sub) {
3287  p->sub = sub;
3288  return 1;
3289  }
3290 
3291  return 0;
3292 }
3293 
3294 static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
3295 {
3296  struct mgcp_endpoint *p = sub->parent;
3297  struct ast_channel *c;
3298  pthread_t t;
3299 
3300  /* Off hook / answer */
3301  if (sub->outgoing) {
3302  /* Answered */
3303  if (sub->owner) {
3304  ast_queue_unhold(sub->owner);
3305  sub->cxmode = MGCP_CX_SENDRECV;
3306  if (!sub->rtp) {
3307  start_rtp(sub);
3308  } else {
3310  }
3311  /*transmit_notify_request(sub, "aw");*/
3314  }
3315  } else {
3316  /* Start switch */
3317  /*sub->cxmode = MGCP_CX_SENDRECV;*/
3318  if (!sub->owner) {
3319  if (!sub->rtp) {
3320  start_rtp(sub);
3321  } else {
3323  }
3324  if (p->immediate) {
3325  /* The channel is immediately up. Start right away */
3326 #ifdef DLINK_BUGGY_FIRMWARE
3328 #else
3329  transmit_notify_request(sub, p->ncs ? "L/rt" : "G/rt");
3330 #endif
3332  if (!c) {
3333  ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
3334  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3335  ast_hangup(c);
3336  }
3337  } else {
3338  if (has_voicemail(p)) {
3339  transmit_notify_request(sub, "L/sl");
3340  } else {
3341  transmit_notify_request(sub, "L/dl");
3342  }
3344  if (c) {
3346  ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
3347  ast_hangup(c);
3348  }
3349  } else {
3350  ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
3351  }
3352  }
3353  } else {
3354  if (p->hookstate == MGCP_OFFHOOK) {
3355  ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name);
3356  } else {
3357  ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name);
3358  ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?\n");
3359  }
3360  ast_queue_unhold(sub->owner);
3361  sub->cxmode = MGCP_CX_SENDRECV;
3362  if (!sub->rtp) {
3363  start_rtp(sub);
3364  } else {
3366  }
3367  /*transmit_notify_request(sub, "aw");*/
3369  /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/
3370  }
3371  }
3372 }
3373 
3374 static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
3375 {
3376  char *ev, *s;
3377  struct ast_frame f = { 0, };
3378  struct mgcp_endpoint *p = sub->parent;
3379  struct mgcp_gateway *g = NULL;
3380  int res;
3381 
3382  ast_debug(1, "Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
3383  /* Clear out potential response */
3384  if (!strcasecmp(req->verb, "RSIP")) {
3385  /* Test if this RSIP request is just a keepalive */
3386  if (!strcasecmp( get_header(req, "RM"), "X-keepalive")) {
3387  ast_verb(3, "Received keepalive request from %s@%s\n", p->name, p->parent->name);
3388  transmit_response(sub, "200", req, "OK");
3389  } else {
3390  dump_queue(p->parent, p);
3391  dump_cmd_queues(p, NULL);
3392 
3393  if ((strcmp(p->name, p->parent->wcardep) != 0)) {
3394  ast_verb(3, "Resetting interface %s@%s\n", p->name, p->parent->name);
3395  }
3396  /* For RSIP on wildcard we reset all endpoints */
3397  if (!strcmp(p->name, p->parent->wcardep)) {
3398  /* Reset all endpoints */
3399  struct mgcp_endpoint *tmp_ep;
3400 
3401  g = p->parent;
3402  for (tmp_ep = g->endpoints; tmp_ep; tmp_ep = tmp_ep->next) {
3403  /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/
3404  if (strcmp(tmp_ep->name, g->wcardep) != 0) {
3405  struct mgcp_subchannel *tmp_sub, *first_sub;
3406  ast_verb(3, "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name);
3407 
3408  first_sub = tmp_ep->sub;
3409  tmp_sub = tmp_ep->sub;
3410  while (tmp_sub) {
3411  mgcp_queue_hangup(tmp_sub);
3412  tmp_sub = tmp_sub->next;
3413  if (tmp_sub == first_sub)
3414  break;
3415  }
3416  }
3417  }
3418  } else if (sub->owner) {
3420  }
3421  transmit_response(sub, "200", req, "OK");
3422  /* We don't send NTFY or AUEP to wildcard ep */
3423  if (strcmp(p->name, p->parent->wcardep) != 0) {
3425  /* Audit endpoint.
3426  Idea is to prevent lost lines due to race conditions
3427  */
3429  }
3430  }
3431  } else if (!strcasecmp(req->verb, "NTFY")) {
3432  /* Acknowledge and be sure we keep looking for the same things */
3433  transmit_response(sub, "200", req, "OK");
3434  /* Notified of an event */
3435  ev = get_header(req, "O");
3436  s = strchr(ev, '/');
3437  if (s) ev = s + 1;
3438  ast_debug(1, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev);
3439  /* Keep looking for events unless this was a hangup */
3440  if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) {
3442  }
3443  if (!strcasecmp(ev, "hd")) {
3444  p->hookstate = MGCP_OFFHOOK;
3445  sub->cxmode = MGCP_CX_SENDRECV;
3446 
3447  if (p) {
3448  /* When the endpoint have a Off hook transition we always
3449  starts without any previous dtmfs */
3450  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3451  }
3452 
3453  handle_hd_hf(sub, ev);
3454  } else if (!strcasecmp(ev, "hf")) {
3455  /* We can assume we are offhook if we received a hookflash */
3456  /* First let's just do call wait and ignore threeway */
3457  /* We're currently in charge */
3458  if (p->hookstate != MGCP_OFFHOOK) {
3459  /* Cisco c7940 sends hf even if the phone is onhook */
3460  /* Thanks to point on IRC for pointing this out */
3461  return -1;
3462  }
3463  /* do not let * conference two down channels */
3464  if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_DOWN && !sub->next->owner)
3465  return -1;
3466 
3467  if (p->callwaiting || p->transfer || p->threewaycalling) {
3468  ast_verb(3, "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
3469  p->sub = p->sub->next;
3470 
3471  /* transfer control to our next subchannel */
3472  if (!sub->next->owner) {
3473  /* plave the first call on hold and start up a new call */
3474  sub->cxmode = MGCP_CX_MUTE;
3475  ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
3477  if (sub->owner) {
3478  ast_queue_hold(sub->owner, NULL);
3479  }
3480  sub->next->cxmode = MGCP_CX_RECVONLY;
3481  handle_hd_hf(sub->next, ev);
3482  } else if (sub->owner && sub->next->owner) {
3483  /* We've got two active calls lets decide whether or not to conference or just flip flop */
3484  if ((!sub->outgoing) && (!sub->next->outgoing)) {
3485  /* We made both calls lets conference */
3486  ast_verb(3, "MGCP Conferencing %d and %d on %s@%s\n",
3487  sub->id, sub->next->id, p->name, p->parent->name);
3488  sub->cxmode = MGCP_CX_CONF;
3489  sub->next->cxmode = MGCP_CX_CONF;
3490  ast_queue_unhold(sub->next->owner);
3493  } else {
3494  /* Let's flipflop between calls */
3495  /* XXX Need to check for state up ??? */
3496  /* XXX Need a way to indicate the current call, or maybe the call that's waiting */
3497  ast_verb(3, "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n",
3498  sub->id, sub->next->id, p->name, p->parent->name);
3499  sub->cxmode = MGCP_CX_MUTE;
3500  ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
3502 
3503  ast_queue_hold(sub->owner, NULL);
3504  ast_queue_hold(sub->next->owner, NULL);
3505 
3506  handle_hd_hf(sub->next, ev);
3507  }
3508  } else {
3509  /* We've most likely lost one of our calls find an active call and bring it up */
3510  if (sub->owner) {
3511  p->sub = sub;
3512  } else if (sub->next->owner) {
3513  p->sub = sub->next;
3514  } else {
3515  /* We seem to have lost both our calls */
3516  /* XXX - What do we do now? */
3517  return -1;
3518  }
3519  ast_queue_unhold(p->sub->owner);
3520  p->sub->cxmode = MGCP_CX_SENDRECV;
3522  }
3523  } else {
3524  ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n",
3525  p->name, p->parent->name);
3526  }
3527  } else if (!strcasecmp(ev, "hu")) {
3528  p->hookstate = MGCP_ONHOOK;
3529  sub->cxmode = MGCP_CX_RECVONLY;
3530  ast_debug(1, "MGCP %s@%s Went on hook\n", p->name, p->parent->name);
3531  /* Do we need to send MDCX before a DLCX ?
3532  if (sub->rtp) {
3533  transmit_modify_request(sub);
3534  }
3535  */
3536  if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) {
3537  /* We're allowed to transfer, we have two active calls and */
3538  /* we made at least one of the calls. Let's try and transfer */
3539  ast_mutex_lock(&p->sub->next->lock);
3540  res = attempt_transfer(p, sub);
3541  if (res) {
3542  ast_log(LOG_WARNING, "Transfer attempt failed\n");
3543  ast_mutex_unlock(&p->sub->next->lock);
3544  return -1;
3545  }
3546  ast_mutex_unlock(&p->sub->next->lock);
3547  } else {
3548  /* Hangup the current call */
3549  /* If there is another active call, mgcp_hangup will ring the phone with the other call */
3550  if (sub->owner) {
3551  sub->alreadygone = 1;
3553  } else {
3554  ast_verb(3, "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n",
3555  p->name, p->parent->name, sub->id);
3556  /* Instruct the other side to remove the connection since it apparently *
3557  * still thinks the channel is active. *
3558  * For Cisco IAD2421 /BAK/ */
3560  }
3561  }
3562  if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) {
3563  p->hidecallerid = 0;
3564  if (p->hascallwaiting && !p->callwaiting) {
3565  ast_verb(3, "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id);
3566  p->callwaiting = -1;
3567  }
3568  if (has_voicemail(p)) {
3569  ast_verb(3, "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name);
3570  transmit_notify_request(sub, "L/vmwi(+)");
3571  } else {
3572  ast_verb(3, "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name);
3573  transmit_notify_request(sub, "L/vmwi(-)");
3574  }
3575  }
3576  } else if ((strlen(ev) == 1) &&
3577  (((ev[0] >= '0') && (ev[0] <= '9')) ||
3578  ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
3579  (ev[0] == '*') || (ev[0] == '#'))) {
3580  if (sub && sub->owner && (ast_channel_state(sub->owner) >= AST_STATE_UP)) {
3582  f.subclass.integer = ev[0];
3583  f.src = "mgcp";
3584  /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */
3585  mgcp_queue_frame(sub, &f);
3586  ast_mutex_lock(&sub->next->lock);
3587  if (sub->next->owner)
3588  mgcp_queue_frame(sub->next, &f);
3589  ast_mutex_unlock(&sub->next->lock);
3590  if (strstr(p->curtone, (p->ncs ? "wt1" : "wt")) && (ev[0] == 'A')) {
3591  memset(p->curtone, 0, sizeof(p->curtone));
3592  }
3593  } else {
3594  p->dtmf_buf[strlen(p->dtmf_buf)] = ev[0];
3595  p->dtmf_buf[strlen(p->dtmf_buf)] = '\0';
3596  }
3597  } else if (!strcasecmp(ev, "T")) {
3598  /* Digit timeout -- unimportant */
3599  } else if (!strcasecmp(ev, "ping")) {
3600  /* ping -- unimportant */
3601  } else {
3602  ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
3603  }
3604  } else {
3605  ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(sin->sin_addr));
3606  transmit_response(sub, "510", req, "Unknown verb");
3607  }
3608  return 0;
3609 }
3610 
3611 static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *req)
3612 {
3613  int seqno=0;
3614  time_t now;
3615  struct mgcp_response *prev = NULL, *cur, *next, *answer = NULL;
3616  time(&now);
3617  if (sscanf(req->identifier, "%30d", &seqno) != 1) {
3618  seqno = 0;
3619  }
3620  for (cur = sub->parent->parent->responses, next = cur ? cur->next : NULL; cur; cur = next, next = cur ? cur->next : NULL) {
3621  if (now - cur->whensent > RESPONSE_TIMEOUT) {
3622  /* Delete this entry */
3623  if (prev)
3624  prev->next = next;
3625  else
3626  sub->parent->parent->responses = next;
3627  ast_free(cur);
3628  } else {
3629  if (seqno == cur->seqno)
3630  answer = cur;
3631  prev = cur;
3632  }
3633  }
3634  if (answer) {
3636  return 1;
3637  }
3638  return 0;
3639 }
3640 
3641 static int mgcpsock_read(int *id, int fd, short events, void *ignore)
3642 {
3643  struct mgcp_request req;
3644  struct sockaddr_in sin;
3645  struct mgcp_subchannel *sub;
3646  int res;
3647  socklen_t len;
3648  int result;
3649  int ident;
3650  len = sizeof(sin);
3651  memset(&req, 0, sizeof(req));
3652  res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
3653  if (res < 0) {
3654  if (errno != ECONNREFUSED)
3655  ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
3656  return 1;
3657  }
3658  req.data[res] = '\0';
3659  req.len = res;
3660  ast_debug(1, "MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
3661  parse(&req);
3662  if (req.headers < 1) {
3663  /* Must have at least one header */
3664  return 1;
3665  }
3666  if (ast_strlen_zero(req.identifier)) {
3667  ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin.sin_addr));
3668  return 1;
3669  }
3670 
3671  if (sscanf(req.verb, "%30d", &result) && sscanf(req.identifier, "%30d", &ident)) {
3672  if (result < 200) {
3673  ast_debug(1, "Ignoring provisional response on transaction %d\n", ident);
3674  return 1;
3675  }
3676  /* Try to find who this message is for, if it's important */
3677  sub = find_subchannel_and_lock(NULL, ident, &sin);
3678  if (sub) {
3679  struct mgcp_gateway *gw = sub->parent->parent;
3680  struct mgcp_message *cur, *prev;
3681 
3682  ast_mutex_unlock(&sub->lock);
3683  ast_mutex_lock(&gw->msgs_lock);
3684  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
3685  if (cur->seqno == ident) {
3686  ast_debug(1, "Got response back on transaction %d\n", ident);
3687  if (prev)
3688  prev->next = cur->next;
3689  else
3690  gw->msgs = cur->next;
3691  break;
3692  }
3693  }
3694 
3695  /* stop retrans timer if the queue is empty */
3696  if (!gw->msgs) {
3698  }
3699 
3701  if (cur) {
3702  handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req);
3703  ast_free(cur);
3704  return 1;
3705  }
3706 
3707  ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n",
3708  gw->name, ident);
3709  }
3710  } else {
3711  if (ast_strlen_zero(req.endpoint) ||
3712  ast_strlen_zero(req.version) ||
3713  ast_strlen_zero(req.verb)) {
3714  ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
3715  return 1;
3716  }
3717  /* Process request, with iflock held */
3718  sub = find_subchannel_and_lock(req.endpoint, 0, &sin);
3719  if (sub) {
3720  /* look first to find a matching response in the queue */
3721  if (!find_and_retrans(sub, &req))
3722  /* pass the request off to the currently mastering subchannel */
3723  handle_request(sub, &req, &sin);
3724  ast_mutex_unlock(&sub->lock);
3725  }
3726  }
3727  return 1;
3728 }
3729 
3730 static int *mgcpsock_read_id = NULL;
3731 
3733 {
3734  struct mgcp_endpoint *enext, *e;
3735  struct mgcp_subchannel *s, *sub;
3736  int i, prune = 1;
3737 
3738  if (g->ha || !g->realtime || ast_mutex_trylock(&g->msgs_lock) || g->msgs) {
3740  return 0;
3741  }
3742 
3743  for (e = g->endpoints; e; e = e->next) {
3744  ast_mutex_lock(&e->lock);
3746  prune = 0;
3747  } else if (e->rqnt_queue || e->cmd_queue) {
3748  prune = 0;
3749  }
3750  s = e->sub;
3751  for (i = 0; (i < MAX_SUBS) && s; i++) {
3752  ast_mutex_lock(&s->lock);
3753  if (!ast_strlen_zero(s->cxident) || s->rtp || ast_mutex_trylock(&s->cx_queue_lock) || s->gate) {
3754  prune = 0;
3755  } else if (s->cx_queue) {
3756  prune = 0;
3757  }
3758  s = s->next;
3759  }
3760  }
3761 
3762  for (e = g->endpoints, sub = e->sub, enext = e->next; e; e = enext, enext = e->next) {
3763  for (i = 0; (i < MAX_SUBS) && sub; i++) {
3764  s = sub;
3765  sub = sub->next;
3766  ast_mutex_unlock(&s->lock);
3768  if (prune) {
3769  ast_mutex_destroy(&s->lock);
3771  ast_free(s);
3772  }
3773  }
3774  ast_mutex_unlock(&e->lock);
3777  if (prune) {
3778  ast_mutex_destroy(&e->lock);
3781  ast_free(e);
3782  }
3783  }
3784  if (prune) {
3785  ast_debug(1, "***** MGCP REALTIME PRUNE GW: %s\n", g->name);
3786  }
3787  return prune;
3788 }
3789 
3790 static void *do_monitor(void *data)
3791 {
3792  int res;
3793  int reloading;
3794  struct mgcp_gateway *g, *gprev;
3795  /*struct mgcp_gateway *g;*/
3796  /*struct mgcp_endpoint *e;*/
3797  /*time_t thispass = 0, lastpass = 0;*/
3798  time_t lastrun = 0;
3799 
3800  /* Add an I/O event to our UDP socket */
3801  if (mgcpsock > -1) {
3803  }
3804  /* This thread monitors all the frame relay interfaces which are not yet in use
3805  (and thus do not have a separate thread) indefinitely */
3806  /* From here on out, we die whenever asked */
3807  for (;;) {
3808  /* Check for a reload request */
3810  reloading = mgcp_reloading;
3811  mgcp_reloading = 0;
3813  if (reloading) {
3814  ast_verb(1, "Reloading MGCP\n");
3815  reload_config(1);
3816  /* Add an I/O event to our UDP socket */
3817  if (mgcpsock > -1 && !mgcpsock_read_id) {
3819  }
3820  }
3821 
3822  /* Check for interfaces needing to be killed */
3823  /* Don't let anybody kill us right away. Nobody should lock the interface list
3824  and wait for the monitor list, but the other way around is okay. */
3826  /* Lock the network interface */
3828 
3829 #if 0
3830  /* XXX THIS IS COMPLETELY HOSED */
3831  /* The gateway goes into a state of panic */
3832  /* If the vmwi indicator is sent while it is reseting interfaces */
3833  lastpass = thispass;
3834  thispass = time(NULL);
3835  g = gateways;
3836  while(g) {
3837  if (thispass != lastpass) {
3838  e = g->endpoints;
3839  while(e) {
3840  if (e->type == TYPE_LINE) {
3841  res = has_voicemail(e);
3842  if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){
3843  if (res) {
3844  transmit_notify_request(e, "L/vmwi(+)");
3845  } else {
3846  transmit_notify_request(e, "L/vmwi(-)");
3847  }
3848  e->msgstate = res;
3849  e->onhooktime = thispass;
3850  }
3851  }
3852  e = e->next;
3853  }
3854  }
3855  g = g->next;
3856  }
3857 #endif
3858  /* pruning unused realtime gateways, running in every 60 seconds*/
3859  if(time(NULL) > (lastrun + 60)) {
3861  g = gateways;
3862  gprev = NULL;
3863  while(g) {
3864  if(g->realtime) {
3866  if(gprev) {
3867  gprev->next = g->next;
3868  } else {
3869  gateways = g->next;
3870  }
3873  ast_free(g);
3874  } else {
3876  gprev = g;
3877  }
3878  } else {
3879  gprev = g;
3880  }
3881  g = g->next;
3882  }
3884  lastrun = time(NULL);
3885  }
3886  /* Okay, now that we know what to do, release the network lock */
3888  /* And from now on, we're okay to be killed, so release the monitor lock as well */
3890  pthread_testcancel();
3891  /* Wait for sched or io */
3892  res = ast_sched_wait(sched);
3893  /* copied from chan_sip.c */
3894  if ((res < 0) || (res > 1000)) {
3895  res = 1000;
3896  }
3897  res = ast_io_wait(io, res);
3899  if (res >= 0) {
3901  }
3903  }
3904  /* Never reached */
3905  return NULL;
3906 }
3907 
3908 static int restart_monitor(void)
3909 {
3910  /* If we're supposed to be stopped -- stay stopped */
3912  return 0;
3913  if (ast_mutex_lock(&monlock)) {
3914  ast_log(LOG_WARNING, "Unable to lock monitor\n");
3915  return -1;
3916  }
3917  if (monitor_thread == pthread_self()) {
3919  ast_log(LOG_WARNING, "Cannot kill myself\n");
3920  return -1;
3921  }
3923  /* Wake up the thread */
3924  pthread_kill(monitor_thread, SIGURG);
3925  } else {
3926  /* Start a new monitor */
3929  ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
3930  return -1;
3931  }
3932  }
3934  return 0;
3935 }
3936 
3937 static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
3938 {
3939  struct mgcp_subchannel *sub;
3940  struct ast_channel *tmpc = NULL;
3941  char tmp[256];
3942 
3944  struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3945  ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n",
3946  ast_format_cap_get_names(cap, &cap_buf));
3947  /*return NULL;*/
3948  }
3949  ast_copy_string(tmp, dest, sizeof(tmp));
3950  if (ast_strlen_zero(tmp)) {
3951  ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n");
3952  return NULL;
3953  }
3954  if (!(sub = find_subchannel_and_lock(tmp, 0, NULL))) {
3955  ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
3956  *cause = AST_CAUSE_UNREGISTERED;
3957  return NULL;
3958  }
3959 
3960  ast_verb(3, "MGCP mgcp_request(%s)\n", tmp);
3961  ast_verb(3, "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n",
3962  sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0);
3963  /* Must be busy */
3964  if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) ||
3965  ((!sub->parent->callwaiting) && (sub->owner)) ||
3966  (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) {
3967  if (sub->parent->hookstate == MGCP_ONHOOK) {
3968  if (has_voicemail(sub->parent)) {
3969  transmit_notify_request(sub,"L/vmwi(+)");
3970  } else {
3971  transmit_notify_request(sub,"L/vmwi(-)");
3972  }
3973  }
3974  *cause = AST_CAUSE_BUSY;
3975  ast_mutex_unlock(&sub->lock);
3976  return NULL;
3977  }
3978  tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, assignedids, requestor);
3979  ast_mutex_unlock(&sub->lock);
3980  if (!tmpc)
3981  ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
3982  restart_monitor();
3983  return tmpc;
3984 }
3985 
3986 /* modified for reload support */
3987 /*! \brief build_gateway: parse mgcp.conf and create gateway/endpoint structures */
3988 static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
3989 {
3990  struct mgcp_gateway *gw;
3991  struct mgcp_endpoint *e;
3992  struct mgcp_subchannel *sub;
3993  struct ast_variable *chanvars = NULL;
3994 
3995  /*char txident[80];*/
3996  int i=0, y=0;
3997  int gw_reload = 0;
3998  int ep_reload = 0;
4000 
4001  /* locate existing gateway */
4002  for (gw = gateways; gw; gw = gw->next) {
4003  if (!strcasecmp(cat, gw->name)) {
4004  /* gateway already exists */
4005  gw->delme = 0;
4006  gw_reload = 1;
4007  break;
4008  }
4009  }
4010 
4011  if (!gw && !(gw = ast_calloc(1, sizeof(*gw)))) {
4012  return NULL;
4013  }
4014 
4015  if (!gw_reload) {
4016  gw->expire = -1;
4017  gw->realtime = 0;
4018  gw->retransid = -1;
4019  ast_mutex_init(&gw->msgs_lock);
4020  ast_copy_string(gw->name, cat, sizeof(gw->name));
4021  /* check if the name is numeric ip */
4022  if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE)
4023  gw->isnamedottedip = 1;
4024  }
4025  for (; v; v = v->next) {
4026  if (!strcasecmp(v->name, "host")) {
4027  if (!strcasecmp(v->value, "dynamic")) {
4028  /* They'll register with us */
4029  gw->dynamic = 1;
4030  memset(&gw->addr.sin_addr, 0, 4);
4031  if (gw->addr.sin_port) {
4032  /* If we've already got a port, make it the default rather than absolute */
4033  gw->defaddr.sin_port = gw->addr.sin_port;
4034  gw->addr.sin_port = 0;
4035  }
4036  } else {
4037  /* Non-dynamic. Make sure we become that way if we're not */
4038  AST_SCHED_DEL(sched, gw->expire);
4039  gw->dynamic = 0;
4040  {
4041  struct ast_sockaddr tmp;
4042 
4043  ast_sockaddr_from_sin(&tmp, &gw->addr);
4044  if (ast_get_ip(&tmp, v->value)) {
4045  if (!gw_reload) {
4047  ast_free(gw);
4048  }
4049  return NULL;
4050  }
4051  ast_sockaddr_to_sin(&tmp, &gw->addr);
4052  }
4053  }
4054  } else if (!strcasecmp(v->name, "defaultip")) {
4055  struct ast_sockaddr tmp;
4056 
4058  if (ast_get_ip(&tmp, v->value)) {
4059  if (!gw_reload) {
4061  ast_free(gw);
4062  }
4063  return NULL;
4064  }
4066  } else if (!strcasecmp(v->name, "permit") ||
4067  !strcasecmp(v->name, "deny")) {
4068  int acl_error = 0;
4069  gw->ha = ast_append_ha(v->name, v->value, gw->ha, &acl_error);
4070  if (acl_error) {
4071  ast_log(LOG_ERROR, "Invalid ACL '%s' specified for MGCP gateway '%s' on line %d. Not creating.\n",
4072  v->value, cat, v->lineno);
4073  if (!gw_reload) {
4075  ast_free(gw);
4076  } else {
4077  gw->delme = 1;
4078  }
4079  return NULL;
4080  }
4081  } else if (!strcasecmp(v->name, "port")) {
4082  gw->addr.sin_port = htons(atoi(v->value));
4083  } else if (!strcasecmp(v->name, "context")) {
4084  ast_copy_string(context, v->value, sizeof(context));
4085  } else if (!strcasecmp(v->name, "dtmfmode")) {
4086  if (!strcasecmp(v->value, "inband"))
4088  else if (!strcasecmp(v->value, "rfc2833"))
4090  else if (!strcasecmp(v->value, "hybrid"))
4092  else if (!strcasecmp(v->value, "none"))
4093  dtmfmode = 0;
4094  else
4095  ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno);
4096  } else if (!strcasecmp(v->name, "nat")) {
4097  nat = ast_true(v->value);
4098  } else if (!strcasecmp(v->name, "ncs")) {
4099  ncs = ast_true(v->value);
4100  } else if (!strcasecmp(v->name, "hangupongateremove")) {
4102  } else if (!strcasecmp(v->name, "pktcgatealloc")) {
4104  } else if (!strcasecmp(v->name, "callerid")) {
4105  if (!strcasecmp(v->value, "asreceived")) {
4106  cid_num[0] = '\0';
4107  cid_name[0] = '\0';
4108  } else {
4109  ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
4110  }
4111  } else if (!strcasecmp(v->name, "language")) {
4112  ast_copy_string(language, v->value, sizeof(language));
4113  } else if (!strcasecmp(v->name, "accountcode")) {
4115  } else if (!strcasecmp(v->name, "amaflags")) {
4117  if (y < 0) {
4118  ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
4119  } else {
4120  amaflags = y;
4121  }
4122  } else if (!strcasecmp(v->name, "setvar")) {
4123  chanvars = add_var(v->value, chanvars);
4124  } else if (!strcasecmp(v->name, "clearvars")) {
4125  if (chanvars) {
4126  ast_variables_destroy(chanvars);
4127  chanvars = NULL;
4128  }
4129  } else if (!strcasecmp(v->name, "musiconhold")) {
4131  } else if (!strcasecmp(v->name, "parkinglot")) {
4133  } else if (!strcasecmp(v->name, "callgroup")) {
4135  } else if (!strcasecmp(v->name, "pickupgroup")) {
4137  } else if (!strcasecmp(v->name, "immediate")) {
4138  immediate = ast_true(v->value);
4139  } else if (!strcasecmp(v->name, "cancallforward")) {
4141  } else if (!strcasecmp(v->name, "singlepath")) {
4142  singlepath = ast_true(v->value);
4143  } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
4144  directmedia = ast_true(v->value);
4145  } else if (!strcasecmp(v->name, "mailbox")) {
4146  ast_copy_string(mailbox, v->value, sizeof(mailbox));
4147  } else if (!strcasecmp(v->name, "hasvoicemail")) {
4148  if (ast_true(v->value) && ast_strlen_zero(mailbox)) {
4149  /*
4150  * hasvoicemail is a users.conf legacy voicemail enable method.
4151  * hasvoicemail is only going to work for