Wed Jan 8 2020 09:50:03

Asterisk developer's documentation


chan_mgcp.c File Reference

Implementation of Media Gateway Control Protocol. More...

#include "asterisk.h"
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/signal.h>
#include <signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <ctype.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/cdr.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/netsock.h"
#include "asterisk/causes.h"
#include "asterisk/dsp.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/event.h"
#include "asterisk/chanvars.h"
#include "asterisk/pktccops.h"

Go to the source code of this file.

Data Structures

struct  mgcp_endpoint
 
struct  mgcp_gateway
 
struct  mgcp_message
 mgcp_message: MGCP message for queuing up More...
 
struct  mgcp_request
 
struct  mgcp_response
 
struct  mgcp_subchannel
 

Macros

#define DEFAULT_EXPIRY   120
 
#define DEFAULT_MGCP_CA_PORT   2727
 
#define DEFAULT_MGCP_GW_PORT   2427
 
#define DEFAULT_RETRANS   1000
 
#define DIRECTMEDIA   1
 
#define INADDR_NONE   (in_addr_t)(-1)
 
#define MAX_EXPIRY   3600
 
#define MAX_RETRANS   5
 
#define MAX_SUBS   2
 
#define MGCP_CX_CONF   3
 
#define MGCP_CX_CONFERENCE   3
 
#define MGCP_CX_INACTIVE   4
 
#define MGCP_CX_MUTE   4
 
#define MGCP_CX_RECVONLY   1
 
#define MGCP_CX_SENDONLY   0
 
#define MGCP_CX_SENDRECV   2
 
#define MGCP_DTMF_HYBRID   (1 << 2)
 
#define MGCP_DTMF_INBAND   (1 << 1)
 
#define MGCP_DTMF_RFC2833   (1 << 0)
 
#define MGCP_MAX_HEADERS   64
 
#define MGCP_MAX_LINES   64
 
#define MGCP_MAX_PACKET   1500
 
#define MGCP_OFFHOOK   2
 
#define MGCP_ONHOOK   1
 
#define MGCP_SUBCHANNEL_MAGIC   "!978!"
 
#define MGCPDUMPER
 
#define RESPONSE_TIMEOUT   30
 
#define SUB_ALT   1
 
#define SUB_REAL   0
 
#define TYPE_LINE   2
 
#define TYPE_TRUNK   1
 

Enumerations

enum  {
  MGCP_CMD_EPCF, MGCP_CMD_CRCX, MGCP_CMD_MDCX, MGCP_CMD_DLCX,
  MGCP_CMD_RQNT, MGCP_CMD_NTFY, MGCP_CMD_AUEP, MGCP_CMD_AUCX,
  MGCP_CMD_RSIP
}
 

Functions

static char * __get_header (struct mgcp_request *req, char *name, int *start, char *def)
 
static int __mgcp_xmit (struct mgcp_gateway *gw, char *data, int len)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static int acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
 
static int add_header (struct mgcp_request *req, const char *var, const char *value)
 
static void add_header_offhook (struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
 
static int add_line (struct mgcp_request *req, char *line)
 
static int add_sdp (struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
 
static struct ast_variableadd_var (const char *buf, struct ast_variable *list)
 
static int attempt_transfer (struct mgcp_endpoint *p)
 
static struct mgcp_gatewaybuild_gateway (char *cat, struct ast_variable *v)
 build_gateway: parse mgcp.conf and create gateway/endpoint structures More...
 
static char * control2str (int ind)
 
static struct ast_variablecopy_vars (struct ast_variable *src)
 duplicate a list of channel variables, More...
 
static void destroy_endpoint (struct mgcp_endpoint *e)
 
static void destroy_gateway (struct mgcp_gateway *g)
 
static void * do_monitor (void *data)
 
static void dump_cmd_queues (struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
 dump_cmd_queues: (SC:) cleanup pending commands More...
 
static void dump_queue (struct mgcp_gateway *gw, struct mgcp_endpoint *p)
 
static int find_and_retrans (struct mgcp_subchannel *sub, struct mgcp_request *req)
 
static struct mgcp_requestfind_command (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request **queue, ast_mutex_t *l, int ident)
 find_command: (SC:) remove command transaction from queue More...
 
static struct mgcp_gatewayfind_realtime_gw (char *name, char *at, struct sockaddr_in *sin)
 
static struct mgcp_subchannelfind_subchannel_and_lock (char *name, int msgid, struct sockaddr_in *sin)
 
static char * get_csv (char *c, int *len, char **next)
 get_csv: (SC:) get comma separated value More...
 
static char * get_header (struct mgcp_request *req, char *name)
 
static char * get_sdp (struct mgcp_request *req, char *name)
 
static char * get_sdp_by_line (char *line, char *name, int nameLen)
 
static char * get_sdp_iterate (int *iterator, struct mgcp_request *req, char *name)
 
static void handle_hd_hf (struct mgcp_subchannel *sub, char *ev)
 
static char * handle_mgcp_audit_endpoint (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_mgcp_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_mgcp_show_endpoints (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int handle_request (struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
 
static void handle_response (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp)
 
static int has_voicemail (struct mgcp_endpoint *p)
 
static int init_req (struct mgcp_endpoint *p, struct mgcp_request *req, char *verb, unsigned int oseq)
 
static int init_resp (struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
 
static int load_module (void)
 load_module: PBX load module - initialization — More...
 
static int mgcp_alloc_pktcgate (struct mgcp_subchannel *sub)
 
static int mgcp_answer (struct ast_channel *ast)
 
static int mgcp_call (struct ast_channel *ast, char *dest, int timeout)
 
static int mgcp_devicestate (void *data)
 mgcp_devicestate: channel callback for device status monitoring More...
 
static int mgcp_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
static format_t mgcp_get_codec (struct ast_channel *chan)
 
static enum ast_rtp_glue_result mgcp_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 
static int mgcp_hangup (struct ast_channel *ast)
 
static int mgcp_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen)
 
static struct ast_channelmgcp_new (struct mgcp_subchannel *sub, int state, const char *linkedid)
 
static int mgcp_pktcgate_open (struct cops_gate *gate)
 
static int mgcp_pktcgate_remove (struct cops_gate *gate)
 
static int mgcp_postrequest (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno)
 
static int mgcp_prune_realtime_gateway (struct mgcp_gateway *g)
 
static void mgcp_queue_control (struct mgcp_subchannel *sub, int control)
 
static void mgcp_queue_frame (struct mgcp_subchannel *sub, struct ast_frame *f)
 
static void mgcp_queue_hangup (struct mgcp_subchannel *sub)
 
static struct ast_framemgcp_read (struct ast_channel *ast)
 
static char * mgcp_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static struct ast_channelmgcp_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
 
static struct ast_framemgcp_rtp_read (struct mgcp_subchannel *sub)
 
static int mgcp_senddigit_begin (struct ast_channel *ast, char digit)
 
static int mgcp_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 
static int mgcp_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
 
static void * mgcp_ss (void *data)
 
static int mgcp_write (struct ast_channel *ast, struct ast_frame *frame)
 
static int mgcpsock_read (int *id, int fd, short events, void *ignore)
 
static void mwi_event_cb (const struct ast_event *event, void *userdata)
 
static void parse (struct mgcp_request *req)
 
static int process_sdp (struct mgcp_subchannel *sub, struct mgcp_request *req)
 
static void prune_gateways (void)
 
static int reload (void)
 
static int reload_config (int reload)
 
static int reqprep (struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
 
static int resend_response (struct mgcp_subchannel *sub, struct mgcp_response *resp)
 
static int respprep (struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
 
static int restart_monitor (void)
 
static int retrans_pkt (const void *data)
 
static void sdpLineNum_iterator_init (int *iterator)
 
static int send_request (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
 
static int send_response (struct mgcp_subchannel *sub, struct mgcp_request *req)
 
static void start_rtp (struct mgcp_subchannel *sub)
 
static int transmit_audit_endpoint (struct mgcp_endpoint *p)
 
static int transmit_connect (struct mgcp_subchannel *sub)
 
static int transmit_connect_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
 
static int transmit_connection_del (struct mgcp_subchannel *sub)
 
static int transmit_connection_del_w_params (struct mgcp_endpoint *p, char *callid, char *cxident)
 
static int transmit_modify_request (struct mgcp_subchannel *sub)
 
static int transmit_modify_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
 
static int transmit_notify_request (struct mgcp_subchannel *sub, char *tone)
 
static int transmit_notify_request_with_callerid (struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
 
static int transmit_response (struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
 
static int unalloc_sub (struct mgcp_subchannel *sub)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Media Gateway Control Protocol (MGCP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_pktccops", }
 
static struct in_addr __ourip
 
static char accountcode [AST_MAX_ACCOUNT_CODE] = ""
 
static int adsi = 0
 
static int amaflags = 0
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct sockaddr_in bindaddr
 
static int callreturn = 0
 
static int callwaiting = 0
 
static int cancallforward = 0
 
static format_t capability = AST_FORMAT_ULAW
 
static char cid_name [AST_MAX_EXTENSION] = ""
 
static char cid_num [AST_MAX_EXTENSION] = ""
 
static struct ast_cli_entry cli_mgcp []
 
static const char config [] = "mgcp.conf"
 
static char context [AST_MAX_EXTENSION] = "default"
 
static ast_group_t cur_callergroup = 0
 
static ast_group_t cur_pickupgroup = 0
 
static struct ast_jb_conf default_jbconf
 
static int directmedia = DIRECTMEDIA
 
static int dtmfmode = 0
 
static int firstdigittimeout = 16000
 
static ast_mutex_t gatelock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 gatelock: mutex for gateway/endpoint lists More...
 
static struct mgcp_gatewaygateways = NULL
 
static int gendigittimeout = 8000
 
static struct ast_jb_conf global_jbconf
 
static int hangupongateremove = 0
 
static int immediate = 0
 
static struct io_contextio
 
static char language [MAX_LANGUAGE] = ""
 
static char mailbox [AST_MAX_EXTENSION]
 
static int matchdigittimeout = 3000
 
static const char *const mgcp_cxmodes []
 
static ast_mutex_t mgcp_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static int mgcp_reloading = 0
 
static struct ast_rtp_glue mgcp_rtp_glue
 
static struct ast_channel_tech mgcp_tech
 
static int mgcpdebug = 0
 
static int mgcpsock = -1
 
static int * mgcpsock_read_id = NULL
 
static pthread_t monitor_thread = AST_PTHREADT_NULL
 
static ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static char musicclass [MAX_MUSICCLASS] = ""
 
static int nat = 0
 
static int ncs = 0
 
static ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static int nonCodecCapability = AST_RTP_DTMF
 
static unsigned int oseq_global = 0
 
static ast_mutex_t oseq_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static char ourhost [MAXHOSTNAMELEN]
 
static int ourport
 
static char parkinglot [AST_MAX_CONTEXT]
 
static int pktcgatealloc = 0
 
struct {
   unsigned int   cos
 
   unsigned int   cos_audio
 
   unsigned int   tos
 
   unsigned int   tos_audio
 
qos = { 0, 0, 0, 0 }
 
static struct sched_contextsched
 
static int singlepath = 0
 
static int slowsequence = 0
 
static const char tdesc [] = "Media Gateway Control Protocol (MGCP)"
 
static int threewaycalling = 0
 
static int transfer = 0
 

Detailed Description

Implementation of Media Gateway Control Protocol.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
See also

Definition in file chan_mgcp.c.

Macro Definition Documentation

#define DEFAULT_EXPIRY   120

Definition at line 89 of file chan_mgcp.c.

#define DEFAULT_MGCP_CA_PORT   2727

From RFC 2705

Definition at line 117 of file chan_mgcp.c.

Referenced by reload_config().

#define DEFAULT_MGCP_GW_PORT   2427

From RFC 2705

Definition at line 116 of file chan_mgcp.c.

Referenced by build_gateway().

#define DEFAULT_RETRANS   1000

How frequently to retransmit

Definition at line 119 of file chan_mgcp.c.

Referenced by __sip_reliable_xmit(), mgcp_postrequest(), and retrans_pkt().

#define DIRECTMEDIA   1

Definition at line 91 of file chan_mgcp.c.

Referenced by build_gateway().

#define INADDR_NONE   (in_addr_t)(-1)

Definition at line 94 of file chan_mgcp.c.

Referenced by build_gateway().

#define MAX_EXPIRY   3600

Definition at line 90 of file chan_mgcp.c.

#define MAX_RETRANS   5

Try only 5 times for retransmissions

Definition at line 120 of file chan_mgcp.c.

Referenced by retrans_pkt().

#define MAX_SUBS   2

Definition at line 284 of file chan_mgcp.c.

Referenced by build_gateway(), destroy_endpoint(), and mgcp_prune_realtime_gateway().

#define MGCP_CX_CONF   3

Definition at line 126 of file chan_mgcp.c.

Referenced by handle_request().

#define MGCP_CX_CONFERENCE   3

Definition at line 127 of file chan_mgcp.c.

#define MGCP_CX_INACTIVE   4

Definition at line 129 of file chan_mgcp.c.

Referenced by build_gateway(), mgcp_hangup(), and unalloc_sub().

#define MGCP_CX_MUTE   4

Definition at line 128 of file chan_mgcp.c.

Referenced by handle_request().

#define MGCP_CX_RECVONLY   1

Definition at line 124 of file chan_mgcp.c.

Referenced by handle_request(), mgcp_call(), and mgcp_hangup().

#define MGCP_CX_SENDONLY   0

MGCP rtp stream modes {

Definition at line 123 of file chan_mgcp.c.

#define MGCP_CX_SENDRECV   2

Definition at line 125 of file chan_mgcp.c.

Referenced by handle_hd_hf(), handle_request(), mgcp_answer(), and mgcp_call().

#define MGCP_DTMF_HYBRID   (1 << 2)
#define MGCP_DTMF_INBAND   (1 << 1)
#define MGCP_DTMF_RFC2833   (1 << 0)
#define MGCP_MAX_HEADERS   64

The private structures of the mgcp channels are linked for selecting outgoing channels

Definition at line 243 of file chan_mgcp.c.

Referenced by add_header(), init_req(), init_resp(), and parse().

#define MGCP_MAX_LINES   64

Definition at line 244 of file chan_mgcp.c.

Referenced by add_line(), and parse().

#define MGCP_MAX_PACKET   1500

Also from RFC 2543, should sub headers tho

Definition at line 118 of file chan_mgcp.c.

#define MGCP_SUBCHANNEL_MAGIC   "!978!"

subchannel magic string. Needed to prove that any subchannel pointer passed by asterisk really points to a valid subchannel memory area. Ugly.. But serves the purpose for the time being.

Definition at line 295 of file chan_mgcp.c.

Referenced by build_gateway(), and mgcp_hangup().

#define MGCPDUMPER

Definition at line 88 of file chan_mgcp.c.

#define RESPONSE_TIMEOUT   30

in seconds

Definition at line 274 of file chan_mgcp.c.

Referenced by find_and_retrans().

#define SUB_ALT   1

Definition at line 287 of file chan_mgcp.c.

#define SUB_REAL   0

Definition at line 286 of file chan_mgcp.c.

#define TYPE_LINE   2

Definition at line 323 of file chan_mgcp.c.

Referenced by build_gateway(), do_monitor(), and mgcp_call().

#define TYPE_TRUNK   1

Definition at line 322 of file chan_mgcp.c.

Referenced by build_gateway().

Enumeration Type Documentation

anonymous enum
Enumerator
MGCP_CMD_EPCF 
MGCP_CMD_CRCX 
MGCP_CMD_MDCX 
MGCP_CMD_DLCX 
MGCP_CMD_RQNT 
MGCP_CMD_NTFY 
MGCP_CMD_AUEP 
MGCP_CMD_AUCX 
MGCP_CMD_RSIP 

Definition at line 140 of file chan_mgcp.c.

Function Documentation

static char* __get_header ( struct mgcp_request req,
char *  name,
int *  start,
char *  def 
)
static

Definition at line 1616 of file chan_mgcp.c.

References mgcp_request::header, mgcp_request::headers, and len().

Referenced by get_header().

1617 {
1618  int x;
1619  int len = strlen(name);
1620  char *r;
1621  for (x = *start; x < req->headers; x++) {
1622  if (!strncasecmp(req->header[x], name, len) &&
1623  (req->header[x][len] == ':')) {
1624  r = req->header[x] + len + 1;
1625  while (*r && (*r < 33)) {
1626  r++;
1627  }
1628  *start = x + 1;
1629  return r;
1630  }
1631  }
1632  /* Don't return NULL, so get_header is always a valid pointer */
1633  return def;
1634 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static const char name[]
char * header[MGCP_MAX_HEADERS]
Definition: chan_mgcp.c:253
static int __mgcp_xmit ( struct mgcp_gateway gw,
char *  data,
int  len 
)
static

Definition at line 545 of file chan_mgcp.c.

References mgcp_gateway::addr, ast_log(), mgcp_gateway::defaddr, errno, and LOG_WARNING.

Referenced by mgcp_postrequest(), resend_response(), retrans_pkt(), and send_response().

546 {
547  int res;
548  if (gw->addr.sin_addr.s_addr)
549  res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in));
550  else
551  res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in));
552  if (res != len) {
553  ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
554  }
555  return res;
556 }
static int mgcpsock
Definition: chan_mgcp.c:425
#define LOG_WARNING
Definition: logger.h:144
struct sockaddr_in defaddr
Definition: chan_mgcp.c:397
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct sockaddr_in addr
Definition: chan_mgcp.c:396
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static void __reg_module ( void  )
static

Definition at line 4936 of file chan_mgcp.c.

static void __unreg_module ( void  )
static

Definition at line 4936 of file chan_mgcp.c.

static int acf_channel_read ( struct ast_channel chan,
const char *  funcname,
char *  preparse,
char *  buf,
size_t  buflen 
)
static

Definition at line 4457 of file chan_mgcp.c.

References ast_log(), LOG_ERROR, mgcp_endpoint::ncs, mgcp_subchannel::parent, ast_channel::tech, and ast_channel::tech_pvt.

4458 {
4459  struct mgcp_subchannel *sub = chan->tech_pvt;
4460  int res = 0;
4461 
4462  /* Sanity check */
4463  if (!chan || chan->tech != &mgcp_tech) {
4464  ast_log(LOG_ERROR, "This function requires a valid MGCP channel\n");
4465  return -1;
4466  }
4467 
4468  if (!strcasecmp(args, "ncs")) {
4469  snprintf(buf, buflen, "%s", sub->parent->ncs ? "yes":"no");
4470  } else {
4471  res = -1;
4472  }
4473  return res;
4474 }
void * tech_pvt
Definition: channel.h:744
static struct ast_channel_tech mgcp_tech
Definition: chan_mgcp.c:464
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
struct ast_channel_tech * tech
Definition: channel.h:743
static int add_header ( struct mgcp_request req,
const char *  var,
const char *  value 
)
static

Definition at line 2045 of file chan_mgcp.c.

References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_request::len, mgcp_request::lines, LOG_WARNING, and MGCP_MAX_HEADERS.

Referenced by add_header_offhook(), transmit_audit_endpoint(), transmit_connect(), transmit_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_request(), transmit_modify_with_sdp(), transmit_notify_request(), and transmit_notify_request_with_callerid().

2046 {
2047  if (req->len >= sizeof(req->data) - 4) {
2048  ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
2049  return -1;
2050  }
2051  if (req->lines) {
2052  ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
2053  return -1;
2054  }
2055  req->header[req->headers] = req->data + req->len;
2056  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
2057  req->len += strlen(req->header[req->headers]);
2058  if (req->headers < MGCP_MAX_HEADERS) {
2059  req->headers++;
2060  } else {
2061  ast_log(LOG_WARNING, "Out of header space\n");
2062  return -1;
2063  }
2064  return 0;
2065 }
#define LOG_WARNING
Definition: logger.h:144
#define var
Definition: ast_expr2f.c:606
int value
Definition: syslog.c:39
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define MGCP_MAX_HEADERS
Definition: chan_mgcp.c:243
char * header[MGCP_MAX_HEADERS]
Definition: chan_mgcp.c:253
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
static void add_header_offhook ( struct mgcp_subchannel sub,
struct mgcp_request resp,
char *  tone 
)
static

Definition at line 2609 of file chan_mgcp.c.

References ast_channel::_state, add_header(), ast_debug, AST_STATE_RINGING, mgcp_endpoint::dtmfmode, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, mgcp_endpoint::ncs, mgcp_subchannel::owner, mgcp_subchannel::parent, and mgcp_endpoint::sub.

Referenced by transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid().

2610 {
2611  struct mgcp_endpoint *p = sub->parent;
2612  char tone_indicate_end = 0;
2613 
2614  /* We also should check the tone to indicate, because it have no sense
2615  to request notify D/[0-9#*] (dtmf keys) if we are sending congestion
2616  tone for example G/cg */
2617  if (p && (!strcasecmp(tone, (p->ncs ? "L/ro" : "G/cg")))) {
2618  tone_indicate_end = 1;
2619  }
2620 
2621  if (p && p->sub && p->sub->owner &&
2622  p->sub->owner->_state >= AST_STATE_RINGING &&
2624  add_header(resp, "R", "L/hu(N),L/hf(N)");
2625 
2626  } else if (!tone_indicate_end){
2627  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)"));
2628  } else {
2629  ast_debug(1, "We don't want more digits if we will end the call\n");
2630  add_header(resp, "R", "L/hu(N),L/hf(N)");
2631  }
2632 }
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_channel * owner
Definition: chan_mgcp.c:299
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
enum ast_channel_state _state
Definition: channel.h:839
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int add_line ( struct mgcp_request req,
char *  line 
)
static

Definition at line 2067 of file chan_mgcp.c.

References ast_copy_string(), ast_log(), mgcp_request::data, mgcp_request::len, mgcp_request::line, mgcp_request::lines, LOG_WARNING, and MGCP_MAX_LINES.

Referenced by add_sdp().

2068 {
2069  if (req->len >= sizeof(req->data) - 4) {
2070  ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
2071  return -1;
2072  }
2073  if (!req->lines) {
2074  /* Add extra empty return */
2075  ast_copy_string(req->data + req->len, "\r\n", sizeof(req->data) - req->len);
2076  req->len += strlen(req->data + req->len);
2077  }
2078  req->line[req->lines] = req->data + req->len;
2079  snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
2080  req->len += strlen(req->line[req->lines]);
2081  if (req->lines < MGCP_MAX_LINES) {
2082  req->lines++;
2083  } else {
2084  ast_log(LOG_WARNING, "Out of line space\n");
2085  return -1;
2086  }
2087  return 0;
2088 }
#define LOG_WARNING
Definition: logger.h:144
#define MGCP_MAX_LINES
Definition: chan_mgcp.c:244
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char * line[MGCP_MAX_LINES]
Definition: chan_mgcp.c:255
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
static int add_sdp ( struct mgcp_request resp,
struct mgcp_subchannel sub,
struct ast_rtp_instance rtp 
)
static

Definition at line 2181 of file chan_mgcp.c.

References add_line(), ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_inet_ntoa(), ast_log(), ast_rtp_codecs_payload_code(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), ast_rtp_lookup_mime_subtype2(), AST_RTP_MAX, ast_sockaddr_to_sin, mgcp_endpoint::capability, len(), LOG_WARNING, mgcp_endpoint::nonCodecCapability, mgcp_gateway::ourip, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_subchannel::rtp, and mgcp_subchannel::tmpdest.

Referenced by transmit_connect_with_sdp(), transmit_modify_request(), and transmit_modify_with_sdp().

2182 {
2183  int len;
2184  int codec;
2185  char costr[80];
2186  struct sockaddr_in sin;
2187  struct ast_sockaddr sin_tmp;
2188  char v[256];
2189  char s[256];
2190  char o[256];
2191  char c[256];
2192  char t[256];
2193  char m[256] = "";
2194  char a[1024] = "";
2195  format_t x;
2196  struct sockaddr_in dest = { 0, };
2197  struct ast_sockaddr dest_tmp;
2198  struct mgcp_endpoint *p = sub->parent;
2199  /* XXX We break with the "recommendation" and send our IP, in order that our
2200  peer doesn't have to ast_gethostbyname() us XXX */
2201  len = 0;
2202  if (!sub->rtp) {
2203  ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
2204  return -1;
2205  }
2206  ast_rtp_instance_get_local_address(sub->rtp, &sin_tmp);
2207  ast_sockaddr_to_sin(&sin_tmp, &sin);
2208  if (rtp) {
2209  ast_rtp_instance_get_remote_address(sub->rtp, &dest_tmp);
2210  ast_sockaddr_to_sin(&dest_tmp, &dest);
2211  } else {
2212  if (sub->tmpdest.sin_addr.s_addr) {
2213  dest.sin_addr = sub->tmpdest.sin_addr;
2214  dest.sin_port = sub->tmpdest.sin_port;
2215  /* Reset temporary destination */
2216  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
2217  } else {
2218  dest.sin_addr = p->parent->ourip;
2219  dest.sin_port = sin.sin_port;
2220  }
2221  }
2222  ast_debug(1, "We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
2223  ast_copy_string(v, "v=0\r\n", sizeof(v));
2224  snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
2225  ast_copy_string(s, "s=session\r\n", sizeof(s));
2226  snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
2227  ast_copy_string(t, "t=0 0\r\n", sizeof(t));
2228  snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
2229  for (x = 1LL; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
2230  if (!(x & AST_FORMAT_AUDIO_MASK)) {
2231  /* Audio is now discontiguous */
2232  continue;
2233  }
2234  if (p->capability & x) {
2235  ast_debug(1, "Answering with capability %s\n", ast_getformatname(x));
2237  if (codec > -1) {
2238  snprintf(costr, sizeof(costr), " %d", codec);
2239  strncat(m, costr, sizeof(m) - strlen(m) - 1);
2240  snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, x, 0));
2241  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2242  }
2243  }
2244  }
2245  for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
2246  if (p->nonCodecCapability & x) {
2247  ast_debug(1, "Answering with non-codec capability %d\n", (int) x);
2249  if (codec > -1) {
2250  snprintf(costr, sizeof(costr), " %d", codec);
2251  strncat(m, costr, sizeof(m) - strlen(m) - 1);
2252  snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, x, 0));
2253  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2254  if (x == AST_RTP_DTMF) {
2255  /* Indicate we support DTMF... Not sure about 16,
2256  but MSN supports it so dang it, we will too... */
2257  snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec);
2258  strncat(a, costr, sizeof(a) - strlen(a) - 1);
2259  }
2260  }
2261  }
2262  }
2263  strncat(m, "\r\n", sizeof(m) - strlen(m) - 1);
2264  len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
2265  snprintf(costr, sizeof(costr), "%d", len);
2266  add_line(resp, v);
2267  add_line(resp, o);
2268  add_line(resp, s);
2269  add_line(resp, c);
2270  add_line(resp, t);
2271  add_line(resp, m);
2272  add_line(resp, a);
2273  return 0;
2274 }
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:483
#define LOG_WARNING
Definition: logger.h:144
struct sockaddr_in tmpdest
Definition: chan_mgcp.c:302
Socket address structure.
Definition: netsock2.h:63
#define AST_RTP_MAX
Definition: rtp_engine.h:224
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct in_addr ourip
Definition: chan_mgcp.c:398
int nonCodecCapability
Definition: chan_mgcp.c:368
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
int64_t format_t
Definition: frame_defs.h:32
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
format_t capability
Definition: chan_mgcp.c:367
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:673
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:430
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static int add_line(struct mgcp_request *req, char *line)
Definition: chan_mgcp.c:2067
#define AST_RTP_DTMF
Definition: rtp_engine.h:218
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
Retrieve a payload based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:654
static struct ast_variable * add_var ( const char *  buf,
struct ast_variable list 
)
static

Definition at line 4587 of file chan_mgcp.c.

References ast_strdupa, ast_variable_new(), and ast_variable::next.

Referenced by build_gateway().

4588 {
4589  struct ast_variable *tmpvar = NULL;
4590  char *varname = ast_strdupa(buf), *varval = NULL;
4591 
4592  if ((varval = strchr(varname, '='))) {
4593  *varval++ = '\0';
4594  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
4595  tmpvar->next = list;
4596  list = tmpvar;
4597  }
4598  }
4599  return list;
4600 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static int attempt_transfer ( struct mgcp_endpoint p)
static

Definition at line 3214 of file chan_mgcp.c.

References ast_channel::_softhangup, ast_channel::_state, mgcp_subchannel::alreadygone, ast_bridged_channel(), ast_channel_masquerade(), AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), ast_log(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RINGING, ast_verb, mgcp_subchannel::id, LOG_WARNING, mgcp_queue_hangup(), mgcp_endpoint::name, mgcp_gateway::name, ast_channel::name, mgcp_subchannel::next, mgcp_subchannel::owner, mgcp_endpoint::parent, mgcp_endpoint::sub, and unalloc_sub().

Referenced by handle_request().

3215 {
3216  /* *************************
3217  * I hope this works.
3218  * Copied out of chan_zap
3219  * Cross your fingers
3220  * *************************/
3221 
3222  /* In order to transfer, we need at least one of the channels to
3223  actually be in a call bridge. We can't conference two applications
3224  together (but then, why would we want to?) */
3225  if (ast_bridged_channel(p->sub->owner)) {
3226  /* The three-way person we're about to transfer to could still be in MOH, so
3227  stop if now if appropriate */
3228  if (ast_bridged_channel(p->sub->next->owner))
3230  if (p->sub->owner->_state == AST_STATE_RINGING) {
3232  }
3234  ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
3236  return -1;
3237  }
3238  /* Orphan the channel */
3239  unalloc_sub(p->sub->next);
3240  } else if (ast_bridged_channel(p->sub->next->owner)) {
3241  if (p->sub->owner->_state == AST_STATE_RINGING) {
3243  }
3246  ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
3248  return -1;
3249  }
3250  /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/
3251  ast_verb(3, "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
3252  p->sub = p->sub->next;
3253  unalloc_sub(p->sub->next);
3254  /* Tell the caller not to hangup */
3255  return 1;
3256  } else {
3257  ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
3258  p->sub->owner->name, p->sub->next->owner->name);
3260  if (p->sub->next->owner) {
3261  p->sub->next->alreadygone = 1;
3262  mgcp_queue_hangup(p->sub->next);
3263  }
3264  }
3265  return 0;
3266 }
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
Weird function made for call transfers.
Definition: channel.c:6110
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
static int unalloc_sub(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:517
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
#define LOG_WARNING
Definition: logger.h:144
static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:632
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
struct ast_channel * owner
Definition: chan_mgcp.c:299
char name[80]
Definition: chan_mgcp.c:394
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
enum ast_channel_state _state
Definition: channel.h:839
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int _softhangup
Definition: channel.h:832
static struct mgcp_gateway * build_gateway ( char *  cat,
struct ast_variable v 
)
static

build_gateway: parse mgcp.conf and create gateway/endpoint structures

Definition at line 3972 of file chan_mgcp.c.

References __ourip, mgcp_endpoint::accountcode, add_var(), mgcp_gateway::addr, adsi, mgcp_endpoint::adsi, amaflags, mgcp_endpoint::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_string(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_free, ast_get_group(), ast_get_ip(), ast_log(), ast_mutex_destroy, ast_mutex_init, ast_ouraddrfor(), ast_random(), AST_SCHED_DEL, ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variables_destroy(), ast_verb, mgcp_endpoint::callgroup, callreturn, mgcp_endpoint::callreturn, callwaiting, mgcp_endpoint::callwaiting, cancallforward, mgcp_endpoint::cancallforward, capability, mgcp_endpoint::capability, mgcp_endpoint::chanvars, mgcp_endpoint::cid_name, mgcp_endpoint::cid_num, mgcp_endpoint::cmd_queue_lock, mgcp_endpoint::context, copy_vars(), cur_callergroup, cur_pickupgroup, mgcp_subchannel::cx_queue_lock, mgcp_subchannel::cxmode, mgcp_gateway::defaddr, DEFAULT_MGCP_GW_PORT, mgcp_endpoint::delme, mgcp_gateway::delme, DIRECTMEDIA, directmedia, mgcp_endpoint::directmedia, dtmfmode, mgcp_endpoint::dtmfmode, mgcp_gateway::dynamic, mgcp_gateway::endpoints, mgcp_gateway::expire, mgcp_subchannel::gate, gateways, mgcp_gateway::ha, hangupongateremove, mgcp_endpoint::hangupongateremove, mgcp_endpoint::hascallwaiting, mgcp_endpoint::hookstate, mgcp_subchannel::id, immediate, mgcp_endpoint::immediate, INADDR_NONE, mgcp_gateway::isnamedottedip, mgcp_endpoint::language, ast_variable::lineno, mgcp_subchannel::lock, mgcp_endpoint::lock, LOG_WARNING, mgcp_subchannel::magic, mgcp_endpoint::mailbox, MAX_SUBS, mbox(), MGCP_CX_INACTIVE, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, MGCP_DTMF_RFC2833, MGCP_ONHOOK, MGCP_SUBCHANNEL_MAGIC, mgcp_gateway::msgs_lock, mgcp_endpoint::msgstate, mgcp_endpoint::musicclass, mwi_event_cb(), mgcp_endpoint::mwi_event_sub, ast_variable::name, mgcp_endpoint::name, mgcp_gateway::name, nat, mgcp_subchannel::nat, ncs, mgcp_endpoint::ncs, mgcp_endpoint::needaudit, ast_variable::next, mgcp_subchannel::next, mgcp_endpoint::next, mgcp_gateway::next, mgcp_endpoint::onhooktime, mgcp_gateway::ourip, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_endpoint::parkinglot, mgcp_endpoint::pickupgroup, pktcgatealloc, mgcp_endpoint::pktcgatealloc, mgcp_gateway::realtime, mgcp_gateway::retransid, mgcp_endpoint::rqnt_ident, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, mgcp_subchannel::sdpsent, singlepath, mgcp_endpoint::singlepath, slowsequence, mgcp_endpoint::slowsequence, strsep(), mgcp_endpoint::sub, threewaycalling, mgcp_endpoint::threewaycalling, transfer, mgcp_endpoint::transfer, mgcp_subchannel::txident, mgcp_endpoint::type, TYPE_LINE, TYPE_TRUNK, ast_variable::value, and mgcp_gateway::wcardep.

Referenced by find_realtime_gw(), and reload_config().

3973 {
3974  struct mgcp_gateway *gw;
3975  struct mgcp_endpoint *e;
3976  struct mgcp_subchannel *sub;
3977  struct ast_variable *chanvars = NULL;
3978 
3979  /*char txident[80];*/
3980  int i=0, y=0;
3981  int gw_reload = 0;
3982  int ep_reload = 0;
3984 
3985  /* locate existing gateway */
3986  for (gw = gateways; gw; gw = gw->next) {
3987  if (!strcasecmp(cat, gw->name)) {
3988  /* gateway already exists */
3989  gw->delme = 0;
3990  gw_reload = 1;
3991  break;
3992  }
3993  }
3994 
3995  if (!gw && !(gw = ast_calloc(1, sizeof(*gw)))) {
3996  return NULL;
3997  }
3998 
3999  if (!gw_reload) {
4000  gw->expire = -1;
4001  gw->realtime = 0;
4002  gw->retransid = -1;
4003  ast_mutex_init(&gw->msgs_lock);
4004  ast_copy_string(gw->name, cat, sizeof(gw->name));
4005  /* check if the name is numeric ip */
4006  if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE)
4007  gw->isnamedottedip = 1;
4008  }
4009  for (; v; v = v->next) {
4010  if (!strcasecmp(v->name, "host")) {
4011  if (!strcasecmp(v->value, "dynamic")) {
4012  /* They'll register with us */
4013  gw->dynamic = 1;
4014  memset(&gw->addr.sin_addr, 0, 4);
4015  if (gw->addr.sin_port) {
4016  /* If we've already got a port, make it the default rather than absolute */
4017  gw->defaddr.sin_port = gw->addr.sin_port;
4018  gw->addr.sin_port = 0;
4019  }
4020  } else {
4021  /* Non-dynamic. Make sure we become that way if we're not */
4022  AST_SCHED_DEL(sched, gw->expire);
4023  gw->dynamic = 0;
4024  {
4025  struct ast_sockaddr tmp;
4026 
4027  ast_sockaddr_from_sin(&tmp, &gw->addr);
4028  if (ast_get_ip(&tmp, v->value)) {
4029  if (!gw_reload) {
4031  ast_free(gw);
4032  }
4033  return NULL;
4034  }
4035  ast_sockaddr_to_sin(&tmp, &gw->addr);
4036  }
4037  }
4038  } else if (!strcasecmp(v->name, "defaultip")) {
4039  struct ast_sockaddr tmp;
4040 
4041  ast_sockaddr_from_sin(&tmp, &gw->defaddr);
4042  if (ast_get_ip(&tmp, v->value)) {
4043  if (!gw_reload) {
4045  ast_free(gw);
4046  }
4047  return NULL;
4048  }
4049  ast_sockaddr_to_sin(&tmp, &gw->defaddr);
4050  } else if (!strcasecmp(v->name, "permit") ||
4051  !strcasecmp(v->name, "deny")) {
4052  gw->ha = ast_append_ha(v->name, v->value, gw->ha, NULL);
4053  } else if (!strcasecmp(v->name, "port")) {
4054  gw->addr.sin_port = htons(atoi(v->value));
4055  } else if (!strcasecmp(v->name, "context")) {
4056  ast_copy_string(context, v->value, sizeof(context));
4057  } else if (!strcasecmp(v->name, "dtmfmode")) {
4058  if (!strcasecmp(v->value, "inband"))
4060  else if (!strcasecmp(v->value, "rfc2833"))
4062  else if (!strcasecmp(v->value, "hybrid"))
4064  else if (!strcasecmp(v->value, "none"))
4065  dtmfmode = 0;
4066  else
4067  ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno);
4068  } else if (!strcasecmp(v->name, "nat")) {
4069  nat = ast_true(v->value);
4070  } else if (!strcasecmp(v->name, "ncs")) {
4071  ncs = ast_true(v->value);
4072  } else if (!strcasecmp(v->name, "hangupongateremove")) {
4074  } else if (!strcasecmp(v->name, "pktcgatealloc")) {
4076  } else if (!strcasecmp(v->name, "callerid")) {
4077  if (!strcasecmp(v->value, "asreceived")) {
4078  cid_num[0] = '\0';
4079  cid_name[0] = '\0';
4080  } else {
4081  ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
4082  }
4083  } else if (!strcasecmp(v->name, "language")) {
4084  ast_copy_string(language, v->value, sizeof(language));
4085  } else if (!strcasecmp(v->name, "accountcode")) {
4087  } else if (!strcasecmp(v->name, "amaflags")) {
4088  y = ast_cdr_amaflags2int(v->value);
4089  if (y < 0) {
4090  ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
4091  } else {
4092  amaflags = y;
4093  }
4094  } else if (!strcasecmp(v->name, "setvar")) {
4095  chanvars = add_var(v->value, chanvars);
4096  } else if (!strcasecmp(v->name, "clearvars")) {
4097  if (chanvars) {
4098  ast_variables_destroy(chanvars);
4099  chanvars = NULL;
4100  }
4101  } else if (!strcasecmp(v->name, "musiconhold")) {
4103  } else if (!strcasecmp(v->name, "parkinglot")) {
4105  } else if (!strcasecmp(v->name, "callgroup")) {
4107  } else if (!strcasecmp(v->name, "pickupgroup")) {
4109  } else if (!strcasecmp(v->name, "immediate")) {
4110  immediate = ast_true(v->value);
4111  } else if (!strcasecmp(v->name, "cancallforward")) {
4113  } else if (!strcasecmp(v->name, "singlepath")) {
4114  singlepath = ast_true(v->value);
4115  } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
4116  directmedia = ast_true(v->value);
4117  } else if (!strcasecmp(v->name, "mailbox")) {
4118  ast_copy_string(mailbox, v->value, sizeof(mailbox));
4119  } else if (!strcasecmp(v->name, "hasvoicemail")) {
4120  if (ast_true(v->value) && ast_strlen_zero(mailbox)) {
4121  ast_copy_string(mailbox, gw->name, sizeof(mailbox));
4122  }
4123  } else if (!strcasecmp(v->name, "adsi")) {
4124  adsi = ast_true(v->value);
4125  } else if (!strcasecmp(v->name, "callreturn")) {
4126  callreturn = ast_true(v->value);
4127  } else if (!strcasecmp(v->name, "callwaiting")) {
4128  callwaiting = ast_true(v->value);
4129  } else if (!strcasecmp(v->name, "slowsequence")) {
4130  slowsequence = ast_true(v->value);
4131  } else if (!strcasecmp(v->name, "transfer")) {
4132  transfer = ast_true(v->value);
4133  } else if (!strcasecmp(v->name, "threewaycalling")) {
4135  } else if (!strcasecmp(v->name, "wcardep")) {
4136  /* locate existing endpoint */
4137  for (e = gw->endpoints; e; e = e->next) {
4138  if (!strcasecmp(v->value, e->name)) {
4139  /* endpoint already exists */
4140  e->delme = 0;
4141  ep_reload = 1;
4142  break;
4143  }
4144  }
4145 
4146  if (!e) {
4147  /* Allocate wildcard endpoint */
4148  e = ast_calloc(1, sizeof(*e));
4149  ep_reload = 0;
4150  }
4151 
4152  if (e) {
4153  if (!ep_reload) {
4154  memset(e, 0, sizeof(struct mgcp_endpoint));
4155  ast_mutex_init(&e->lock);
4158  ast_copy_string(e->name, v->value, sizeof(e->name));
4159  e->needaudit = 1;
4160  }
4161  ast_copy_string(gw->wcardep, v->value, sizeof(gw->wcardep));
4162  /* XXX Should we really check for uniqueness?? XXX */
4164  ast_copy_string(e->context, context, sizeof(e->context));
4165  ast_copy_string(e->cid_num, cid_num, sizeof(e->cid_num));
4166  ast_copy_string(e->cid_name, cid_name, sizeof(e->cid_name));
4167  ast_copy_string(e->language, language, sizeof(e->language));
4169  ast_copy_string(e->mailbox, mailbox, sizeof(e->mailbox));
4171  if (!ast_strlen_zero(e->mailbox)) {
4172  char *mbox, *cntx;
4173  cntx = mbox = ast_strdupa(e->mailbox);
4174  strsep(&cntx, "@");
4175  if (ast_strlen_zero(cntx)) {
4176  cntx = "default";
4177  }
4178  e->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "MGCP MWI subscription", NULL,
4183  }
4184  snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", (unsigned long)ast_random());
4185  e->msgstate = -1;
4186  e->amaflags = amaflags;
4187  e->capability = capability;
4188  e->parent = gw;
4189  e->ncs = ncs;
4190  e->dtmfmode = dtmfmode;
4191  if (!ep_reload && e->sub && e->sub->rtp) {
4192  e->dtmfmode |= MGCP_DTMF_INBAND;
4193  }
4194  e->adsi = adsi;
4195  e->type = TYPE_LINE;
4196  e->immediate = immediate;
4199  e->callreturn = callreturn;
4201  e->singlepath = singlepath;
4202  e->directmedia = directmedia;
4203  e->callwaiting = callwaiting;
4206  e->transfer = transfer;
4208  e->onhooktime = time(NULL);
4209  /* ASSUME we're onhook */
4210  e->hookstate = MGCP_ONHOOK;
4211  e->chanvars = copy_vars(chanvars);
4212  if (!ep_reload) {
4213  /*snprintf(txident, sizeof(txident), "%08lx", (unsigned long)ast_random());*/
4214  for (i = 0; i < MAX_SUBS; i++) {
4215  sub = ast_calloc(1, sizeof(*sub));
4216  if (sub) {
4217  ast_verb(3, "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name);
4218  ast_mutex_init(&sub->lock);
4220  sub->parent = e;
4221  sub->id = i;
4222  snprintf(sub->txident, sizeof(sub->txident), "%08lx", (unsigned long)ast_random());
4223  /*stnrcpy(sub->txident, txident, sizeof(sub->txident) - 1);*/
4224  sub->cxmode = MGCP_CX_INACTIVE;
4225  sub->nat = nat;
4226  sub->gate = NULL;
4227  sub->sdpsent = 0;
4228  sub->next = e->sub;
4229  e->sub = sub;
4230  } else {
4231  /* XXX Should find a way to clean up our memory */
4232  ast_log(LOG_WARNING, "Out of memory allocating subchannel\n");
4233  return NULL;
4234  }
4235  }
4236  /* Make out subs a circular linked list so we can always sping through the whole bunch */
4237  /* find the end of the list */
4238  for (sub = e->sub; sub && sub->next; sub = sub->next);
4239  /* set the last sub->next to the first sub */
4240  sub->next = e->sub;
4241 
4242  e->next = gw->endpoints;
4243  gw->endpoints = e;
4244  }
4245  }
4246  } else if (!strcasecmp(v->name, "trunk") ||
4247  !strcasecmp(v->name, "line")) {
4248 
4249  /* locate existing endpoint */
4250  for (e = gw->endpoints; e; e = e->next) {
4251  if (!strcasecmp(v->value, e->name)) {
4252  /* endpoint already exists */
4253  e->delme = 0;
4254  ep_reload = 1;
4255  break;
4256  }
4257  }
4258 
4259  if (!e) {
4260  e = ast_calloc(1, sizeof(*e));
4261  ep_reload = 0;
4262  }
4263 
4264  if (e) {
4265  if (!ep_reload) {
4266  ast_mutex_init(&e->lock);
4269  ast_copy_string(e->name, v->value, sizeof(e->name));
4270  e->needaudit = 1;
4271  }
4272  /* XXX Should we really check for uniqueness?? XXX */
4274  ast_copy_string(e->context, context, sizeof(e->context));
4275  ast_copy_string(e->cid_num, cid_num, sizeof(e->cid_num));
4276  ast_copy_string(e->cid_name, cid_name, sizeof(e->cid_name));
4277  ast_copy_string(e->language, language, sizeof(e->language));
4279  ast_copy_string(e->mailbox, mailbox, sizeof(e->mailbox));
4281  if (!ast_strlen_zero(mailbox)) {
4282  ast_verb(3, "Setting mailbox '%s' on %s@%s\n", mailbox, gw->name, e->name);
4283  }
4284  if (!ep_reload) {
4285  /* XXX potential issue due to reload */
4286  e->msgstate = -1;
4287  e->parent = gw;
4288  }
4289  e->amaflags = amaflags;
4290  e->capability = capability;
4291  e->dtmfmode = dtmfmode;
4292  e->ncs = ncs;
4295  e->adsi = adsi;
4296  e->type = (!strcasecmp(v->name, "trunk")) ? TYPE_TRUNK : TYPE_LINE;
4297  e->immediate = immediate;
4300  e->callreturn = callreturn;
4302  e->directmedia = directmedia;
4303  e->singlepath = singlepath;
4304  e->callwaiting = callwaiting;
4307  e->transfer = transfer;
4309 
4310  /* If we already have a valid chanvars, it's not a new endpoint (it's a reload),
4311  so first, free previous mem
4312  */
4313  if (e->chanvars) {
4315  e->chanvars = NULL;
4316  }
4317  e->chanvars = copy_vars(chanvars);
4318 
4319  if (!ep_reload) {
4320  e->onhooktime = time(NULL);
4321  /* ASSUME we're onhook */
4322  e->hookstate = MGCP_ONHOOK;
4323  snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", (unsigned long)ast_random());
4324  }
4325 
4326  for (i = 0, sub = NULL; i < MAX_SUBS; i++) {
4327  if (!ep_reload) {
4328  sub = ast_calloc(1, sizeof(*sub));
4329  } else {
4330  if (!sub) {
4331  sub = e->sub;
4332  } else {
4333  sub = sub->next;
4334  }
4335  }
4336 
4337  if (sub) {
4338  if (!ep_reload) {
4339  ast_verb(3, "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name);
4340  ast_mutex_init(&sub->lock);
4342  ast_copy_string(sub->magic, MGCP_SUBCHANNEL_MAGIC, sizeof(sub->magic));
4343  sub->parent = e;
4344  sub->id = i;
4345  snprintf(sub->txident, sizeof(sub->txident), "%08lx", (unsigned long)ast_random());
4346  sub->cxmode = MGCP_CX_INACTIVE;
4347  sub->next = e->sub;
4348  e->sub = sub;
4349  }
4350  sub->nat = nat;
4351  } else {
4352  /* XXX Should find a way to clean up our memory */
4353  ast_log(LOG_WARNING, "Out of memory allocating subchannel\n");
4354  return NULL;
4355  }
4356  }
4357  if (!ep_reload) {
4358  /* Make out subs a circular linked list so we can always sping through the whole bunch */
4359  /* find the end of the list */
4360  for (sub = e->sub; sub && sub->next; sub = sub->next);
4361  /* set the last sub->next to the first sub */
4362  sub->next = e->sub;
4363 
4364  e->next = gw->endpoints;
4365  gw->endpoints = e;
4366  }
4367  }
4368  } else if (!strcasecmp(v->name, "name") || !strcasecmp(v->name, "lines")) {
4369  /* just eliminate realtime warnings */
4370  } else {
4371  ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
4372  }
4373  }
4374  if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) {
4375  ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name);
4376  if (!gw_reload) {
4378  ast_free(gw);
4379  }
4380 
4381  /* Return NULL */
4382  gw_reload = 1;
4383  } else {
4384  gw->defaddr.sin_family = AF_INET;
4385  gw->addr.sin_family = AF_INET;
4386  if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port)) {
4387  gw->defaddr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
4388  }
4389  if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port)) {
4390  gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
4391  }
4392  {
4393  struct ast_sockaddr tmp1, tmp2;
4394  struct sockaddr_in tmp3 = {0,};
4395 
4396  tmp3.sin_addr = gw->ourip;
4397  ast_sockaddr_from_sin(&tmp1, &gw->addr);
4398  ast_sockaddr_from_sin(&tmp2, &tmp3);
4399  if (gw->addr.sin_addr.s_addr && ast_ouraddrfor(&tmp1, &tmp2)) {
4400  memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
4401  } else {
4402  ast_sockaddr_to_sin(&tmp2, &tmp3);
4403  gw->ourip = tmp3.sin_addr;
4404  }
4405  }
4406  }
4407 
4408  if (chanvars) {
4409  ast_variables_destroy(chanvars);
4410  chanvars = NULL;
4411  }
4412  return (gw_reload ? NULL : gw);
4413 }
static char musicclass[MAX_MUSICCLASS]
Definition: chan_mgcp.c:155
#define TYPE_LINE
Definition: chan_mgcp.c:323
static int adsi
Definition: chan_mgcp.c:201
static int slowsequence
Definition: chan_mgcp.c:182
struct cops_gate * gate
Definition: chan_mgcp.c:315
static int dtmfmode
Definition: chan_mgcp.c:160
char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:333
static ast_group_t cur_pickupgroup
Definition: chan_mgcp.c:167
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:156
char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:334
int hascallwaiting
Definition: chan_mgcp.c:346
char * strsep(char **str, const char *delims)
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1093
#define TYPE_TRUNK
Definition: chan_mgcp.c:322
ast_mutex_t cmd_queue_lock
Definition: chan_mgcp.c:378
int slowsequence
Definition: chan_mgcp.c:362
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
#define MAX_SUBS
Definition: chan_mgcp.c:284
#define DEFAULT_MGCP_GW_PORT
Definition: chan_mgcp.c:116
static int callwaiting
Definition: chan_mgcp.c:178
char musicclass[MAX_MUSICCLASS]
Definition: chan_mgcp.c:338
#define MGCP_DTMF_RFC2833
Definition: chan_mgcp.c:112
#define LOG_WARNING
Definition: logger.h:144
static int nat
Definition: chan_mgcp.c:161
int lineno
Definition: config.h:87
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
int cancallforward
Definition: chan_mgcp.c:350
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
Definition: sched.c:57
ast_mutex_t lock
Definition: chan_mgcp.c:297
static int callreturn
Definition: chan_mgcp.c:180
ast_group_t pickupgroup
Definition: chan_mgcp.c:344
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
char rqnt_ident[80]
Definition: chan_mgcp.c:374
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
Socket address structure.
Definition: netsock2.h:63
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
#define ast_verb(level,...)
Definition: logger.h:243
static int transfer
Definition: chan_mgcp.c:187
static int threewaycalling
Definition: chan_mgcp.c:184
static const char * mbox(struct ast_vm_user *vmu, int id)
int hangupongateremove
Definition: chan_mgcp.c:360
static int cancallforward
Definition: chan_mgcp.c:189
char language[MAX_LANGUAGE]
Definition: chan_mgcp.c:332
char wcardep[30]
Definition: chan_mgcp.c:409
char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:341
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:705
char name[80]
Definition: chan_mgcp.c:327
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
const char * value
Definition: config.h:79
static int immediate
Definition: chan_mgcp.c:176
struct in_addr ourip
Definition: chan_mgcp.c:398
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
struct sockaddr_in defaddr
Definition: chan_mgcp.c:397
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_variable * chanvars
Definition: chan_mgcp.c:387
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
long int ast_random(void)
Definition: utils.c:1640
static int amaflags
Definition: chan_mgcp.c:199
char name[80]
Definition: chan_mgcp.c:394
const char * name
Definition: config.h:77
#define DIRECTMEDIA
Definition: chan_mgcp.c:91
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7987
int isnamedottedip
Definition: chan_mgcp.c:395
char context[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:331
ast_group_t callgroup
Definition: chan_mgcp.c:343
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_mgcp.c:329
int threewaycalling
Definition: chan_mgcp.c:348
struct ast_event_sub * mwi_event_sub
Definition: chan_mgcp.c:342
static char language[MAX_LANGUAGE]
Definition: chan_mgcp.c:154
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct ast_variable * add_var(const char *buf, struct ast_variable *list)
Definition: chan_mgcp.c:4587
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
ast_mutex_t cx_queue_lock
Definition: chan_mgcp.c:309
int pktcgatealloc
Definition: chan_mgcp.c:359
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static void mwi_event_cb(const struct ast_event *event, void *userdata)
Definition: chan_mgcp.c:484
int ast_cdr_amaflags2int(const char *flag)
Convert a string to a detail record AMA flag.
Definition: cdr.c:1105
#define INADDR_NONE
Definition: chan_mgcp.c:94
ast_mutex_t lock
Definition: chan_mgcp.c:326
static int singlepath
Definition: chan_mgcp.c:191
struct sockaddr_in addr
Definition: chan_mgcp.c:396
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int ncs
Definition: chan_mgcp.c:162
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
Definition: acl.c:700
#define ast_free(a)
Definition: astmm.h:97
ast_mutex_t rqnt_queue_lock
Definition: chan_mgcp.c:376
static format_t capability
Definition: chan_mgcp.c:228
static ast_group_t cur_callergroup
Definition: chan_mgcp.c:166
struct ast_ha * ha
Definition: chan_mgcp.c:402
format_t capability
Definition: chan_mgcp.c:367
char txident[80]
Definition: chan_mgcp.c:303
static int pktcgatealloc
Definition: chan_mgcp.c:163
static struct mgcp_gateway * gateways
char magic[6]
Definition: chan_mgcp.c:296
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
static int directmedia
Definition: chan_mgcp.c:193
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_mgcp.c:195
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static struct ast_variable * copy_vars(struct ast_variable *src)
duplicate a list of channel variables,
Definition: chan_mgcp.c:4605
static int hangupongateremove
Definition: chan_mgcp.c:164
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
Definition: event.c:909
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:152
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:399
#define MGCP_CX_INACTIVE
Definition: chan_mgcp.c:129
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct ast_variable * next
Definition: config.h:82
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_mutex_destroy(a)
Definition: lock.h:154
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define MGCP_SUBCHANNEL_MAGIC
Definition: chan_mgcp.c:295
static struct in_addr __ourip
Definition: chan_mgcp.c:232
char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:340
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
Mailbox name.
Definition: event_defs.h:83
static char* control2str ( int  ind)
static

Definition at line 1408 of file chan_mgcp.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, and AST_CONTROL_WINK.

Referenced by mgcp_indicate().

1408  {
1409  switch (ind) {
1410  case AST_CONTROL_HANGUP:
1411  return "Other end has hungup";
1412  case AST_CONTROL_RING:
1413  return "Local ring";
1414  case AST_CONTROL_RINGING:
1415  return "Remote end is ringing";
1416  case AST_CONTROL_ANSWER:
1417  return "Remote end has answered";
1418  case AST_CONTROL_BUSY:
1419  return "Remote end is busy";
1421  return "Make it go off hook";
1422  case AST_CONTROL_OFFHOOK:
1423  return "Line is off hook";
1425  return "Congestion (circuits busy)";
1426  case AST_CONTROL_FLASH:
1427  return "Flash hook";
1428  case AST_CONTROL_WINK:
1429  return "Wink";
1430  case AST_CONTROL_OPTION:
1431  return "Set a low-level option";
1432  case AST_CONTROL_RADIO_KEY:
1433  return "Key Radio";
1435  return "Un-Key Radio";
1436  }
1437  return "UNKNOWN";
1438 }
static struct ast_variable * copy_vars ( struct ast_variable src)
static

duplicate a list of channel variables,

Returns
the copy.

Definition at line 4605 of file chan_mgcp.c.

References ast_variable_new(), and ast_variable::next.

Referenced by build_gateway().

4606 {
4607  struct ast_variable *res = NULL, *tmp, *v = NULL;
4608 
4609  for (v = src ; v ; v = v->next) {
4610  if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
4611  tmp->next = res;
4612  res = tmp;
4613  }
4614  }
4615  return res;
4616 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static void destroy_endpoint ( struct mgcp_endpoint e)
static

Definition at line 4477 of file chan_mgcp.c.

References ast_dsp_free(), ast_event_unsubscribe(), ast_free, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_destroy(), ast_strlen_zero(), ast_variables_destroy(), mgcp_endpoint::chanvars, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cxident, mgcp_endpoint::dsp, dump_cmd_queues(), dump_queue(), mgcp_subchannel::gate, cops_gate::gate_open, cops_gate::gate_remove, cops_gate::got_dq_gi, mgcp_subchannel::lock, mgcp_endpoint::lock, mgcp_subchannel::magic, MAX_SUBS, mgcp_queue_hangup(), mgcp_endpoint::mwi_event_sub, mgcp_subchannel::next, mgcp_endpoint::parent, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, mgcp_endpoint::sub, cops_gate::tech_pvt, and transmit_connection_del().

Referenced by prune_gateways().

4478 {
4479  struct mgcp_subchannel *sub = e->sub->next, *s;
4480  int i;
4481 
4482  for (i = 0; i < MAX_SUBS; i++) {
4483  ast_mutex_lock(&sub->lock);
4484  if (!ast_strlen_zero(sub->cxident)) {
4486  }
4487  if (sub->rtp) {
4489  sub->rtp = NULL;
4490  }
4491  memset(sub->magic, 0, sizeof(sub->magic));
4492  mgcp_queue_hangup(sub);
4493  dump_cmd_queues(NULL, sub);
4494  if(sub->gate) {
4495  sub->gate->tech_pvt = NULL;
4496  sub->gate->got_dq_gi = NULL;
4497  sub->gate->gate_remove = NULL;
4498  sub->gate->gate_open = NULL;
4499  }
4500  ast_mutex_unlock(&sub->lock);
4501  sub = sub->next;
4502  }
4503 
4504  if (e->dsp) {
4505  ast_dsp_free(e->dsp);
4506  }
4507 
4508  dump_queue(e->parent, e);
4509  dump_cmd_queues(e, NULL);
4510 
4511  sub = e->sub;
4512  for (i = 0; (i < MAX_SUBS) && sub; i++) {
4513  s = sub;
4514  sub = sub->next;
4515  ast_mutex_destroy(&s->lock);
4516  ast_mutex_destroy(&s->cx_queue_lock);
4517  ast_free(s);
4518  }
4519 
4520  if (e->mwi_event_sub)
4522 
4523  if (e->chanvars) {
4525  e->chanvars = NULL;
4526  }
4527 
4528  ast_mutex_destroy(&e->lock);
4531  ast_free(e);
4532 }
struct cops_gate * gate
Definition: chan_mgcp.c:315
ast_mutex_t cmd_queue_lock
Definition: chan_mgcp.c:378
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
#define MAX_SUBS
Definition: chan_mgcp.c:284
int(* gate_remove)(struct cops_gate *gate)
Definition: pktccops.h:65
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1650
static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:632
ast_mutex_t lock
Definition: chan_mgcp.c:297
int(* gate_open)(struct cops_gate *gate)
Definition: pktccops.h:66
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
void * tech_pvt
Definition: pktccops.h:67
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_variable * chanvars
Definition: chan_mgcp.c:387
static int transmit_connection_del(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2651
struct ast_dsp * dsp
Definition: chan_mgcp.c:381
struct ast_event_sub * mwi_event_sub
Definition: chan_mgcp.c:342
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
ast_mutex_t lock
Definition: chan_mgcp.c:326
char cxident[80]
Definition: chan_mgcp.c:305
#define ast_free(a)
Definition: astmm.h:97
ast_mutex_t rqnt_queue_lock
Definition: chan_mgcp.c:376
char magic[6]
Definition: chan_mgcp.c:296
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
dump_cmd_queues: (SC:) cleanup pending commands
Definition: chan_mgcp.c:2695
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:301
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
int(* got_dq_gi)(struct cops_gate *gate)
Definition: pktccops.h:64
#define ast_mutex_destroy(a)
Definition: lock.h:154
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
Definition: chan_mgcp.c:581
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void destroy_gateway ( struct mgcp_gateway g)
static

Definition at line 4534 of file chan_mgcp.c.

References ast_free, ast_free_ha(), dump_queue(), and mgcp_gateway::ha.

Referenced by prune_gateways().

4535 {
4536  if (g->ha)
4537  ast_free_ha(g->ha);
4538 
4539  dump_queue(g, NULL);
4540 
4541  ast_free(g);
4542 }
#define ast_free(a)
Definition: astmm.h:97
struct ast_ha * ha
Definition: chan_mgcp.c:402
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:223
static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
Definition: chan_mgcp.c:581
static void* do_monitor ( void *  data)
static

Definition at line 3774 of file chan_mgcp.c.

References ast_io_add(), AST_IO_IN, ast_io_wait(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, mgcp_gateway::endpoints, free, gatelock, gateways, has_voicemail(), MGCP_ONHOOK, mgcp_prune_realtime_gateway(), mgcp_reload_lock, mgcp_reloading, mgcpsock_read(), monlock, mgcp_gateway::msgs_lock, netlock, mgcp_gateway::next, mgcp_gateway::realtime, reload_config(), transmit_notify_request(), and TYPE_LINE.

Referenced by restart_monitor().

3775 {
3776  int res;
3777  int reloading;
3778  struct mgcp_gateway *g, *gprev;
3779  /*struct mgcp_gateway *g;*/
3780  /*struct mgcp_endpoint *e;*/
3781  /*time_t thispass = 0, lastpass = 0;*/
3782  time_t lastrun = 0;
3783 
3784  /* Add an I/O event to our UDP socket */
3785  if (mgcpsock > -1) {
3787  }
3788  /* This thread monitors all the frame relay interfaces which are not yet in use
3789  (and thus do not have a separate thread) indefinitely */
3790  /* From here on out, we die whenever asked */
3791  for (;;) {
3792  /* Check for a reload request */
3794  reloading = mgcp_reloading;
3795  mgcp_reloading = 0;
3797  if (reloading) {
3798  ast_verb(1, "Reloading MGCP\n");
3799  reload_config(1);
3800  /* Add an I/O event to our UDP socket */
3801  if (mgcpsock > -1 && !mgcpsock_read_id) {
3803  }
3804  }
3805 
3806  /* Check for interfaces needing to be killed */
3807  /* Don't let anybody kill us right away. Nobody should lock the interface list
3808  and wait for the monitor list, but the other way around is okay. */
3810  /* Lock the network interface */
3812 
3813 #if 0
3814  /* XXX THIS IS COMPLETELY HOSED */
3815  /* The gateway goes into a state of panic */
3816  /* If the vmwi indicator is sent while it is reseting interfaces */
3817  lastpass = thispass;
3818  thispass = time(NULL);
3819  g = gateways;
3820  while(g) {
3821  if (thispass != lastpass) {
3822  e = g->endpoints;
3823  while(e) {
3824  if (e->type == TYPE_LINE) {
3825  res = has_voicemail(e);
3826  if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){
3827  if (res) {
3828  transmit_notify_request(e, "L/vmwi(+)");
3829  } else {
3830  transmit_notify_request(e, "L/vmwi(-)");
3831  }
3832  e->msgstate = res;
3833  e->onhooktime = thispass;
3834  }
3835  }
3836  e = e->next;
3837  }
3838  }
3839  g = g->next;
3840  }
3841 #endif
3842  /* pruning unused realtime gateways, running in every 60 seconds*/
3843  if(time(NULL) > (lastrun + 60)) {
3845  g = gateways;
3846  gprev = NULL;
3847  while(g) {
3848  if(g->realtime) {
3850  if(gprev) {
3851  gprev->next = g->next;
3852  } else {
3853  gateways = g->next;
3854  }
3857  free(g);
3858  } else {
3860  gprev = g;
3861  }
3862  } else {
3863  gprev = g;
3864  }
3865  g = g->next;
3866  }
3868  lastrun = time(NULL);
3869  }
3870  /* Okay, now that we know what to do, release the network lock */
3872  /* And from now on, we're okay to be killed, so release the monitor lock as well */
3874  pthread_testcancel();
3875  /* Wait for sched or io */
3876  res = ast_sched_wait(sched);
3877  /* copied from chan_sip.c */
3878  if ((res < 0) || (res > 1000)) {
3879  res = 1000;
3880  }
3881  res = ast_io_wait(io, res);
3883  if (res >= 0) {
3885  }
3887  }
3888  /* Never reached */
3889  return NULL;
3890 }
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:273
#define TYPE_LINE
Definition: chan_mgcp.c:323
static int mgcpsock
Definition: chan_mgcp.c:425
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
static int * mgcpsock_read_id
Definition: chan_mgcp.c:3714
#define AST_IO_IN
Definition: io.h:33
Definition: sched.c:57
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition: io.c:157
#define ast_mutex_lock(a)
Definition: lock.h:155
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
#define ast_verb(level,...)
Definition: logger.h:243
static ast_mutex_t netlock
Definition: chan_mgcp.c:217
static int mgcp_prune_realtime_gateway(struct mgcp_gateway *g)
Definition: chan_mgcp.c:3716
static int reload_config(int reload)
Definition: chan_mgcp.c:4619
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
static struct io_context * io
Definition: chan_mgcp.c:238
static ast_mutex_t monlock
Definition: chan_mgcp.c:219
#define free(a)
Definition: astmm.h:94
static int mgcp_reloading
Definition: chan_mgcp.c:420
static struct mgcp_gateway * gateways
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
static int has_voicemail(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:492
static ast_mutex_t mgcp_reload_lock
Definition: chan_mgcp.c:419
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
#define ast_mutex_destroy(a)
Definition: lock.h:154
static int mgcpsock_read(int *id, int fd, short events, void *ignore)
Definition: chan_mgcp.c:3625
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void dump_cmd_queues ( struct mgcp_endpoint p,
struct mgcp_subchannel sub 
)
static

dump_cmd_queues: (SC:) cleanup pending commands

Definition at line 2695 of file chan_mgcp.c.

References ast_free, ast_mutex_lock, ast_mutex_unlock, mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_request::next, mgcp_subchannel::next, mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, and mgcp_endpoint::sub.

Referenced by destroy_endpoint(), handle_request(), handle_response(), and unalloc_sub().

2696 {
2697  struct mgcp_request *t, *q;
2698 
2699  if (p) {
2701  for (q = p->rqnt_queue; q; t = q->next, ast_free(q), q=t);
2702  p->rqnt_queue = NULL;
2704 
2706  for (q = p->cmd_queue; q; t = q->next, ast_free(q), q=t);
2707  p->cmd_queue = NULL;
2709 
2711  for (q = p->sub->cx_queue; q; t = q->next, ast_free(q), q=t);
2712  p->sub->cx_queue = NULL;
2714 
2716  for (q = p->sub->next->cx_queue; q; t = q->next, ast_free(q), q=t);
2717  p->sub->next->cx_queue = NULL;
2719  } else if (sub) {
2721  for (q = sub->cx_queue; q; t = q->next, ast_free(q), q=t);
2722  sub->cx_queue = NULL;
2724  }
2725 }
struct mgcp_request * cx_queue
Definition: chan_mgcp.c:308
ast_mutex_t cmd_queue_lock
Definition: chan_mgcp.c:378
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
struct mgcp_request * next
Definition: chan_mgcp.c:259
#define ast_mutex_lock(a)
Definition: lock.h:155
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
struct mgcp_request * rqnt_queue
Definition: chan_mgcp.c:375
ast_mutex_t cx_queue_lock
Definition: chan_mgcp.c:309
#define ast_free(a)
Definition: astmm.h:97
ast_mutex_t rqnt_queue_lock
Definition: chan_mgcp.c:376
struct mgcp_request * cmd_queue
Definition: chan_mgcp.c:377
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void dump_queue ( struct mgcp_gateway gw,
struct mgcp_endpoint p 
)
static

Definition at line 581 of file chan_mgcp.c.

References ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_NOTICE, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_message::owner_ep, and mgcp_message::seqno.

Referenced by destroy_endpoint(), destroy_gateway(), and handle_request().

582 {
583  struct mgcp_message *cur, *q = NULL, *w, *prev;
584 
586  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
587  if (!p || cur->owner_ep == p) {
588  if (prev) {
589  prev->next = cur->next;
590  } else {
591  gw->msgs = cur->next;
592  }
593 
594  ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n",
595  gw->name, cur->seqno);
596 
597  w = cur;
598  if (q) {
599  w->next = q;
600  } else {
601  w->next = NULL;
602  }
603  q = w;
604  }
605  }
607 
608  while (q) {
609  cur = q;
610  q = q->next;
611  ast_free(cur);
612  }
613 }
struct mgcp_endpoint * owner_ep
Definition: chan_mgcp.c:264
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
mgcp_message: MGCP message for queuing up
Definition: chan_mgcp.c:263
struct mgcp_message * msgs
Definition: chan_mgcp.c:410
char name[80]
Definition: chan_mgcp.c:394
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ast_free(a)
Definition: astmm.h:97
struct mgcp_message * next
Definition: chan_mgcp.c:270
unsigned int seqno
Definition: chan_mgcp.c:268
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int find_and_retrans ( struct mgcp_subchannel sub,
struct mgcp_request req 
)
static

Definition at line 3595 of file chan_mgcp.c.

References ast_free, mgcp_request::identifier, mgcp_response::next, mgcp_subchannel::parent, mgcp_endpoint::parent, resend_response(), RESPONSE_TIMEOUT, and mgcp_gateway::responses.

Referenced by mgcpsock_read().

3596 {
3597  int seqno=0;
3598  time_t now;
3599  struct mgcp_response *prev = NULL, *cur, *next, *answer = NULL;
3600  time(&now);
3601  if (sscanf(req->identifier, "%30d", &seqno) != 1) {
3602  seqno = 0;
3603  }
3604  for (cur = sub->parent->parent->responses, next = cur ? cur->next : NULL; cur; cur = next, next = cur ? cur->next : NULL) {
3605  if (now - cur->whensent > RESPONSE_TIMEOUT) {
3606  /* Delete this entry */
3607  if (prev)
3608  prev->next = next;
3609  else
3610  sub->parent->parent->responses = next;
3611  ast_free(cur);
3612  } else {
3613  if (seqno == cur->seqno)
3614  answer = cur;
3615  prev = cur;
3616  }
3617  }
3618  if (answer) {
3619  resend_response(sub, answer);
3620  return 1;
3621  }
3622  return 0;
3623 }
char * identifier
Definition: chan_mgcp.c:249
struct mgcp_response * responses
Definition: chan_mgcp.c:415
static int resend_response(struct mgcp_subchannel *sub, struct mgcp_response *resp)
Definition: chan_mgcp.c:558
struct mgcp_response * next
Definition: chan_mgcp.c:280
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
#define RESPONSE_TIMEOUT
Definition: chan_mgcp.c:274
#define ast_free(a)
Definition: astmm.h:97
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
unsigned int seqno
Definition: chan_mgcp.c:268
static struct mgcp_request* find_command ( struct mgcp_endpoint p,
struct mgcp_subchannel sub,
struct mgcp_request **  queue,
ast_mutex_t l,
int  ident 
)
static

find_command: (SC:) remove command transaction from queue

Definition at line 2729 of file chan_mgcp.c.

References mgcp_gateway::addr, ast_debug, ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, mgcp_postrequest(), mgcp_request::next, and mgcp_endpoint::parent.

Referenced by handle_response().

2731 {
2732  struct mgcp_request *prev, *req;
2733 
2734  ast_mutex_lock(l);
2735  for (prev = NULL, req = *queue; req; prev = req, req = req->next) {
2736  if (req->trid == ident) {
2737  /* remove from queue */
2738  if (!prev)
2739  *queue = req->next;
2740  else
2741  prev->next = req->next;
2742 
2743  /* send next pending command */
2744  if (*queue) {
2745  ast_debug(1, "Posting Queued Request:\n%s to %s:%d\n", (*queue)->data,
2746  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
2747 
2748  mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid);
2749  }
2750  break;
2751  }
2752  }
2753  ast_mutex_unlock(l);
2754  return req;
2755 }
struct mgcp_request * next
Definition: chan_mgcp.c:259
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno)
Definition: chan_mgcp.c:710
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct sockaddr_in addr
Definition: chan_mgcp.c:396
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct mgcp_gateway* find_realtime_gw ( char *  name,
char *  at,
struct sockaddr_in *  sin 
)
static
Note
This is a fairly odd way of instantiating lines. Instead of each line created by virtue of being in the database (and loaded via ast_load_realtime_multientry), this code forces a specific order with a "lines" entry in the "mgcpgw" record. This has benefits, because as with chan_dahdi, values are inherited across definitions. The downside is that it's not as clear what the values will be simply by looking at a single row in the database, and it's probable that the sanest configuration should have the first column in the "mgcpep" table be "clearvars", with a static value of "all", if any variables are set at all. It may be worth making this assumption explicit in the code in the future, and then just using ast_load_realtime_multientry for the "mgcpep" records.

Definition at line 1667 of file chan_mgcp.c.

References args, AST_APP_ARG, ast_check_realtime(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_load_realtime(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_variables_destroy(), build_gateway(), mgcp_gateway::endpoints, gateways, ast_variable::name, mgcp_endpoint::needaudit, ast_variable::next, mgcp_endpoint::next, mgcp_gateway::next, mgcp_gateway::realtime, transmit_audit_endpoint(), and ast_variable::value.

Referenced by find_subchannel_and_lock().

1668 {
1669  struct mgcp_gateway *g = NULL;
1670  struct ast_variable *mgcpgwconfig = NULL;
1671  struct ast_variable *gwv, *epname = NULL;
1672  struct mgcp_endpoint *e;
1673  char lines[256];
1674  int i, j;
1675 
1676  ast_debug(1, "*** find Realtime MGCPGW\n");
1677 
1678  if (!(i = ast_check_realtime("mgcpgw")) || !(j = ast_check_realtime("mgcpep"))) {
1679  return NULL;
1680  }
1681 
1682  if (ast_strlen_zero(at)) {
1683  ast_debug(1, "null gw name\n");
1684  return NULL;
1685  }
1686 
1687  if (!(mgcpgwconfig = ast_load_realtime("mgcpgw", "name", at, NULL))) {
1688  return NULL;
1689  }
1690 
1691  /*!
1692  * \note This is a fairly odd way of instantiating lines. Instead of each
1693  * line created by virtue of being in the database (and loaded via
1694  * ast_load_realtime_multientry), this code forces a specific order with a
1695  * "lines" entry in the "mgcpgw" record. This has benefits, because as with
1696  * chan_dahdi, values are inherited across definitions. The downside is
1697  * that it's not as clear what the values will be simply by looking at a
1698  * single row in the database, and it's probable that the sanest configuration
1699  * should have the first column in the "mgcpep" table be "clearvars", with a
1700  * static value of "all", if any variables are set at all. It may be worth
1701  * making this assumption explicit in the code in the future, and then just
1702  * using ast_load_realtime_multientry for the "mgcpep" records.
1703  */
1704  lines[0] = '\0';
1705  for (gwv = mgcpgwconfig; gwv; gwv = gwv->next) {
1706  if (!strcasecmp(gwv->name, "lines")) {
1707  ast_copy_string(lines, gwv->value, sizeof(lines));
1708  break;
1709  }
1710  }
1711  /* Position gwv at the end of the list */
1712  for (gwv = gwv && gwv->next ? gwv : mgcpgwconfig; gwv->next; gwv = gwv->next);
1713 
1714  if (!ast_strlen_zero(lines)) {
1716  AST_APP_ARG(line)[100];
1717  );
1718  AST_STANDARD_APP_ARGS(args, lines);
1719  for (i = 0; i < args.argc; i++) {
1720  gwv->next = ast_load_realtime("mgcpep", "name", at, "line", args.line[i], NULL);
1721 
1722  /* Remove "line" AND position gwv at the end of the list. */
1723  for (epname = NULL; gwv->next; gwv = gwv->next) {
1724  if (!strcasecmp(gwv->next->name, "line")) {
1725  /* Remove it from the list */
1726  epname = gwv->next;
1727  gwv->next = gwv->next->next;
1728  }
1729  }
1730  /* Since "line" instantiates the configuration, we have to move it to the end. */
1731  if (epname) {
1732  gwv->next = epname;
1733  epname->next = NULL;
1734  gwv = gwv->next;
1735  }
1736  }
1737  }
1738  for (gwv = mgcpgwconfig; gwv; gwv = gwv->next) {
1739  ast_debug(1, "MGCP Realtime var: %s => %s\n", gwv->name, gwv->value);
1740  }
1741 
1742  if (mgcpgwconfig) {
1743  g = build_gateway(at, mgcpgwconfig);
1744  ast_variables_destroy(mgcpgwconfig);
1745  }
1746  if (g) {
1747  g->next = gateways;
1748  g->realtime = 1;
1749  gateways = g;
1750  for (e = g->endpoints; e; e = e->next) {
1752  e->needaudit = 0;
1753  }
1754  }
1755  return g;
1756 }
static struct mgcp_gateway * build_gateway(char *cat, struct ast_variable *v)
build_gateway: parse mgcp.conf and create gateway/endpoint structures
Definition: chan_mgcp.c:3972
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static int transmit_audit_endpoint(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:2637
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
const char * name
Definition: config.h:77
static struct @350 args
static struct mgcp_gateway * gateways
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
struct ast_variable * next
Definition: config.h:82
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
static struct mgcp_subchannel* find_subchannel_and_lock ( char *  name,
int  msgid,
struct sockaddr_in *  sin 
)
static

Definition at line 1758 of file chan_mgcp.c.

References __ourip, mgcp_gateway::addr, ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_ouraddrfor(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_verb, mgcp_gateway::defaddr, mgcp_gateway::dynamic, mgcp_gateway::endpoints, find_realtime_gw(), gatelock, gateways, mgcp_subchannel::id, mgcp_subchannel::lock, LOG_NOTICE, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::next, mgcp_gateway::next, mgcp_gateway::ourip, and mgcp_endpoint::sub.

Referenced by mgcp_request(), and mgcpsock_read().

1759 {
1760  struct mgcp_endpoint *p = NULL;
1761  struct mgcp_subchannel *sub = NULL;
1762  struct mgcp_gateway *g;
1763  char tmp[256] = "";
1764  char *at = NULL, *c;
1765  int found = 0;
1766  if (name) {
1767  ast_copy_string(tmp, name, sizeof(tmp));
1768  at = strchr(tmp, '@');
1769  if (!at) {
1770  ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name);
1771  return NULL;
1772  }
1773  *at++ = '\0';
1774  }
1776  if (at && (at[0] == '[')) {
1777  at++;
1778  c = strrchr(at, ']');
1779  if (c) {
1780  *c = '\0';
1781  }
1782  }
1783  for (g = gateways ? gateways : find_realtime_gw(name, at, sin); g; g = g->next ? g->next : find_realtime_gw(name, at, sin)) {
1784  if ((!name || !strcasecmp(g->name, at)) &&
1785  (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) {
1786  /* Found the gateway. If it's dynamic, save it's address -- now for the endpoint */
1787  if (sin && g->dynamic && name) {
1788  if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1789  (g->addr.sin_port != sin->sin_port)) {
1790  memcpy(&g->addr, sin, sizeof(g->addr));
1791  {
1792  struct ast_sockaddr tmp1, tmp2;
1793  struct sockaddr_in tmp3 = {0,};
1794 
1795  tmp3.sin_addr = g->ourip;
1796  ast_sockaddr_from_sin(&tmp1, &g->addr);
1797  ast_sockaddr_from_sin(&tmp2, &tmp3);
1798  if (ast_ouraddrfor(&tmp1, &tmp2)) {
1799  memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
1800  }
1801  ast_sockaddr_to_sin(&tmp2, &tmp3);
1802  g->ourip = tmp3.sin_addr;
1803  }
1804  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));
1805  }
1806  /* not dynamic, check if the name matches */
1807  } else if (name) {
1808  if (strcasecmp(g->name, at)) {
1809  g = g->next;
1810  continue;
1811  }
1812  /* not dynamic, no name, check if the addr matches */
1813  } else if (!name && sin) {
1814  if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1815  (g->addr.sin_port != sin->sin_port)) {
1816  if(!g->next)
1817  g = find_realtime_gw(name, at, sin);
1818  else
1819  g = g->next;
1820  continue;
1821  }
1822  } else {
1823  continue;
1824  }
1825  for (p = g->endpoints; p; p = p->next) {
1826  ast_debug(1, "Searching on %s@%s for subchannel\n", p->name, g->name);
1827  if (msgid) {
1828  sub = p->sub;
1829  found = 1;
1830  break;
1831  } else if (name && !strcasecmp(p->name, tmp)) {
1832  ast_debug(1, "Coundn't determine subchannel, assuming current master %s@%s-%d\n",
1833  p->name, g->name, p->sub->id);
1834  sub = p->sub;
1835  found = 1;
1836  break;
1837  }
1838  }
1839  if (sub && found) {
1840  ast_mutex_lock(&sub->lock);
1841  break;
1842  }
1843  }
1844  }
1846  if (!sub) {
1847  if (name) {
1848  if (g) {
1849  ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp, at);
1850  } else {
1851  ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
1852  }
1853  }
1854  }
1855  return sub;
1856 }
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
Socket address structure.
Definition: netsock2.h:63
#define ast_verb(level,...)
Definition: logger.h:243
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:705
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
struct in_addr ourip
Definition: chan_mgcp.c:398
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
struct sockaddr_in defaddr
Definition: chan_mgcp.c:397
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
char name[80]
Definition: chan_mgcp.c:394
struct sockaddr_in addr
Definition: chan_mgcp.c:396
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static const char name[]
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
static struct mgcp_gateway * gateways
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static struct mgcp_gateway * find_realtime_gw(char *name, char *at, struct sockaddr_in *sin)
Definition: chan_mgcp.c:1667
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
static struct in_addr __ourip
Definition: chan_mgcp.c:232
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* get_csv ( char *  c,
int *  len,
char **  next 
)
static

get_csv: (SC:) get comma separated value

Definition at line 1643 of file chan_mgcp.c.

Referenced by handle_response().

1644 {
1645  char *s;
1646 
1647  *next = NULL, *len = 0;
1648  if (!c) return NULL;
1649 
1650  while (*c && (*c < 33 || *c == ',')) {
1651  c++;
1652  }
1653 
1654  s = c;
1655  while (*c && (*c >= 33 && *c != ',')) {
1656  c++, (*len)++;
1657  }
1658  *next = c;
1659 
1660  if (*len == 0) {
1661  s = NULL, *next = NULL;
1662  }
1663 
1664  return s;
1665 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char* get_header ( struct mgcp_request req,
char *  name 
)
static

Definition at line 1636 of file chan_mgcp.c.

References __get_header().

Referenced by handle_request(), and handle_response().

1637 {
1638  int start = 0;
1639  return __get_header(req, name, &start, "");
1640 }
static const char name[]
static char * __get_header(struct mgcp_request *req, char *name, int *start, char *def)
Definition: chan_mgcp.c:1616
static char* get_sdp ( struct mgcp_request req,
char *  name 
)
static

Definition at line 1587 of file chan_mgcp.c.

References get_sdp_by_line(), len(), mgcp_request::line, and mgcp_request::lines.

Referenced by process_sdp().

1588 {
1589  int x;
1590  int len = strlen(name);
1591  char *r;
1592 
1593  for (x = 0; x < req->lines; x++) {
1594  r = get_sdp_by_line(req->line[x], name, len);
1595  if (r[0] != '\0') return r;
1596  }
1597  return "";
1598 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * get_sdp_by_line(char *line, char *name, int nameLen)
Definition: chan_mgcp.c:1577
static const char name[]
char * line[MGCP_MAX_LINES]
Definition: chan_mgcp.c:255
static char* get_sdp_by_line ( char *  line,
char *  name,
int  nameLen 
)
static

Definition at line 1577 of file chan_mgcp.c.

Referenced by get_sdp(), and get_sdp_iterate().

1578 {
1579  if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
1580  char *r = line + nameLen + 1;
1581  while (*r && (*r < 33)) ++r;
1582  return r;
1583  }
1584  return "";
1585 }
static const char name[]
static char* get_sdp_iterate ( int *  iterator,
struct mgcp_request req,
char *  name 
)
static

Definition at line 1605 of file chan_mgcp.c.

References get_sdp_by_line(), len(), and mgcp_request::line.

Referenced by process_sdp().

1606 {
1607  int len = strlen(name);
1608  char *r;
1609  while (*iterator < req->lines) {
1610  r = get_sdp_by_line(req->line[(*iterator)++], name, len);
1611  if (r[0] != '\0') return r;
1612  }
1613  return "";
1614 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * get_sdp_by_line(char *line, char *name, int nameLen)
Definition: chan_mgcp.c:1577
static const char name[]
char * line[MGCP_MAX_LINES]
Definition: chan_mgcp.c:255
static void handle_hd_hf ( struct mgcp_subchannel sub,
char *  ev 
)
static

Definition at line 3268 of file chan_mgcp.c.

References ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_UNHOLD, ast_hangup(), ast_log(), ast_pthread_create_detached, ast_queue_control(), AST_STATE_DOWN, AST_STATE_RING, mgcp_subchannel::cxmode, errno, has_voicemail(), mgcp_endpoint::hookstate, mgcp_endpoint::immediate, LOG_WARNING, MGCP_CX_SENDRECV, mgcp_new(), MGCP_OFFHOOK, mgcp_queue_control(), mgcp_ss(), mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::ncs, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_subchannel::rtp, start_rtp(), transmit_modify_request(), and transmit_notify_request().

Referenced by handle_request().

3269 {
3270  struct mgcp_endpoint *p = sub->parent;
3271  struct ast_channel *c;
3272  pthread_t t;
3273 
3274  /* Off hook / answer */
3275  if (sub->outgoing) {
3276  /* Answered */
3277  if (sub->owner) {
3278  if (ast_bridged_channel(sub->owner))
3280  sub->cxmode = MGCP_CX_SENDRECV;
3281  if (!sub->rtp) {
3282  start_rtp(sub);
3283  } else {
3285  }
3286  /*transmit_notify_request(sub, "aw");*/
3287  transmit_notify_request(sub, "");
3289  }
3290  } else {
3291  /* Start switch */
3292  /*sub->cxmode = MGCP_CX_SENDRECV;*/
3293  if (!sub->owner) {
3294  if (!sub->rtp) {
3295  start_rtp(sub);
3296  } else {
3298  }
3299  if (p->immediate) {
3300  /* The channel is immediately up. Start right away */
3301 #ifdef DLINK_BUGGY_FIRMWARE
3302  transmit_notify_request(sub, "rt");
3303 #else
3304  transmit_notify_request(sub, p->ncs ? "L/rt" : "G/rt");
3305 #endif
3306  c = mgcp_new(sub, AST_STATE_RING, NULL);
3307  if (!c) {
3308  ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
3309  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3310  ast_hangup(c);
3311  }
3312  } else {
3313  if (has_voicemail(p)) {
3314  transmit_notify_request(sub, "L/sl");
3315  } else {
3316  transmit_notify_request(sub, "L/dl");
3317  }
3318  c = mgcp_new(sub, AST_STATE_DOWN, NULL);
3319  if (c) {
3320  if (ast_pthread_create_detached(&t, NULL, mgcp_ss, c)) {
3321  ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
3322  ast_hangup(c);
3323  }
3324  } else {
3325  ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
3326  }
3327  }
3328  } else {
3329  if (p->hookstate == MGCP_OFFHOOK) {
3330  ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name);
3331  } else {
3332  ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name);
3333  ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?\n");
3334  }
3335  if (ast_bridged_channel(sub->owner))
3337  sub->cxmode = MGCP_CX_SENDRECV;
3338  if (!sub->rtp) {
3339  start_rtp(sub);
3340  } else {
3342  }
3343  /*transmit_notify_request(sub, "aw");*/
3344  transmit_notify_request(sub, "");
3345  /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/
3346  }
3347  }
3348 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
static void start_rtp(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2928
Main Channel structure associated with a channel.
Definition: channel.h:742
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:422
#define LOG_WARNING
Definition: logger.h:144
static struct ast_channel * mgcp_new(struct mgcp_subchannel *sub, int state, const char *linkedid)
Definition: chan_mgcp.c:1494
static void * mgcp_ss(void *data)
Definition: chan_mgcp.c:2961
char name[80]
Definition: chan_mgcp.c:327
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
#define MGCP_CX_SENDRECV
Definition: chan_mgcp.c:125
struct ast_channel * owner
Definition: chan_mgcp.c:299
char name[80]
Definition: chan_mgcp.c:394
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
static int has_voicemail(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:492
static void mgcp_queue_control(struct mgcp_subchannel *sub, int control)
Definition: chan_mgcp.c:649
static int transmit_modify_request(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2537
static char* handle_mgcp_audit_endpoint ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1081 of file chan_mgcp.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_strdupa, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, mgcp_gateway::endpoints, ast_cli_args::fd, gatelock, gateways, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::next, mgcp_gateway::next, transmit_audit_endpoint(), and ast_cli_entry::usage.

1082 {
1083  struct mgcp_gateway *mg;
1084  struct mgcp_endpoint *me;
1085  int found = 0;
1086  char *ename,*gname, *c;
1087 
1088  switch (cmd) {
1089  case CLI_INIT:
1090  e->command = "mgcp audit endpoint";
1091  e->usage =
1092  "Usage: mgcp audit endpoint <endpointid>\n"
1093  " Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n"
1094  " mgcp debug MUST be on to see the results of this command.\n";
1095  return NULL;
1096  case CLI_GENERATE:
1097  return NULL;
1098  }
1099 
1100  if (!mgcpdebug) {
1101  return CLI_SHOWUSAGE;
1102  }
1103  if (a->argc != 4)
1104  return CLI_SHOWUSAGE;
1105  /* split the name into parts by null */
1106  ename = ast_strdupa(a->argv[3]);
1107  for (gname = ename; *gname; gname++) {
1108  if (*gname == '@') {
1109  *gname = 0;
1110  gname++;
1111  break;
1112  }
1113  }
1114  if (gname[0] == '[') {
1115  gname++;
1116  }
1117  if ((c = strrchr(gname, ']'))) {
1118  *c = '\0';
1119  }
1121  for (mg = gateways; mg; mg = mg->next) {
1122  if (!strcasecmp(mg->name, gname)) {
1123  for (me = mg->endpoints; me; me = me->next) {
1124  if (!strcasecmp(me->name, ename)) {
1125  found = 1;
1127  break;
1128  }
1129  }
1130  if (found) {
1131  break;
1132  }
1133  }
1134  }
1135  if (!found) {
1136  ast_cli(a->fd, " << Could not find endpoint >> ");
1137  }
1139  return CLI_SUCCESS;
1140 }
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
const int argc
Definition: cli.h:154
Definition: cli.h:146
static int mgcpdebug
Definition: chan_mgcp.c:235
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int transmit_audit_endpoint(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:2637
char name[80]
Definition: chan_mgcp.c:327
const int fd
Definition: cli.h:153
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
char name[80]
Definition: chan_mgcp.c:394
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
static struct mgcp_gateway * gateways
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_mgcp_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1142 of file chan_mgcp.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

1143 {
1144  switch (cmd) {
1145  case CLI_INIT:
1146  e->command = "mgcp set debug {on|off}";
1147  e->usage =
1148  "Usage: mgcp set debug {on|off}\n"
1149  " Enables/Disables dumping of MGCP packets for debugging purposes\n";
1150  return NULL;
1151  case CLI_GENERATE:
1152  return NULL;
1153  }
1154 
1155  if (a->argc != e->args)
1156  return CLI_SHOWUSAGE;
1157 
1158  if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
1159  mgcpdebug = 1;
1160  ast_cli(a->fd, "MGCP Debugging Enabled\n");
1161  } else if (!strncasecmp(a->argv[3], "off", 3)) {
1162  mgcpdebug = 0;
1163  ast_cli(a->fd, "MGCP Debugging Disabled\n");
1164  } else {
1165  return CLI_SHOWUSAGE;
1166  }
1167  return CLI_SUCCESS;
1168 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static int mgcpdebug
Definition: chan_mgcp.c:235
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_mgcp_show_endpoints ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1039 of file chan_mgcp.c.

References mgcp_gateway::addr, ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, mgcp_endpoint::chanvars, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, mgcp_endpoint::context, mgcp_gateway::defaddr, mgcp_gateway::dynamic, mgcp_gateway::endpoints, ast_cli_args::fd, gatelock, gateways, ast_variable::name, mgcp_endpoint::name, mgcp_gateway::name, ast_variable::next, mgcp_endpoint::next, mgcp_gateway::next, mgcp_subchannel::owner, mgcp_gateway::realtime, mgcp_endpoint::sub, ast_cli_entry::usage, and ast_variable::value.

1040 {
1041  struct mgcp_gateway *mg;
1042  struct mgcp_endpoint *me;
1043  int hasendpoints = 0;
1044  struct ast_variable * v = NULL;
1045 
1046  switch (cmd) {
1047  case CLI_INIT:
1048  e->command = "mgcp show endpoints";
1049  e->usage =
1050  "Usage: mgcp show endpoints\n"
1051  " Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";
1052  return NULL;
1053  case CLI_GENERATE:
1054  return NULL;
1055  }
1056 
1057  if (a->argc != 3) {
1058  return CLI_SHOWUSAGE;
1059  }
1061  for (mg = gateways; mg; mg = mg->next) {
1062  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");
1063  for (me = mg->endpoints; me; me = me->next) {
1064  ast_cli(a->fd, " -- '%s@%s in '%s' is %s\n", me->name, mg->name, me->context, me->sub->owner ? "active" : "idle");
1065  if (me->chanvars) {
1066  ast_cli(a->fd, " Variables:\n");
1067  for (v = me->chanvars ; v ; v = v->next) {
1068  ast_cli(a->fd, " %s = '%s'\n", v->name, v->value);
1069  }
1070  }
1071  hasendpoints = 1;
1072  }
1073  if (!hasendpoints) {
1074  ast_cli(a->fd, " << No Endpoints Defined >> ");
1075  }
1076  }
1078  return CLI_SUCCESS;
1079 }
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
const int argc
Definition: cli.h:154
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char name[80]
Definition: chan_mgcp.c:327
const char * value
Definition: config.h:79
const int fd
Definition: cli.h:153
struct sockaddr_in defaddr
Definition: chan_mgcp.c:397
struct ast_variable * chanvars
Definition: chan_mgcp.c:387
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
struct ast_channel * owner
Definition: chan_mgcp.c:299
char name[80]
Definition: chan_mgcp.c:394
const char * name
Definition: config.h:77
char context[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:331
#define CLI_SHOWUSAGE
Definition: cli.h:44
struct sockaddr_in addr
Definition: chan_mgcp.c:396
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
char * command
Definition: cli.h:180
static struct mgcp_gateway * gateways
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct ast_variable * next
Definition: config.h:82
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int handle_request ( struct mgcp_subchannel sub,
struct mgcp_request req,
struct sockaddr_in *  sin 
)
static

Definition at line 3350 of file chan_mgcp.c.

References ast_channel::_state, mgcp_subchannel::alreadygone, ast_bridged_channel(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_DTMF, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_queue_control(), AST_STATE_DOWN, AST_STATE_UP, ast_verb, attempt_transfer(), mgcp_endpoint::callwaiting, mgcp_endpoint::curtone, mgcp_subchannel::cxmode, mgcp_endpoint::dtmf_buf, dump_cmd_queues(), dump_queue(), mgcp_gateway::endpoints, ast_frame::frametype, get_header(), handle_hd_hf(), has_voicemail(), mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, mgcp_endpoint::hookstate, mgcp_subchannel::id, ast_frame_subclass::integer, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, MGCP_CX_CONF, MGCP_CX_MUTE, MGCP_CX_RECVONLY, MGCP_CX_SENDRECV, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_queue_frame(), mgcp_queue_hangup(), mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::ncs, mgcp_subchannel::next, mgcp_endpoint::next, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_subchannel::rtp, ast_frame::src, mgcp_endpoint::sub, ast_frame::subclass, mgcp_endpoint::threewaycalling, mgcp_endpoint::transfer, transmit_audit_endpoint(), transmit_connection_del(), transmit_modify_request(), transmit_notify_request(), transmit_response(), mgcp_request::verb, and mgcp_gateway::wcardep.

Referenced by mgcpsock_read().

3351 {
3352  char *ev, *s;
3353  struct ast_frame f = { 0, };
3354  struct mgcp_endpoint *p = sub->parent;
3355  struct mgcp_gateway *g = NULL;
3356  int res;
3357 
3358  ast_debug(1, "Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
3359  /* Clear out potential response */
3360  if (!strcasecmp(req->verb, "RSIP")) {
3361  /* Test if this RSIP request is just a keepalive */
3362  if (!strcasecmp( get_header(req, "RM"), "X-keepalive")) {
3363  ast_verb(3, "Received keepalive request from %s@%s\n", p->name, p->parent->name);
3364  transmit_response(sub, "200", req, "OK");
3365  } else {
3366  dump_queue(p->parent, p);
3367  dump_cmd_queues(p, NULL);
3368 
3369  if ((strcmp(p->name, p->parent->wcardep) != 0)) {
3370  ast_verb(3, "Resetting interface %s@%s\n", p->name, p->parent->name);
3371  }
3372  /* For RSIP on wildcard we reset all endpoints */
3373  if (!strcmp(p->name, p->parent->wcardep)) {
3374  /* Reset all endpoints */
3375  struct mgcp_endpoint *tmp_ep;
3376 
3377  g = p->parent;
3378  for (tmp_ep = g->endpoints; tmp_ep; tmp_ep = tmp_ep->next) {
3379  /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/
3380  if (strcmp(tmp_ep->name, g->wcardep) != 0) {
3381  struct mgcp_subchannel *tmp_sub, *first_sub;
3382  ast_verb(3, "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name);
3383 
3384  first_sub = tmp_ep->sub;
3385  tmp_sub = tmp_ep->sub;
3386  while (tmp_sub) {
3387  mgcp_queue_hangup(tmp_sub);
3388  tmp_sub = tmp_sub->next;
3389  if (tmp_sub == first_sub)
3390  break;
3391  }
3392  }
3393  }
3394  } else if (sub->owner) {
3395  mgcp_queue_hangup(sub);
3396  }
3397  transmit_response(sub, "200", req, "OK");
3398  /* We don't send NTFY or AUEP to wildcard ep */
3399  if (strcmp(p->name, p->parent->wcardep) != 0) {
3400  transmit_notify_request(sub, "");
3401  /* Audit endpoint.
3402  Idea is to prevent lost lines due to race conditions
3403  */
3405  }
3406  }
3407  } else if (!strcasecmp(req->verb, "NTFY")) {
3408  /* Acknowledge and be sure we keep looking for the same things */
3409  transmit_response(sub, "200", req, "OK");
3410  /* Notified of an event */
3411  ev = get_header(req, "O");
3412  s = strchr(ev, '/');
3413  if (s) ev = s + 1;
3414  ast_debug(1, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev);
3415  /* Keep looking for events unless this was a hangup */
3416  if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) {
3418  }
3419  if (!strcasecmp(ev, "hd")) {
3420  p->hookstate = MGCP_OFFHOOK;
3421  sub->cxmode = MGCP_CX_SENDRECV;
3422 
3423  if (p) {
3424  /* When the endpoint have a Off hook transition we allways
3425  starts without any previous dtmfs */
3426  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3427  }
3428 
3429  handle_hd_hf(sub, ev);
3430  } else if (!strcasecmp(ev, "hf")) {
3431  /* We can assume we are offhook if we received a hookflash */
3432  /* First let's just do call wait and ignore threeway */
3433  /* We're currently in charge */
3434  if (p->hookstate != MGCP_OFFHOOK) {
3435  /* Cisco c7940 sends hf even if the phone is onhook */
3436  /* Thanks to point on IRC for pointing this out */
3437  return -1;
3438  }
3439  /* do not let * conference two down channels */
3440  if (sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner)
3441  return -1;
3442 
3443  if (p->callwaiting || p->transfer || p->threewaycalling) {
3444  ast_verb(3, "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
3445  p->sub = p->sub->next;
3446 
3447  /* transfer control to our next subchannel */
3448  if (!sub->next->owner) {
3449  /* plave the first call on hold and start up a new call */
3450  sub->cxmode = MGCP_CX_MUTE;
3451  ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
3453  if (sub->owner && ast_bridged_channel(sub->owner))
3455  sub->next->cxmode = MGCP_CX_RECVONLY;
3456  handle_hd_hf(sub->next, ev);
3457  } else if (sub->owner && sub->next->owner) {
3458  /* We've got two active calls lets decide whether or not to conference or just flip flop */
3459  if ((!sub->outgoing) && (!sub->next->outgoing)) {
3460  /* We made both calls lets conferenct */
3461  ast_verb(3, "MGCP Conferencing %d and %d on %s@%s\n",
3462  sub->id, sub->next->id, p->name, p->parent->name);
3463  sub->cxmode = MGCP_CX_CONF;
3464  sub->next->cxmode = MGCP_CX_CONF;
3465  if (ast_bridged_channel(sub->next->owner))
3469  } else {
3470  /* Let's flipflop between calls */
3471  /* XXX Need to check for state up ??? */
3472  /* XXX Need a way to indicate the current call, or maybe the call that's waiting */
3473  ast_verb(3, "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n",
3474  sub->id, sub->next->id, p->name, p->parent->name);
3475  sub->cxmode = MGCP_CX_MUTE;
3476  ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
3478  if (ast_bridged_channel(sub->owner))
3480 
3481  if (ast_bridged_channel(sub->next->owner))
3483 
3484  handle_hd_hf(sub->next, ev);
3485  }
3486  } else {
3487  /* We've most likely lost one of our calls find an active call and bring it up */
3488  if (sub->owner) {
3489  p->sub = sub;
3490  } else if (sub->next->owner) {
3491  p->sub = sub->next;
3492  } else {
3493  /* We seem to have lost both our calls */
3494  /* XXX - What do we do now? */
3495  return -1;
3496  }
3497  if (ast_bridged_channel(p->sub->owner))
3499  p->sub->cxmode = MGCP_CX_SENDRECV;
3501  }
3502  } else {
3503  ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n",
3504  p->name, p->parent->name);
3505  }
3506  } else if (!strcasecmp(ev, "hu")) {
3507  p->hookstate = MGCP_ONHOOK;
3508  sub->cxmode = MGCP_CX_RECVONLY;
3509  ast_debug(1, "MGCP %s@%s Went on hook\n", p->name, p->parent->name);
3510  /* Do we need to send MDCX before a DLCX ?
3511  if (sub->rtp) {
3512  transmit_modify_request(sub);
3513  }
3514  */
3515  if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) {
3516  /* We're allowed to transfer, we have two avtive calls and */
3517  /* we made at least one of the calls. Let's try and transfer */
3518  ast_mutex_lock(&p->sub->next->lock);
3519  res = attempt_transfer(p);
3520  if (res < 0) {
3521  if (p->sub->next->owner) {
3522  sub->next->alreadygone = 1;
3523  mgcp_queue_hangup(sub->next);
3524  }
3525  } else if (res) {
3526  ast_log(LOG_WARNING, "Transfer attempt failed\n");
3527  ast_mutex_unlock(&p->sub->next->lock);
3528  return -1;
3529  }
3530  ast_mutex_unlock(&p->sub->next->lock);
3531  } else {
3532  /* Hangup the current call */
3533  /* If there is another active call, mgcp_hangup will ring the phone with the other call */
3534  if (sub->owner) {
3535  sub->alreadygone = 1;
3536  mgcp_queue_hangup(sub);
3537  } else {
3538  ast_verb(3, "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n",
3539  p->name, p->parent->name, sub->id);
3540  /* Instruct the other side to remove the connection since it apparently *
3541  * still thinks the channel is active. *
3542  * For Cisco IAD2421 /BAK/ */
3544  }
3545  }
3546  if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) {
3547  p->hidecallerid = 0;
3548  if (p->hascallwaiting && !p->callwaiting) {
3549  ast_verb(3, "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id);
3550  p->callwaiting = -1;
3551  }
3552  if (has_voicemail(p)) {
3553  ast_verb(3, "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name);
3554  transmit_notify_request(sub, "L/vmwi(+)");
3555  } else {
3556  ast_verb(3, "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name);
3557  transmit_notify_request(sub, "L/vmwi(-)");
3558  }
3559  }
3560  } else if ((strlen(ev) == 1) &&
3561  (((ev[0] >= '0') && (ev[0] <= '9')) ||
3562  ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
3563  (ev[0] == '*') || (ev[0] == '#'))) {
3564  if (sub && sub->owner && (sub->owner->_state >= AST_STATE_UP)) {
3566  f.subclass.integer = ev[0];
3567  f.src = "mgcp";
3568  /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */
3569  mgcp_queue_frame(sub, &f);
3570  ast_mutex_lock(&sub->next->lock);
3571  if (sub->next->owner)
3572  mgcp_queue_frame(sub->next, &f);
3573  ast_mutex_unlock(&sub->next->lock);
3574  if (strstr(p->curtone, (p->ncs ? "wt1" : "wt")) && (ev[0] == 'A')) {
3575  memset(p->curtone, 0, sizeof(p->curtone));
3576  }
3577  } else {
3578  p->dtmf_buf[strlen(p->dtmf_buf)] = ev[0];
3579  p->dtmf_buf[strlen(p->dtmf_buf)] = '\0';
3580  }
3581  } else if (!strcasecmp(ev, "T")) {
3582  /* Digit timeout -- unimportant */
3583  } else if (!strcasecmp(ev, "ping")) {
3584  /* ping -- unimportant */
3585  } else {
3586  ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
3587  }
3588  } else {
3589  ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(sin->sin_addr));
3590  transmit_response(sub, "510", req, "Unknown verb");
3591  }
3592  return 0;
3593 }
union ast_frame_subclass subclass
Definition: frame.h:146
static void mgcp_queue_frame(struct mgcp_subchannel *sub, struct ast_frame *f)
Definition: chan_mgcp.c:615
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
int hascallwaiting
Definition: chan_mgcp.c:346
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
int hidecallerid
Definition: chan_mgcp.c:355
static char * get_header(struct mgcp_request *req, char *name)
Definition: chan_mgcp.c:1636
#define LOG_WARNING
Definition: logger.h:144
char dtmf_buf[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:336
#define AST_FRAME_DTMF
Definition: frame.h:128
static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:632
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define MGCP_CX_MUTE
Definition: chan_mgcp.c:128
#define ast_mutex_lock(a)
Definition: lock.h:155
char curtone[80]
Definition: chan_mgcp.c:339
char * verb
Definition: chan_mgcp.c:248
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
Definition: chan_mgcp.c:2154
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
#define ast_verb(level,...)
Definition: logger.h:243
static int transmit_audit_endpoint(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:2637
static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
Definition: chan_mgcp.c:3268
char wcardep[30]
Definition: chan_mgcp.c:409
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
const char * src
Definition: frame.h:158
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
#define MGCP_CX_SENDRECV
Definition: chan_mgcp.c:125
struct ast_channel * owner
Definition: chan_mgcp.c:299
char name[80]
Definition: chan_mgcp.c:394
static int transmit_connection_del(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2651
int threewaycalling
Definition: chan_mgcp.c:348
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int attempt_transfer(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:3214
enum ast_channel_state _state
Definition: channel.h:839
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
static struct ast_format f[]
Definition: format_g726.c:181
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
dump_cmd_queues: (SC:) cleanup pending commands
Definition: chan_mgcp.c:2695
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
static int has_voicemail(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:492
Data structure associated with a single frame of data.
Definition: frame.h:142
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
enum ast_frame_type frametype
Definition: frame.h:144
#define MGCP_CX_CONF
Definition: chan_mgcp.c:126
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
static int transmit_modify_request(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2537
#define MGCP_CX_RECVONLY
Definition: chan_mgcp.c:124
static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
Definition: chan_mgcp.c:581
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void handle_response ( struct mgcp_endpoint p,
struct mgcp_subchannel sub,
int  result,
unsigned int  ident,
struct mgcp_request resp 
)
static

Definition at line 2758 of file chan_mgcp.c.

References ast_channel::_state, AST_CONTROL_RINGING, ast_copy_string(), ast_free, ast_log(), ast_queue_control(), AST_STATE_RINGING, ast_strlen_zero(), ast_verb, mgcp_request::cmd, mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_subchannel::cxident, dump_cmd_queues(), find_command(), get_csv(), get_header(), mgcp_endpoint::hookstate, mgcp_subchannel::id, len(), mgcp_request::lines, LOG_NOTICE, LOG_WARNING, MGCP_CMD_AUEP, MGCP_CMD_CRCX, MGCP_CMD_MDCX, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_queue_hangup(), mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::next, mgcp_subchannel::owner, mgcp_endpoint::parent, process_sdp(), mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, mgcp_endpoint::slowsequence, start_rtp(), mgcp_endpoint::sub, mgcp_subchannel::tmpdest, transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_with_sdp(), transmit_notify_request(), and transmit_response().

Referenced by mgcpsock_read(), and retrans_pkt().

2760 {
2761  char *c;
2762  struct mgcp_request *req;
2763  struct mgcp_gateway *gw = p->parent;
2764 
2765  if (result < 200) {
2766  /* provisional response */
2767  return;
2768  }
2769 
2770  if (p->slowsequence)
2771  req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2772  else if (sub)
2773  req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident);
2774  else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident)))
2775  req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
2776 
2777  if (!req) {
2778  ast_verb(3, "No command found on [%s] for transaction %u. Ignoring...\n",
2779  gw->name, ident);
2780  return;
2781  }
2782 
2783  if (p && (result >= 400) && (result <= 599)) {
2784  switch (result) {
2785  case 401:
2786  p->hookstate = MGCP_OFFHOOK;
2787  break;
2788  case 402:
2789  p->hookstate = MGCP_ONHOOK;
2790  break;
2791  case 406:
2792  ast_log(LOG_NOTICE, "Transaction %u timed out\n", ident);
2793  break;
2794  case 407:
2795  ast_log(LOG_NOTICE, "Transaction %u aborted\n", ident);
2796  break;
2797  }
2798  if (sub) {
2799  if (!sub->cxident[0] && (req->cmd == MGCP_CMD_CRCX)) {
2800  ast_log(LOG_NOTICE, "DLCX for all connections on %s due to error %d\n", gw->name, result);
2802  }
2803  if (sub->owner) {
2804  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2805  result, p->name, p->parent->name, sub ? sub->id:-1);
2806  mgcp_queue_hangup(sub);
2807  }
2808  } else {
2809  if (p->sub->next->owner) {
2810  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2811  result, p->name, p->parent->name, sub ? sub->id:-1);
2812  mgcp_queue_hangup(p->sub);
2813  }
2814 
2815  if (p->sub->owner) {
2816  ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
2817  result, p->name, p->parent->name, sub ? sub->id:-1);
2818  mgcp_queue_hangup(p->sub);
2819  }
2820 
2821  dump_cmd_queues(p, NULL);
2822  }
2823  }
2824 
2825  if (resp) {
2826  /* responseAck: */
2827  if (result == 200 && (req->cmd == MGCP_CMD_CRCX || req->cmd == MGCP_CMD_MDCX)) {
2828  if (sub) {
2829  transmit_response(sub, "000", resp, "OK");
2830  if (sub->owner && sub->owner->_state == AST_STATE_RINGING) {
2832  }
2833  }
2834  }
2835  if (req->cmd == MGCP_CMD_CRCX) {
2836  if ((c = get_header(resp, "I"))) {
2837  if (!ast_strlen_zero(c) && sub) {
2838  /* if we are hanging up do not process this conn. */
2839  if (sub->owner) {
2840  if (!ast_strlen_zero(sub->cxident)) {
2841  if (strcasecmp(c, sub->cxident)) {
2842  ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c);
2843  }
2844  }
2845  ast_copy_string(sub->cxident, c, sizeof(sub->cxident));
2846  if (sub->tmpdest.sin_addr.s_addr) {
2847  transmit_modify_with_sdp(sub, NULL, 0);
2848  }
2849  } else {
2850  /* XXX delete this one
2851  callid and conn id may already be lost.
2852  so the following del conn may have a side effect of
2853  cleaning up the next subchannel */
2855  }
2856  }
2857  }
2858  }
2859 
2860  if (req->cmd == MGCP_CMD_AUEP) {
2861  /* check stale connection ids */
2862  if ((c = get_header(resp, "I"))) {
2863  char *v, *n;
2864  int len;
2865  while ((v = get_csv(c, &len, &n))) {
2866  if (len) {
2867  if (strncasecmp(v, p->sub->cxident, len) &&
2868  strncasecmp(v, p->sub->next->cxident, len)) {
2869  /* connection id not found. delete it */
2870  char cxident[80] = "";
2871 
2872  if (len > (sizeof(cxident) - 1))
2873  len = sizeof(cxident) - 1;
2874  ast_copy_string(cxident, v, len);
2875  ast_verb(3, "Non existing connection id %s on %s@%s \n",
2876  cxident, p->name, gw->name);
2877  transmit_connection_del_w_params(p, NULL, cxident);
2878  }
2879  }
2880  c = n;
2881  }
2882  }
2883 
2884  /* Try to determine the hookstate returned from an audit endpoint command */
2885  if ((c = get_header(resp, "ES"))) {
2886  if (!ast_strlen_zero(c)) {
2887  if (strstr(c, "hu")) {
2888  if (p->hookstate != MGCP_ONHOOK) {
2889  /* XXX cleanup if we think we are offhook XXX */
2890  if ((p->sub->owner || p->sub->next->owner ) &&
2891  p->hookstate == MGCP_OFFHOOK)
2892  mgcp_queue_hangup(sub);
2893  p->hookstate = MGCP_ONHOOK;
2894 
2895  /* update the requested events according to the new hookstate */
2896  transmit_notify_request(p->sub, "");
2897 
2898  ast_verb(3, "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name);
2899  }
2900  } else if (strstr(c, "hd")) {
2901  if (p->hookstate != MGCP_OFFHOOK) {
2902  p->hookstate = MGCP_OFFHOOK;
2903 
2904  /* update the requested events according to the new hookstate */
2905  transmit_notify_request(p->sub, "");
2906 
2907  ast_verb(3, "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name);
2908  }
2909  }
2910  }
2911  }
2912  }
2913 
2914  if (resp && resp->lines) {
2915  /* do not process sdp if we are hanging up. this may be a late response */
2916  if (sub && sub->owner) {
2917  if (!sub->rtp)
2918  start_rtp(sub);
2919  if (sub->rtp)
2920  process_sdp(sub, resp);
2921  }
2922  }
2923  }
2924 
2925  ast_free(req);
2926 }
static void start_rtp(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2928
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
struct mgcp_request * cx_queue
Definition: chan_mgcp.c:308
ast_mutex_t cmd_queue_lock
Definition: chan_mgcp.c:378
int slowsequence
Definition: chan_mgcp.c:362
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
static char * get_csv(char *c, int *len, char **next)
get_csv: (SC:) get comma separated value
Definition: chan_mgcp.c:1643
static char * get_header(struct mgcp_request *req, char *name)
Definition: chan_mgcp.c:1636
#define LOG_WARNING
Definition: logger.h:144
static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:632
struct sockaddr_in tmpdest
Definition: chan_mgcp.c:302
static struct mgcp_request * find_command(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request **queue, ast_mutex_t *l, int ident)
find_command: (SC:) remove command transaction from queue
Definition: chan_mgcp.c:2729
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
Definition: chan_mgcp.c:2154
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
#define ast_verb(level,...)
Definition: logger.h:243
static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
Definition: chan_mgcp.c:2674
char name[80]
Definition: chan_mgcp.c:327
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
struct ast_channel * owner
Definition: chan_mgcp.c:299
struct mgcp_request * rqnt_queue
Definition: chan_mgcp.c:375
static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
Definition: chan_mgcp.c:1956
char name[80]
Definition: chan_mgcp.c:394
static int transmit_connection_del(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2651
ast_mutex_t cx_queue_lock
Definition: chan_mgcp.c:309
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_channel_state _state
Definition: channel.h:839
char cxident[80]
Definition: chan_mgcp.c:305
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ast_free(a)
Definition: astmm.h:97
ast_mutex_t rqnt_queue_lock
Definition: chan_mgcp.c:376
struct mgcp_request * cmd_queue
Definition: chan_mgcp.c:377
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
dump_cmd_queues: (SC:) cleanup pending commands
Definition: chan_mgcp.c:2695
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
Definition: chan_mgcp.c:2276
static int has_voicemail ( struct mgcp_endpoint p)
static

Definition at line 492 of file chan_mgcp.c.

References ast_app_has_voicemail(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_strdupa, ast_strlen_zero(), mgcp_endpoint::mailbox, mbox(), and strsep().

Referenced by do_monitor(), handle_hd_hf(), handle_request(), mgcp_hangup(), and mgcp_request().

493 {
494  int new_msgs;
495  struct ast_event *event;
496  char *mbox, *cntx;
497 
498  cntx = mbox = ast_strdupa(p->mailbox);
499  strsep(&cntx, "@");
500  if (ast_strlen_zero(cntx))
501  cntx = "default";
502 
507 
508  if (event) {
509  new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
510  ast_event_destroy(event);
511  } else
512  new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
513 
514  return new_msgs;
515 }
An event.
Definition: event.c:85
char * strsep(char **str, const char *delims)
int ast_app_has_voicemail(const char *mailbox, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to &quot;INBOX&quot;. If folder is &quot;INBOX&quot;, includes the number of messages in the &quot;Urgent&quot; folder.
Definition: app.c:421
struct ast_event * ast_event_get_cached(enum ast_event_type,...)
Retrieve an event from the cache.
Definition: event.c:1342
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
static const char * mbox(struct ast_vm_user *vmu, int id)
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:1314
char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:340
Mailbox name.
Definition: event_defs.h:83
static int init_req ( struct mgcp_endpoint p,
struct mgcp_request req,
char *  verb,
unsigned int  oseq 
)
static

Definition at line 2108 of file chan_mgcp.c.

References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_gateway::isnamedottedip, mgcp_request::len, LOG_WARNING, MGCP_MAX_HEADERS, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::ncs, and mgcp_endpoint::parent.

Referenced by reqprep().

2109 {
2110  /* Initialize a response */
2111  if (req->headers || req->len) {
2112  ast_log(LOG_WARNING, "Request already initialized?!?\n");
2113  return -1;
2114  }
2115  req->header[req->headers] = req->data + req->len;
2116  /* check if we need brackets around the gw name */
2117  if (p->parent->isnamedottedip) {
2118  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" : "");
2119  } else {
2120 + 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" : "");
2121  }
2122  req->len += strlen(req->header[req->headers]);
2123  if (req->headers < MGCP_MAX_HEADERS) {
2124  req->headers++;
2125  } else {
2126  ast_log(LOG_WARNING, "Out of header space\n");
2127  }
2128  return 0;
2129 }
#define LOG_WARNING
Definition: logger.h:144
char name[80]
Definition: chan_mgcp.c:327
char name[80]
Definition: chan_mgcp.c:394
int isnamedottedip
Definition: chan_mgcp.c:395
Definition: logger.c:927
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define MGCP_MAX_HEADERS
Definition: chan_mgcp.c:243
char * header[MGCP_MAX_HEADERS]
Definition: chan_mgcp.c:253
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
static int init_resp ( struct mgcp_request req,
char *  resp,
struct mgcp_request orig,
char *  resprest 
)
static

Definition at line 2090 of file chan_mgcp.c.

References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_request::identifier, mgcp_request::len, LOG_WARNING, and MGCP_MAX_HEADERS.

Referenced by respprep().

2091 {
2092  /* Initialize a response */
2093  if (req->headers || req->len) {
2094  ast_log(LOG_WARNING, "Request already initialized?!?\n");
2095  return -1;
2096  }
2097  req->header[req->headers] = req->data + req->len;
2098  snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
2099  req->len += strlen(req->header[req->headers]);
2100  if (req->headers < MGCP_MAX_HEADERS) {
2101  req->headers++;
2102  } else {
2103  ast_log(LOG_WARNING, "Out of header space\n");
2104  }
2105  return 0;
2106 }
#define LOG_WARNING
Definition: logger.h:144
char * identifier
Definition: chan_mgcp.c:249
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define MGCP_MAX_HEADERS
Definition: chan_mgcp.c:243
char * header[MGCP_MAX_HEADERS]
Definition: chan_mgcp.c:253
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
static int load_module ( void  )
static

load_module: PBX load module - initialization —

Definition at line 4794 of file chan_mgcp.c.

References ast_channel_register(), ast_cli_register_multiple(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_rtp_glue_register, io_context_create(), io_context_destroy(), LOG_ERROR, LOG_WARNING, reload_config(), restart_monitor(), sched_context_create(), and sched_context_destroy().

4795 {
4796  if (!(sched = sched_context_create())) {
4797  ast_log(LOG_WARNING, "Unable to create schedule context\n");
4798  return AST_MODULE_LOAD_FAILURE;
4799  }
4800 
4801  if (!(io = io_context_create())) {
4802  ast_log(LOG_WARNING, "Unable to create I/O context\n");
4804  return AST_MODULE_LOAD_FAILURE;
4805  }
4806 
4807  if (reload_config(0))
4808  return AST_MODULE_LOAD_DECLINE;
4809 
4810  /* Make sure we can register our mgcp channel type */
4812  ast_log(LOG_ERROR, "Unable to register channel class 'MGCP'\n");
4815  return AST_MODULE_LOAD_FAILURE;
4816  }
4817 
4819  ast_cli_register_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
4820 
4821  /* And start the monitor for the first time */
4822  restart_monitor();
4823 
4824  return AST_MODULE_LOAD_SUCCESS;
4825 }
static int restart_monitor(void)
Definition: chan_mgcp.c:3892
descriptor for a cli entry.
Definition: cli.h:165
#define LOG_WARNING
Definition: logger.h:144
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:476
Definition: sched.c:57
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:907
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition: io.c:102
static int reload_config(int reload)
Definition: chan_mgcp.c:4619
static struct io_context * io
Definition: chan_mgcp.c:238
static struct ast_channel_tech mgcp_tech
Definition: chan_mgcp.c:464
#define LOG_ERROR
Definition: logger.h:155
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free&#39;s) the given sched_context structure
Definition: sched.c:267
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct sched_context * sched_context_create(void)
New schedule context.
Definition: sched.c:246
static struct ast_cli_entry cli_mgcp[]
Definition: chan_mgcp.c:1170
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static struct ast_rtp_glue mgcp_rtp_glue
Definition: chan_mgcp.c:4449
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition: io.c:76
static int mgcp_alloc_pktcgate ( struct mgcp_subchannel sub)
static

Definition at line 2416 of file chan_mgcp.c.

References mgcp_gateway::addr, ast_pktccops_gate_alloc(), mgcp_subchannel::gate, cops_gate::gate_open, GATE_SET, mgcp_pktcgate_open(), mgcp_pktcgate_remove(), mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_endpoint::sub, and cops_gate::tech_pvt.

Referenced by start_rtp().

2417 {
2418  struct mgcp_endpoint *p = sub->parent;
2419  sub->gate = ast_pktccops_gate_alloc(GATE_SET, NULL, ntohl(p->parent->addr.sin_addr.s_addr),
2420  8, 128000, 232, 0, 0, NULL, &mgcp_pktcgate_remove);
2421 
2422  if (!sub->gate) {
2423  return 0;
2424  }
2425  sub->gate->tech_pvt = sub;
2427  return 1;
2428 }
struct cops_gate * gate
Definition: chan_mgcp.c:315
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
struct cops_gate * ast_pktccops_gate_alloc(int cmd, struct cops_gate *gate, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, int(*const got_dq_gi)(struct cops_gate *gate), int(*const gate_remove)(struct cops_gate *gate))
Definition: res_pktccops.c:470
int(* gate_open)(struct cops_gate *gate)
Definition: pktccops.h:66
void * tech_pvt
Definition: pktccops.h:67
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct sockaddr_in addr
Definition: chan_mgcp.c:396
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int mgcp_pktcgate_open(struct cops_gate *gate)
Definition: chan_mgcp.c:2403
static int mgcp_pktcgate_remove(struct cops_gate *gate)
Definition: chan_mgcp.c:2380
static int mgcp_answer ( struct ast_channel ast)
static

Definition at line 1177 of file chan_mgcp.c.

References ast_channel::_state, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, ast_verb, mgcp_subchannel::cxmode, mgcp_subchannel::id, mgcp_subchannel::lock, MGCP_CX_SENDRECV, mgcp_endpoint::name, mgcp_gateway::name, ast_channel::name, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_subchannel::rtp, start_rtp(), ast_channel::tech_pvt, transmit_modify_request(), and transmit_notify_request().

1178 {
1179  int res = 0;
1180  struct mgcp_subchannel *sub = ast->tech_pvt;
1181  struct mgcp_endpoint *p = sub->parent;
1182 
1183  ast_mutex_lock(&sub->lock);
1184  sub->cxmode = MGCP_CX_SENDRECV;
1185  if (!sub->rtp) {
1186  start_rtp(sub);
1187  } else {
1189  }
1190  ast_verb(3, "MGCP mgcp_answer(%s) on %s@%s-%d\n",
1191  ast->name, p->name, p->parent->name, sub->id);
1192  if (ast->_state != AST_STATE_UP) {
1193  ast_setstate(ast, AST_STATE_UP);
1194  ast_debug(1, "mgcp_answer(%s)\n", ast->name);
1195  transmit_notify_request(sub, "");
1197  }
1198  ast_mutex_unlock(&sub->lock);
1199  return res;
1200 }
static void start_rtp(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2928
void * tech_pvt
Definition: channel.h:744
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
#define MGCP_CX_SENDRECV
Definition: chan_mgcp.c:125
char name[80]
Definition: chan_mgcp.c:394
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
static int transmit_modify_request(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2537
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mgcp_call ( struct ast_channel ast,
char *  dest,
int  timeout 
)
static

Definition at line 837 of file chan_mgcp.c.

References ast_channel::_state, ast_copy_string(), ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_var_name(), ast_var_value(), mgcp_subchannel::callid, ast_channel::connected, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, ast_var_t::entries, mgcp_endpoint::hookstate, ast_party_connected_line::id, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, MGCP_CX_RECVONLY, MGCP_CX_SENDRECV, MGCP_OFFHOOK, MGCP_ONHOOK, ast_party_id::name, ast_channel::name, mgcp_endpoint::ncs, mgcp_subchannel::next, ast_party_id::number, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_subchannel::rtp, S_COR, start_rtp(), ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, transmit_modify_request(), transmit_notify_request_with_callerid(), mgcp_endpoint::type, TYPE_LINE, ast_party_name::valid, ast_party_number::valid, and ast_channel::varshead.

838 {
839  int res;
840  struct mgcp_endpoint *p;
841  struct mgcp_subchannel *sub;
842  char tone[50] = "";
843  const char *distinctive_ring = NULL;
844  struct varshead *headp;
845  struct ast_var_t *current;
846 
847  ast_debug(3, "MGCP mgcp_call(%s)\n", ast->name);
848  sub = ast->tech_pvt;
849  p = sub->parent;
850  headp = &ast->varshead;
851  AST_LIST_TRAVERSE(headp,current,entries) {
852  /* Check whether there is an ALERT_INFO variable */
853  if (strcasecmp(ast_var_name(current),"ALERT_INFO") == 0) {
854  distinctive_ring = ast_var_value(current);
855  }
856  }
857 
858  ast_mutex_lock(&sub->lock);
859  switch (p->hookstate) {
860  case MGCP_OFFHOOK:
861  if (!ast_strlen_zero(distinctive_ring)) {
862  snprintf(tone, sizeof(tone), "L/wt%s", distinctive_ring);
863  ast_debug(3, "MGCP distinctive callwait %s\n", tone);
864  } else {
865  ast_copy_string(tone, (p->ncs ? "L/wt1" : "L/wt"), sizeof(tone));
866  ast_debug(3, "MGCP normal callwait %s\n", tone);
867  }
868  break;
869  case MGCP_ONHOOK:
870  default:
871  if (!ast_strlen_zero(distinctive_ring)) {
872  snprintf(tone, sizeof(tone), "L/r%s", distinctive_ring);
873  ast_debug(3, "MGCP distinctive ring %s\n", tone);
874  } else {
875  ast_copy_string(tone, "L/rg", sizeof(tone));
876  ast_debug(3, "MGCP default ring\n");
877  }
878  break;
879  }
880 
881  if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
882  ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name);
883  ast_mutex_unlock(&sub->lock);
884  return -1;
885  }
886 
887  res = 0;
888  sub->outgoing = 1;
889  sub->cxmode = MGCP_CX_RECVONLY;
891  if (p->type == TYPE_LINE) {
892  if (!sub->rtp) {
893  start_rtp(sub);
894  } else {
896  }
897 
898  if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
899  /* try to prevent a callwait from disturbing the other connection */
900  sub->next->cxmode = MGCP_CX_RECVONLY;
902  }
903 
905  S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
906  S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""));
908 
909  if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
910  /* Put the connection back in sendrecv */
911  sub->next->cxmode = MGCP_CX_SENDRECV;
913  }
914  } else {
915  ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n");
916  res = -1;
917  }
918  ast_mutex_unlock(&sub->lock);
919  return res;
920 }
#define TYPE_LINE
Definition: chan_mgcp.c:323
static void start_rtp(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2928
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
char callid[80]
Definition: chan_mgcp.c:306
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
void * tech_pvt
Definition: channel.h:744
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
#define LOG_WARNING
Definition: logger.h:144
ast_mutex_t lock
Definition: chan_mgcp.c:297
char * str
Subscriber name (Malloced)
Definition: channel.h:214
static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
Definition: chan_mgcp.c:2492
#define ast_mutex_lock(a)
Definition: lock.h:155
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
#define MGCP_CX_SENDRECV
Definition: chan_mgcp.c:125
struct ast_channel * owner
Definition: chan_mgcp.c:299
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
char cxident[80]
Definition: chan_mgcp.c:305
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_var_t::@158 entries
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
static int transmit_modify_request(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2537
#define MGCP_CX_RECVONLY
Definition: chan_mgcp.c:124
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct varshead varshead
Definition: channel.h:817
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int mgcp_devicestate ( void *  data)
static

mgcp_devicestate: channel callback for device status monitoring

Parameters
datatech/resource name of MGCP device to query

Callback for device state management in channel subsystem to obtain device status (up/down) of a specific MGCP endpoint

Returns
device status result (from devicestate.h) AST_DEVICE_INVALID (not available) or AST_DEVICE_UNKNOWN (available but unknown state)

Definition at line 1362 of file chan_mgcp.c.

References AST_DEVICE_INVALID, AST_DEVICE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, ast_strdupa, mgcp_gateway::endpoints, gatelock, gateways, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::next, and mgcp_gateway::next.

1363 {
1364  struct mgcp_gateway *g;
1365  struct mgcp_endpoint *e = NULL;
1366  char *tmp, *endpt, *gw;
1367  int ret = AST_DEVICE_INVALID;
1368 
1369  endpt = ast_strdupa(data);
1370  if ((tmp = strchr(endpt, '@'))) {
1371  *tmp++ = '\0';
1372  gw = tmp;
1373  } else
1374  goto error;
1375 
1377  for (g = gateways; g; g = g->next) {
1378  if (strcasecmp(g->name, gw) == 0) {
1379  e = g->endpoints;
1380  break;
1381  }
1382  }
1383 
1384  if (!e)
1385  goto error;
1386 
1387  for (; e; e = e->next) {
1388  if (strcasecmp(e->name, endpt) == 0) {
1389  break;
1390  }
1391  }
1392 
1393  if (!e)
1394  goto error;
1395 
1396  /*
1397  * As long as the gateway/endpoint is valid, we'll
1398  * assume that the device is available and its state
1399  * can be tracked.
1400  */
1401  ret = AST_DEVICE_UNKNOWN;
1402 
1403 error:
1405  return ret;
1406 }
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
#define ast_mutex_lock(a)
Definition: lock.h:155
char name[80]
Definition: chan_mgcp.c:327
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
char name[80]
Definition: chan_mgcp.c:394
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct mgcp_gateway * gateways
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mgcp_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 1284 of file chan_mgcp.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, ast_channel::name, mgcp_subchannel::owner, and ast_channel::tech_pvt.

1285 {
1286  struct mgcp_subchannel *sub = newchan->tech_pvt;
1287 
1288  ast_mutex_lock(&sub->lock);
1289  ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name);
1290  if (sub->owner != oldchan) {
1291  ast_mutex_unlock(&sub->lock);
1292  ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
1293  return -1;
1294  }
1295  sub->owner = newchan;
1296  ast_mutex_unlock(&sub->lock);
1297  return 0;
1298 }
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_channel * owner
Definition: chan_mgcp.c:299
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ast_mutex_unlock(a)
Definition: lock.h:156
static format_t mgcp_get_codec ( struct ast_channel chan)
static

Definition at line 4442 of file chan_mgcp.c.

References mgcp_endpoint::capability, mgcp_subchannel::parent, and ast_channel::tech_pvt.

4443 {
4444  struct mgcp_subchannel *sub = chan->tech_pvt;
4445  struct mgcp_endpoint *p = sub->parent;
4446  return p->capability;
4447 }
void * tech_pvt
Definition: channel.h:744
format_t capability
Definition: chan_mgcp.c:367
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static enum ast_rtp_glue_result mgcp_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
)
static

Definition at line 4415 of file chan_mgcp.c.

References ao2_ref, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, mgcp_endpoint::directmedia, mgcp_subchannel::parent, mgcp_subchannel::rtp, and ast_channel::tech_pvt.

4416 {
4417  struct mgcp_subchannel *sub = NULL;
4418 
4419  if (!(sub = chan->tech_pvt) || !(sub->rtp))
4421 
4422  *instance = sub->rtp ? ao2_ref(sub->rtp, +1), sub->rtp : NULL;
4423 
4424  if (sub->parent->directmedia)
4426  else
4428 }
void * tech_pvt
Definition: channel.h:744
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int mgcp_hangup ( struct ast_channel ast)
static

Definition at line 922 of file chan_mgcp.c.

References mgcp_subchannel::alreadygone, ast_bridged_channel(), ast_debug, ast_dsp_free(), ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, ast_pktccops_gate_alloc(), ast_rtp_instance_destroy(), ast_strlen_zero(), ast_verb, ast_channel::caller, mgcp_subchannel::callid, mgcp_endpoint::callwaiting, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, cops_gate::deltimer, mgcp_endpoint::dsp, mgcp_endpoint::dtmf_buf, mgcp_endpoint::dtmfmode, mgcp_subchannel::gate, GATE_ALLOC_PROGRESS, GATE_ALLOCATED, GATE_DEL, cops_gate::gate_open, cops_gate::gate_remove, cops_gate::got_dq_gi, has_voicemail(), mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, mgcp_endpoint::hookstate, ast_party_caller::id, mgcp_subchannel::lock, mgcp_subchannel::magic, MGCP_CX_INACTIVE, MGCP_CX_RECVONLY, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, MGCP_SUBCHANNEL_MAGIC, ast_party_id::name, mgcp_endpoint::name, mgcp_gateway::name, ast_channel::name, mgcp_endpoint::ncs, mgcp_subchannel::next, ast_party_id::number, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_endpoint::pktcgatealloc, mgcp_subchannel::rtp, S_COR, ast_module_info::self, cops_gate::state, ast_party_name::str, ast_party_number::str, mgcp_endpoint::sub, cops_gate::tech_pvt, ast_channel::tech_pvt, mgcp_subchannel::tmpdest, transmit_connection_del(), transmit_modify_request(), transmit_notify_request(), transmit_notify_request_with_callerid(), ast_party_name::valid, and ast_party_number::valid.

923 {
924  struct mgcp_subchannel *sub = ast->tech_pvt;
925  struct mgcp_endpoint *p = sub->parent;
926  struct ast_channel *bridged;
927 
928  ast_debug(1, "mgcp_hangup(%s)\n", ast->name);
929  if (!ast->tech_pvt) {
930  ast_debug(1, "Asked to hangup channel not connected\n");
931  return 0;
932  }
933  if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) {
934  ast_debug(1, "Invalid magic. MGCP subchannel freed up already.\n");
935  return 0;
936  }
937  ast_mutex_lock(&sub->lock);
938  ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name);
939 
940  if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) {
941  /* check whether other channel is active. */
942  if (!sub->next->owner) {
943  if (p->dtmfmode & MGCP_DTMF_HYBRID) {
944  p->dtmfmode &= ~MGCP_DTMF_INBAND;
945  }
946  ast_debug(2, "MGCP free dsp on %s@%s\n", p->name, p->parent->name);
947  ast_dsp_free(p->dsp);
948  p->dsp = NULL;
949  }
950  }
951 
952  sub->owner = NULL;
953 
954  /* for deleting gate */
955  if (p->pktcgatealloc && sub->gate) {
956  sub->gate->gate_open = NULL;
957  sub->gate->gate_remove = NULL;
958  sub->gate->got_dq_gi = NULL;
959  sub->gate->tech_pvt = NULL;
960  if (sub->gate->state == GATE_ALLOC_PROGRESS || sub->gate->state == GATE_ALLOCATED) {
961  ast_pktccops_gate_alloc(GATE_DEL, sub->gate, 0, 0, 0, 0, 0, 0, NULL, NULL);
962  } else {
963  sub->gate->deltimer = time(NULL) + 5;
964  }
965  sub->gate = NULL;
966  }
967 
968  if (!ast_strlen_zero(sub->cxident)) {
970  }
971  sub->cxident[0] = '\0';
972  if ((sub == p->sub) && sub->next->owner) {
973  if (p->hookstate == MGCP_OFFHOOK) {
974  if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
975  /* ncs fix! */
976  bridged = ast_bridged_channel(sub->next->owner);
977  transmit_notify_request_with_callerid(p->sub, (p->ncs ? "L/wt1" : "L/wt"),
978  S_COR(bridged->caller.id.number.valid, bridged->caller.id.number.str, ""),
979  S_COR(bridged->caller.id.name.valid, bridged->caller.id.name.str, ""));
980  }
981  } else {
982  /* set our other connection as the primary and swith over to it */
983  p->sub = sub->next;
986  if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
987  bridged = ast_bridged_channel(sub->next->owner);
989  S_COR(bridged->caller.id.number.valid, bridged->caller.id.number.str, ""),
990  S_COR(bridged->caller.id.name.valid, bridged->caller.id.name.str, ""));
991  }
992  }
993 
994  } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) {
995  transmit_notify_request(sub, p->ncs ? "" : "L/v");
996  } else if (p->hookstate == MGCP_OFFHOOK) {
997  transmit_notify_request(sub, "L/ro");
998  } else {
999  transmit_notify_request(sub, "");
1000  }
1001 
1002  ast->tech_pvt = NULL;
1003  sub->alreadygone = 0;
1004  sub->outgoing = 0;
1005  sub->cxmode = MGCP_CX_INACTIVE;
1006  sub->callid[0] = '\0';
1007  if (p) {
1008  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
1009  }
1010  /* Reset temporary destination */
1011  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
1012  if (sub->rtp) {
1014  sub->rtp = NULL;
1015  }
1016 
1018 
1019  if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) {
1020  p->hidecallerid = 0;
1021  if (p->hascallwaiting && !p->callwaiting) {
1022  ast_verb(3, "Enabling call waiting on %s\n", ast->name);
1023  p->callwaiting = -1;
1024  }
1025  if (has_voicemail(p)) {
1026  ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n",
1027  ast->name, p->name, p->parent->name);
1028  transmit_notify_request(sub, "L/vmwi(+)");
1029  } else {
1030  ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n",
1031  ast->name, p->name, p->parent->name);
1032  transmit_notify_request(sub, "L/vmwi(-)");
1033  }
1034  }
1035  ast_mutex_unlock(&sub->lock);
1036  return 0;
1037 }
Main Channel structure associated with a channel.
Definition: channel.h:742
struct cops_gate * gate
Definition: chan_mgcp.c:315
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
char callid[80]
Definition: chan_mgcp.c:306
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int hascallwaiting
Definition: chan_mgcp.c:346
int state
Definition: pktccops.h:59
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
int(* gate_remove)(struct cops_gate *gate)
Definition: pktccops.h:65
struct cops_gate * ast_pktccops_gate_alloc(int cmd, struct cops_gate *gate, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, int(*const got_dq_gi)(struct cops_gate *gate), int(*const gate_remove)(struct cops_gate *gate))
Definition: res_pktccops.c:470
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
int hidecallerid
Definition: chan_mgcp.c:355
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1650
void * tech_pvt
Definition: channel.h:744
char dtmf_buf[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:336
time_t deltimer
Definition: pktccops.h:62
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
ast_mutex_t lock
Definition: chan_mgcp.c:297
char * str
Subscriber name (Malloced)
Definition: channel.h:214
static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
Definition: chan_mgcp.c:2492
struct sockaddr_in tmpdest
Definition: chan_mgcp.c:302
int(* gate_open)(struct cops_gate *gate)
Definition: pktccops.h:66
#define ast_mutex_lock(a)
Definition: lock.h:155
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
void * tech_pvt
Definition: pktccops.h:67
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
#define ast_verb(level,...)
Definition: logger.h:243
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
struct ast_module * self
Definition: module.h:227
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
struct ast_channel * owner
Definition: chan_mgcp.c:299
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
char name[80]
Definition: chan_mgcp.c:394
static int transmit_connection_del(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2651
struct ast_dsp * dsp
Definition: chan_mgcp.c:381
int pktcgatealloc
Definition: chan_mgcp.c:359
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
char cxident[80]
Definition: chan_mgcp.c:305
char magic[6]
Definition: chan_mgcp.c:296
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:301
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
static int has_voicemail(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:492
int(* got_dq_gi)(struct cops_gate *gate)
Definition: pktccops.h:64
#define MGCP_CX_INACTIVE
Definition: chan_mgcp.c:129
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define MGCP_SUBCHANNEL_MAGIC
Definition: chan_mgcp.c:295
static int transmit_modify_request(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2537
#define MGCP_CX_RECVONLY
Definition: chan_mgcp.c:124
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int mgcp_indicate ( struct ast_channel ast,
int  ind,
const void *  data,
size_t  datalen 
)
static

Definition at line 1440 of file chan_mgcp.c.

References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), control2str(), mgcp_subchannel::lock, LOG_WARNING, ast_channel::name, mgcp_endpoint::ncs, mgcp_subchannel::parent, mgcp_subchannel::rtp, mgcp_subchannel::sdpsent, ast_channel::tech_pvt, transmit_modify_request(), and transmit_notify_request().

1441 {
1442  struct mgcp_subchannel *sub = ast->tech_pvt;
1443  int res = 0;
1444 
1445  ast_debug(3, "MGCP asked to indicate %d '%s' condition on channel %s\n",
1446  ind, control2str(ind), ast->name);
1447  ast_mutex_lock(&sub->lock);
1448  switch(ind) {
1449  case AST_CONTROL_RINGING:
1450 #ifdef DLINK_BUGGY_FIRMWARE
1451  transmit_notify_request(sub, "rt");
1452 #else
1453  if (!sub->sdpsent) { /* will hide the inband progress!!! */
1454  transmit_notify_request(sub, sub->parent->ncs ? "L/rt" : "G/rt");
1455  }
1456 #endif
1457  break;
1458  case AST_CONTROL_BUSY:
1459  transmit_notify_request(sub, "L/bz");
1460  break;
1462  /* We do not currently support resetting of the Interdigit Timer, so treat
1463  * Incomplete control frames as a congestion response
1464  */
1466  transmit_notify_request(sub, sub->parent->ncs ? "L/cg" : "G/cg");
1467  break;
1468  case AST_CONTROL_HOLD:
1469  ast_moh_start(ast, data, NULL);
1470  break;
1471  case AST_CONTROL_UNHOLD:
1472  ast_moh_stop(ast);
1473  break;
1474  case AST_CONTROL_SRCUPDATE:
1476  break;
1477  case AST_CONTROL_SRCCHANGE:
1479  break;
1480  case AST_CONTROL_PROGRESS:
1483  case -1:
1484  transmit_notify_request(sub, "");
1485  break;
1486  default:
1487  ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
1488  res = -1;
1489  }
1490  ast_mutex_unlock(&sub->lock);
1491  return res;
1492 }
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
Definition: rtp_engine.c:767
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: channel.h:787
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:8040
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
static char * control2str(int ind)
Definition: chan_mgcp.c:1408
static int transmit_modify_request(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2537
void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
Indicate that the RTP marker bit should be set on an RTP stream.
Definition: rtp_engine.c:760
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_channel* mgcp_new ( struct mgcp_subchannel sub,
int  state,
const char *  linkedid 
)
static

Definition at line 1494 of file chan_mgcp.c.

References mgcp_endpoint::accountcode, mgcp_endpoint::adsi, ast_channel::adsicpe, mgcp_endpoint::amaflags, ast_channel::amaflags, ast_party_caller::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_channel_set_fd(), ast_copy_string(), ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), ast_get_encoded_str(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_rtp_instance_fd(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_verb, mgcp_endpoint::call_forward, ast_channel::caller, mgcp_endpoint::callgroup, ast_channel::callgroup, capability, mgcp_endpoint::capability, mgcp_endpoint::chanvars, mgcp_endpoint::cid_name, mgcp_endpoint::cid_num, mgcp_endpoint::context, ast_channel::context, mgcp_endpoint::dsp, DSP_DIGITMODE_NOQUELCH, DSP_FEATURE_DIGIT_DETECT, mgcp_endpoint::dtmfmode, mgcp_endpoint::exten, ast_channel::exten, global_jbconf, mgcp_subchannel::id, mgcp_endpoint::language, LOG_WARNING, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, mgcp_tech, ast_variable::name, mgcp_endpoint::name, mgcp_gateway::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, ast_party_id::number, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::parent, pbx_builtin_setvar_helper(), mgcp_endpoint::pickupgroup, ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, mgcp_subchannel::rtp, ast_module_info::self, ast_party_number::str, mgcp_endpoint::sub, ast_channel::tech, ast_channel::tech_pvt, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.

Referenced by handle_hd_hf(), and mgcp_request().

1495 {
1496  struct ast_channel *tmp;
1497  struct ast_variable *v = NULL;
1498  struct mgcp_endpoint *i = sub->parent;
1499  int fmt;
1500 
1501  tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
1502  if (tmp) {
1503  tmp->tech = &mgcp_tech;
1504  tmp->nativeformats = i->capability;
1505  if (!tmp->nativeformats) {
1506  tmp->nativeformats = capability;
1507  }
1508  fmt = ast_best_codec(tmp->nativeformats);
1509  if (sub->rtp) {
1510  ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
1511  }
1513  i->dsp = ast_dsp_new();
1515  /* this is to prevent clipping of dtmf tones during dsp processing */
1517  } else {
1518  i->dsp = NULL;
1519  }
1520  if (state == AST_STATE_RING)
1521  tmp->rings = 1;
1522  tmp->writeformat = fmt;
1523  tmp->rawwriteformat = fmt;
1524  tmp->readformat = fmt;
1525  tmp->rawreadformat = fmt;
1526  tmp->tech_pvt = sub;
1527  if (!ast_strlen_zero(i->language))
1529  if (!ast_strlen_zero(i->accountcode))
1531  if (i->amaflags)
1532  tmp->amaflags = i->amaflags;
1533  sub->owner = tmp;
1535  tmp->callgroup = i->callgroup;
1536  tmp->pickupgroup = i->pickupgroup;
1538  ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
1539  ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
1540 
1541  /* Don't use ast_set_callerid() here because it will
1542  * generate a needless NewCallerID event */
1543  if (!ast_strlen_zero(i->cid_num)) {
1544  tmp->caller.ani.number.valid = 1;
1545  tmp->caller.ani.number.str = ast_strdup(i->cid_num);
1546  }
1547 
1548  if (!i->adsi) {
1550  }
1551  tmp->priority = 1;
1552 
1553  /* Set channel variables for this call from configuration */
1554  for (v = i->chanvars ; v ; v = v->next) {
1555  char valuebuf[1024];
1556  pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
1557  }
1558 
1559  if (sub->rtp) {
1561  }
1562  if (state != AST_STATE_DOWN) {
1563  if (ast_pbx_start(tmp)) {
1564  ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
1565  ast_hangup(tmp);
1566  tmp = NULL;
1567  }
1568  }
1569  ast_verb(3, "MGCP mgcp_new(%s) created in state: %s\n",
1570  tmp->name, ast_state2str(state));
1571  } else {
1572  ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
1573  }
1574  return tmp;
1575 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int rings
Definition: channel.h:840
char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:333
char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:334
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
#define ast_strdup(a)
Definition: astmm.h:109
format_t writeformat
Definition: channel.h:854
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
void * tech_pvt
Definition: channel.h:744
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: app.c:2197
#define LOG_WARNING
Definition: logger.h:144
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
struct ast_dsp * ast_dsp_new(void)
Definition: dsp.c:1607
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
char call_forward[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:337
format_t rawwriteformat
Definition: channel.h:856
format_t ast_best_codec(format_t fmts)
Pick the best audio codec.
Definition: channel.c:1062
ast_group_t pickupgroup
Definition: chan_mgcp.c:344
format_t nativeformats
Definition: channel.h:852
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:1007
enum ast_channel_adsicpe adsicpe
Definition: channel.h:844
format_t rawreadformat
Definition: channel.h:855
ast_group_t pickupgroup
Definition: channel.h:819
#define ast_verb(level,...)
Definition: logger.h:243
ast_group_t callgroup
Definition: channel.h:818
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
char language[MAX_LANGUAGE]
Definition: chan_mgcp.c:332
char name[80]
Definition: chan_mgcp.c:327
const char * value
Definition: config.h:79
struct ast_module * self
Definition: module.h:227
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_variable * chanvars
Definition: chan_mgcp.c:387
struct ast_channel * owner
Definition: chan_mgcp.c:299
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
char name[80]
Definition: chan_mgcp.c:394
const char * name
Definition: config.h:77
static struct ast_channel_tech mgcp_tech
Definition: chan_mgcp.c:464
char context[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:331
ast_group_t callgroup
Definition: chan_mgcp.c:343
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_mgcp.c:329
struct ast_dsp * dsp
Definition: chan_mgcp.c:381
static char language[MAX_LANGUAGE]
Definition: chan_mgcp.c:154
char exten[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:330
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_jb_conf global_jbconf
Definition: chan_mgcp.c:107
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1642
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:786
static format_t capability
Definition: chan_mgcp.c:228
format_t capability
Definition: chan_mgcp.c:367
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2631
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:616
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_mgcp.c:195
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
format_t readformat
Definition: channel.h:853
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
#define DSP_DIGITMODE_NOQUELCH
Definition: dsp.h:34
int amaflags
Definition: channel.h:843
struct ast_channel_tech * tech
Definition: channel.h:743
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1739
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int mgcp_pktcgate_open ( struct cops_gate gate)
static

Definition at line 2403 of file chan_mgcp.c.

References ast_debug, ast_mutex_lock, ast_mutex_unlock, cops_gate::gateid, mgcp_subchannel::lock, mgcp_subchannel::sdpsent, cops_gate::tech_pvt, and transmit_modify_with_sdp().

Referenced by mgcp_alloc_pktcgate().

2404 {
2405  struct mgcp_subchannel *sub = gate->tech_pvt;
2406  if (!sub) {
2407  return 1;
2408  }
2409  ast_mutex_lock(&sub->lock);
2410  ast_debug(1, "Pktc: gate 0x%x open\n", gate->gateid);
2411  if (!sub->sdpsent) transmit_modify_with_sdp(sub, NULL, 0);
2412  ast_mutex_unlock(&sub->lock);
2413  return 1;
2414 }
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
void * tech_pvt
Definition: pktccops.h:67
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
uint32_t gateid
Definition: pktccops.h:55
static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
Definition: chan_mgcp.c:2276
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mgcp_pktcgate_remove ( struct cops_gate gate)
static

Definition at line 2380 of file chan_mgcp.c.

References AST_CAUSE_REQUESTED_CHAN_UNAVAIL, ast_channel_unlock, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_softhangup(), mgcp_subchannel::gate, GATE_CLOSED, cops_gate::gateid, mgcp_endpoint::hangupongateremove, mgcp_subchannel::lock, mgcp_subchannel::owner, mgcp_subchannel::parent, cops_gate::state, and cops_gate::tech_pvt.

Referenced by mgcp_alloc_pktcgate().

2381 {
2382  struct mgcp_subchannel *sub = gate->tech_pvt;
2383 
2384  if (!sub) {
2385  return 1;
2386  }
2387 
2388  ast_mutex_lock(&sub->lock);
2389  ast_debug(1, "Pktc: gate 0x%x deleted\n", gate->gateid);
2390  if (sub->gate->state != GATE_CLOSED && sub->parent->hangupongateremove) {
2391  sub->gate = NULL;
2392  if (sub->owner) {
2394  ast_channel_unlock(sub->owner);
2395  }
2396  } else {
2397  sub->gate = NULL;
2398  }
2399  ast_mutex_unlock(&sub->lock);
2400  return 1;
2401 }
struct cops_gate * gate
Definition: chan_mgcp.c:315
int state
Definition: pktccops.h:59
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
void * tech_pvt
Definition: pktccops.h:67
int hangupongateremove
Definition: chan_mgcp.c:360
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
struct ast_channel * owner
Definition: chan_mgcp.c:299
uint32_t gateid
Definition: pktccops.h:55
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:124
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mgcp_postrequest ( struct mgcp_endpoint p,
struct mgcp_subchannel sub,
char *  data,
int  len,
unsigned int  seqno 
)
static

Definition at line 710 of file chan_mgcp.c.

References __mgcp_xmit(), ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), ast_tvnow(), mgcp_message::buf, DEFAULT_RETRANS, mgcp_message::expire, mgcp_message::len, len(), mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_message::next, mgcp_message::owner_ep, mgcp_message::owner_sub, mgcp_endpoint::parent, mgcp_message::retrans, retrans_pkt(), mgcp_gateway::retransid, and mgcp_message::seqno.

Referenced by find_command(), and send_request().

712 {
713  struct mgcp_message *msg;
714  struct mgcp_message *cur;
715  struct mgcp_gateway *gw;
716  struct timeval now;
717 
718  if (!(msg = ast_malloc(sizeof(*msg) + len))) {
719  return -1;
720  }
721  if (!(gw = ((p && p->parent) ? p->parent : NULL))) {
722  ast_free(msg);
723  return -1;
724  }
725 
726  msg->owner_sub = sub;
727  msg->owner_ep = p;
728  msg->seqno = seqno;
729  msg->next = NULL;
730  msg->len = len;
731  msg->retrans = 0;
732  memcpy(msg->buf, data, msg->len);
733 
735  for (cur = gw->msgs; cur && cur->next; cur = cur->next);
736  if (cur) {
737  cur->next = msg;
738  } else {
739  gw->msgs = msg;
740  }
741 
742  now = ast_tvnow();
743  msg->expire = now.tv_sec * 1000 + now.tv_usec / 1000 + DEFAULT_RETRANS;
744 
745  if (gw->retransid == -1)
748  __mgcp_xmit(gw, msg->buf, msg->len);
749  /* XXX Should schedule retransmission XXX */
750  return 0;
751 }
static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
Definition: chan_mgcp.c:545
struct mgcp_endpoint * owner_ep
Definition: chan_mgcp.c:264
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
Definition: sched.c:57
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
mgcp_message: MGCP message for queuing up
Definition: chan_mgcp.c:263
char buf[0]
Definition: chan_mgcp.c:271
struct mgcp_message * msgs
Definition: chan_mgcp.c:410
#define DEFAULT_RETRANS
Definition: chan_mgcp.c:119
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:97
unsigned long expire
Definition: chan_mgcp.c:267
struct mgcp_message * next
Definition: chan_mgcp.c:270
unsigned int seqno
Definition: chan_mgcp.c:268
#define ast_malloc(a)
Definition: astmm.h:91
static int retrans_pkt(const void *data)
Definition: chan_mgcp.c:655
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct mgcp_subchannel * owner_sub
Definition: chan_mgcp.c:265
static int mgcp_prune_realtime_gateway ( struct mgcp_gateway g)
static

Definition at line 3716 of file chan_mgcp.c.

References ast_debug, ast_mutex_destroy, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_strlen_zero(), mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_subchannel::cxident, mgcp_endpoint::dsp, mgcp_gateway::endpoints, free, mgcp_subchannel::gate, mgcp_gateway::ha, mgcp_subchannel::lock, mgcp_endpoint::lock, MAX_SUBS, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_subchannel::next, mgcp_endpoint::next, mgcp_gateway::realtime, mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, and mgcp_endpoint::sub.

Referenced by do_monitor().

3717 {
3718  struct mgcp_endpoint *enext, *e;
3719  struct mgcp_subchannel *s, *sub;
3720  int i, prune = 1;
3721 
3722  if (g->ha || !g->realtime || ast_mutex_trylock(&g->msgs_lock) || g->msgs) {
3724  return 0;
3725  }
3726 
3727  for (e = g->endpoints; e; e = e->next) {
3728  ast_mutex_lock(&e->lock);
3730  prune = 0;
3731  } else if (e->rqnt_queue || e->cmd_queue) {
3732  prune = 0;
3733  }
3734  s = e->sub;
3735  for (i = 0; (i < MAX_SUBS) && s; i++) {
3736  ast_mutex_lock(&s->lock);
3737  if (!ast_strlen_zero(s->cxident) || s->rtp || ast_mutex_trylock(&s->cx_queue_lock) || s->gate) {
3738  prune = 0;
3739  } else if (s->cx_queue) {
3740  prune = 0;
3741  }
3742  s = s->next;
3743  }
3744  }
3745 
3746  for (e = g->endpoints, sub = e->sub, enext = e->next; e; e = enext, enext = e->next) {
3747  for (i = 0; (i < MAX_SUBS) && sub; i++) {
3748  s = sub;
3749  sub = sub->next;
3750  ast_mutex_unlock(&s->lock);
3752  if (prune) {
3753  ast_mutex_destroy(&s->lock);
3755  free(s);
3756  }
3757  }
3758  ast_mutex_unlock(&e->lock);
3761  if (prune) {
3762  ast_mutex_destroy(&e->lock);
3765  free(e);
3766  }
3767  }
3768  if (prune) {
3769  ast_debug(1, "***** MGCP REALTIME PRUNE GW: %s\n", g->name);
3770  }
3771  return prune;
3772 }
struct cops_gate * gate
Definition: chan_mgcp.c:315
struct mgcp_request * cx_queue
Definition: chan_mgcp.c:308
ast_mutex_t cmd_queue_lock
Definition: chan_mgcp.c:378
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
#define MAX_SUBS
Definition: chan_mgcp.c:284
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ast_mutex_trylock(a)
Definition: lock.h:157
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct mgcp_request * rqnt_queue
Definition: chan_mgcp.c:375
struct mgcp_message * msgs
Definition: chan_mgcp.c:410
char name[80]
Definition: chan_mgcp.c:394
struct ast_dsp * dsp
Definition: chan_mgcp.c:381
#define free(a)
Definition: astmm.h:94
ast_mutex_t cx_queue_lock
Definition: chan_mgcp.c:309
ast_mutex_t lock
Definition: chan_mgcp.c:326
char cxident[80]
Definition: chan_mgcp.c:305
ast_mutex_t rqnt_queue_lock
Definition: chan_mgcp.c:376
struct ast_ha * ha
Definition: chan_mgcp.c:402
struct mgcp_request * cmd_queue
Definition: chan_mgcp.c:377
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
#define ast_mutex_destroy(a)
Definition: lock.h:154
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void mgcp_queue_control ( struct mgcp_subchannel sub,
int  control 
)
static

Definition at line 649 of file chan_mgcp.c.

References AST_FRAME_CONTROL, and mgcp_queue_frame().

Referenced by handle_hd_hf().

650 {
651  struct ast_frame f = { AST_FRAME_CONTROL, { control } };
652  return mgcp_queue_frame(sub, &f);
653 }
static void mgcp_queue_frame(struct mgcp_subchannel *sub, struct ast_frame *f)
Definition: chan_mgcp.c:615
static struct ast_format f[]
Definition: format_g726.c:181
Data structure associated with a single frame of data.
Definition: frame.h:142
static void mgcp_queue_frame ( struct mgcp_subchannel sub,
struct ast_frame f 
)
static

Definition at line 615 of file chan_mgcp.c.

References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, mgcp_subchannel::lock, and mgcp_subchannel::owner.

Referenced by handle_request(), and mgcp_queue_control().

616 {
617  for (;;) {
618  if (sub->owner) {
619  if (!ast_channel_trylock(sub->owner)) {
620  ast_queue_frame(sub->owner, f);
622  break;
623  } else {
624  DEADLOCK_AVOIDANCE(&sub->lock);
625  }
626  } else {
627  break;
628  }
629  }
630 }
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
ast_mutex_t lock
Definition: chan_mgcp.c:297
struct ast_channel * owner
Definition: chan_mgcp.c:299
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static void mgcp_queue_hangup ( struct mgcp_subchannel sub)
static

Definition at line 632 of file chan_mgcp.c.

References ast_channel_trylock, ast_channel_unlock, ast_queue_hangup(), DEADLOCK_AVOIDANCE, mgcp_subchannel::lock, and mgcp_subchannel::owner.

Referenced by attempt_transfer(), destroy_endpoint(), handle_request(), handle_response(), and start_rtp().

633 {
634  for (;;) {
635  if (sub->owner) {
636  if (!ast_channel_trylock(sub->owner)) {
637  ast_queue_hangup(sub->owner);
639  break;
640  } else {
641  DEADLOCK_AVOIDANCE(&sub->lock);
642  }
643  } else {
644  break;
645  }
646  }
647 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1569
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
ast_mutex_t lock
Definition: chan_mgcp.c:297
struct ast_channel * owner
Definition: chan_mgcp.c:299
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static struct ast_frame * mgcp_read ( struct ast_channel ast)
static

Definition at line 1233 of file chan_mgcp.c.

References ast_mutex_lock, ast_mutex_unlock, f, mgcp_subchannel::lock, mgcp_rtp_read(), and ast_channel::tech_pvt.

1234 {
1235  struct ast_frame *f;
1236  struct mgcp_subchannel *sub = ast->tech_pvt;
1237  ast_mutex_lock(&sub->lock);
1238  f = mgcp_rtp_read(sub);
1239  ast_mutex_unlock(&sub->lock);
1240  return f;
1241 }
static struct ast_frame * mgcp_rtp_read(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:1202
void * tech_pvt
Definition: channel.h:744
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct ast_format f[]
Definition: format_g726.c:181
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char * mgcp_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4827 of file chan_mgcp.c.

References ast_cli_args::argc, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, LOG_WARNING, mgcp_reload_lock, restart_monitor(), and ast_cli_entry::usage.

Referenced by reload(), and unload_module().

4828 {
4829  static int deprecated = 0;
4830 
4831  if (e) {
4832  switch (cmd) {
4833  case CLI_INIT:
4834  e->command = "mgcp reload";
4835  e->usage =
4836  "Usage: mgcp reload\n"
4837  " 'mgcp reload' is deprecated. Please use 'reload chan_mgcp.so' instead.\n";
4838  return NULL;
4839  case CLI_GENERATE:
4840  return NULL;
4841  }
4842  }
4843 
4844  if (!deprecated && a && a->argc > 0) {
4845  ast_log(LOG_WARNING, "'mgcp reload' is deprecated. Please use 'reload chan_mgcp.so' instead.\n");
4846  deprecated = 1;
4847  }
4848 
4850  if (mgcp_reloading) {
4851  ast_verbose("Previous mgcp reload not yet done\n");
4852  } else {
4853  mgcp_reloading = 1;
4854  }
4856  restart_monitor();
4857  return CLI_SUCCESS;
4858 }
static int restart_monitor(void)
Definition: chan_mgcp.c:3892
const int argc
Definition: cli.h:154
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
static int mgcp_reloading
Definition: chan_mgcp.c:420
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static ast_mutex_t mgcp_reload_lock
Definition: chan_mgcp.c:419
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_channel * mgcp_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
)
static

Definition at line 3921 of file chan_mgcp.c.

References AST_CAUSE_BUSY, AST_CAUSE_UNREGISTERED, ast_copy_string(), ast_getformatname_multiple(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strlen_zero(), ast_verb, mgcp_endpoint::call_forward, mgcp_endpoint::callwaiting, capability, ast_channel::data, mgcp_endpoint::dnd, find_subchannel_and_lock(), has_voicemail(), mgcp_endpoint::hookstate, ast_channel::linkedid, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, mgcp_new(), MGCP_ONHOOK, mgcp_subchannel::next, mgcp_subchannel::owner, mgcp_subchannel::parent, restart_monitor(), and transmit_notify_request().

3922 {
3923  struct mgcp_subchannel *sub;
3924  struct ast_channel *tmpc = NULL;
3925  char tmp[256];
3926  char *dest = data;
3927 
3928  format &= capability;
3929  if (!format) {
3930  ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
3931  /*return NULL;*/
3932  }
3933  ast_copy_string(tmp, dest, sizeof(tmp));
3934  if (ast_strlen_zero(tmp)) {
3935  ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n");
3936  return NULL;
3937  }
3938  if (!(sub = find_subchannel_and_lock(tmp, 0, NULL))) {
3939  ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
3940  *cause = AST_CAUSE_UNREGISTERED;
3941  return NULL;
3942  }
3943 
3944  ast_verb(3, "MGCP mgcp_request(%s)\n", tmp);
3945  ast_verb(3, "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n",
3946  sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0);
3947  /* Must be busy */
3948  if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) ||
3949  ((!sub->parent->callwaiting) && (sub->owner)) ||
3950  (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) {
3951  if (sub->parent->hookstate == MGCP_ONHOOK) {
3952  if (has_voicemail(sub->parent)) {
3953  transmit_notify_request(sub,"L/vmwi(+)");
3954  } else {
3955  transmit_notify_request(sub,"L/vmwi(-)");
3956  }
3957  }
3958  *cause = AST_CAUSE_BUSY;
3959  ast_mutex_unlock(&sub->lock);
3960  return NULL;
3961  }
3962  tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
3963  ast_mutex_unlock(&sub->lock);
3964  if (!tmpc)
3965  ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
3966  restart_monitor();
3967  return tmpc;
3968 }
Main Channel structure associated with a channel.
Definition: channel.h:742
static int restart_monitor(void)
Definition: chan_mgcp.c:3892
#define LOG_WARNING
Definition: logger.h:144
char call_forward[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:337
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
const char * data
Definition: channel.h:755
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
const ast_string_field linkedid
Definition: channel.h:787
static struct ast_channel * mgcp_new(struct mgcp_subchannel *sub, int state, const char *linkedid)
Definition: chan_mgcp.c:1494
#define ast_verb(level,...)
Definition: logger.h:243
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_channel * owner
Definition: chan_mgcp.c:299
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
static format_t capability
Definition: chan_mgcp.c:228
static struct mgcp_subchannel * find_subchannel_and_lock(char *name, int msgid, struct sockaddr_in *sin)
Definition: chan_mgcp.c:1758
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
static int has_voicemail(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:492
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define AST_CAUSE_BUSY
Definition: causes.h:148
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Definition: frame.c:591
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_frame* mgcp_rtp_read ( struct mgcp_subchannel sub)
static

Definition at line 1202 of file chan_mgcp.c.

References ast_debug, ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_frame_subclass::codec, mgcp_endpoint::dsp, mgcp_endpoint::dtmfmode, f, ast_frame::frametype, LOG_NOTICE, MGCP_DTMF_INBAND, MGCP_DTMF_RFC2833, ast_channel::nativeformats, mgcp_subchannel::owner, mgcp_subchannel::parent, ast_channel::readformat, mgcp_subchannel::rtp, ast_frame::subclass, and ast_channel::writeformat.

Referenced by mgcp_read().

1203 {
1204  /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
1205  struct ast_frame *f;
1206 
1207  f = ast_rtp_instance_read(sub->rtp, 0);
1208  /* Don't send RFC2833 if we're not supposed to */
1209  if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833))
1210  return &ast_null_frame;
1211  if (sub->owner) {
1212  /* We already hold the channel lock */
1213  if (f->frametype == AST_FRAME_VOICE) {
1214  if (f->subclass.codec != sub->owner->nativeformats) {
1215  ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
1216  sub->owner->nativeformats = f->subclass.codec;
1219  }
1220  /* Courtesy fearnor aka alex@pilosoft.com */
1221  if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
1222 #if 0
1223  ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n");
1224 #endif
1225  f = ast_dsp_process(sub->owner, sub->parent->dsp, f);
1226  }
1227  }
1228  }
1229  return f;
1230 }
union ast_frame_subclass subclass
Definition: frame.h:146
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1392
struct ast_frame ast_null_frame
Definition: frame.c:131
format_t writeformat
Definition: channel.h:854
#define MGCP_DTMF_RFC2833
Definition: chan_mgcp.c:112
#define AST_FRAME_DTMF
Definition: frame.h:128
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
format_t nativeformats
Definition: channel.h:852
format_t codec
Definition: frame.h:137
int ast_set_write_format(struct ast_channel *chan, format_t format)
Sets write format on channel chan Set write format for channel to whichever component of &quot;format&quot; is ...
Definition: channel.c:5307
int ast_set_read_format(struct ast_channel *chan, format_t format)
Sets read format on channel chan Set read format for channel to whichever component of &quot;format&quot; is be...
Definition: channel.c:5301
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_channel * owner
Definition: chan_mgcp.c:299
struct ast_dsp * dsp
Definition: chan_mgcp.c:381
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static struct ast_format f[]
Definition: format_g726.c:181
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
format_t readformat
Definition: channel.h:853
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:379
static int mgcp_senddigit_begin ( struct ast_channel ast,
char  digit 
)
static

Definition at line 1300 of file chan_mgcp.c.

References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_dtmf_begin(), mgcp_endpoint::dtmfmode, mgcp_subchannel::lock, LOG_ERROR, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, MGCP_DTMF_RFC2833, mgcp_subchannel::parent, mgcp_subchannel::rtp, and ast_channel::tech_pvt.

1301 {
1302  struct mgcp_subchannel *sub = ast->tech_pvt;
1303  struct mgcp_endpoint *p = sub->parent;
1304  int res = 0;
1305 
1306  ast_mutex_lock(&sub->lock);
1308  ast_debug(1, "Sending DTMF using inband/hybrid\n");
1309  res = -1; /* Let asterisk play inband indications */
1310  } else if (p->dtmfmode & MGCP_DTMF_RFC2833) {
1311  ast_debug(1, "Sending DTMF using RFC2833\n");
1312  ast_rtp_instance_dtmf_begin(sub->rtp, digit);
1313  } else {
1314  ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
1315  }
1316  ast_mutex_unlock(&sub->lock);
1317 
1318  return res;
1319 }
void * tech_pvt
Definition: channel.h:744
#define MGCP_DTMF_RFC2833
Definition: chan_mgcp.c:112
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
#define LOG_ERROR
Definition: logger.h:155
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:736
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mgcp_senddigit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Definition at line 1321 of file chan_mgcp.c.

References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_dtmf_end(), mgcp_endpoint::dtmfmode, mgcp_subchannel::lock, LOG_ERROR, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, MGCP_DTMF_RFC2833, mgcp_endpoint::ncs, mgcp_subchannel::parent, mgcp_subchannel::rtp, ast_channel::tech_pvt, and transmit_notify_request().

1322 {
1323  struct mgcp_subchannel *sub = ast->tech_pvt;
1324  struct mgcp_endpoint *p = sub->parent;
1325  int res = 0;
1326  char tmp[4];
1327 
1328  ast_mutex_lock(&sub->lock);
1330  ast_debug(1, "Stopping DTMF using inband/hybrid\n");
1331  res = -1; /* Tell Asterisk to stop inband indications */
1332  } else if (p->dtmfmode & MGCP_DTMF_RFC2833) {
1333  ast_debug(1, "Stopping DTMF using RFC2833\n");
1334  if (sub->parent->ncs) {
1335  tmp[0] = digit;
1336  tmp[1] = '\0';
1337  } else {
1338  tmp[0] = 'D';
1339  tmp[1] = '/';
1340  tmp[2] = digit;
1341  tmp[3] = '\0';
1342  }
1343  transmit_notify_request(sub, tmp);
1344  ast_rtp_instance_dtmf_end(sub->rtp, digit);
1345  } else {
1346  ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
1347  }
1348  ast_mutex_unlock(&sub->lock);
1349 
1350  return res;
1351 }
void * tech_pvt
Definition: channel.h:744
#define MGCP_DTMF_RFC2833
Definition: chan_mgcp.c:112
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
Stop sending a DTMF digit.
Definition: rtp_engine.c:741
static int mgcp_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_rtp_instance vrtp,
struct ast_rtp_instance trtp,
format_t  codecs,
int  nat_active 
)
static

Definition at line 4430 of file chan_mgcp.c.

References mgcp_subchannel::alreadygone, ast_channel::tech_pvt, and transmit_modify_with_sdp().

4431 {
4432  /* XXX Is there such thing as video support with MGCP? XXX */
4433  struct mgcp_subchannel *sub;
4434  sub = chan->tech_pvt;
4435  if (sub && !sub->alreadygone) {
4436  transmit_modify_with_sdp(sub, rtp, codecs);
4437  return 0;
4438  }
4439  return -1;
4440 }
void * tech_pvt
Definition: channel.h:744
static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
Definition: chan_mgcp.c:2276
static void* mgcp_ss ( void *  data)
static

Definition at line 2961 of file chan_mgcp.c.

References ast_party_caller::ani, ast_bridged_channel(), ast_canmatch_extension(), ast_copy_string(), ast_db_put(), ast_debug, ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_indicate(), ast_log(), ast_masq_park_call_exten(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext_valid(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_strdup, ast_strlen_zero(), ast_verb, ast_waitfordigit(), mgcp_endpoint::call_forward, ast_channel::caller, mgcp_endpoint::callreturn, mgcp_endpoint::callwaiting, mgcp_endpoint::cancallforward, mgcp_endpoint::cid_name, mgcp_endpoint::cid_num, ast_channel::context, ast_channel::data, ast_channel::dialed, mgcp_endpoint::dnd, mgcp_endpoint::dtmf_buf, mgcp_endpoint::dtmfmode, exten, ast_channel::exten, firstdigittimeout, gendigittimeout, mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, ast_party_caller::id, ast_channel::language, mgcp_endpoint::lastcallerid, len(), LOG_WARNING, matchdigittimeout, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, mgcp_endpoint::name, mgcp_gateway::name, ast_channel::name, mgcp_endpoint::ncs, mgcp_subchannel::next, ast_party_id::number, ast_party_dialed::number, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::parent, ast_channel::rings, S_COR, start_rtp(), ast_party_number::str, ast_party_dialed::str, ast_channel::tech_pvt, transmit_notify_request(), and ast_party_number::valid.

Referenced by handle_hd_hf().

2962 {
2963  struct ast_channel *chan = data;
2964  struct mgcp_subchannel *sub = chan->tech_pvt;
2965  struct mgcp_endpoint *p = sub->parent;
2966  /* char exten[AST_MAX_EXTENSION] = ""; */
2967  int len = 0;
2968  int timeout = firstdigittimeout;
2969  int res= 0;
2970  int getforward = 0;
2971  int loop_pause = 100;
2972 
2973  len = strlen(p->dtmf_buf);
2974 
2975  while (len < AST_MAX_EXTENSION - 1) {
2976  ast_debug(1, "Dtmf buffer '%s' for '%s@%s'\n", p->dtmf_buf, p->name, p->parent->name);
2977  res = 1; /* Assume that we will get a digit */
2978  while (strlen(p->dtmf_buf) == len) {
2979  ast_safe_sleep(chan, loop_pause);
2980  timeout -= loop_pause;
2981  if (timeout <= 0){
2982  res = 0;
2983  break;
2984  }
2985  res = 1;
2986  }
2987 
2988  timeout = 0;
2989  len = strlen(p->dtmf_buf);
2990 
2991  if (!ast_ignore_pattern(chan->context, p->dtmf_buf)) {
2992  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
2993  ast_indicate(chan, -1);
2994  } else {
2995  /* XXX Redundant? We should already be playing dialtone */
2996  /*tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
2997  transmit_notify_request(sub, "L/dl");
2998  }
2999  if (ast_exists_extension(chan, chan->context, p->dtmf_buf, 1, p->cid_num)) {
3000  if (!res || !ast_matchmore_extension(chan, chan->context, p->dtmf_buf, 1, p->cid_num)) {
3001  if (getforward) {
3002  /* Record this as the forwarding extension */
3003  ast_copy_string(p->call_forward, p->dtmf_buf, sizeof(p->call_forward));
3004  ast_verb(3, "Setting call forward to '%s' on channel %s\n",
3005  p->call_forward, chan->name);
3006  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3007  transmit_notify_request(sub, "L/sl");
3008  if (res)
3009  break;
3010  usleep(500000);
3011  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3012  ast_indicate(chan, -1);
3013  sleep(1);
3014  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3015  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
3016  transmit_notify_request(sub, "L/dl");
3017  len = 0;
3018  getforward = 0;
3019  } else {
3020  /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
3021  ast_indicate(chan, -1);
3022  ast_copy_string(chan->exten, p->dtmf_buf, sizeof(chan->exten));
3023  chan->dialed.number.str = ast_strdup(p->dtmf_buf);
3024  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3025  ast_set_callerid(chan,
3026  p->hidecallerid ? "" : p->cid_num,
3027  p->hidecallerid ? "" : p->cid_name,
3028  chan->caller.ani.number.valid ? NULL : p->cid_num);
3030  /*dahdi_enable_ec(p);*/
3031  if (p->dtmfmode & MGCP_DTMF_HYBRID) {
3032  p->dtmfmode |= MGCP_DTMF_INBAND;
3033  ast_indicate(chan, -1);
3034  }
3035  res = ast_pbx_run(chan);
3036  if (res) {
3037  ast_log(LOG_WARNING, "PBX exited non-zero\n");
3038  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3039  /*transmit_notify_request(p, "nbz", 1);*/
3040  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3041  }
3042  return NULL;
3043  }
3044  } else {
3045  /* It's a match, but they just typed a digit, and there is an ambiguous match,
3046  so just set the timeout to matchdigittimeout and wait some more */
3047  timeout = matchdigittimeout;
3048  }
3049  } else if (res == 0) {
3050  ast_debug(1, "not enough digits (and no ambiguous match)...\n");
3051  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3052  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3053  /*dahdi_wait_event(p->subs[index].zfd);*/
3054  ast_hangup(chan);
3055  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3056  return NULL;
3057  } else if (p->hascallwaiting && p->callwaiting && !strcmp(p->dtmf_buf, "*70")) {
3058  ast_verb(3, "Disabling call waiting on %s\n", chan->name);
3059  /* Disable call waiting if enabled */
3060  p->callwaiting = 0;
3061  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3062  transmit_notify_request(sub, "L/sl");
3063  len = 0;
3064  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3065  timeout = firstdigittimeout;
3066  } else if (!strcmp(p->dtmf_buf,ast_pickup_ext())) {
3067  /* Scan all channels and see if any there
3068  * ringing channqels with that have call groups
3069  * that equal this channels pickup group
3070  */
3071  if (ast_pickup_call(chan)) {
3072  ast_log(LOG_WARNING, "No call pickup possible...\n");
3073  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);*/
3074  transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
3075  }
3076  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3077  ast_hangup(chan);
3078  return NULL;
3079  } else if (!p->hidecallerid && !strcmp(p->dtmf_buf, "*67")) {
3080  ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
3081  /* Disable Caller*ID if enabled */
3082  p->hidecallerid = 1;
3083  ast_set_callerid(chan, "", "", NULL);
3084  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3085  transmit_notify_request(sub, "L/sl");
3086  len = 0;
3087  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3088  timeout = firstdigittimeout;
3089  } else if (p->callreturn && !strcmp(p->dtmf_buf, "*69")) {
3090  res = 0;
3091  if (!ast_strlen_zero(p->lastcallerid)) {
3092  res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language);
3093  }
3094  if (!res)
3095  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3096  transmit_notify_request(sub, "L/sl");
3097  break;
3098  } else if (!strcmp(p->dtmf_buf, "*78")) {
3099  /* Do not disturb */
3100  ast_verb(3, "Enabled DND on channel %s\n", chan->name);
3101  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3102  transmit_notify_request(sub, "L/sl");
3103  p->dnd = 1;
3104  getforward = 0;
3105  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3106  len = 0;
3107  } else if (!strcmp(p->dtmf_buf, "*79")) {
3108  /* Do not disturb */
3109  ast_verb(3, "Disabled DND on channel %s\n", chan->name);
3110  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3111  transmit_notify_request(sub, "L/sl");
3112  p->dnd = 0;
3113  getforward = 0;
3114  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3115  len = 0;
3116  } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*72")) {
3117  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3118  transmit_notify_request(sub, "L/sl");
3119  getforward = 1;
3120  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3121  len = 0;
3122  } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*73")) {
3123  ast_verb(3, "Cancelling call forwarding on channel %s\n", chan->name);
3124  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3125  transmit_notify_request(sub, "L/sl");
3126  memset(p->call_forward, 0, sizeof(p->call_forward));
3127  getforward = 0;
3128  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3129  len = 0;
3130  } else if (ast_parking_ext_valid(p->dtmf_buf, chan, chan->context) &&
3131  sub->next->owner && ast_bridged_channel(sub->next->owner)) {
3132  /* This is a three way call, the main call being a real channel,
3133  and we're parking the first call. */
3135  p->dtmf_buf, chan->context, 0, NULL);
3136  ast_verb(3, "Parking call to '%s'\n", chan->name);
3137  break;
3138  } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(p->dtmf_buf, "*60")) {
3139  ast_verb(3, "Blacklisting number %s\n", p->lastcallerid);
3140  res = ast_db_put("blacklist", p->lastcallerid, "1");
3141  if (!res) {
3142  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3143  transmit_notify_request(sub, "L/sl");
3144  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3145  len = 0;
3146  }
3147  } else if (p->hidecallerid && !strcmp(p->dtmf_buf, "*82")) {
3148  ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
3149  /* Enable Caller*ID if enabled */
3150  p->hidecallerid = 0;
3151  ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
3152  /*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
3153  transmit_notify_request(sub, "L/sl");
3154  len = 0;
3155  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3156  timeout = firstdigittimeout;
3157  } else if (!ast_canmatch_extension(chan, chan->context, p->dtmf_buf, 1,
3158  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
3159  && ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
3160  ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf,
3161  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"),
3162  chan->context);
3163  break;
3164  }
3165  if (!timeout)
3166  timeout = gendigittimeout;
3167  if (len && !ast_ignore_pattern(chan->context, p->dtmf_buf))
3168  /*tone_zone_play_tone(p->subs[index].zfd, -1);*/
3169  ast_indicate(chan, -1);
3170  }
3171 #if 0
3172  for (;;) {
3173  res = ast_waitfordigit(chan, to);
3174  if (!res) {
3175  ast_debug(1, "Timeout...\n");
3176  break;
3177  }
3178  if (res < 0) {
3179  ast_debug(1, "Got hangup...\n");
3180  ast_hangup(chan);
3181  break;
3182  }
3183  exten[pos++] = res;
3184  if (!ast_ignore_pattern(chan->context, exten))
3185  ast_indicate(chan, -1);
3186  if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
3187  if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid))
3188  to = 3000;
3189  else
3190  to = 8000;
3191  } else
3192  break;
3193  }
3194  if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
3195  ast_copy_string(chan->exten, exten, sizeof(chan->exten)1);
3196  if (!p->rtp) {
3197  start_rtp(p);
3198  }
3200  chan->rings = 1;
3201  if (ast_pbx_run(chan)) {
3202  ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
3203  } else {
3204  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3205  return NULL;
3206  }
3207  }
3208 #endif
3209  ast_hangup(chan);
3210  memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
3211  return NULL;
3212 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1916
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7051
static void start_rtp(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2928
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:5420
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int rings
Definition: channel.h:840
char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:333
static int firstdigittimeout
Definition: chan_mgcp.c:207
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
char lastcallerid[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:335
char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:334
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int hascallwaiting
Definition: chan_mgcp.c:346
#define ast_strdup(a)
Definition: astmm.h:109
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
int hidecallerid
Definition: chan_mgcp.c:355
void * tech_pvt
Definition: channel.h:744
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
char dtmf_buf[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:336
int cancallforward
Definition: chan_mgcp.c:350
#define MGCP_DTMF_INBAND
Definition: chan_mgcp.c:113
char call_forward[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:337
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8415
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:8650
const char * data
Definition: channel.h:755
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: features.c:7380
struct mgcp_subchannel * next
Definition: chan_mgcp.c:316
#define ast_verb(level,...)
Definition: logger.h:243
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:5415
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
struct ast_party_dialed::@155 number
Dialed/Called number.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
struct ast_channel * owner
Definition: chan_mgcp.c:299
#define MGCP_DTMF_HYBRID
Definition: chan_mgcp.c:114
char name[80]
Definition: chan_mgcp.c:394
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
static int gendigittimeout
Definition: chan_mgcp.c:210
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
Definition: chan_mgcp.c:2464
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:5926
int ast_masq_park_call_exten(struct ast_channel *park_me, struct ast_channel *parker, const char *park_exten, const char *park_context, int timeout, int *extout)
Park a call via a masqueraded channel.
Definition: features.c:1803
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: db.c:260
int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
Determine if parking extension exists in a given context.
Definition: features.c:844
static int matchdigittimeout
Definition: chan_mgcp.c:213
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
const char * ast_pickup_ext(void)
Determine system call pickup extension.
Definition: features.c:849
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int mgcp_write ( struct ast_channel ast,
struct ast_frame frame 
)
static

Definition at line 1243 of file chan_mgcp.c.

References ast_debug, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_write(), ast_frame_subclass::codec, ast_frame::frametype, mgcp_subchannel::gate, GATE_ALLOCATED, mgcp_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, mgcp_subchannel::parent, ast_channel::readformat, mgcp_subchannel::rtp, mgcp_subchannel::sdpsent, mgcp_endpoint::singlepath, cops_gate::state, mgcp_endpoint::sub, ast_frame::subclass, ast_channel::tech_pvt, transmit_modify_with_sdp(), and ast_channel::writeformat.

1244 {
1245  struct mgcp_subchannel *sub = ast->tech_pvt;
1246  int res = 0;
1247  char buf[256];
1248 
1249  if (frame->frametype != AST_FRAME_VOICE) {
1250  if (frame->frametype == AST_FRAME_IMAGE)
1251  return 0;
1252  else {
1253  ast_log(LOG_WARNING, "Can't send %u type frames with MGCP write\n", frame->frametype);
1254  return 0;
1255  }
1256  } else {
1257  if (!(frame->subclass.codec & ast->nativeformats)) {
1258  ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1260  ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
1263  /* return -1; */
1264  }
1265  }
1266  if (sub) {
1267  ast_mutex_lock(&sub->lock);
1268  if (!sub->sdpsent && sub->gate) {
1269  if (sub->gate->state == GATE_ALLOCATED) {
1270  ast_debug(1, "GATE ALLOCATED, sending sdp\n");
1271  transmit_modify_with_sdp(sub, NULL, 0);
1272  }
1273  }
1274  if ((sub->parent->sub == sub) || !sub->parent->singlepath) {
1275  if (sub->rtp) {
1276  res = ast_rtp_instance_write(sub->rtp, frame);
1277  }
1278  }
1279  ast_mutex_unlock(&sub->lock);
1280  }
1281  return res;
1282 }
union ast_frame_subclass subclass
Definition: frame.h:146
struct cops_gate * gate
Definition: chan_mgcp.c:315
int state
Definition: pktccops.h:59
format_t writeformat
Definition: channel.h:854
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:374
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
format_t nativeformats
Definition: channel.h:852
format_t codec
Definition: frame.h:137
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
format_t readformat
Definition: channel.h:853
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Definition: frame.c:591
static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
Definition: chan_mgcp.c:2276
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mgcpsock_read ( int *  id,
int  fd,
short  events,
void *  ignore 
)
static

Definition at line 3625 of file chan_mgcp.c.

References ast_debug, ast_free, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_strlen_zero(), mgcp_request::data, mgcp_request::endpoint, errno, find_and_retrans(), find_subchannel_and_lock(), handle_request(), handle_response(), mgcp_request::headers, mgcp_request::identifier, mgcp_request::len, len(), mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_message::owner_ep, mgcp_message::owner_sub, mgcp_subchannel::parent, mgcp_endpoint::parent, parse(), mgcp_gateway::retransid, mgcp_message::seqno, mgcp_request::verb, and mgcp_request::version.

Referenced by do_monitor().

3626 {
3627  struct mgcp_request req;
3628  struct sockaddr_in sin;
3629  struct mgcp_subchannel *sub;
3630  int res;
3631  socklen_t len;
3632  int result;
3633  int ident;
3634  len = sizeof(sin);
3635  memset(&req, 0, sizeof(req));
3636  res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
3637  if (res < 0) {
3638  if (errno != ECONNREFUSED)
3639  ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
3640  return 1;
3641  }
3642  req.data[res] = '\0';
3643  req.len = res;
3644  ast_debug(1, "MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
3645  parse(&req);
3646  if (req.headers < 1) {
3647  /* Must have at least one header */
3648  return 1;
3649  }
3650  if (ast_strlen_zero(req.identifier)) {
3651  ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin.sin_addr));
3652  return 1;
3653  }
3654 
3655  if (sscanf(req.verb, "%30d", &result) && sscanf(req.identifier, "%30d", &ident)) {
3656  if (result < 200) {
3657  ast_debug(1, "Ignoring provisional response on transaction %d\n", ident);
3658  return 1;
3659  }
3660  /* Try to find who this message is for, if it's important */
3661  sub = find_subchannel_and_lock(NULL, ident, &sin);
3662  if (sub) {
3663  struct mgcp_gateway *gw = sub->parent->parent;
3664  struct mgcp_message *cur, *prev;
3665 
3666  ast_mutex_unlock(&sub->lock);
3667  ast_mutex_lock(&gw->msgs_lock);
3668  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
3669  if (cur->seqno == ident) {
3670  ast_debug(1, "Got response back on transaction %d\n", ident);
3671  if (prev)
3672  prev->next = cur->next;
3673  else
3674  gw->msgs = cur->next;
3675  break;
3676  }
3677  }
3678 
3679  /* stop retrans timer if the queue is empty */
3680  if (!gw->msgs) {
3682  }
3683 
3685  if (cur) {
3686  handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req);
3687  ast_free(cur);
3688  return 1;
3689  }
3690 
3691  ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n",
3692  gw->name, ident);
3693  }
3694  } else {
3695  if (ast_strlen_zero(req.endpoint) ||
3696  ast_strlen_zero(req.version) ||
3697  ast_strlen_zero(req.verb)) {
3698  ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
3699  return 1;
3700  }
3701  /* Process request, with iflock held */
3702  sub = find_subchannel_and_lock(req.endpoint, 0, &sin);
3703  if (sub) {
3704  /* look first to find a matching response in the queue */
3705  if (!find_and_retrans(sub, &req))
3706  /* pass the request off to the currently mastering subchannel */
3707  handle_request(sub, &req, &sin);
3708  ast_mutex_unlock(&sub->lock);
3709  }
3710  }
3711  return 1;
3712 }
static int mgcpsock
Definition: chan_mgcp.c:425
static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp)
Definition: chan_mgcp.c:2758
struct mgcp_endpoint * owner_ep
Definition: chan_mgcp.c:264
#define LOG_WARNING
Definition: logger.h:144
Definition: sched.c:57
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
mgcp_message: MGCP message for queuing up
Definition: chan_mgcp.c:263
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct mgcp_message * msgs
Definition: chan_mgcp.c:410
char name[80]
Definition: chan_mgcp.c:394
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int errno
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ast_free(a)
Definition: astmm.h:97
static struct mgcp_subchannel * find_subchannel_and_lock(char *name, int msgid, struct sockaddr_in *sin)
Definition: chan_mgcp.c:1758
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *req)
Definition: chan_mgcp.c:3595
struct mgcp_message * next
Definition: chan_mgcp.c:270
static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
Definition: chan_mgcp.c:3350
unsigned int seqno
Definition: chan_mgcp.c:268
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct mgcp_subchannel * owner_sub
Definition: chan_mgcp.c:265
static void mwi_event_cb ( const struct ast_event event,
void *  userdata 
)
static

Definition at line 484 of file chan_mgcp.c.

Referenced by build_gateway().

485 {
486  /* This module does not handle MWI in an event-based manner. However, it
487  * subscribes to MWI for each mailbox that is configured so that the core
488  * knows that we care about it. Then, chan_mgcp will get the MWI from the
489  * event cache instead of checking the mailbox directly. */
490 }
static void parse ( struct mgcp_request req)
static

Definition at line 1858 of file chan_mgcp.c.

References ast_debug, ast_log(), ast_strlen_zero(), mgcp_request::data, mgcp_request::endpoint, f, mgcp_request::header, mgcp_request::headers, mgcp_request::identifier, mgcp_request::line, mgcp_request::lines, LOG_WARNING, MGCP_MAX_HEADERS, MGCP_MAX_LINES, mgcp_request::verb, and mgcp_request::version.

Referenced by acf_jabberreceive_read(), acf_meetme_info(), add_agent(), app_exec(), aqm_exec(), ast_masq_park_call_exten(), ast_park_call_exten(), ast_parse_allow_disallow(), celgenuserevent_exec(), chanspy_exec(), conf_exec(), conf_run(), confbridge_exec(), config_function_read(), cut_internal(), dahdi_accept_r2_call_exec(), dahdi_send_callrerouting_facility_exec(), dial_exec_full(), dictate_exec(), directory_exec(), dundi_query_read(), dundi_result_read(), dundifunc_read(), enum_query_read(), enum_result_read(), execif_exec(), expand_gosub_args(), extenspy_exec(), find_conf(), function_agent(), get_comma(), get_in_brackets_const(), get_in_brackets_full(), gosub_exec(), handle_statechange(), iconv_read(), isAnsweringMachine(), isexten_function_read(), log_exec(), login_exec(), man_do_variable_value(), mgcpsock_read(), misdn_check_l2l1(), misdn_facility_exec(), misdn_set_opt_exec(), mixmonitor_exec(), originate_exec(), oss_call(), oss_request(), page_exec(), park_call_exec(), parked_call_exec(), parse_cookies(), pbx_builtin_answer(), pbx_builtin_background(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_waitexten(), pickupchan_exec(), play_moh_exec(), pqm_exec(), privacy_exec(), process_echocancel(), ql_exec(), queue_exec(), rcvfax_exec(), receivefax_exec(), record_exec(), reload_single_member(), retrydial_exec(), rqm_exec(), saycountedadj_exec(), saycountednoun_exec(), sayunixtime_exec(), sendfax_exec(), sip_acf_channel_read(), sla_trunk_exec(), smdi_msg_read(), smdi_msg_retrieve_read(), sms_exec(), sndfax_exec(), softhangup_exec(), speech_background(), srv_result_read(), start_moh_exec(), start_monitor_exec(), transfer_exec(), upqm_exec(), userevent_exec(), verbose_exec(), vm_execmain(), xfer_park_call_helper(), and zapateller_exec().

1859 {
1860  /* Divide fields by NULL's */
1861  char *c;
1862  int f = 0;
1863  c = req->data;
1864 
1865  /* First header starts immediately */
1866  req->header[f] = c;
1867  for (; *c; c++) {
1868  if (*c == '\n') {
1869  /* We've got a new header */
1870  *c = 0;
1871  ast_debug(3, "Header: %s (%d)\n", req->header[f], (int) strlen(req->header[f]));
1872  if (ast_strlen_zero(req->header[f])) {
1873  /* Line by itself means we're now in content */
1874  c++;
1875  break;
1876  }
1877  if (f >= MGCP_MAX_HEADERS - 1) {
1878  ast_log(LOG_WARNING, "Too many MGCP headers...\n");
1879  } else {
1880  f++;
1881  }
1882  req->header[f] = c + 1;
1883  } else if (*c == '\r') {
1884  /* Ignore but eliminate \r's */
1885  *c = 0;
1886  }
1887  }
1888  /* Check for last header */
1889  if (!ast_strlen_zero(req->header[f])) {
1890  f++;
1891  }
1892  req->headers = f;
1893  /* Now we process any mime content */
1894  f = 0;
1895  req->line[f] = c;
1896  for (; *c; c++) {
1897  if (*c == '\n') {
1898  /* We've got a new line */
1899  *c = 0;
1900  ast_debug(3, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
1901  if (f >= MGCP_MAX_LINES - 1) {
1902  ast_log(LOG_WARNING, "Too many SDP lines...\n");
1903  } else {
1904  f++;
1905  }
1906  req->line[f] = c + 1;
1907  } else if (*c == '\r') {
1908  /* Ignore and eliminate \r's */
1909  *c = 0;
1910  }
1911  }
1912  /* Check for last line */
1913  if (!ast_strlen_zero(req->line[f])) {
1914  f++;
1915  }
1916  req->lines = f;
1917  /* Parse up the initial header */
1918  c = req->header[0];
1919  while (*c && *c < 33) c++;
1920  /* First the verb */
1921  req->verb = c;
1922  while (*c && (*c > 32)) c++;
1923  if (*c) {
1924  *c = '\0';
1925  c++;
1926  while (*c && (*c < 33)) c++;
1927  req->identifier = c;
1928  while (*c && (*c > 32)) c++;
1929  if (*c) {
1930  *c = '\0';
1931  c++;
1932  while (*c && (*c < 33)) c++;
1933  req->endpoint = c;
1934  while (*c && (*c > 32)) c++;
1935  if (*c) {
1936  *c = '\0';
1937  c++;
1938  while (*c && (*c < 33)) c++;
1939  req->version = c;
1940  while (*c && (*c > 32)) c++;
1941  while (*c && (*c < 33)) c++;
1942  while (*c && (*c > 32)) c++;
1943  *c = '\0';
1944  }
1945  }
1946  }
1947 
1948  ast_debug(1, "Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
1949  req->verb, req->identifier, req->endpoint, req->version);
1950  ast_debug(1, "%d headers, %d lines\n", req->headers, req->lines);
1951  if (*c) {
1952  ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
1953  }
1954 }
#define LOG_WARNING
Definition: logger.h:144
char * identifier
Definition: chan_mgcp.c:249
char * verb
Definition: chan_mgcp.c:248
char * endpoint
Definition: chan_mgcp.c:250
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_MAX_LINES
Definition: chan_mgcp.c:244
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_format f[]
Definition: format_g726.c:181
#define MGCP_MAX_HEADERS
Definition: chan_mgcp.c:243
char * line[MGCP_MAX_LINES]
Definition: chan_mgcp.c:255
char * header[MGCP_MAX_HEADERS]
Definition: chan_mgcp.c:253
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
char * version
Definition: chan_mgcp.c:251
static int process_sdp ( struct mgcp_subchannel sub,
struct mgcp_request req 
)
static

Definition at line 1956 of file chan_mgcp.c.

References ast_debug, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_set_m_type(), ast_rtp_codecs_payloads_set_rtpmap_type(), ast_rtp_instance_get_codecs(), ast_rtp_instance_set_remote_address(), ast_sockaddr_from_sin, ast_strdupa, ast_strlen_zero(), mgcp_endpoint::capability, get_sdp(), get_sdp_iterate(), hp, len(), LOG_WARNING, mgcp_endpoint::nonCodecCapability, mgcp_subchannel::parent, mgcp_subchannel::rtp, and sdpLineNum_iterator_init().

Referenced by handle_response().

1957 {
1958  char *m;
1959  char *c;
1960  char *a;
1961  char host[258];
1962  int len = 0;
1963  int portno;
1964  format_t peercapability;
1965  int peerNonCodecCapability;
1966  struct sockaddr_in sin;
1967  struct ast_sockaddr sin_tmp;
1968  char *codecs;
1969  struct ast_hostent ahp; struct hostent *hp;
1970  int codec, codec_count=0;
1971  int iterator;
1972  struct mgcp_endpoint *p = sub->parent;
1973  char tmp1[256], tmp2[256], tmp3[256];
1974 
1975  /* Get codec and RTP info from SDP */
1976  m = get_sdp(req, "m");
1977  c = get_sdp(req, "c");
1978  if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
1979  ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
1980  return -1;
1981  }
1982  if (sscanf(c, "IN IP4 %256s", host) != 1) {
1983  ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
1984  return -1;
1985  }
1986  /* XXX This could block for a long time, and block the main thread! XXX */
1987  hp = ast_gethostbyname(host, &ahp);
1988  if (!hp) {
1989  ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
1990  return -1;
1991  }
1992  if (sscanf(m, "audio %30d RTP/AVP %n", &portno, &len) != 1 || !len) {
1993  ast_log(LOG_WARNING, "Malformed media stream descriptor: %s\n", m);
1994  return -1;
1995  }
1996  sin.sin_family = AF_INET;
1997  memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
1998  sin.sin_port = htons(portno);
1999  ast_sockaddr_from_sin(&sin_tmp, &sin);
2000  ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
2001  ast_debug(3, "Peer RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2002  /* Scan through the RTP payload types specified in a "m=" line: */
2004  codecs = ast_strdupa(m + len);
2005  while (!ast_strlen_zero(codecs)) {
2006  if (sscanf(codecs, "%30d%n", &codec, &len) != 1) {
2007  if (codec_count) {
2008  break;
2009  }
2010  ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs);
2011  return -1;
2012  }
2014  codec_count++;
2015  codecs += len;
2016  }
2017 
2018  /* Next, scan through each "a=rtpmap:" line, noting each */
2019  /* specified RTP payload type (with corresponding MIME subtype): */
2020  sdpLineNum_iterator_init(&iterator);
2021  while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
2022  char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
2023  if (sscanf(a, "rtpmap: %30d %127[^/]/", &codec, mimeSubtype) != 2)
2024  continue;
2025  /* Note: should really look at the 'freq' and '#chans' params too */
2026  ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, codec, "audio", mimeSubtype, 0);
2027  }
2028 
2029  /* Now gather all of the codecs that were asked for: */
2030  ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), &peercapability, &peerNonCodecCapability);
2031  p->capability = capability & peercapability;
2032  ast_debug(1, "Capabilities: us - %s, them - %s, combined - %s\n",
2033  ast_getformatname_multiple(tmp1, sizeof(tmp1), capability),
2034  ast_getformatname_multiple(tmp2, sizeof(tmp2), peercapability),
2035  ast_getformatname_multiple(tmp3, sizeof(tmp3), p->capability));
2036  ast_debug(1, "Non-codec capabilities: us - %d, them - %d, combined - %d\n",
2037  nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
2038  if (!p->capability) {
2039  ast_log(LOG_WARNING, "No compatible codecs!\n");
2040  return -1;
2041  }
2042  return 0;
2043 }
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:483
#define LOG_WARNING
Definition: logger.h:144
static void sdpLineNum_iterator_init(int *iterator)
Definition: chan_mgcp.c:1600
Socket address structure.
Definition: netsock2.h:63
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:391
int nonCodecCapability
Definition: chan_mgcp.c:368
int ast_rtp_codecs_payloads_set_rtpmap_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload, char *mimetype, char *mimesubtype, enum ast_rtp_options options)
Record payload information that was seen in an a=rtpmap: SDP line.
Definition: rtp_engine.c:597
static struct ast_hostent ahp
Definition: chan_skinny.c:1047
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int nonCodecCapability
Definition: chan_mgcp.c:229
int64_t format_t
Definition: frame_defs.h:32
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
static format_t capability
Definition: chan_mgcp.c:228
format_t capability
Definition: chan_mgcp.c:367
void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
Clear payload information from an RTP instance.
Definition: rtp_engine.c:488
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
Definition: utils.c:195
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Definition: frame.c:591
static char * get_sdp_iterate(int *iterator, struct mgcp_request *req, char *name)
Definition: chan_mgcp.c:1605
static char * get_sdp(struct mgcp_request *req, char *name)
Definition: chan_mgcp.c:1587
static struct hostent * hp
Definition: chan_skinny.c:1048
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Record payload information that was seen in an m= SDP line.
Definition: rtp_engine.c:532
void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *astformats, int *nonastformats)
Retrieve all formats that were found.
Definition: rtp_engine.c:636
static void prune_gateways ( void  )
static

Definition at line 4544 of file chan_mgcp.c.

References ast_mutex_lock, ast_mutex_unlock, mgcp_endpoint::delme, mgcp_gateway::delme, destroy_endpoint(), destroy_gateway(), mgcp_gateway::endpoints, gatelock, gateways, mgcp_endpoint::next, mgcp_gateway::next, and mgcp_gateway::realtime.

Referenced by reload_config(), and unload_module().

4545 {
4546  struct mgcp_gateway *g, *z, *r;
4547  struct mgcp_endpoint *e, *p, *t;
4548 
4550 
4551  /* prune gateways */
4552  for (z = NULL, g = gateways; g;) {
4553  /* prune endpoints */
4554  for (p = NULL, e = g->endpoints; e; ) {
4555  if (!g->realtime && (e->delme || g->delme)) {
4556  t = e;
4557  e = e->next;
4558  if (!p)
4559  g->endpoints = e;
4560  else
4561  p->next = e;
4562  destroy_endpoint(t);
4563  } else {
4564  p = e;
4565  e = e->next;
4566  }
4567  }
4568 
4569  if (g->delme) {
4570  r = g;
4571  g = g->next;
4572  if (!z)
4573  gateways = g;
4574  else
4575  z->next = g;
4576 
4577  destroy_gateway(r);
4578  } else {
4579  z = g;
4580  g = g->next;
4581  }
4582  }
4583 
4585 }
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
static void destroy_gateway(struct mgcp_gateway *g)
Definition: chan_mgcp.c:4534
#define ast_mutex_lock(a)
Definition: lock.h:155
static void destroy_endpoint(struct mgcp_endpoint *e)
Definition: chan_mgcp.c:4477
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
static struct mgcp_gateway * gateways
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int reload ( void  )
static

Definition at line 4860 of file chan_mgcp.c.

References mgcp_reload().

4861 {
4862  mgcp_reload(NULL, 0, NULL);
4863  return 0;
4864 }
static char * mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_mgcp.c:4827
static int reload_config ( int  reload)
static

Definition at line 4619 of file chan_mgcp.c.

References __ourip, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_getformatbyname(), ast_gethostbyname(), ast_inet_ntoa(), ast_io_remove(), ast_io_wait(), ast_jb_read_conf(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_netsock_set_qos(), ast_sched_runq(), ast_str2cos(), ast_str2tos(), ast_variable_browse(), ast_verb, bindaddr, build_gateway(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MGCP_CA_PORT, mgcp_endpoint::delme, mgcp_gateway::delme, mgcp_gateway::endpoints, errno, format, gatelock, gateways, global_jbconf, hp, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::needaudit, netlock, ast_variable::next, mgcp_endpoint::next, mgcp_gateway::next, prune_gateways(), qos, transmit_audit_endpoint(), and ast_variable::value.

Referenced by do_monitor(), and load_module().

4620 {
4621  struct ast_config *cfg;
4622  struct ast_variable *v;
4623  struct mgcp_gateway *g;
4624  struct mgcp_endpoint *e;
4625  char *cat;
4626  struct ast_hostent ahp;
4627  struct hostent *hp;
4628  int format;
4629  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
4630 
4631  if (gethostname(ourhost, sizeof(ourhost)-1)) {
4632  ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n");
4633  return 0;
4634  }
4635  cfg = ast_config_load(config, config_flags);
4636 
4637  /* We *must* have a config file otherwise stop immediately */
4638  if (!cfg) {
4639  ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config);
4640  return 0;
4641  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
4642  return 0;
4643  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
4644  ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
4645  return 0;
4646  }
4647 
4648  memset(&bindaddr, 0, sizeof(bindaddr));
4649  dtmfmode = 0;
4650 
4651  /* Copy the default jb config over global_jbconf */
4652  memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
4653 
4654  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
4655  /* handle jb conf */
4656  if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
4657  continue;
4658  }
4659 
4660  /* Create the interface list */
4661  if (!strcasecmp(v->name, "bindaddr")) {
4662  if (!(hp = ast_gethostbyname(v->value, &ahp))) {
4663  ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
4664  } else {
4665  memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
4666  }
4667  } else if (!strcasecmp(v->name, "allow")) {
4668  format = ast_getformatbyname(v->value);
4669  if (format < 1) {
4670  ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
4671  } else {
4672  capability |= format;
4673  }
4674  } else if (!strcasecmp(v->name, "disallow")) {
4675  format = ast_getformatbyname(v->value);
4676  if (format < 1) {
4677  ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
4678  } else {
4679  capability &= ~format;
4680  }
4681  } else if (!strcasecmp(v->name, "tos")) {
4682  if (ast_str2tos(v->value, &qos.tos)) {
4683  ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
4684  }
4685  } else if (!strcasecmp(v->name, "tos_audio")) {
4686  if (ast_str2tos(v->value, &qos.tos_audio))
4687  ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
4688  } else if (!strcasecmp(v->name, "cos")) {
4689  if (ast_str2cos(v->value, &qos.cos))
4690  ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
4691  } else if (!strcasecmp(v->name, "cos_audio")) {
4692  if (ast_str2cos(v->value, &qos.cos_audio))
4693  ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
4694  } else if (!strcasecmp(v->name, "port")) {
4695  if (sscanf(v->value, "%5d", &ourport) == 1) {
4696  bindaddr.sin_port = htons(ourport);
4697  } else {
4698  ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
4699  }
4700  } else if (!strcasecmp(v->name, "firstdigittimeout")) {
4701  firstdigittimeout = atoi(v->value);
4702  } else if (!strcasecmp(v->name, "gendigittimeout")) {
4703  gendigittimeout = atoi(v->value);
4704  } else if (!strcasecmp(v->name, "matchdigittimeout")) {
4705  matchdigittimeout = atoi(v->value);
4706  }
4707  }
4708 
4709  /* mark existing entries for deletion */
4711  for (g = gateways; g; g = g->next) {
4712  g->delme = 1;
4713  for (e = g->endpoints; e; e = e->next) {
4714  e->delme = 1;
4715  }
4716  }
4718 
4719  for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
4720  if (strcasecmp(cat, "general")) {
4722  if ((g = build_gateway(cat, ast_variable_browse(cfg, cat)))) {
4723  ast_verb(3, "Added gateway '%s'\n", g->name);
4724  g->next = gateways;
4725  gateways = g;
4726  }
4728 
4729  /* FS: process queue and IO */
4730  if (monitor_thread == pthread_self()) {
4731  if (sched) ast_sched_runq(sched);
4732  if (io) ast_io_wait(io, 10);
4733  }
4734  }
4735  }
4736 
4737  /* prune deleted entries etc. */
4738  prune_gateways();
4739 
4740  if (ntohl(bindaddr.sin_addr.s_addr)) {
4741  memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
4742  } else {
4743  hp = ast_gethostbyname(ourhost, &ahp);
4744  if (!hp) {
4745  ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n");
4746  ast_config_destroy(cfg);
4747  return 0;
4748  }
4749  memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
4750  }
4751  if (!ntohs(bindaddr.sin_port))
4752  bindaddr.sin_port = htons(DEFAULT_MGCP_CA_PORT);
4753  bindaddr.sin_family = AF_INET;
4755  if (mgcpsock > -1)
4756  close(mgcpsock);
4757 
4758  if (mgcpsock_read_id != NULL)
4760  mgcpsock_read_id = NULL;
4761 
4762  mgcpsock = socket(AF_INET, SOCK_DGRAM, 0);
4763  if (mgcpsock < 0) {
4764  ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno));
4765  } else {
4766  if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
4767  ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
4768  ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
4769  strerror(errno));
4770  close(mgcpsock);
4771  mgcpsock = -1;
4772  } else {
4773  ast_verb(2, "MGCP Listening on %s:%d\n",
4774  ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
4775  ast_netsock_set_qos(mgcpsock, qos.tos, qos.cos, "MGCP");
4776  }
4777  }
4779  ast_config_destroy(cfg);
4780 
4781  /* send audit only to the new endpoints */
4782  for (g = gateways; g; g = g->next) {
4783  for (e = g->endpoints; e && e->needaudit; e = e->next) {
4784  e->needaudit = 0;
4786  ast_verb(3, "MGCP Auditing endpoint %s@%s for hookstate\n", e->name, g->name);
4787  }
4788  }
4789 
4790  return 0;
4791 }
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:273
static int mgcpsock
Definition: chan_mgcp.c:425
static int dtmfmode
Definition: chan_mgcp.c:160
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
static int firstdigittimeout
Definition: chan_mgcp.c:207
static struct mgcp_gateway * build_gateway(char *cat, struct ast_variable *v)
build_gateway: parse mgcp.conf and create gateway/endpoint structures
Definition: chan_mgcp.c:3972
static int * mgcpsock_read_id
Definition: chan_mgcp.c:3714
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:577
int lineno
Definition: config.h:87
static const char config[]
Definition: chan_mgcp.c:110
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static char ourhost[MAXHOSTNAMELEN]
Definition: chan_mgcp.c:231
Definition: sched.c:57
int ast_netsock_set_qos(int netsocket, int tos, int cos, const char *desc)
Definition: netsock.c:158
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition: acl.c:667
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int transmit_audit_endpoint(struct mgcp_endpoint *p)
Definition: chan_mgcp.c:2637
static void prune_gateways(void)
Definition: chan_mgcp.c:4544
#define DEFAULT_MGCP_CA_PORT
Definition: chan_mgcp.c:117
static ast_mutex_t netlock
Definition: chan_mgcp.c:217
char name[80]
Definition: chan_mgcp.c:327
const char * value
Definition: config.h:79
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
static struct io_context * io
Definition: chan_mgcp.c:238
char name[80]
Definition: chan_mgcp.c:394
const char * name
Definition: config.h:77
static int reload(void)
Definition: chan_mgcp.c:4860
static struct ast_hostent ahp
Definition: chan_skinny.c:1047
static int gendigittimeout
Definition: chan_mgcp.c:210
format_t ast_getformatbyname(const char *name)
Gets a format from a name.
Definition: frame.c:641
static pthread_t monitor_thread
Definition: chan_mgcp.c:224
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static struct ast_jb_conf global_jbconf
Definition: chan_mgcp.c:107
int errno
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition: acl.c:653
static format_t capability
Definition: chan_mgcp.c:228
static struct mgcp_gateway * gateways
Structure used to handle boolean flags.
Definition: utils.h:200
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:240
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
static struct sockaddr_in bindaddr
Definition: chan_gtalk.c:225
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
Definition: utils.c:195
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int matchdigittimeout
Definition: chan_mgcp.c:213
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
static struct in_addr __ourip
Definition: chan_mgcp.c:232
static struct ast_jb_conf default_jbconf
Definition: chan_mgcp.c:99
static struct hostent * hp
Definition: chan_skinny.c:1048
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static int ourport
Definition: chan_mgcp.c:233
General jitterbuffer configuration.
Definition: abstract_jb.h:55
static struct @97 qos
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int reqprep ( struct mgcp_request req,
struct mgcp_endpoint p,
char *  verb 
)
static

Definition at line 2139 of file chan_mgcp.c.

References ast_mutex_lock, ast_mutex_unlock, init_req(), oseq_global, and oseq_lock.

Referenced by transmit_audit_endpoint(), transmit_connect(), transmit_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_request(), transmit_modify_with_sdp(), transmit_notify_request(), and transmit_notify_request_with_callerid().

2140 {
2141  unsigned int oseq;
2142  memset(req, 0, sizeof(struct mgcp_request));
2144  oseq_global++;
2145  if (oseq_global > 999999999) {
2146  oseq_global = 1;
2147  }
2148  oseq = oseq_global;
2150  init_req(p, req, verb, oseq);
2151  return oseq;
2152 }
static unsigned int oseq_global
Definition: chan_mgcp.c:203
#define ast_mutex_lock(a)
Definition: lock.h:155
Definition: logger.c:927
static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb, unsigned int oseq)
Definition: chan_mgcp.c:2108
static ast_mutex_t oseq_lock
Definition: chan_mgcp.c:204
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int resend_response ( struct mgcp_subchannel sub,
struct mgcp_response resp 
)
static

Definition at line 558 of file chan_mgcp.c.

References __mgcp_xmit(), mgcp_gateway::addr, ast_debug, ast_inet_ntoa(), mgcp_response::buf, mgcp_response::len, mgcp_subchannel::parent, and mgcp_endpoint::parent.

Referenced by find_and_retrans().

559 {
560  struct mgcp_endpoint *p = sub->parent;
561  int res;
562  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));
563  res = __mgcp_xmit(p->parent, resp->buf, resp->len);
564  if (res > 0)
565  res = 0;
566  return res;
567 }
static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
Definition: chan_mgcp.c:545
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct sockaddr_in addr
Definition: chan_mgcp.c:396
char buf[0]
Definition: chan_mgcp.c:281
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int respprep ( struct mgcp_request resp,
struct mgcp_endpoint p,
char *  msg,
struct mgcp_request req,
char *  msgrest 
)
static

Definition at line 2132 of file chan_mgcp.c.

References init_resp().

Referenced by transmit_response().

2133 {
2134  memset(resp, 0, sizeof(*resp));
2135  init_resp(resp, msg, req, msgrest);
2136  return 0;
2137 }
static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
Definition: chan_mgcp.c:2090
static int restart_monitor ( void  )
static

Definition at line 3892 of file chan_mgcp.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monlock.

Referenced by load_module(), mgcp_reload(), and mgcp_request().

3893 {
3894  /* If we're supposed to be stopped -- stay stopped */
3896  return 0;
3897  if (ast_mutex_lock(&monlock)) {
3898  ast_log(LOG_WARNING, "Unable to lock monitor\n");
3899  return -1;
3900  }
3901  if (monitor_thread == pthread_self()) {
3903  ast_log(LOG_WARNING, "Cannot kill myself\n");
3904  return -1;
3905  }
3907  /* Wake up the thread */
3908  pthread_kill(monitor_thread, SIGURG);
3909  } else {
3910  /* Start a new monitor */
3911  if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
3913  ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
3914  return -1;
3915  }
3916  }
3918  return 0;
3919 }
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
static void * do_monitor(void *data)
Definition: chan_mgcp.c:3774
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define AST_PTHREADT_NULL
Definition: lock.h:65
static pthread_t monitor_thread
Definition: chan_mgcp.c:224
static ast_mutex_t monlock
Definition: chan_mgcp.c:219
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_PTHREADT_STOP
Definition: lock.h:66
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int retrans_pkt ( const void *  data)
static

Definition at line 655 of file chan_mgcp.c.

References __mgcp_xmit(), ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, mgcp_message::buf, handle_response(), mgcp_message::len, LOG_WARNING, MAX_RETRANS, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_message::owner_ep, mgcp_message::owner_sub, mgcp_message::retrans, mgcp_gateway::retransid, and mgcp_message::seqno.

Referenced by mgcp_postrequest().

656 {
657  struct mgcp_gateway *gw = (struct mgcp_gateway *)data;
658  struct mgcp_message *cur, *exq = NULL, *w, *prev;
659  int res = 0;
660 
661  /* find out expired msgs */
663 
664  for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
665  if (cur->retrans < MAX_RETRANS) {
666  cur->retrans++;
667  ast_debug(1, "Retransmitting #%d transaction %u on [%s]\n",
668  cur->retrans, cur->seqno, gw->name);
669  __mgcp_xmit(gw, cur->buf, cur->len);
670  } else {
671  if (prev)
672  prev->next = cur->next;
673  else
674  gw->msgs = cur->next;
675 
676  ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n",
677  cur->seqno, gw->name);
678 
679  w = cur;
680 
681  if (exq) {
682  w->next = exq;
683  } else {
684  w->next = NULL;
685  }
686  exq = w;
687  }
688  }
689 
690  if (!gw->msgs) {
691  gw->retransid = -1;
692  res = 0;
693  } else {
694  res = 1;
695  }
697 
698  while (exq) {
699  cur = exq;
700  /* time-out transaction */
701  handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL);
702  exq = exq->next;
703  ast_free(cur);
704  }
705 
706  return res;
707 }
static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
Definition: chan_mgcp.c:545
static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp)
Definition: chan_mgcp.c:2758
struct mgcp_endpoint * owner_ep
Definition: chan_mgcp.c:264
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t msgs_lock
Definition: chan_mgcp.c:411
mgcp_message: MGCP message for queuing up
Definition: chan_mgcp.c:263
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char buf[0]
Definition: chan_mgcp.c:271
struct mgcp_message * msgs
Definition: chan_mgcp.c:410
char name[80]
Definition: chan_mgcp.c:394
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
#define MAX_RETRANS
Definition: chan_mgcp.c:120
struct mgcp_message * next
Definition: chan_mgcp.c:270
unsigned int seqno
Definition: chan_mgcp.c:268
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct mgcp_subchannel * owner_sub
Definition: chan_mgcp.c:265
static void sdpLineNum_iterator_init ( int *  iterator)
static

Definition at line 1600 of file chan_mgcp.c.

Referenced by process_sdp().

1601 {
1602  *iterator = 0;
1603 }
static int send_request ( struct mgcp_endpoint p,
struct mgcp_subchannel sub,
struct mgcp_request req,
unsigned int  seqno 
)
static

Definition at line 754 of file chan_mgcp.c.

References mgcp_gateway::addr, ast_debug, ast_free, ast_inet_ntoa(), ast_log(), ast_malloc, ast_mutex_lock, ast_mutex_unlock, mgcp_request::cmd, mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_request::data, mgcp_request::len, LOG_WARNING, MGCP_CMD_CRCX, MGCP_CMD_DLCX, MGCP_CMD_MDCX, MGCP_CMD_RQNT, mgcp_postrequest(), mgcp_endpoint::ncs, mgcp_request::next, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, and mgcp_endpoint::slowsequence.

Referenced by transmit_audit_endpoint(), transmit_connect(), transmit_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_request(), transmit_modify_with_sdp(), transmit_notify_request(), and transmit_notify_request_with_callerid().

756 {
757  int res = 0;
758  struct mgcp_request **queue, *q, *r, *t;
759  ast_mutex_t *l;
760 
761  ast_debug(1, "Slow sequence is %d\n", p->slowsequence);
762  if (p->slowsequence) {
763  queue = &p->cmd_queue;
764  l = &p->cmd_queue_lock;
765  ast_mutex_lock(l);
766  } else {
767  switch (req->cmd) {
768  case MGCP_CMD_DLCX:
769  queue = &sub->cx_queue;
770  l = &sub->cx_queue_lock;
771  ast_mutex_lock(l);
772  q = sub->cx_queue;
773  /* delete pending cx cmds */
774  /* buggy sb5120 */
775  if (!sub->parent->ncs) {
776  while (q) {
777  r = q->next;
778  ast_free(q);
779  q = r;
780  }
781  *queue = NULL;
782  }
783  break;
784 
785  case MGCP_CMD_CRCX:
786  case MGCP_CMD_MDCX:
787  queue = &sub->cx_queue;
788  l = &sub->cx_queue_lock;
789  ast_mutex_lock(l);
790  break;
791 
792  case MGCP_CMD_RQNT:
793  queue = &p->rqnt_queue;
794  l = &p->rqnt_queue_lock;
795  ast_mutex_lock(l);
796  break;
797 
798  default:
799  queue = &p->cmd_queue;
800  l = &p->cmd_queue_lock;
801  ast_mutex_lock(l);
802  break;
803  }
804  }
805 
806  if (!(r = ast_malloc(sizeof(*r)))) {
807  ast_log(LOG_WARNING, "Cannot post MGCP request: insufficient memory\n");
808  ast_mutex_unlock(l);
809  return -1;
810  }
811  memcpy(r, req, sizeof(*r));
812 
813  if (!(*queue)) {
814  ast_debug(1, "Posting Request:\n%s to %s:%d\n", req->data,
815  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
816 
817  res = mgcp_postrequest(p, sub, req->data, req->len, seqno);
818  } else {
819  ast_debug(1, "Queueing Request:\n%s to %s:%d\n", req->data,
820  ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
821  }
822 
823  /* XXX find tail. We could also keep tail in the data struct for faster access */
824  for (t = *queue; t && t->next; t = t->next);
825 
826  r->next = NULL;
827  if (t)
828  t->next = r;
829  else
830  *queue = r;
831 
832  ast_mutex_unlock(l);
833 
834  return res;
835 }
struct mgcp_request * cx_queue
Definition: chan_mgcp.c:308
ast_mutex_t cmd_queue_lock
Definition: chan_mgcp.c:378
int slowsequence
Definition: chan_mgcp.c:362
#define LOG_WARNING
Definition: logger.h:144
struct mgcp_request * next
Definition: chan_mgcp.c:259
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct mgcp_request * rqnt_queue
Definition: chan_mgcp.c:375
static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno)
Definition: chan_mgcp.c:710
ast_mutex_t cx_queue_lock
Definition: chan_mgcp.c:309
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct sockaddr_in addr
Definition: chan_mgcp.c:396
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ast_free(a)
Definition: astmm.h:97
ast_mutex_t rqnt_queue_lock
Definition: chan_mgcp.c:376
struct mgcp_request * cmd_queue
Definition: chan_mgcp.c:377
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
#define ast_malloc(a)
Definition: astmm.h:91
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
Structure for mutex and tracking information.
Definition: lock.h:121
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int send_response ( struct mgcp_subchannel sub,
struct mgcp_request req 
)
static

Definition at line 569 of file chan_mgcp.c.

References __mgcp_xmit(), mgcp_gateway::addr, ast_debug, ast_inet_ntoa(), mgcp_request::data, mgcp_request::len, mgcp_subchannel::parent, and mgcp_endpoint::parent.

Referenced by transmit_response().

570 {
571  struct mgcp_endpoint *p = sub->parent;
572  int res;
573  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));
574  res = __mgcp_xmit(p->parent, req->data, req->len);
575  if (res > 0)
576  res = 0;
577  return res;
578 }
static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
Definition: chan_mgcp.c:545
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct sockaddr_in addr
Definition: chan_mgcp.c:396
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
char data[MGCP_MAX_PACKET]
Definition: chan_mgcp.c:256
static void start_rtp ( struct mgcp_subchannel sub)
static

Definition at line 2928 of file chan_mgcp.c.

References ast_channel_set_fd(), ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_rtp_instance_destroy(), ast_rtp_instance_fd(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), AST_RTP_PROPERTY_NAT, ast_sockaddr_from_sin, bindaddr, mgcp_subchannel::callid, mgcp_subchannel::gate, mgcp_subchannel::lock, mgcp_alloc_pktcgate(), mgcp_queue_hangup(), mgcp_subchannel::nat, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::pktcgatealloc, qos, mgcp_subchannel::rtp, transmit_connect(), transmit_connect_with_sdp(), and mgcp_subchannel::txident.

Referenced by handle_hd_hf(), handle_response(), mgcp_answer(), mgcp_call(), and mgcp_ss().

2929 {
2930  struct ast_sockaddr bindaddr_tmp;
2931 
2932  ast_mutex_lock(&sub->lock);
2933  /* check again to be on the safe side */
2934  if (sub->rtp) {
2936  sub->rtp = NULL;
2937  }
2938  /* Allocate the RTP now */
2939  ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
2940  sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
2941  if (sub->rtp && sub->owner)
2942  ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
2943  if (sub->rtp) {
2944  ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "MGCP RTP");
2946  }
2947  /* Make a call*ID */
2948  snprintf(sub->callid, sizeof(sub->callid), "%08lx%s", (unsigned long)ast_random(), sub->txident);
2949  /* Transmit the connection create */
2950  if(!sub->parent->pktcgatealloc) {
2951  transmit_connect_with_sdp(sub, NULL);
2952  } else {
2953  transmit_connect(sub);
2954  sub->gate = NULL;
2955  if(!mgcp_alloc_pktcgate(sub))
2956  mgcp_queue_hangup(sub);
2957  }
2958  ast_mutex_unlock(&sub->lock);
2959 }
struct cops_gate * gate
Definition: chan_mgcp.c:315
char callid[80]
Definition: chan_mgcp.c:306
static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
Definition: chan_mgcp.c:2334
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
Definition: rtp_engine.c:774
static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:632
Definition: sched.c:57
ast_mutex_t lock
Definition: chan_mgcp.c:297
#define ast_mutex_lock(a)
Definition: lock.h:155
Socket address structure.
Definition: netsock2.h:63
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static int mgcp_alloc_pktcgate(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2416
static int transmit_connect(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2430
struct ast_channel * owner
Definition: chan_mgcp.c:299
long int ast_random(void)
Definition: utils.c:1640
int pktcgatealloc
Definition: chan_mgcp.c:359
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:786
char txident[80]
Definition: chan_mgcp.c:303
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:308
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:301
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2631
static struct sockaddr_in bindaddr
Definition: chan_gtalk.c:225
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:469
static struct @97 qos
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int transmit_audit_endpoint ( struct mgcp_endpoint p)
static

Definition at line 2637 of file chan_mgcp.c.

References add_header(), mgcp_request::cmd, MGCP_CMD_AUEP, reqprep(), send_request(), and mgcp_request::trid.

Referenced by find_realtime_gw(), handle_mgcp_audit_endpoint(), handle_request(), and reload_config().

2638 {
2639  struct mgcp_request resp;
2640  unsigned int oseq;
2641  oseq = reqprep(&resp, p, "AUEP");
2642  /* removed unknown param VS */
2643  /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/
2644  add_header(&resp, "F", "A");
2645  /* fill in new fields */
2646  resp.cmd = MGCP_CMD_AUEP;
2647  resp.trid = oseq;
2648  return send_request(p, NULL, &resp, oseq);
2649 }
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_connect ( struct mgcp_subchannel sub)
static

Definition at line 2430 of file chan_mgcp.c.

References add_header(), ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_rtp_lookup_mime_subtype2(), mgcp_subchannel::callid, mgcp_endpoint::capability, mgcp_request::cmd, mgcp_subchannel::cxmode, mgcp_subchannel::id, MGCP_CMD_CRCX, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::parent, mgcp_endpoint::parent, reqprep(), mgcp_subchannel::sdpsent, send_request(), mgcp_request::trid, and mgcp_subchannel::txident.

Referenced by start_rtp().

2431 {
2432  struct mgcp_request resp;
2433  char local[256];
2434  char tmp[80];
2435  format_t x;
2436  struct mgcp_endpoint *p = sub->parent;
2437  unsigned int oseq;
2438 
2439  ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
2440 
2441  for (x = 1LL; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
2442  if (p->capability & x) {
2443  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
2444  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2445  }
2446  }
2447 
2448  ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2449  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2450  sub->sdpsent = 0;
2451  oseq = reqprep(&resp, p, "CRCX");
2452  add_header(&resp, "C", sub->callid);
2453  add_header(&resp, "L", local);
2454  add_header(&resp, "M", "inactive");
2455  /* X header should not be sent. kept for compatibility */
2456  add_header(&resp, "X", sub->txident);
2457  /*add_header(&resp, "S", "");*/
2458  /* fill in new fields */
2459  resp.cmd = MGCP_CMD_CRCX;
2460  resp.trid = oseq;
2461  return send_request(p, sub, &resp, oseq);
2462 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
char callid[80]
Definition: chan_mgcp.c:306
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
char name[80]
Definition: chan_mgcp.c:394
int64_t format_t
Definition: frame_defs.h:32
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
format_t capability
Definition: chan_mgcp.c:367
char txident[80]
Definition: chan_mgcp.c:303
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:673
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_connect_with_sdp ( struct mgcp_subchannel sub,
struct ast_rtp_instance rtp 
)
static

Definition at line 2334 of file chan_mgcp.c.

References add_header(), add_sdp(), ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_rtp_lookup_mime_subtype2(), mgcp_subchannel::callid, mgcp_endpoint::capability, mgcp_request::cmd, mgcp_subchannel::cxmode, mgcp_subchannel::gate, GATE_ALLOCATED, cops_gate::gateid, mgcp_subchannel::id, MGCP_CMD_CRCX, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::parent, mgcp_endpoint::parent, reqprep(), mgcp_subchannel::sdpsent, send_request(), cops_gate::state, mgcp_request::trid, and mgcp_subchannel::txident.

Referenced by start_rtp().

2335 {
2336  struct mgcp_request resp;
2337  char local[256];
2338  char tmp[80];
2339  int x;
2340  struct mgcp_endpoint *p = sub->parent;
2341  unsigned int oseq;
2342 
2343  ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2344  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2345 
2346  ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
2347 
2348  for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
2349  if (!(x & AST_FORMAT_AUDIO_MASK)) {
2350  /* No longer contiguous */
2351  continue;
2352  }
2353  if (p->capability & x) {
2354  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
2355  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2356  }
2357  }
2358 
2359  if (sub->gate) {
2360  if(sub->gate->state == GATE_ALLOCATED) {
2361  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2362  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2363  }
2364  }
2365  sub->sdpsent = 1;
2366  oseq = reqprep(&resp, p, "CRCX");
2367  add_header(&resp, "C", sub->callid);
2368  add_header(&resp, "L", local);
2369  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2370  /* X header should not be sent. kept for compatibility */
2371  add_header(&resp, "X", sub->txident);
2372  /*add_header(&resp, "S", "");*/
2373  add_sdp(&resp, sub, rtp);
2374  /* fill in new fields */
2375  resp.cmd = MGCP_CMD_CRCX;
2376  resp.trid = oseq;
2377  return send_request(p, sub, &resp, oseq);
2378 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
struct cops_gate * gate
Definition: chan_mgcp.c:315
char callid[80]
Definition: chan_mgcp.c:306
static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
Definition: chan_mgcp.c:2181
int state
Definition: pktccops.h:59
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
char name[80]
Definition: chan_mgcp.c:394
uint32_t gateid
Definition: pktccops.h:55
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
format_t capability
Definition: chan_mgcp.c:367
char txident[80]
Definition: chan_mgcp.c:303
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:673
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_connection_del ( struct mgcp_subchannel sub)
static

Definition at line 2651 of file chan_mgcp.c.

References add_header(), ast_debug, mgcp_subchannel::callid, mgcp_request::cmd, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_subchannel::id, MGCP_CMD_DLCX, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::parent, mgcp_endpoint::parent, reqprep(), send_request(), mgcp_request::trid, and mgcp_subchannel::txident.

Referenced by destroy_endpoint(), handle_request(), handle_response(), mgcp_hangup(), and unalloc_sub().

2652 {
2653  struct mgcp_endpoint *p = sub->parent;
2654  struct mgcp_request resp;
2655  unsigned int oseq;
2656 
2657  ast_debug(3, "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n",
2658  sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2659  oseq = reqprep(&resp, p, "DLCX");
2660  /* check if call id is avail */
2661  if (sub->callid[0])
2662  add_header(&resp, "C", sub->callid);
2663  /* X header should not be sent. kept for compatibility */
2664  add_header(&resp, "X", sub->txident);
2665  /* check if cxident is avail */
2666  if (sub->cxident[0])
2667  add_header(&resp, "I", sub->cxident);
2668  /* fill in new fields */
2669  resp.cmd = MGCP_CMD_DLCX;
2670  resp.trid = oseq;
2671  return send_request(p, sub, &resp, oseq);
2672 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
char callid[80]
Definition: chan_mgcp.c:306
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
char name[80]
Definition: chan_mgcp.c:394
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
char cxident[80]
Definition: chan_mgcp.c:305
char txident[80]
Definition: chan_mgcp.c:303
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_connection_del_w_params ( struct mgcp_endpoint p,
char *  callid,
char *  cxident 
)
static

Definition at line 2674 of file chan_mgcp.c.

References add_header(), ast_debug, mgcp_request::cmd, MGCP_CMD_DLCX, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::parent, reqprep(), send_request(), mgcp_endpoint::sub, and mgcp_request::trid.

Referenced by handle_response().

2675 {
2676  struct mgcp_request resp;
2677  unsigned int oseq;
2678 
2679  ast_debug(3, "Delete connection %s %s@%s on callid: %s\n",
2680  cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
2681  oseq = reqprep(&resp, p, "DLCX");
2682  /* check if call id is avail */
2683  if (callid && *callid)
2684  add_header(&resp, "C", callid);
2685  /* check if cxident is avail */
2686  if (cxident && *cxident)
2687  add_header(&resp, "I", cxident);
2688  /* fill in new fields */
2689  resp.cmd = MGCP_CMD_DLCX;
2690  resp.trid = oseq;
2691  return send_request(p, p->sub, &resp, oseq);
2692 }
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
char name[80]
Definition: chan_mgcp.c:394
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_modify_request ( struct mgcp_subchannel sub)
static

Definition at line 2537 of file chan_mgcp.c.

References add_header(), add_header_offhook(), add_sdp(), ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_rtp_lookup_mime_subtype2(), ast_strlen_zero(), mgcp_subchannel::callid, mgcp_endpoint::capability, mgcp_request::cmd, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_subchannel::gate, GATE_ALLOCATED, GATE_OPEN, cops_gate::gateid, mgcp_endpoint::hookstate, mgcp_subchannel::id, MGCP_CMD_MDCX, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::ncs, mgcp_subchannel::parent, mgcp_endpoint::parent, reqprep(), mgcp_subchannel::sdpsent, send_request(), cops_gate::state, mgcp_request::trid, and mgcp_subchannel::txident.

Referenced by handle_hd_hf(), handle_request(), mgcp_answer(), mgcp_call(), mgcp_hangup(), and mgcp_indicate().

2538 {
2539  struct mgcp_request resp;
2540  struct mgcp_endpoint *p = sub->parent;
2541  format_t x;
2542  int fc = 1;
2543  char local[256];
2544  char tmp[80];
2545  unsigned int oseq;
2546 
2547  if (ast_strlen_zero(sub->cxident)) {
2548  /* We don't have a CXident yet, store the destination and
2549  wait a bit */
2550  return 0;
2551  }
2552  ast_debug(3, "Modified %s@%s-%d with new mode: %s on callid: %s\n",
2553  p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
2554 
2555  ast_copy_string(local, "", sizeof(local));
2556  for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
2557  if (p->capability & x) {
2558  if (p->ncs && !fc) {
2559  p->capability = x; /* sb5120e bug */
2560  break;
2561  } else {
2562  fc = 0;
2563  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
2564  }
2565  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2566  }
2567  }
2568 
2569  if (!sub->sdpsent) {
2570  if (sub->gate) {
2571  if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
2572  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2573  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2574  } else {
2575  /* we still don't have gateid wait */
2576  return 0;
2577  }
2578  }
2579  }
2580 
2581  oseq = reqprep(&resp, p, "MDCX");
2582  add_header(&resp, "C", sub->callid);
2583  if (!sub->sdpsent) {
2584  add_header(&resp, "L", local);
2585  }
2586  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2587  /* X header should not be sent. kept for compatibility */
2588  add_header(&resp, "X", sub->txident);
2589  add_header(&resp, "I", sub->cxident);
2590  switch (sub->parent->hookstate) {
2591  case MGCP_ONHOOK:
2592  add_header(&resp, "R", "L/hd(N)");
2593  break;
2594  case MGCP_OFFHOOK:
2595  add_header_offhook(sub, &resp, "");
2596  break;
2597  }
2598  if (!sub->sdpsent) {
2599  add_sdp(&resp, sub, NULL);
2600  sub->sdpsent = 1;
2601  }
2602  /* fill in new fields */
2603  resp.cmd = MGCP_CMD_MDCX;
2604  resp.trid = oseq;
2605  return send_request(p, sub, &resp, oseq);
2606 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
struct cops_gate * gate
Definition: chan_mgcp.c:315
char callid[80]
Definition: chan_mgcp.c:306
static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
Definition: chan_mgcp.c:2181
int state
Definition: pktccops.h:59
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
char name[80]
Definition: chan_mgcp.c:394
uint32_t gateid
Definition: pktccops.h:55
int64_t format_t
Definition: frame_defs.h:32
static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
Definition: chan_mgcp.c:2609
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
char cxident[80]
Definition: chan_mgcp.c:305
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
format_t capability
Definition: chan_mgcp.c:367
char txident[80]
Definition: chan_mgcp.c:303
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:673
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_modify_with_sdp ( struct mgcp_subchannel sub,
struct ast_rtp_instance rtp,
format_t  codecs 
)
static

Definition at line 2276 of file chan_mgcp.c.

References add_header(), add_sdp(), ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_rtp_instance_get_remote_address(), ast_rtp_lookup_mime_subtype2(), ast_sockaddr_to_sin, ast_strlen_zero(), mgcp_subchannel::callid, mgcp_endpoint::capability, mgcp_request::cmd, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_subchannel::gate, GATE_ALLOCATED, GATE_OPEN, cops_gate::gateid, MGCP_CMD_MDCX, mgcp_subchannel::parent, reqprep(), mgcp_subchannel::sdpsent, send_request(), cops_gate::state, mgcp_subchannel::tmpdest, mgcp_request::trid, and mgcp_subchannel::txident.

Referenced by handle_response(), mgcp_pktcgate_open(), mgcp_set_rtp_peer(), and mgcp_write().

2277 {
2278  struct mgcp_request resp;
2279  char local[256];
2280  char tmp[80];
2281  struct mgcp_endpoint *p = sub->parent;
2282  format_t x;
2283  struct ast_sockaddr sub_tmpdest_tmp;
2284  unsigned int oseq;
2285 
2286  if (ast_strlen_zero(sub->cxident) && rtp) {
2287  /* We don't have a CXident yet, store the destination and
2288  wait a bit */
2289  ast_rtp_instance_get_remote_address(rtp, &sub_tmpdest_tmp);
2290  ast_sockaddr_to_sin(&sub_tmpdest_tmp, &sub->tmpdest);
2291  return 0;
2292  }
2293  ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
2294  for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
2295  if (!(x & AST_FORMAT_AUDIO_MASK)) {
2296  /* No longer contiguous */
2297  continue;
2298  }
2299  if (p->capability & x) {
2300  snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
2301  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2302  }
2303  }
2304 
2305  if (sub->gate) {
2306  if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
2307  snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
2308  strncat(local, tmp, sizeof(local) - strlen(local) - 1);
2309  sub->sdpsent = 1;
2310  } else {
2311  /* oops wait */
2312  ast_debug(1, "Waiting for opened gate...\n");
2313  sub->sdpsent = 0;
2314  return 0;
2315  }
2316  }
2317 
2318 
2319  oseq = reqprep(&resp, p, "MDCX");
2320  add_header(&resp, "C", sub->callid);
2321  add_header(&resp, "L", local);
2322  add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
2323  /* X header should not be sent. kept for compatibility */
2324  add_header(&resp, "X", sub->txident);
2325  add_header(&resp, "I", sub->cxident);
2326  /*add_header(&resp, "S", "");*/
2327  add_sdp(&resp, sub, rtp);
2328  /* fill in new fields */
2329  resp.cmd = MGCP_CMD_MDCX;
2330  resp.trid = oseq;
2331  return send_request(p, sub, &resp, oseq);
2332 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
struct cops_gate * gate
Definition: chan_mgcp.c:315
char callid[80]
Definition: chan_mgcp.c:306
static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
Definition: chan_mgcp.c:2181
int state
Definition: pktccops.h:59
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
struct sockaddr_in tmpdest
Definition: chan_mgcp.c:302
Socket address structure.
Definition: netsock2.h:63
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
uint32_t gateid
Definition: pktccops.h:55
int64_t format_t
Definition: frame_defs.h:32
char cxident[80]
Definition: chan_mgcp.c:305
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
format_t capability
Definition: chan_mgcp.c:367
char txident[80]
Definition: chan_mgcp.c:303
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:673
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_notify_request ( struct mgcp_subchannel sub,
char *  tone 
)
static

Definition at line 2464 of file chan_mgcp.c.

References add_header(), add_header_offhook(), ast_copy_string(), ast_debug, ast_strlen_zero(), mgcp_request::cmd, mgcp_endpoint::curtone, mgcp_subchannel::cxmode, mgcp_endpoint::hookstate, mgcp_subchannel::id, MGCP_CMD_RQNT, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::parent, mgcp_endpoint::parent, reqprep(), mgcp_endpoint::rqnt_ident, send_request(), and mgcp_request::trid.

Referenced by do_monitor(), handle_hd_hf(), handle_request(), handle_response(), mgcp_answer(), mgcp_hangup(), mgcp_indicate(), mgcp_request(), mgcp_senddigit_end(), and mgcp_ss().

2465 {
2466  struct mgcp_request resp;
2467  struct mgcp_endpoint *p = sub->parent;
2468  unsigned int oseq;
2469 
2470  ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2471  tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2472  ast_copy_string(p->curtone, tone, sizeof(p->curtone));
2473  oseq = reqprep(&resp, p, "RQNT");
2474  add_header(&resp, "X", p->rqnt_ident);
2475  switch (p->hookstate) {
2476  case MGCP_ONHOOK:
2477  add_header(&resp, "R", "L/hd(N)");
2478  break;
2479  case MGCP_OFFHOOK:
2480  add_header_offhook(sub, &resp, tone);
2481  break;
2482  }
2483  if (!ast_strlen_zero(tone)) {
2484  add_header(&resp, "S", tone);
2485  }
2486  /* fill in new fields */
2487  resp.cmd = MGCP_CMD_RQNT;
2488  resp.trid = oseq;
2489  return send_request(p, NULL, &resp, oseq);
2490 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
char curtone[80]
Definition: chan_mgcp.c:339
char rqnt_ident[80]
Definition: chan_mgcp.c:374
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
char name[80]
Definition: chan_mgcp.c:394
static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
Definition: chan_mgcp.c:2609
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_notify_request_with_callerid ( struct mgcp_subchannel sub,
char *  tone,
char *  callernum,
char *  callername 
)
static

Definition at line 2492 of file chan_mgcp.c.

References add_header(), add_header_offhook(), ast_copy_string(), ast_debug, ast_localtime(), ast_strlen_zero(), ast_tvnow(), mgcp_request::cmd, mgcp_endpoint::curtone, mgcp_subchannel::cxmode, mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_endpoint::lastcallerid, MGCP_CMD_RQNT, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::parent, mgcp_endpoint::parent, reqprep(), mgcp_endpoint::rqnt_ident, send_request(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, and mgcp_request::trid.

Referenced by mgcp_call(), and mgcp_hangup().

2493 {
2494  struct mgcp_request resp;
2495  char tone2[256];
2496  char *l, *n;
2497  struct timeval t = ast_tvnow();
2498  struct ast_tm tm;
2499  struct mgcp_endpoint *p = sub->parent;
2500  unsigned int oseq;
2501 
2502  ast_localtime(&t, &tm, NULL);
2503  n = callername;
2504  l = callernum;
2505  if (!n)
2506  n = "";
2507  if (!l)
2508  l = "";
2509 
2510  /* Keep track of last callerid for blacklist and callreturn */
2511  ast_copy_string(p->lastcallerid, l, sizeof(p->lastcallerid));
2512 
2513  snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone,
2514  tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
2515  ast_copy_string(p->curtone, tone, sizeof(p->curtone));
2516  oseq = reqprep(&resp, p, "RQNT");
2517  add_header(&resp, "X", p->rqnt_ident);
2518  switch (p->hookstate) {
2519  case MGCP_ONHOOK:
2520  add_header(&resp, "R", "L/hd(N)");
2521  break;
2522  case MGCP_OFFHOOK:
2523  add_header_offhook(sub, &resp, tone);
2524  break;
2525  }
2526  if (!ast_strlen_zero(tone2)) {
2527  add_header(&resp, "S", tone2);
2528  }
2529  ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2530  tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
2531  /* fill in new fields */
2532  resp.cmd = MGCP_CMD_RQNT;
2533  resp.trid = oseq;
2534  return send_request(p, NULL, &resp, oseq);
2535 }
static const char *const mgcp_cxmodes[]
Definition: chan_mgcp.c:132
char lastcallerid[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:335
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
Definition: chan_mgcp.c:2139
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
char curtone[80]
Definition: chan_mgcp.c:339
char rqnt_ident[80]
Definition: chan_mgcp.c:374
#define MGCP_ONHOOK
Definition: chan_mgcp.c:319
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MGCP_OFFHOOK
Definition: chan_mgcp.c:320
char name[80]
Definition: chan_mgcp.c:394
static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
Definition: chan_mgcp.c:2609
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
Definition: chan_mgcp.c:754
static int add_header(struct mgcp_request *req, const char *var, const char *value)
Definition: chan_mgcp.c:2045
static int transmit_response ( struct mgcp_subchannel sub,
char *  msg,
struct mgcp_request req,
char *  msgrest 
)
static

Definition at line 2154 of file chan_mgcp.c.

References ast_calloc, mgcp_response::buf, mgcp_request::data, mgcp_request::identifier, mgcp_request::len, mgcp_response::len, mgcp_response::next, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_gateway::responses, respprep(), send_response(), mgcp_response::seqno, and mgcp_response::whensent.

Referenced by handle_request(), and handle_response().

2155 {
2156  struct mgcp_request resp;
2157  struct mgcp_endpoint *p = sub->parent;
2158  struct mgcp_response *mgr;
2159 
2160  if (!sub) {
2161  return -1;
2162  }
2163 
2164  respprep(&resp, p, msg, req, msgrest);
2165  if (!(mgr = ast_calloc(1, sizeof(*mgr) + resp.len + 1))) {
2166  return send_response(sub, &resp);
2167  }
2168  /* Store MGCP response in case we have to retransmit */
2169  sscanf(req->identifier, "%30d", &mgr->seqno);
2170  time(&mgr->whensent);
2171  mgr->len = resp.len;
2172  memcpy(mgr->buf, resp.data, resp.len);
2173  mgr->buf[resp.len] = '\0';
2174  mgr->next = p->parent->responses;
2175  p->parent->responses = mgr;
2176 
2177  return send_response(sub, &resp);
2178 }
char * identifier
Definition: chan_mgcp.c:249
static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req)
Definition: chan_mgcp.c:569
struct mgcp_response * responses
Definition: chan_mgcp.c:415
struct mgcp_response * next
Definition: chan_mgcp.c:280
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
char buf[0]
Definition: chan_mgcp.c:281
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
#define ast_calloc(a, b)
Definition: astmm.h:82
static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
Definition: chan_mgcp.c:2132
time_t whensent
Definition: chan_mgcp.c:277
static int unalloc_sub ( struct mgcp_subchannel sub)
static

Definition at line 517 of file chan_mgcp.c.

References mgcp_subchannel::alreadygone, ast_debug, ast_log(), ast_rtp_instance_destroy(), ast_strlen_zero(), mgcp_subchannel::callid, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, dump_cmd_queues(), mgcp_subchannel::id, LOG_WARNING, MGCP_CX_INACTIVE, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_subchannel::rtp, mgcp_endpoint::sub, mgcp_subchannel::tmpdest, and transmit_connection_del().

Referenced by attempt_transfer().

518 {
519  struct mgcp_endpoint *p = sub->parent;
520  if (p->sub == sub) {
521  ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, p->parent->name);
522  return -1;
523  }
524  ast_debug(1, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name);
525 
526  sub->owner = NULL;
527  if (!ast_strlen_zero(sub->cxident)) {
529  }
530  sub->cxident[0] = '\0';
531  sub->callid[0] = '\0';
532  sub->cxmode = MGCP_CX_INACTIVE;
533  sub->outgoing = 0;
534  sub->alreadygone = 0;
535  memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
536  if (sub->rtp) {
538  sub->rtp = NULL;
539  }
540  dump_cmd_queues(NULL, sub);
541  return 0;
542 }
char callid[80]
Definition: chan_mgcp.c:306
struct mgcp_subchannel * sub
Definition: chan_mgcp.c:328
#define LOG_WARNING
Definition: logger.h:144
struct sockaddr_in tmpdest
Definition: chan_mgcp.c:302
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[80]
Definition: chan_mgcp.c:327
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_channel * owner
Definition: chan_mgcp.c:299
char name[80]
Definition: chan_mgcp.c:394
static int transmit_connection_del(struct mgcp_subchannel *sub)
Definition: chan_mgcp.c:2651
struct mgcp_gateway * parent
Definition: chan_mgcp.c:389
char cxident[80]
Definition: chan_mgcp.c:305
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
dump_cmd_queues: (SC:) cleanup pending commands
Definition: chan_mgcp.c:2695
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:301
struct ast_rtp_instance * rtp
Definition: chan_mgcp.c:301
struct mgcp_endpoint * parent
Definition: chan_mgcp.c:300
#define MGCP_CX_INACTIVE
Definition: chan_mgcp.c:129
static int unload_module ( void  )
static

Definition at line 4866 of file chan_mgcp.c.

References ast_channel_register(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), mgcp_endpoint::delme, mgcp_gateway::delme, mgcp_gateway::endpoints, gatelock, gateways, LOG_WARNING, mgcp_reload(), mgcp_reload_lock, monlock, mgcp_endpoint::next, mgcp_gateway::next, prune_gateways(), and sched_context_destroy().

4867 {
4868  struct mgcp_endpoint *e;
4869  struct mgcp_gateway *g;
4870 
4871  /* Check to see if we're reloading */
4873  ast_log(LOG_WARNING, "MGCP is currently reloading. Unable to remove module.\n");
4874  return -1;
4875  } else {
4876  mgcp_reloading = 1;
4878  }
4879 
4880  /* First, take us out of the channel loop */
4882 
4883  /* Shut down the monitoring thread */
4884  if (!ast_mutex_lock(&monlock)) {
4886  pthread_cancel(monitor_thread);
4887  pthread_kill(monitor_thread, SIGURG);
4888  pthread_join(monitor_thread, NULL);
4889  }
4892  } else {
4893  ast_log(LOG_WARNING, "Unable to lock the monitor\n");
4894  /* We always want to leave this in a consistent state */
4896  mgcp_reloading = 0;
4897  mgcp_reload(NULL, 0, NULL);
4898  return -1;
4899  }
4900 
4901  if (!ast_mutex_lock(&gatelock)) {
4902  for (g = gateways; g; g = g->next) {
4903  g->delme = 1;
4904  for (e = g->endpoints; e; e = e->next) {
4905  e->delme = 1;
4906  }
4907  }
4908 
4909  prune_gateways();
4911  } else {
4912  ast_log(LOG_WARNING, "Unable to lock the gateways list.\n");
4913  /* We always want to leave this in a consistent state */
4915  /* Allow the monitor to restart */
4917  mgcp_reloading = 0;
4918  mgcp_reload(NULL, 0, NULL);
4919  return -1;
4920  }
4921 
4922  close(mgcpsock);
4924  ast_cli_unregister_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
4926 
4927  return 0;
4928 }
static int mgcpsock
Definition: chan_mgcp.c:425
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
Definition: chan_mgcp.c:423
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
static char * mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_mgcp.c:4827
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:938
descriptor for a cli entry.
Definition: cli.h:165
#define LOG_WARNING
Definition: logger.h:144
Definition: sched.c:57
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:907
static void prune_gateways(void)
Definition: chan_mgcp.c:4544
#define ast_mutex_trylock(a)
Definition: lock.h:157
#define AST_PTHREADT_NULL
Definition: lock.h:65
struct mgcp_gateway * next
Definition: chan_mgcp.c:416
static struct ast_channel_tech mgcp_tech
Definition: chan_mgcp.c:464
static pthread_t monitor_thread
Definition: chan_mgcp.c:224
static ast_mutex_t monlock
Definition: chan_mgcp.c:219
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free&#39;s) the given sched_context structure
Definition: sched.c:267
static int mgcp_reloading
Definition: chan_mgcp.c:420
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct mgcp_gateway * gateways
static struct ast_cli_entry cli_mgcp[]
Definition: chan_mgcp.c:1170
static ast_mutex_t mgcp_reload_lock
Definition: chan_mgcp.c:419
static struct ast_rtp_glue mgcp_rtp_glue
Definition: chan_mgcp.c:4449
#define AST_PTHREADT_STOP
Definition: lock.h:66
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:266
struct mgcp_endpoint * endpoints
Definition: chan_mgcp.c:401
struct mgcp_endpoint * next
Definition: chan_mgcp.c:388
#define ast_mutex_unlock(a)
Definition: lock.h:156

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Media Gateway Control Protocol (MGCP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_pktccops", }
static

Definition at line 4936 of file chan_mgcp.c.

struct in_addr __ourip
static

Definition at line 232 of file chan_mgcp.c.

Referenced by build_gateway(), find_subchannel_and_lock(), and reload_config().

char accountcode[AST_MAX_ACCOUNT_CODE] = ""
static

Definition at line 195 of file chan_mgcp.c.

int adsi = 0
static

Definition at line 201 of file chan_mgcp.c.

Referenced by build_gateway().

int amaflags = 0
static

Definition at line 199 of file chan_mgcp.c.

Referenced by build_gateway().

Definition at line 4936 of file chan_mgcp.c.

struct sockaddr_in bindaddr
static

Definition at line 427 of file chan_mgcp.c.

int callreturn = 0
static

Definition at line 180 of file chan_mgcp.c.

Referenced by build_gateway().

int callwaiting = 0
static

Definition at line 178 of file chan_mgcp.c.

Referenced by build_gateway().

int cancallforward = 0
static

Definition at line 189 of file chan_mgcp.c.

Referenced by build_gateway().

struct ast_cli_entry cli_mgcp[]
static

Definition at line 1170 of file chan_mgcp.c.

const char config[] = "mgcp.conf"
static

Definition at line 110 of file chan_mgcp.c.

char context[AST_MAX_EXTENSION] = "default"
static

Definition at line 152 of file chan_mgcp.c.

unsigned int cos

Definition at line 172 of file chan_mgcp.c.

unsigned int cos_audio

Definition at line 173 of file chan_mgcp.c.

ast_group_t cur_callergroup = 0
static

Definition at line 166 of file chan_mgcp.c.

Referenced by build_gateway().

ast_group_t cur_pickupgroup = 0
static

Definition at line 167 of file chan_mgcp.c.

Referenced by build_gateway().

struct ast_jb_conf default_jbconf
static

Global jitterbuffer configuration - by default, jb is disabled

Note
Values shown here match the defaults shown in mgcp.conf.sample

Definition at line 99 of file chan_mgcp.c.

int directmedia = DIRECTMEDIA
static

Definition at line 193 of file chan_mgcp.c.

Referenced by build_gateway().

int dtmfmode = 0
static

Definition at line 160 of file chan_mgcp.c.

Referenced by build_gateway(), and set_local_capabilities().

int firstdigittimeout = 16000
static

Wait up to 16 seconds for first digit (FXO logic)

Definition at line 207 of file chan_mgcp.c.

Referenced by mgcp_ss().

ast_mutex_t gatelock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static
int gendigittimeout = 8000
static

How long to wait for following digits (FXO logic)

Definition at line 210 of file chan_mgcp.c.

Referenced by mgcp_ss().

struct ast_jb_conf global_jbconf
static

Definition at line 107 of file chan_mgcp.c.

Referenced by mgcp_new(), and reload_config().

int hangupongateremove = 0
static

Definition at line 164 of file chan_mgcp.c.

Referenced by build_gateway().

int immediate = 0
static

Definition at line 176 of file chan_mgcp.c.

Referenced by build_gateway().

struct io_context* io
static

Definition at line 238 of file chan_mgcp.c.

char language[MAX_LANGUAGE] = ""
static

Definition at line 154 of file chan_mgcp.c.

int matchdigittimeout = 3000
static

How long to wait for an extra digit, if there is an ambiguous match

Definition at line 213 of file chan_mgcp.c.

Referenced by mgcp_ss().

const char* const mgcp_cxmodes[]
static

}

Definition at line 132 of file chan_mgcp.c.

ast_mutex_t mgcp_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 419 of file chan_mgcp.c.

Referenced by do_monitor(), mgcp_reload(), and unload_module().

int mgcp_reloading = 0
static

Definition at line 420 of file chan_mgcp.c.

Referenced by do_monitor().

struct ast_rtp_glue mgcp_rtp_glue
static

Definition at line 4449 of file chan_mgcp.c.

struct ast_channel_tech mgcp_tech
static

Definition at line 464 of file chan_mgcp.c.

Referenced by mgcp_new().

int mgcpdebug = 0
static

Definition at line 235 of file chan_mgcp.c.

int mgcpsock = -1
static

Definition at line 425 of file chan_mgcp.c.

int* mgcpsock_read_id = NULL
static

Definition at line 3714 of file chan_mgcp.c.

pthread_t monitor_thread = AST_PTHREADT_NULL
static

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 224 of file chan_mgcp.c.

ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 219 of file chan_mgcp.c.

Referenced by do_monitor(), restart_monitor(), and unload_module().

int nat = 0
static

Definition at line 161 of file chan_mgcp.c.

Referenced by ast_udptl_setnat(), and build_gateway().

int ncs = 0
static

Definition at line 162 of file chan_mgcp.c.

Referenced by build_gateway().

ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Definition at line 217 of file chan_mgcp.c.

Referenced by do_monitor(), and reload_config().

int nonCodecCapability = AST_RTP_DTMF
static

Definition at line 229 of file chan_mgcp.c.

unsigned int oseq_global = 0
static

Definition at line 203 of file chan_mgcp.c.

Referenced by reqprep().

ast_mutex_t oseq_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 204 of file chan_mgcp.c.

Referenced by reqprep().

char ourhost[MAXHOSTNAMELEN]
static

Definition at line 231 of file chan_mgcp.c.

Referenced by ast_find_ourip().

int ourport
static

Definition at line 233 of file chan_mgcp.c.

Referenced by initreqprep(), and transmit_notify_with_mwi().

int pktcgatealloc = 0
static

Definition at line 163 of file chan_mgcp.c.

Referenced by build_gateway().

struct { ... } qos

Referenced by reload_config(), and start_rtp().

struct sched_context* sched
static

Definition at line 237 of file chan_mgcp.c.

int singlepath = 0
static

Definition at line 191 of file chan_mgcp.c.

Referenced by build_gateway().

int slowsequence = 0
static

Definition at line 182 of file chan_mgcp.c.

Referenced by build_gateway().

const char tdesc[] = "Media Gateway Control Protocol (MGCP)"
static

Definition at line 109 of file chan_mgcp.c.

int threewaycalling = 0
static

Definition at line 184 of file chan_mgcp.c.

Referenced by build_gateway().

unsigned int tos

Definition at line 170 of file chan_mgcp.c.

unsigned int tos_audio

Definition at line 171 of file chan_mgcp.c.

int transfer = 0
static

This is for flashhook transfers

Definition at line 187 of file chan_mgcp.c.

Referenced by build_gateway(), iax2_send(), leave_voicemail(), and send_packet().