Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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 ast_sockaddr addr = { {0,} };
1953  char *codecs;
1954  int codec, codec_count=0;
1955  int iterator;
1956  struct mgcp_endpoint *p = sub->parent;
1957  struct ast_str *global_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1958  struct ast_str *peer_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1959  struct ast_str *pvt_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1960 
1961  /* Get codec and RTP info from SDP */
1962  m = get_sdp(req, "m");
1963  c = get_sdp(req, "c");
1964  if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
1965  ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
1966  return -1;
1967  }
1968  if (sscanf(c, "IN IP4 %256s", host) != 1) {
1969  ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
1970  return -1;
1971  }
1972  /* XXX This could block for a long time, and block the main thread! XXX */
1973  if (ast_sockaddr_resolve_first_af(&addr, host, PARSE_PORT_FORBID, AF_INET)) {
1974  ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
1975  return -1;
1976  }
1977  if (sscanf(m, "audio %30d RTP/AVP %n", &portno, &len) != 1 || !len) {
1978  ast_log(LOG_WARNING, "Malformed media stream descriptor: %s\n", m);
1979  return -1;
1980  }
1981  ast_sockaddr_set_port(&addr, portno);
1983  ast_debug(3, "Peer RTP is at port %s\n", ast_sockaddr_stringify(&addr));
1984  /* Scan through the RTP payload types specified in a "m=" line: */
1985  codecs = ast_strdupa(m + len);
1986  while (!ast_strlen_zero(codecs)) {
1987  if (sscanf(codecs, "%30d%n", &codec, &len) != 1) {
1988  if (codec_count) {
1989  break;
1990  }
1991  ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs);
1992  return -1;
1993  }
1995  codec_count++;
1996  codecs += len;
1997  }
1998 
1999  /* Next, scan through each "a=rtpmap:" line, noting each */
2000  /* specified RTP payload type (with corresponding MIME subtype): */
2001  sdpLineNum_iterator_init(&iterator);
2002  while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
2003  char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
2004  if (sscanf(a, "rtpmap: %30d %127[^/]/", &codec, mimeSubtype) != 2)
2005  continue;
2006  /* Note: should really look at the 'freq' and '#chans' params too */
2007  ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, codec, "audio", mimeSubtype, 0);
2008  }
2009 
2010  /* Now gather all of the codecs that were asked for: */
2012  return -1;
2013  }
2014  ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), peercap, &peerNonCodecCapability);
2016  ast_debug(1, "Capabilities: us - %s, them - %s, combined - %s\n",
2018  ast_format_cap_get_names(peercap, &peer_buf),
2019  ast_format_cap_get_names(p->cap, &pvt_buf));
2020  ao2_ref(peercap, -1);
2021 
2022  ast_debug(1, "Non-codec capabilities: us - %d, them - %d, combined - %d\n",
2023  nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
2024  if (!ast_format_cap_count(p->cap)) {
2025  ast_log(LOG_WARNING, "No compatible codecs!\n");
2026  return -1;
2027  }
2028  return 0;
2029 }
2030 
2031 static int add_header(struct mgcp_request *req, const char *var, const char *value)
2032 {
2033  if (req->len >= sizeof(req->data) - 4) {
2034  ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
2035  return -1;
2036  }
2037  if (req->lines) {
2038  ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
2039  return -1;
2040  }
2041  req->header[req->headers] = req->data + req->len;
2042  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
2043  req->len += strlen(req->header[req->headers]);
2044  if (req->headers < MGCP_MAX_HEADERS) {
2045  req->headers++;
2046  } else {
2047  ast_log(LOG_WARNING, "Out of header space\n");
2048  return -1;
2049  }
2050  return 0;
2051 }
2052 
2053 static int add_line(struct mgcp_request *req, char *line)
2054 {
2055  if (req->len >= sizeof(req->data) - 4) {
2056  ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
2057  return -1;
2058  }
2059  if (!req->lines) {
2060  /* Add extra empty return */
2061  ast_copy_string(req->data + req->len, "\r\n", sizeof(req->data) - req->len);
2062  req->len += strlen(req->data + req->len);
2063  }
2064  req->line[req->lines] = req->data + req->len;
2065  snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
2066  req->len += strlen(req->line[req->lines]);
2067  if (req->lines < MGCP_MAX_LINES) {
2068  req->lines++;
2069  } else {
2070  ast_log(LOG_WARNING, "Out of line space\n");
2071  return -1;
2072  }
2073  return 0;
2074 }
2075 
2076 static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
2077 {
2078  /* Initialize a response */
2079  if (req->headers || req->len) {
2080  ast_log(LOG_WARNING, "Request already initialized?!?\n");
2081  return -1;
2082  }
2083  req->header[req->headers] = req->data + req->len;
2084  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
2085  req->len += strlen(req->header[req->headers]);
2086  if (req->headers < MGCP_MAX_HEADERS) {
2087  req->headers++;
2088  } else {
2089  ast_log(LOG_WARNING, "Out of header space\n");
2090  }
2091  return 0;
2092 }
2093 
2094 static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb, unsigned int oseq)
2095 {
2096  /* Initialize a response */
2097  if (req->headers || req->len) {
2098  ast_log(LOG_WARNING, "Request already initialized?!?\n");
2099  return -1;
2100  }
2101  req->header[req->headers] = req->data + req->len;
2102  /* check if we need brackets around the gw name */
2103  if (p->parent->isnamedottedip) {
2104  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" : "");
2105  } else {
2106 + 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" : "");
2107  }
2108  req->len += strlen(req->header[req->headers]);
2109  if (req->headers < MGCP_MAX_HEADERS) {
2110  req->headers++;
2111  } else {
2112  ast_log(LOG_WARNING, "Out of header space\n");
2113  }
2114  return 0;
2115 }
2116 
2117 
2118 static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
2119 {
2120  memset(resp, 0, sizeof(*resp));
2121  init_resp(resp, msg, req, msgrest);
2122  return 0;
2123 }
2124 
2125 static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
2126 {
2127  unsigned int oseq;
2128  memset(req, 0, sizeof(struct mgcp_request));
2130  oseq_global++;
2131  if (oseq_global > 999999999) {
2132  oseq_global = 1;
2133  }
2134  oseq = oseq_global;
2136  init_req(p, req, verb, oseq);
2137  return oseq;
2138 }
2139 
2140 static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
2141 {
2142  struct mgcp_request resp;
2143  struct mgcp_endpoint *p = sub->parent;
2144  struct mgcp_response *mgr;
2145 
2146  if (!sub) {
2147  return -1;
2148  }
2149 
2150  respprep(&resp, p, msg, req, msgrest);
2151  if (!(mgr = ast_calloc(1, sizeof(*mgr) + resp.len + 1))) {
2152  return send_response(sub, &resp);
2153  }
2154  /* Store MGCP response in case we have to retransmit */
2155  sscanf(req->identifier, "%30d", &mgr->seqno);
2156  time(&mgr->whensent);
2157  mgr->len = resp.len;
2158  memcpy(mgr->buf, resp.data, resp.len);
2159  mgr->buf[resp.len] = '\0';
2160  mgr->next = p->parent->responses;
2161  p->parent->responses = mgr;
2162 
2163  return send_response(sub, &resp);
2164 }
2165 
2166 
2167 static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
2168 {
2169  int len;
2170  int codec;
2171  char costr[80];
2172  struct sockaddr_in sin;
2173  struct ast_sockaddr sin_tmp;
2174  char v[256];
2175  char s[256];
2176  char o[256];
2177  char c[256];
2178  char t[256];
2179  char m[256] = "";
2180  char a[1024] = "";
2181  int x;
2182  struct sockaddr_in dest = { 0, };
2183  struct ast_sockaddr dest_tmp;
2184  struct mgcp_endpoint *p = sub->parent;
2185  /* XXX We break with the "recommendation" and send our IP, in order that our
2186  peer doesn't have to ast_gethostbyname() us XXX */
2187  len = 0;
2188  if (!sub->rtp) {
2189  ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
2190  return -1;
2191  }
2192  ast_rtp_instance_get_local_address(sub->rtp, &sin_tmp);
2193  ast_sockaddr_to_sin(&sin_tmp, &sin);
2194  if (rtp) {
2195  ast_rtp_instance_get_remote_address(sub->rtp, &dest_tmp);
2196  ast_sockaddr_to_sin(&dest_tmp, &dest);
2197  } else {
2198  if (sub->tmpdest.sin_addr.s_addr) {
2199  dest.sin_addr = sub->tmpdest.sin_addr;
2200  dest.sin_port = sub->tmpdest.sin_port;
2201  /* Reset temporary destination */
2202  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
2203  } else {
2204  dest.sin_addr = p->parent->ourip;
2205  dest.sin_port = sin.sin_port;
2206  }
2207  }
2208  ast_debug(1, "We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
2209  ast_copy_string(v, "v=0\r\n", sizeof(v));
2210  snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
2211  ast_copy_string(s, "s=session\r\n", sizeof(s));
2212  snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
2213  ast_copy_string(t, "t=0 0\r\n", sizeof(t));
2214  snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
2215 
2216  for (x = 0; x < ast_format_cap_count(p->cap); x++) {
2218 
2220  ao2_ref(format, -1);
2221  continue;
2222  }
2223 
2224  ast_debug(1, "Answering with capability %s\n", ast_format_get_name(format));
2226  if (codec > -1) {
2227  snprintf(costr, sizeof(costr), " %d", codec);
2228  strncat(m, costr, sizeof(m) - strlen(m) - 1);
2229  snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2230  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2231  }
2232 
2233  ao2_ref(format, -1);
2234  }
2235 
2236  for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
2237  if (p->nonCodecCapability & x) {
2238  ast_debug(1, "Answering with non-codec capability %d\n", (int) x);
2240  if (codec > -1) {
2241  snprintf(costr, sizeof(costr), " %d", codec);
2242  strncat(m, costr, sizeof(m) - strlen(m) - 1);
2243  snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, NULL, x, 0));
2244  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2245  if (x == AST_RTP_DTMF) {
2246  /* Indicate we support DTMF... Not sure about 16,
2247  but MSN supports it so dang it, we will too... */
2248  snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec);
2249  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2250  }
2251  }
2252  }
2253  }
2254  strncat(m, "\r\n", sizeof(m) - strlen(m) - 1);
2255  len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
2256  snprintf(costr, sizeof(costr), "%d", len);
2257  add_line(resp, v);
2258  add_line(resp, o);
2259  add_line(resp, s);
2260  add_line(resp, c);
2261  add_line(resp, t);
2262  add_line(resp, m);
2263  add_line(resp, a);
2264  return 0;
2265 }
2266 
2268 {
2269  struct mgcp_request resp;
2270  char local[256];
2271  char tmp[80];
2272  struct mgcp_endpoint *p = sub->parent;
2273  int i;
2274  struct ast_sockaddr sub_tmpdest_tmp;
2275  unsigned int oseq;
2276 
2277  if (ast_strlen_zero(sub->cxident) && rtp) {
2278  /* We don't have a CXident yet, store the destination and
2279  wait a bit */
2280  ast_rtp_instance_get_remote_address(rtp, &sub_tmpdest_tmp);
2281  ast_sockaddr_to_sin(&sub_tmpdest_tmp, &sub->tmpdest);
2282  return 0;
2283  }
2284  ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
2285 
2286  for (i = 0; i < ast_format_cap_count(p->cap); i++) {
2288 
2290  ao2_ref(format, -1);
2291  continue;
2292  }
2293 
2294  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2295  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2296 
2297  ao2_ref(format, -1);
2298  }
2299 
2300  if (sub->gate) {
2301  if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
2302  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2303  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2304  sub->sdpsent = 1;
2305  } else {
2306  /* oops wait */
2307  ast_debug(1, "Waiting for opened gate...\n");
2308  sub->sdpsent = 0;
2309  return 0;
2310  }
2311  }
2312 
2313 
2314  oseq = reqprep(&resp, p, "MDCX");
2315  add_header(&resp, "C", sub->callid);
2316  add_header(&resp, "L", local);
2317  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2318  /* X header should not be sent. kept for compatibility */
2319  add_header(&resp, "X", sub->txident);
2320  add_header(&resp, "I", sub->cxident);
2321  /*add_header(&resp, "S", "");*/
2322  add_sdp(&resp, sub, rtp);
2323  /* fill in new fields */
2324  resp.cmd = MGCP_CMD_MDCX;
2325  resp.trid = oseq;
2326  return send_request(p, sub, &resp, oseq);
2327 }
2328 
2330 {
2331  struct mgcp_request resp;
2332  char local[256];
2333  char tmp[80];
2334  int i;
2335  struct mgcp_endpoint *p = sub->parent;
2336  unsigned int oseq;
2337 
2338  ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2339  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2340 
2341  ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
2342 
2343  for (i = 0; i < ast_format_cap_count(p->cap); i++) {
2345 
2347  ao2_ref(format, -1);
2348  continue;
2349  }
2350 
2351  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2352  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2353 
2354  ao2_ref(format, -1);
2355  }
2356 
2357  if (sub->gate) {
2358  if(sub->gate->state == GATE_ALLOCATED) {
2359  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2360  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2361  }
2362  }
2363  sub->sdpsent = 1;
2364  oseq = reqprep(&resp, p, "CRCX");
2365  add_header(&resp, "C", sub->callid);
2366  add_header(&resp, "L", local);
2367  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2368  /* X header should not be sent. kept for compatibility */
2369  add_header(&resp, "X", sub->txident);
2370  /*add_header(&resp, "S", "");*/
2371  add_sdp(&resp, sub, rtp);
2372  /* fill in new fields */
2373  resp.cmd = MGCP_CMD_CRCX;
2374  resp.trid = oseq;
2375  return send_request(p, sub, &resp, oseq);
2376 }
2377 
2378 static int mgcp_pktcgate_remove(struct cops_gate *gate)
2379 {
2380  struct mgcp_subchannel *sub = gate->tech_pvt;
2381 
2382  if (!sub) {
2383  return 1;
2384  }
2385 
2386  ast_mutex_lock(&sub->lock);
2387  ast_debug(1, "Pktc: gate 0x%x deleted\n", gate->gateid);
2388  if (sub->gate->state != GATE_CLOSED && sub->parent->hangupongateremove) {
2389  sub->gate = NULL;
2390  if (sub->owner) {
2392  ast_channel_unlock(sub->owner);
2393  }
2394  } else {
2395  sub->gate = NULL;
2396  }
2397  ast_mutex_unlock(&sub->lock);
2398  return 1;
2399 }
2400 
2401 static int mgcp_pktcgate_open(struct cops_gate *gate)
2402 {
2403  struct mgcp_subchannel *sub = gate->tech_pvt;
2404  if (!sub) {
2405  return 1;
2406  }
2407  ast_mutex_lock(&sub->lock);
2408  ast_debug(1, "Pktc: gate 0x%x open\n", gate->gateid);
2409  if (!sub->sdpsent) transmit_modify_with_sdp(sub, NULL, 0);
2410  ast_mutex_unlock(&sub->lock);
2411  return 1;
2412 }
2413 
2415 {
2416  struct mgcp_endpoint *p = sub->parent;
2417  sub->gate = ast_pktccops_gate_alloc(GATE_SET, NULL, ntohl(p->parent->addr.sin_addr.s_addr),
2418  8, 128000, 232, 0, 0, NULL, &mgcp_pktcgate_remove);
2419 
2420  if (!sub->gate) {
2421  return 0;
2422  }
2423  sub->gate->tech_pvt = sub;
2424  sub->gate->gate_open = &mgcp_pktcgate_open;
2425  return 1;
2426 }
2427 
2429 {
2430  struct mgcp_request resp;
2431  int x;
2432  char local[256];
2433  char tmp[80];
2434  struct ast_format *tmpfmt;
2435  struct mgcp_endpoint *p = sub->parent;
2436  unsigned int oseq;
2437 
2438  ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
2439 
2440  for (x = 0; x < ast_format_cap_count(p->cap); x++) {
2441  tmpfmt = ast_format_cap_get_format(p->cap, x);
2442 
2443  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, tmpfmt, 0, 0));
2444  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2445 
2446  ao2_ref(tmpfmt, -1);
2447  }
2448 
2449  ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2450  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2451  sub->sdpsent = 0;
2452  oseq = reqprep(&resp, p, "CRCX");
2453  add_header(&resp, "C", sub->callid);
2454  add_header(&resp, "L", local);
2455  add_header(&resp, "M", "inactive");
2456  /* X header should not be sent. kept for compatibility */
2457  add_header(&resp, "X", sub->txident);
2458  /*add_header(&resp, "S", "");*/
2459  /* fill in new fields */
2460  resp.cmd = MGCP_CMD_CRCX;
2461  resp.trid = oseq;
2462  return send_request(p, sub, &resp, oseq);
2463 }
2464 
2465 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
2466 {
2467  struct mgcp_request resp;
2468  struct mgcp_endpoint *p = sub->parent;
2469  unsigned int oseq;
2470 
2471  ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2472  tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2473  ast_copy_string(p->curtone, tone, sizeof(p->curtone));
2474  oseq = reqprep(&resp, p, "RQNT");
2475  add_header(&resp, "X", p->rqnt_ident);
2476  switch (p->hookstate) {
2477  case MGCP_ONHOOK:
2478  add_header(&resp, "R", "L/hd(N)");
2479  break;
2480  case MGCP_OFFHOOK:
2481  add_header_offhook(sub, &resp, tone);
2482  break;
2483  }
2484  if (!ast_strlen_zero(tone)) {
2485  add_header(&resp, "S", tone);
2486  }
2487  /* fill in new fields */
2488  resp.cmd = MGCP_CMD_RQNT;
2489  resp.trid = oseq;
2490  return send_request(p, NULL, &resp, oseq);
2491 }
2492 
2493 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
2494 {
2495  struct mgcp_request resp;
2496  char tone2[256];
2497  char *l, *n;
2498  struct timeval t = ast_tvnow();
2499  struct ast_tm tm;
2500  struct mgcp_endpoint *p = sub->parent;
2501  unsigned int oseq;
2502 
2503  ast_localtime(&t, &tm, NULL);
2504  n = callername;
2505  l = callernum;
2506  if (!n)
2507  n = "";
2508  if (!l)
2509  l = "";
2510 
2511  /* Keep track of last callerid for blacklist and callreturn */
2512  ast_copy_string(p->lastcallerid, l, sizeof(p->lastcallerid));
2513 
2514  snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone,
2515  tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
2516  ast_copy_string(p->curtone, tone, sizeof(p->curtone));
2517  oseq = reqprep(&resp, p, "RQNT");
2518  add_header(&resp, "X", p->rqnt_ident);
2519  switch (p->hookstate) {
2520  case MGCP_ONHOOK:
2521  add_header(&resp, "R", "L/hd(N)");
2522  break;
2523  case MGCP_OFFHOOK:
2524  add_header_offhook(sub, &resp, tone);
2525  break;
2526  }
2527  if (!ast_strlen_zero(tone2)) {
2528  add_header(&resp, "S", tone2);
2529  }
2530  ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2531  tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2532  /* fill in new fields */
2533  resp.cmd = MGCP_CMD_RQNT;
2534  resp.trid = oseq;
2535  return send_request(p, NULL, &resp, oseq);
2536 }
2537 
2539 {
2540  struct mgcp_request resp;
2541  struct mgcp_endpoint *p = sub->parent;
2542  int i;
2543  int fc = 1;
2544  char local[256];
2545  char tmp[80];
2546  unsigned int oseq;
2547 
2548  if (ast_strlen_zero(sub->cxident)) {
2549  /* We don't have a CXident yet, store the destination and
2550  wait a bit */
2551  return 0;
2552  }
2553  ast_debug(3, "Modified %s@%s-%d with new mode: %s on callid: %s\n",
2554  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2555 
2556  ast_copy_string(local, "", sizeof(local));
2557  for (i = 0; i < ast_format_cap_count(p->cap); i++) {
2559 
2560  if (p->ncs && !fc) {
2562  ast_format_cap_append(p->cap, format, 0); /* sb5120e bug */
2563  ao2_ref(format, -1);
2564  break;
2565  } else {
2566  fc = 0;
2567  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
2568  }
2569  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2570 
2571  ao2_ref(format, -1);
2572  }
2573 
2574  if (!sub->sdpsent) {
2575  if (sub->gate) {
2576  if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
2577  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2578  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2579  } else {
2580  /* we still don't have gateid wait */
2581  return 0;
2582  }
2583  }
2584  }
2585 
2586  oseq = reqprep(&resp, p, "MDCX");
2587  add_header(&resp, "C", sub->callid);
2588  if (!sub->sdpsent) {
2589  add_header(&resp, "L", local);
2590  }
2591  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2592  /* X header should not be sent. kept for compatibility */
2593  add_header(&resp, "X", sub->txident);
2594  add_header(&resp, "I", sub->cxident);
2595  switch (sub->parent->hookstate) {
2596  case MGCP_ONHOOK:
2597  add_header(&resp, "R", "L/hd(N)");
2598  break;
2599  case MGCP_OFFHOOK:
2600  add_header_offhook(sub, &resp, "");
2601  break;
2602  }
2603  if (!sub->sdpsent) {
2604  add_sdp(&resp, sub, NULL);
2605  sub->sdpsent = 1;
2606  }
2607  /* fill in new fields */
2608  resp.cmd = MGCP_CMD_MDCX;
2609  resp.trid = oseq;
2610  return send_request(p, sub, &resp, oseq);
2611 }
2612 
2613 
2614 static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
2615 {
2616  struct mgcp_endpoint *p = sub->parent;
2617  char tone_indicate_end = 0;
2618 
2619  /* We also should check the tone to indicate, because it have no sense
2620  to request notify D/[0-9#*] (dtmf keys) if we are sending congestion
2621  tone for example G/cg */
2622  if (p && (!strcasecmp(tone, (p->ncs ? "L/ro" : "G/cg")))) {
2623  tone_indicate_end = 1;
2624  }
2625 
2626  if (p && p->sub && p->sub->owner &&
2629  add_header(resp, "R", "L/hu(N),L/hf(N)");
2630 
2631  } else if (!tone_indicate_end){
2632  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)"));
2633  } else {
2634  ast_debug(1, "We don't want more digits if we will end the call\n");
2635  add_header(resp, "R", "L/hu(N),L/hf(N)");
2636  }
2637 }
2638 
2639 
2640 
2641 
2643 {
2644  struct mgcp_request resp;
2645  unsigned int oseq;
2646  oseq = reqprep(&resp, p, "AUEP");
2647  /* removed unknown param VS */
2648  /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/
2649  add_header(&resp, "F", "A");
2650  /* fill in new fields */
2651  resp.cmd = MGCP_CMD_AUEP;
2652  resp.trid = oseq;
2653  return send_request(p, NULL, &resp, oseq);
2654 }
2655 
2657 {
2658  struct mgcp_endpoint *p = sub->parent;
2659  struct mgcp_request resp;
2660  unsigned int oseq;
2661 
2662  ast_debug(3, "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n",
2663  sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2664  oseq = reqprep(&resp, p, "DLCX");
2665  /* check if call id is avail */
2666  if (sub->callid[0])
2667  add_header(&resp, "C", sub->callid);
2668  /* X header should not be sent. kept for compatibility */
2669  add_header(&resp, "X", sub->txident);
2670  /* check if cxident is avail */
2671  if (sub->cxident[0])
2672  add_header(&resp, "I", sub->cxident);
2673  /* fill in new fields */
2674  resp.cmd = MGCP_CMD_DLCX;
2675  resp.trid = oseq;
2676  return send_request(p, sub, &resp, oseq);
2677 }
2678 
2679 static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
2680 {
2681  struct mgcp_request resp;
2682  unsigned int oseq;
2683 
2684  ast_debug(3, "Delete connection %s %s@%s on callid: %s\n",
2685  cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
2686  oseq = reqprep(&resp, p, "DLCX");
2687  /* check if call id is avail */
2688  if (callid && *callid)
2689  add_header(&resp, "C", callid);
2690  /* check if cxident is avail */
2691  if (cxident && *cxident)
2692  add_header(&resp, "I", cxident);
2693  /* fill in new fields */
2694  resp.cmd = MGCP_CMD_DLCX;
2695  resp.trid = oseq;
2696  return send_request(p, p->sub, &resp, oseq);
2697 }
2698 
2699 /*! \brief dump_cmd_queues: (SC:) cleanup pending commands */
2700 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
2701 {
2702  struct mgcp_request *t, *q;
2703 
2704  if (p) {
2706  for (q = p->rqnt_queue; q; t = q->next, ast_free(q), q=t);
2707  p->rqnt_queue = NULL;
2709 
2711  for (q = p->cmd_queue; q; t = q->next, ast_free(q), q=t);
2712  p->cmd_queue = NULL;
2714 
2716  for (q = p->sub->cx_queue; q; t = q->next, ast_free(q), q=t);
2717  p->sub->cx_queue = NULL;
2719 
2721  for (q = p->sub->next->cx_queue; q; t = q->next, ast_free(q), q=t);
2722  p->sub->next->cx_queue = NULL;
2724  } else if (sub) {
2725  ast_mutex_lock(&sub->cx_queue_lock);
2726  for (q = sub->cx_queue; q; t = q->next, ast_free(q), q=t);
2727  sub->cx_queue = NULL;
2728  ast_mutex_unlock(&sub->cx_queue_lock);
2729  }
2730 }
2731 
2732 
2733 /*! \brief find_command: (SC:) remove command transaction from queue */
2734 static struct mgcp_request *find_command(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
2735  struct mgcp_request **queue, ast_mutex_t *l, int ident)
2736 {
2737  struct mgcp_request *prev, *req;
2738 
2739  ast_mutex_lock(l);
2740  for (prev = NULL, req = *queue; req; prev = req, req = req->next) {
2741  if (req->trid == ident) {
2742  /* remove from queue */
2743  if (!prev)
2744  *queue = req->next;
2745  else
2746  prev->next = req->next;
2747 
2748  /* send next pending command */
2749  if (*queue) {
2750  ast_debug(1, "Posting Queued Request:\n%s to %s:%d\n", (*queue)->data,
2751  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
2752 
2753  mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid);
2754  }
2755  break;
2756  }
2757  }
2758  ast_mutex_unlock(l);
2759  return req;
2760 }
2761 
2762 /* modified for new transport mechanism */
2763 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
2764  int result, unsigned int ident, struct mgcp_request *resp)
2765 {
2766  char *c;
2767  struct mgcp_request *req;
2768  struct mgcp_gateway *gw = p->parent;
2769 
2770  if (result < 200) {
2771  /* provisional response */
2772  return;
2773  }
2774 
2775  if (p->slowsequence)
2776  req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2777  else if (sub)
2778  req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident);
2779  else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident)))
2780  req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2781 
2782  if (!req) {
2783  ast_verb(3, "No command found on [%s] for transaction %u. Ignoring...\n",
2784  gw->name, ident);
2785  return;
2786  }
2787 
2788  if (p && (result >= 400) && (result <= 599)) {
2789  switch (result) {
2790  case 401:
2791  p->hookstate = MGCP_OFFHOOK;
2792  break;
2793  case 402:
2794  p->hookstate = MGCP_ONHOOK;
2795  break;
2796  case 406:
2797  ast_log(LOG_NOTICE, "Transaction %u timed out\n", ident);
2798  break;
2799  case 407:
2800  ast_log(LOG_NOTICE, "Transaction %u aborted\n", ident);
2801  break;
2802  }
2803  if (sub) {
2804  if (!sub->cxident[0] && (req->cmd == MGCP_CMD_CRCX)) {
2805  ast_log(LOG_NOTICE, "DLCX for all connections on %s due to error %d\n", gw->name, result);
2807  }
2808  if (sub->owner) {
2809  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2810  result, p->name, p->parent->name, sub ? sub->id:-1);
2812  }
2813  } else {
2814  if (p->sub->next->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);
2817  mgcp_queue_hangup(p->sub);
2818  }
2819 
2820  if (p->sub->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  dump_cmd_queues(p, NULL);
2827  }
2828  }
2829 
2830  if (resp) {
2831  /* responseAck: */
2832  if (result == 200 && (req->cmd == MGCP_CMD_CRCX || req->cmd == MGCP_CMD_MDCX)) {
2833  if (sub) {
2834  transmit_response(sub, "000", resp, "OK");
2835  if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_RINGING) {
2837  }
2838  }
2839  }
2840  if (req->cmd == MGCP_CMD_CRCX) {
2841  if ((c = get_header(resp, "I"))) {
2842  if (!ast_strlen_zero(c) && sub) {
2843  /* if we are hanging up do not process this conn. */
2844  if (sub->owner) {
2845  if (!ast_strlen_zero(sub->cxident)) {
2846  if (strcasecmp(c, sub->cxident)) {
2847  ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c);
2848  }
2849  }
2850  ast_copy_string(sub->cxident, c, sizeof(sub->cxident));
2851  if (sub->tmpdest.sin_addr.s_addr) {
2853  }
2854  } else {
2855  /* XXX delete this one
2856  callid and conn id may already be lost.
2857  so the following del conn may have a side effect of
2858  cleaning up the next subchannel */
2860  }
2861  }
2862  }
2863  }
2864 
2865  if (req->cmd == MGCP_CMD_AUEP) {
2866  /* check stale connection ids */
2867  if ((c = get_header(resp, "I"))) {
2868  char *v, *n;
2869  int len;
2870  while ((v = get_csv(c, &len, &n))) {
2871  if (len) {
2872  if (strncasecmp(v, p->sub->cxident, len) &&
2873  strncasecmp(v, p->sub->next->cxident, len)) {
2874  /* connection id not found. delete it */
2875  char cxident[80] = "";
2876 
2877  if (len > (sizeof(cxident) - 1))
2878  len = sizeof(cxident) - 1;
2879  ast_copy_string(cxident, v, len);
2880  ast_verb(3, "Non existing connection id %s on %s@%s \n",
2881  cxident, p->name, gw->name);
2883  }
2884  }
2885  c = n;
2886  }
2887  }
2888 
2889  /* Try to determine the hookstate returned from an audit endpoint command */
2890  if ((c = get_header(resp, "ES"))) {
2891  if (!ast_strlen_zero(c)) {
2892  if (strstr(c, "hu")) {
2893  if (p->hookstate != MGCP_ONHOOK) {
2894  /* XXX cleanup if we think we are offhook XXX */
2895  if ((p->sub->owner || p->sub->next->owner ) &&
2896  p->hookstate == MGCP_OFFHOOK)
2898  p->hookstate = MGCP_ONHOOK;
2899 
2900  /* update the requested events according to the new hookstate */
2901  transmit_notify_request(p->sub, "");
2902 
2903  ast_verb(3, "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name);
2904  }
2905  } else if (strstr(c, "hd")) {
2906  if (p->hookstate != MGCP_OFFHOOK) {
2907  p->hookstate = MGCP_OFFHOOK;
2908 
2909  /* update the requested events according to the new hookstate */
2910  transmit_notify_request(p->sub, "");
2911 
2912  ast_verb(3, "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name);
2913  }
2914  }
2915  }
2916  }
2917  }
2918 
2919  if (resp && resp->lines) {
2920  /* do not process sdp if we are hanging up. this may be a late response */
2921  if (sub && sub->owner) {
2922  if (!sub->rtp)
2923  start_rtp(sub);
2924  if (sub->rtp)
2925  process_sdp(sub, resp);
2926  }
2927  }
2928  }
2929 
2930  ast_free(req);
2931 }
2932 
2933 static void start_rtp(struct mgcp_subchannel *sub)
2934 {
2935  struct ast_sockaddr bindaddr_tmp;
2936 
2937  ast_mutex_lock(&sub->lock);
2938  /* check again to be on the safe side */
2939  if (sub->rtp) {
2941  sub->rtp = NULL;
2942  }
2943  /* Allocate the RTP now */
2944  ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
2945  sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
2946  if (sub->rtp && sub->owner)
2947  ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
2948  if (sub->rtp) {
2949  ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "MGCP RTP");
2951  }
2952  /* Make a call*ID */
2953  snprintf(sub->callid, sizeof(sub->callid), "%08lx%s", (unsigned long)ast_random(), sub->txident);
2954  /* Transmit the connection create */
2955  if(!sub->parent->pktcgatealloc) {
2957  } else {
2959  sub->gate = NULL;
2960  if(!mgcp_alloc_pktcgate(sub))
2962  }
2963  ast_mutex_unlock(&sub->lock);
2964 }
2965 
2966 static void *mgcp_ss(void *data)
2967 {
2968  struct ast_channel *chan = data;
2969  struct mgcp_subchannel *sub = ast_channel_tech_pvt(chan);
2970  struct mgcp_endpoint *p = sub->parent;
2971  /* char exten[AST_MAX_EXTENSION] = ""; */
2972  int len = 0;
2973  int timeout = firstdigittimeout;
2974  int res= 0;
2975  int getforward = 0;
2976  int loop_pause = 100;
2977  RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
2978  const char *pickupexten;
2979 
2980  len = strlen(p->dtmf_buf);
2981 
2982  ast_channel_lock(chan);
2983  pickup_cfg = ast_get_chan_features_pickup_config(chan);
2984  if (!pickup_cfg) {
2985  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
2986  pickupexten = "";
2987  } else {
2988  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
2989  }
2990  ast_channel_unlock(chan);
2991 
2992  while (len < AST_MAX_EXTENSION - 1) {
2993  ast_debug(1, "Dtmf buffer '%s' for '%s@%s'\n", p->dtmf_buf, p->name, p->parent->name);
2994  res = 1; /* Assume that we will get a digit */
2995  while (strlen(p->dtmf_buf) == len) {
2996  ast_safe_sleep(chan, loop_pause);
2997  timeout -= loop_pause;
2998  if (timeout <= 0){
2999  res = 0;
3000  break;
3001  }
3002  res = 1;
3003  }
3004 
3005  timeout = 0;
3006  len = strlen(p->dtmf_buf);
3007 
3009  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3010  ast_indicate(chan, -1);
3011  } else {
3012  /* XXX Redundant? We should already be playing dialtone */
3013  /*tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
3014  transmit_notify_request(sub, "L/dl");
3015  }
3016  if (ast_exists_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1, p->cid_num)) {
3017  if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1, p->cid_num)) {
3018  if (getforward) {
3019  /* Record this as the forwarding extension */
3020  ast_copy_string(p->call_forward, p->dtmf_buf, sizeof(p->call_forward));
3021  ast_verb(3, "Setting call forward to '%s' on channel %s\n",
3022  p->call_forward, ast_channel_name(chan));
3023  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3024  transmit_notify_request(sub, "L/sl");
3025  if (res)
3026  break;
3027  usleep(500000);
3028  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3029  ast_indicate(chan, -1);
3030  sleep(1);
3031  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3032  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
3033  transmit_notify_request(sub, "L/dl");
3034  len = 0;
3035  getforward = 0;
3036  } else {
3037  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3038  ast_indicate(chan, -1);
3039  ast_channel_lock(chan);
3040  ast_channel_exten_set(chan, p->dtmf_buf);
3042  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3043  ast_set_callerid(chan,
3044  p->hidecallerid ? "" : p->cid_num,
3045  p->hidecallerid ? "" : p->cid_name,
3046  ast_channel_caller(chan)->ani.number.valid ? NULL : p->cid_num);
3048  ast_channel_unlock(chan);
3049  if (p->dtmfmode & MGCP_DTMF_HYBRID) {
3050  p->dtmfmode |= MGCP_DTMF_INBAND;
3051  ast_indicate(chan, -1);
3052  }
3053  res = ast_pbx_run(chan);
3054  if (res) {
3055  ast_log(LOG_WARNING, "PBX exited non-zero\n");
3056  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3057  /*transmit_notify_request(p, "nbz", 1);*/
3058  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3059  }
3060  return NULL;
3061  }
3062  } else {
3063  /* It's a match, but they just typed a digit, and there is an ambiguous match,
3064  so just set the timeout to matchdigittimeout and wait some more */
3065  timeout = matchdigittimeout;
3066  }
3067  } else if (res == 0) {
3068  ast_debug(1, "not enough digits (and no ambiguous match)...\n");
3069  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3070  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3071  /*dahdi_wait_event(p->subs[index].zfd);*/
3072  ast_hangup(chan);
3073  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3074  return NULL;
3075  } else if (p->hascallwaiting && p->callwaiting && !strcmp(p->dtmf_buf, "*70")) {
3076  ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan));
3077  /* Disable call waiting if enabled */
3078  p->callwaiting = 0;
3079  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3080  transmit_notify_request(sub, "L/sl");
3081  len = 0;
3082  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3083  timeout = firstdigittimeout;
3084  } else if (!strcmp(p->dtmf_buf, pickupexten)) {
3085  /* Scan all channels and see if any there
3086  * ringing channels with that have call groups
3087  * that equal this channels pickup group
3088  */
3089  if (ast_pickup_call(chan)) {
3090  ast_log(LOG_WARNING, "No call pickup possible...\n");
3091  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3092  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3093  }
3094  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3095  ast_hangup(chan);
3096  return NULL;
3097  } else if (!p->hidecallerid && !strcmp(p->dtmf_buf, "*67")) {
3098  ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
3099  /* Disable Caller*ID if enabled */
3100  p->hidecallerid = 1;
3101  ast_set_callerid(chan, "", "", NULL);
3102  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3103  transmit_notify_request(sub, "L/sl");
3104  len = 0;
3105  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3106  timeout = firstdigittimeout;
3107  } else if (p->callreturn && !strcmp(p->dtmf_buf, "*69")) {
3108  res = 0;
3109  if (!ast_strlen_zero(p->lastcallerid)) {
3110  res = ast_say_digit_str(chan, p->lastcallerid, "", ast_channel_language(chan));
3111  }
3112  if (!res)
3113  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3114  transmit_notify_request(sub, "L/sl");
3115  break;
3116  } else if (!strcmp(p->dtmf_buf, "*78")) {
3117  /* Do not disturb */
3118  ast_verb(3, "Enabled DND on channel %s\n", ast_channel_name(chan));
3119  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3120  transmit_notify_request(sub, "L/sl");
3121  p->dnd = 1;
3122  getforward = 0;
3123  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3124  len = 0;
3125  } else if (!strcmp(p->dtmf_buf, "*79")) {
3126  /* Do not disturb */
3127  ast_verb(3, "Disabled DND on channel %s\n", ast_channel_name(chan));
3128  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3129  transmit_notify_request(sub, "L/sl");
3130  p->dnd = 0;
3131  getforward = 0;
3132  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3133  len = 0;
3134  } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*72")) {
3135  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3136  transmit_notify_request(sub, "L/sl");
3137  getforward = 1;
3138  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3139  len = 0;
3140  } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*73")) {
3141  ast_verb(3, "Cancelling call forwarding on channel %s\n", ast_channel_name(chan));
3142  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3143  transmit_notify_request(sub, "L/sl");
3144  memset(p->call_forward, 0, sizeof(p->call_forward));
3145  getforward = 0;
3146  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3147  len = 0;
3149  sub->next->owner) {
3150  RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
3151  /* This is a three way call, the main call being a real channel,
3152  and we're parking the first call. */
3153  ast_channel_lock(chan);
3154  bridge_channel = ast_channel_get_bridge_channel(chan);
3155  ast_channel_unlock(chan);
3156  if (bridge_channel && !ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), p->dtmf_buf, NULL, NULL)) {
3157  ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
3158  }
3159  break;
3160  } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(p->dtmf_buf, "*60")) {
3161  ast_verb(3, "Blacklisting number %s\n", p->lastcallerid);
3162  res = ast_db_put("blacklist", p->lastcallerid, "1");
3163  if (!res) {
3164  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3165  transmit_notify_request(sub, "L/sl");
3166  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3167  len = 0;
3168  }
3169  } else if (p->hidecallerid && !strcmp(p->dtmf_buf, "*82")) {
3170  ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
3171  /* Enable Caller*ID if enabled */
3172  p->hidecallerid = 0;
3173  ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
3174  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3175  transmit_notify_request(sub, "L/sl");
3176  len = 0;
3177  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3178  timeout = firstdigittimeout;
3179  } else if (!ast_canmatch_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1,
3180  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
3181  && ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
3182  ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf,
3183  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
3184  ast_channel_context(chan));
3185  break;
3186  }
3187  if (!timeout)
3188  timeout = gendigittimeout;
3190  /*tone_zone_play_tone(p->subs[index].zfd, -1);*/
3191  ast_indicate(chan, -1);
3192  }
3193 #if 0
3194  for (;;) {
3195  res = ast_waitfordigit(chan, to);
3196  if (!res) {
3197  ast_debug(1, "Timeout...\n");
3198  break;
3199  }
3200  if (res < 0) {
3201  ast_debug(1, "Got hangup...\n");
3202  ast_hangup(chan);
3203  break;
3204  }
3205  exten[pos++] = res;
3206  if (!ast_ignore_pattern(chan->context, exten))
3207  ast_indicate(chan, -1);
3208  if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
3209  if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid))
3210  to = 3000;
3211  else
3212  to = 8000;
3213  } else
3214  break;
3215  }
3216  if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
3217  ast_copy_string(chan->exten, exten, sizeof(chan->exten)1);
3218  if (!p->rtp) {
3219  start_rtp(p);
3220  }
3222  chan->rings = 1;
3223  if (ast_pbx_run(chan)) {
3224  ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
3225  } else {
3226  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3227  return NULL;
3228  }
3229  }
3230 #endif
3231  ast_hangup(chan);
3232  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3233  return NULL;
3234 }
3235 
3236 /*! \brief Complete an attended transfer
3237  *
3238  * \param p The endpoint performing the attended transfer
3239  * \param sub The sub-channel completing the attended transfer
3240  *
3241  * \note p->sub is the currently active sub-channel (the channel the phone is using)
3242  * \note p->sub->next is the sub-channel not in use, potentially on hold
3243  *
3244  * \retval 0 when channel should be hung up
3245  * \retval 1 when channel should not be hung up
3246  */
3247 static int attempt_transfer(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
3248 {
3249  enum ast_transfer_result res;
3250 
3251  /* Ensure that the other channel goes off hold and that it is indicating properly */
3252  ast_queue_unhold(sub->next->owner);
3253  if (ast_channel_state(sub->owner) == AST_STATE_RINGING) {
3254  ast_queue_control(sub->next->owner, AST_CONTROL_RINGING);
3255  }
3256 
3257  ast_mutex_unlock(&p->sub->next->lock);
3258  ast_mutex_unlock(&p->sub->lock);
3259  res = ast_bridge_transfer_attended(sub->owner, sub->next->owner);
3260 
3261  /* Subs are only freed when the endpoint itself is destroyed, so they will continue to exist
3262  * after ast_bridge_transfer_attended returns making this safe without reference counting
3263  */
3264  ast_mutex_lock(&p->sub->lock);
3265  ast_mutex_lock(&p->sub->next->lock);
3266 
3267  if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
3268  /* If transferring fails hang up the other channel if present and us */
3269  if (sub->next->owner) {
3271  mgcp_queue_hangup(sub->next);
3272  }
3273  sub->next->alreadygone = 1;
3274  return 0;
3275  }
3276 
3277  unalloc_sub(sub->next);
3278 
3279  /* If the active sub is NOT the one completing the transfer change it to be, and hang up the other sub */
3280  if (p->sub != sub) {
3281  p->sub = sub;
3282  return 1;
3283  }
3284 
3285  return 0;
3286 }
3287 
3288 static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
3289 {
3290  struct mgcp_endpoint *p = sub->parent;
3291  struct ast_channel *c;
3292  pthread_t t;
3293 
3294  /* Off hook / answer */
3295  if (sub->outgoing) {
3296  /* Answered */
3297  if (sub->owner) {
3298  ast_queue_unhold(sub->owner);
3299  sub->cxmode = MGCP_CX_SENDRECV;
3300  if (!sub->rtp) {
3301  start_rtp(sub);
3302  } else {
3304  }
3305  /*transmit_notify_request(sub, "aw");*/
3308  }
3309  } else {
3310  /* Start switch */
3311  /*sub->cxmode = MGCP_CX_SENDRECV;*/
3312  if (!sub->owner) {
3313  if (!sub->rtp) {
3314  start_rtp(sub);
3315  } else {
3317  }
3318  if (p->immediate) {
3319  /* The channel is immediately up. Start right away */
3320 #ifdef DLINK_BUGGY_FIRMWARE
3322 #else
3323  transmit_notify_request(sub, p->ncs ? "L/rt" : "G/rt");
3324 #endif
3326  if (!c) {
3327  ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
3328  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3329  ast_hangup(c);
3330  }
3331  } else {
3332  if (has_voicemail(p)) {
3333  transmit_notify_request(sub, "L/sl");
3334  } else {
3335  transmit_notify_request(sub, "L/dl");
3336  }
3338  if (c) {
3340  ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
3341  ast_hangup(c);
3342  }
3343  } else {
3344  ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
3345  }
3346  }
3347  } else {
3348  if (p->hookstate == MGCP_OFFHOOK) {
3349  ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name);
3350  } else {
3351  ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name);
3352  ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?\n");
3353  }
3354  ast_queue_unhold(sub->owner);
3355  sub->cxmode = MGCP_CX_SENDRECV;
3356  if (!sub->rtp) {
3357  start_rtp(sub);
3358  } else {
3360  }
3361  /*transmit_notify_request(sub, "aw");*/
3363  /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/
3364  }
3365  }
3366 }
3367 
3368 static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
3369 {
3370  char *ev, *s;
3371  struct ast_frame f = { 0, };
3372  struct mgcp_endpoint *p = sub->parent;
3373  struct mgcp_gateway *g = NULL;
3374  int res;
3375 
3376  ast_debug(1, "Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
3377  /* Clear out potential response */
3378  if (!strcasecmp(req->verb, "RSIP")) {
3379  /* Test if this RSIP request is just a keepalive */
3380  if (!strcasecmp( get_header(req, "RM"), "X-keepalive")) {
3381  ast_verb(3, "Received keepalive request from %s@%s\n", p->name, p->parent->name);
3382  transmit_response(sub, "200", req, "OK");
3383  } else {
3384  dump_queue(p->parent, p);
3385  dump_cmd_queues(p, NULL);
3386 
3387  if ((strcmp(p->name, p->parent->wcardep) != 0)) {
3388  ast_verb(3, "Resetting interface %s@%s\n", p->name, p->parent->name);
3389  }
3390  /* For RSIP on wildcard we reset all endpoints */
3391  if (!strcmp(p->name, p->parent->wcardep)) {
3392  /* Reset all endpoints */
3393  struct mgcp_endpoint *tmp_ep;
3394 
3395  g = p->parent;
3396  for (tmp_ep = g->endpoints; tmp_ep; tmp_ep = tmp_ep->next) {
3397  /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/
3398  if (strcmp(tmp_ep->name, g->wcardep) != 0) {
3399  struct mgcp_subchannel *tmp_sub, *first_sub;
3400  ast_verb(3, "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name);
3401 
3402  first_sub = tmp_ep->sub;
3403  tmp_sub = tmp_ep->sub;
3404  while (tmp_sub) {
3405  mgcp_queue_hangup(tmp_sub);
3406  tmp_sub = tmp_sub->next;
3407  if (tmp_sub == first_sub)
3408  break;
3409  }
3410  }
3411  }
3412  } else if (sub->owner) {
3414  }
3415  transmit_response(sub, "200", req, "OK");
3416  /* We don't send NTFY or AUEP to wildcard ep */
3417  if (strcmp(p->name, p->parent->wcardep) != 0) {
3419  /* Audit endpoint.
3420  Idea is to prevent lost lines due to race conditions
3421  */
3423  }
3424  }
3425  } else if (!strcasecmp(req->verb, "NTFY")) {
3426  /* Acknowledge and be sure we keep looking for the same things */
3427  transmit_response(sub, "200", req, "OK");
3428  /* Notified of an event */
3429  ev = get_header(req, "O");
3430  s = strchr(ev, '/');
3431  if (s) ev = s + 1;
3432  ast_debug(1, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev);
3433  /* Keep looking for events unless this was a hangup */
3434  if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) {
3436  }
3437  if (!strcasecmp(ev, "hd")) {
3438  p->hookstate = MGCP_OFFHOOK;
3439  sub->cxmode = MGCP_CX_SENDRECV;
3440 
3441  if (p) {
3442  /* When the endpoint have a Off hook transition we always
3443  starts without any previous dtmfs */
3444  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3445  }
3446 
3447  handle_hd_hf(sub, ev);
3448  } else if (!strcasecmp(ev, "hf")) {
3449  /* We can assume we are offhook if we received a hookflash */
3450  /* First let's just do call wait and ignore threeway */
3451  /* We're currently in charge */
3452  if (p->hookstate != MGCP_OFFHOOK) {
3453  /* Cisco c7940 sends hf even if the phone is onhook */
3454  /* Thanks to point on IRC for pointing this out */
3455  return -1;
3456  }
3457  /* do not let * conference two down channels */
3458  if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_DOWN && !sub->next->owner)
3459  return -1;
3460 
3461  if (p->callwaiting || p->transfer || p->threewaycalling) {
3462  ast_verb(3, "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
3463  p->sub = p->sub->next;
3464 
3465  /* transfer control to our next subchannel */
3466  if (!sub->next->owner) {
3467  /* plave the first call on hold and start up a new call */
3468  sub->cxmode = MGCP_CX_MUTE;
3469  ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
3471  if (sub->owner) {
3472  ast_queue_hold(sub->owner, NULL);
3473  }
3474  sub->next->cxmode = MGCP_CX_RECVONLY;
3475  handle_hd_hf(sub->next, ev);
3476  } else if (sub->owner && sub->next->owner) {
3477  /* We've got two active calls lets decide whether or not to conference or just flip flop */
3478  if ((!sub->outgoing) && (!sub->next->outgoing)) {
3479  /* We made both calls lets conference */
3480  ast_verb(3, "MGCP Conferencing %d and %d on %s@%s\n",
3481  sub->id, sub->next->id, p->name, p->parent->name);
3482  sub->cxmode = MGCP_CX_CONF;
3483  sub->next->cxmode = MGCP_CX_CONF;
3484  ast_queue_unhold(sub->next->owner);
3487  } else {
3488  /* Let's flipflop between calls */
3489  /* XXX Need to check for state up ??? */
3490  /* XXX Need a way to indicate the current call, or maybe the call that's waiting */
3491  ast_verb(3, "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n",
3492  sub->id, sub->next->id, p->name, p->parent->name);
3493  sub->cxmode = MGCP_CX_MUTE;
3494  ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
3496 
3497  ast_queue_hold(sub->owner, NULL);
3498  ast_queue_hold(sub->next->owner, NULL);
3499 
3500  handle_hd_hf(sub->next, ev);
3501  }
3502  } else {
3503  /* We've most likely lost one of our calls find an active call and bring it up */
3504  if (sub->owner) {
3505  p->sub = sub;
3506  } else if (sub->next->owner) {
3507  p->sub = sub->next;
3508  } else {
3509  /* We seem to have lost both our calls */
3510  /* XXX - What do we do now? */
3511  return -1;
3512  }
3513  ast_queue_unhold(p->sub->owner);
3514  p->sub->cxmode = MGCP_CX_SENDRECV;
3516  }
3517  } else {
3518  ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n",
3519  p->name, p->parent->name);
3520  }
3521  } else if (!strcasecmp(ev, "hu")) {
3522  p->hookstate = MGCP_ONHOOK;
3523  sub->cxmode = MGCP_CX_RECVONLY;
3524  ast_debug(1, "MGCP %s@%s Went on hook\n", p->name, p->parent->name);
3525  /* Do we need to send MDCX before a DLCX ?
3526  if (sub->rtp) {
3527  transmit_modify_request(sub);
3528  }
3529  */
3530  if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) {
3531  /* We're allowed to transfer, we have two active calls and */
3532  /* we made at least one of the calls. Let's try and transfer */
3533  ast_mutex_lock(&p->sub->next->lock);
3534  res = attempt_transfer(p, sub);
3535  if (res) {
3536  ast_log(LOG_WARNING, "Transfer attempt failed\n");
3537  ast_mutex_unlock(&p->sub->next->lock);
3538  return -1;
3539  }
3540  ast_mutex_unlock(&p->sub->next->lock);
3541  } else {
3542  /* Hangup the current call */
3543  /* If there is another active call, mgcp_hangup will ring the phone with the other call */
3544  if (sub->owner) {
3545  sub->alreadygone = 1;
3547  } else {
3548  ast_verb(3, "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n",
3549  p->name, p->parent->name, sub->id);
3550  /* Instruct the other side to remove the connection since it apparently *
3551  * still thinks the channel is active. *
3552  * For Cisco IAD2421 /BAK/ */
3554  }
3555  }
3556  if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) {
3557  p->hidecallerid = 0;
3558  if (p->hascallwaiting && !p->callwaiting) {
3559  ast_verb(3, "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id);
3560  p->callwaiting = -1;
3561  }
3562  if (has_voicemail(p)) {
3563  ast_verb(3, "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name);
3564  transmit_notify_request(sub, "L/vmwi(+)");
3565  } else {
3566  ast_verb(3, "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name);
3567  transmit_notify_request(sub, "L/vmwi(-)");
3568  }
3569  }
3570  } else if ((strlen(ev) == 1) &&
3571  (((ev[0] >= '0') && (ev[0] <= '9')) ||
3572  ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
3573  (ev[0] == '*') || (ev[0] == '#'))) {
3574  if (sub && sub->owner && (ast_channel_state(sub->owner) >= AST_STATE_UP)) {
3576  f.subclass.integer = ev[0];
3577  f.src = "mgcp";
3578  /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */
3579  mgcp_queue_frame(sub, &f);
3580  ast_mutex_lock(&sub->next->lock);
3581  if (sub->next->owner)
3582  mgcp_queue_frame(sub->next, &f);
3583  ast_mutex_unlock(&sub->next->lock);
3584  if (strstr(p->curtone, (p->ncs ? "wt1" : "wt")) && (ev[0] == 'A')) {
3585  memset(p->curtone, 0, sizeof(p->curtone));
3586  }
3587  } else {
3588  p->dtmf_buf[strlen(p->dtmf_buf)] = ev[0];
3589  p->dtmf_buf[strlen(p->dtmf_buf)] = '\0';
3590  }
3591  } else if (!strcasecmp(ev, "T")) {
3592  /* Digit timeout -- unimportant */
3593  } else if (!strcasecmp(ev, "ping")) {
3594  /* ping -- unimportant */
3595  } else {
3596  ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
3597  }
3598  } else {
3599  ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(sin->sin_addr));
3600  transmit_response(sub, "510", req, "Unknown verb");
3601  }
3602  return 0;
3603 }
3604 
3605 static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *req)
3606 {
3607  int seqno=0;
3608  time_t now;
3609  struct mgcp_response *prev = NULL, *cur, *next, *answer = NULL;
3610  time(&now);
3611  if (sscanf(req->identifier, "%30d", &seqno) != 1) {
3612  seqno = 0;
3613  }
3614  for (cur = sub->parent->parent->responses, next = cur ? cur->next : NULL; cur; cur = next, next = cur ? cur->next : NULL) {
3615  if (now - cur->whensent > RESPONSE_TIMEOUT) {
3616  /* Delete this entry */
3617  if (prev)
3618  prev->next = next;
3619  else
3620  sub->parent->parent->responses = next;
3621  ast_free(cur);
3622  } else {
3623  if (seqno == cur->seqno)
3624  answer = cur;
3625  prev = cur;
3626  }
3627  }
3628  if (answer) {
3630  return 1;
3631  }
3632  return 0;
3633 }
3634 
3635 static int mgcpsock_read(int *id, int fd, short events, void *ignore)
3636 {
3637  struct mgcp_request req;
3638  struct sockaddr_in sin;
3639  struct mgcp_subchannel *sub;
3640  int res;
3641  socklen_t len;
3642  int result;
3643  int ident;
3644  len = sizeof(sin);
3645  memset(&req, 0, sizeof(req));
3646  res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
3647  if (res < 0) {
3648  if (errno != ECONNREFUSED)
3649  ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
3650  return 1;
3651  }
3652  req.data[res] = '\0';
3653  req.len = res;
3654  ast_debug(1, "MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
3655  parse(&req);
3656  if (req.headers < 1) {
3657  /* Must have at least one header */
3658  return 1;
3659  }
3660  if (ast_strlen_zero(req.identifier)) {
3661  ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin.sin_addr));
3662  return 1;
3663  }
3664 
3665  if (sscanf(req.verb, "%30d", &result) && sscanf(req.identifier, "%30d", &ident)) {
3666  if (result < 200) {
3667  ast_debug(1, "Ignoring provisional response on transaction %d\n", ident);
3668  return 1;
3669  }
3670  /* Try to find who this message is for, if it's important */
3671  sub = find_subchannel_and_lock(NULL, ident, &sin);
3672  if (sub) {
3673  struct mgcp_gateway *gw = sub->parent->parent;
3674  struct mgcp_message *cur, *prev;
3675 
3676  ast_mutex_unlock(&sub->lock);
3677  ast_mutex_lock(&gw->msgs_lock);
3678  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
3679  if (cur->seqno == ident) {
3680  ast_debug(1, "Got response back on transaction %d\n", ident);
3681  if (prev)
3682  prev->next = cur->next;
3683  else
3684  gw->msgs = cur->next;
3685  break;
3686  }
3687  }
3688 
3689  /* stop retrans timer if the queue is empty */
3690  if (!gw->msgs) {
3692  }
3693 
3695  if (cur) {
3696  handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req);
3697  ast_free(cur);
3698  return 1;
3699  }
3700 
3701  ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n",
3702  gw->name, ident);
3703  }
3704  } else {
3705  if (ast_strlen_zero(req.endpoint) ||
3706  ast_strlen_zero(req.version) ||
3707  ast_strlen_zero(req.verb)) {
3708  ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
3709  return 1;
3710  }
3711  /* Process request, with iflock held */
3712  sub = find_subchannel_and_lock(req.endpoint, 0, &sin);
3713  if (sub) {
3714  /* look first to find a matching response in the queue */
3715  if (!find_and_retrans(sub, &req))
3716  /* pass the request off to the currently mastering subchannel */
3717  handle_request(sub, &req, &sin);
3718  ast_mutex_unlock(&sub->lock);
3719  }
3720  }
3721  return 1;
3722 }
3723 
3724 static int *mgcpsock_read_id = NULL;
3725 
3727 {
3728  struct mgcp_endpoint *enext, *e;
3729  struct mgcp_subchannel *s, *sub;
3730  int i, prune = 1;
3731 
3732  if (g->ha || !g->realtime || ast_mutex_trylock(&g->msgs_lock) || g->msgs) {
3734  return 0;
3735  }
3736 
3737  for (e = g->endpoints; e; e = e->next) {
3738  ast_mutex_lock(&e->lock);
3740  prune = 0;
3741  } else if (e->rqnt_queue || e->cmd_queue) {
3742  prune = 0;
3743  }
3744  s = e->sub;
3745  for (i = 0; (i < MAX_SUBS) && s; i++) {
3746  ast_mutex_lock(&s->lock);
3747  if (!ast_strlen_zero(s->cxident) || s->rtp || ast_mutex_trylock(&s->cx_queue_lock) || s->gate) {
3748  prune = 0;
3749  } else if (s->cx_queue) {
3750  prune = 0;
3751  }
3752  s = s->next;
3753  }
3754  }
3755 
3756  for (e = g->endpoints, sub = e->sub, enext = e->next; e; e = enext, enext = e->next) {
3757  for (i = 0; (i < MAX_SUBS) && sub; i++) {
3758  s = sub;
3759  sub = sub->next;
3760  ast_mutex_unlock(&s->lock);
3762  if (prune) {
3763  ast_mutex_destroy(&s->lock);
3765  ast_free(s);
3766  }
3767  }
3768  ast_mutex_unlock(&e->lock);
3771  if (prune) {
3772  ast_mutex_destroy(&e->lock);
3775  ast_free(e);
3776  }
3777  }
3778  if (prune) {
3779  ast_debug(1, "***** MGCP REALTIME PRUNE GW: %s\n", g->name);
3780  }
3781  return prune;
3782 }
3783 
3784 static void *do_monitor(void *data)
3785 {
3786  int res;
3787  int reloading;
3788  struct mgcp_gateway *g, *gprev;
3789  /*struct mgcp_gateway *g;*/
3790  /*struct mgcp_endpoint *e;*/
3791  /*time_t thispass = 0, lastpass = 0;*/
3792  time_t lastrun = 0;
3793 
3794  /* Add an I/O event to our UDP socket */
3795  if (mgcpsock > -1) {
3797  }
3798  /* This thread monitors all the frame relay interfaces which are not yet in use
3799  (and thus do not have a separate thread) indefinitely */
3800  /* From here on out, we die whenever asked */
3801  for (;;) {
3802  /* Check for a reload request */
3804  reloading = mgcp_reloading;
3805  mgcp_reloading = 0;
3807  if (reloading) {
3808  ast_verb(1, "Reloading MGCP\n");
3809  reload_config(1);
3810  /* Add an I/O event to our UDP socket */
3811  if (mgcpsock > -1 && !mgcpsock_read_id) {
3813  }
3814  }
3815 
3816  /* Check for interfaces needing to be killed */
3817  /* Don't let anybody kill us right away. Nobody should lock the interface list
3818  and wait for the monitor list, but the other way around is okay. */
3820  /* Lock the network interface */
3822 
3823 #if 0
3824  /* XXX THIS IS COMPLETELY HOSED */
3825  /* The gateway goes into a state of panic */
3826  /* If the vmwi indicator is sent while it is reseting interfaces */
3827  lastpass = thispass;
3828  thispass = time(NULL);
3829  g = gateways;
3830  while(g) {
3831  if (thispass != lastpass) {
3832  e = g->endpoints;
3833  while(e) {
3834  if (e->type == TYPE_LINE) {
3835  res = has_voicemail(e);
3836  if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){
3837  if (res) {
3838  transmit_notify_request(e, "L/vmwi(+)");
3839  } else {
3840  transmit_notify_request(e, "L/vmwi(-)");
3841  }
3842  e->msgstate = res;
3843  e->onhooktime = thispass;
3844  }
3845  }
3846  e = e->next;
3847  }
3848  }
3849  g = g->next;
3850  }
3851 #endif
3852  /* pruning unused realtime gateways, running in every 60 seconds*/
3853  if(time(NULL) > (lastrun + 60)) {
3855  g = gateways;
3856  gprev = NULL;
3857  while(g) {
3858  if(g->realtime) {
3860  if(gprev) {
3861  gprev->next = g->next;
3862  } else {
3863  gateways = g->next;
3864  }
3867  ast_free(g);
3868  } else {
3870  gprev = g;
3871  }
3872  } else {
3873  gprev = g;
3874  }
3875  g = g->next;
3876  }
3878  lastrun = time(NULL);
3879  }
3880  /* Okay, now that we know what to do, release the network lock */
3882  /* And from now on, we're okay to be killed, so release the monitor lock as well */
3884  pthread_testcancel();
3885  /* Wait for sched or io */
3886  res = ast_sched_wait(sched);
3887  /* copied from chan_sip.c */
3888  if ((res < 0) || (res > 1000)) {
3889  res = 1000;
3890  }
3891  res = ast_io_wait(io, res);
3893  if (res >= 0) {
3895  }
3897  }
3898  /* Never reached */
3899  return NULL;
3900 }
3901 
3902 static int restart_monitor(void)
3903 {
3904  /* If we're supposed to be stopped -- stay stopped */
3906  return 0;
3907  if (ast_mutex_lock(&monlock)) {
3908  ast_log(LOG_WARNING, "Unable to lock monitor\n");
3909  return -1;
3910  }
3911  if (monitor_thread == pthread_self()) {
3913  ast_log(LOG_WARNING, "Cannot kill myself\n");
3914  return -1;
3915  }
3917  /* Wake up the thread */
3918  pthread_kill(monitor_thread, SIGURG);
3919  } else {
3920  /* Start a new monitor */
3923  ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
3924  return -1;
3925  }
3926  }
3928  return 0;
3929 }
3930 
3931 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)
3932 {
3933  struct mgcp_subchannel *sub;
3934  struct ast_channel *tmpc = NULL;
3935  char tmp[256];
3936 
3938  struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3939  ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n",
3940  ast_format_cap_get_names(cap, &cap_buf));
3941  /*return NULL;*/
3942  }
3943  ast_copy_string(tmp, dest, sizeof(tmp));
3944  if (ast_strlen_zero(tmp)) {
3945  ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n");
3946  return NULL;
3947  }
3948  if (!(sub = find_subchannel_and_lock(tmp, 0, NULL))) {
3949  ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
3950  *cause = AST_CAUSE_UNREGISTERED;
3951  return NULL;
3952  }
3953 
3954  ast_verb(3, "MGCP mgcp_request(%s)\n", tmp);
3955  ast_verb(3, "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n",
3956  sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0);
3957  /* Must be busy */
3958  if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) ||
3959  ((!sub->parent->callwaiting) && (sub->owner)) ||
3960  (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) {
3961  if (sub->parent->hookstate == MGCP_ONHOOK) {
3962  if (has_voicemail(sub->parent)) {
3963  transmit_notify_request(sub,"L/vmwi(+)");
3964  } else {
3965  transmit_notify_request(sub,"L/vmwi(-)");
3966  }
3967  }
3968  *cause = AST_CAUSE_BUSY;
3969  ast_mutex_unlock(&sub->lock);
3970  return NULL;
3971  }
3972  tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, assignedids, requestor);
3973  ast_mutex_unlock(&sub->lock);
3974  if (!tmpc)
3975  ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
3976  restart_monitor();
3977  return tmpc;
3978 }
3979 
3980 /* modified for reload support */
3981 /*! \brief build_gateway: parse mgcp.conf and create gateway/endpoint structures */
3982 static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
3983 {
3984  struct mgcp_gateway *gw;
3985  struct mgcp_endpoint *e;
3986  struct mgcp_subchannel *sub;
3987  struct ast_variable *chanvars = NULL;
3988 
3989  /*char txident[80];*/
3990  int i=0, y=0;
3991  int gw_reload = 0;
3992  int ep_reload = 0;
3994 
3995  /* locate existing gateway */
3996  for (gw = gateways; gw; gw = gw->next) {
3997  if (!strcasecmp(cat, gw->name)) {
3998  /* gateway already exists */
3999  gw->delme = 0;
4000  gw_reload = 1;
4001  break;
4002  }
4003  }
4004 
4005  if (!gw && !(gw = ast_calloc(1, sizeof(*gw)))) {
4006  return NULL;
4007  }
4008 
4009  if (!gw_reload) {
4010  gw->expire = -1;
4011  gw->realtime = 0;
4012  gw->retransid = -1;
4013  ast_mutex_init(&gw->msgs_lock);
4014  ast_copy_string(gw->name, cat, sizeof(gw->name));
4015  /* check if the name is numeric ip */
4016  if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE)
4017  gw->isnamedottedip = 1;
4018  }
4019  for (; v; v = v->next) {
4020  if (!strcasecmp(v->name, "host")) {
4021  if (!strcasecmp(v->value, "dynamic")) {
4022  /* They'll register with us */
4023  gw->dynamic = 1;
4024  memset(&gw->addr.sin_addr, 0, 4);
4025  if (gw->addr.sin_port) {
4026  /* If we've already got a port, make it the default rather than absolute */
4027  gw->defaddr.sin_port = gw->addr.sin_port;
4028  gw->addr.sin_port = 0;
4029  }
4030  } else {
4031  /* Non-dynamic. Make sure we become that way if we're not */
4032  AST_SCHED_DEL(sched, gw->expire);
4033  gw->dynamic = 0;
4034  {
4035  struct ast_sockaddr tmp;
4036 
4037  ast_sockaddr_from_sin(&tmp, &gw->addr);
4038  if (ast_get_ip(&tmp, v->value)) {
4039  if (!gw_reload) {
4041  ast_free(gw);
4042  }
4043  return NULL;
4044  }
4045  ast_sockaddr_to_sin(&tmp, &gw->addr);
4046  }
4047  }
4048  } else if (!strcasecmp(v->name, "defaultip")) {
4049  struct ast_sockaddr tmp;
4050 
4052  if (ast_get_ip(&tmp, v->value)) {
4053  if (!gw_reload) {
4055  ast_free(gw);
4056  }
4057  return NULL;
4058  }
4060  } else if (!strcasecmp(v->name, "permit") ||
4061  !strcasecmp(v->name, "deny")) {
4062  int acl_error = 0;
4063  gw->ha = ast_append_ha(v->name, v->value, gw->ha, &acl_error);
4064  if (acl_error) {
4065  ast_log(LOG_ERROR, "Invalid ACL '%s' specified for MGCP gateway '%s' on line %d. Not creating.\n",
4066  v->value, cat, v->lineno);
4067  if (!gw_reload) {
4069  ast_free(gw);
4070  } else {
4071  gw->delme = 1;
4072  }
4073  return NULL;
4074  }
4075  } else if (!strcasecmp(v->name, "port")) {
4076  gw->addr.sin_port = htons(atoi(v->value));
4077  } else if (!strcasecmp(v->name, "context")) {
4078  ast_copy_string(context, v->value, sizeof(context));
4079  } else if (!strcasecmp(v->name, "dtmfmode")) {
4080  if (!strcasecmp(v->value, "inband"))
4082  else if (!strcasecmp(v->value, "rfc2833"))
4084  else if (!strcasecmp(v->value, "hybrid"))
4086  else if (!strcasecmp(v->value, "none"))
4087  dtmfmode = 0;
4088  else
4089  ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno);
4090  } else if (!strcasecmp(v->name, "nat")) {
4091  nat = ast_true(v->value);
4092  } else if (!strcasecmp(v->name, "ncs")) {
4093  ncs = ast_true(v->value);
4094  } else if (!strcasecmp(v->name, "hangupongateremove")) {
4096  } else if (!strcasecmp(v->name, "pktcgatealloc")) {
4098  } else if (!strcasecmp(v->name, "callerid")) {
4099  if (!strcasecmp(v->value, "asreceived")) {
4100  cid_num[0] = '\0';
4101  cid_name[0] = '\0';
4102  } else {
4103  ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
4104  }
4105  } else if (!strcasecmp(v->name, "language")) {
4106  ast_copy_string(language, v->value, sizeof(language));
4107  } else if (!strcasecmp(v->name, "accountcode")) {
4109  } else if (!strcasecmp(v->name, "amaflags")) {
4111  if (y < 0) {
4112  ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
4113  } else {
4114  amaflags = y;
4115  }
4116  } else if (!strcasecmp(v->name, "setvar")) {
4117  chanvars = add_var(v->value</