Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:09 2007

Asterisk developer's documentation :: Codename Pineapple


chan_mgcp.c File Reference


Detailed Description

Implementation of Media Gateway Control Protocol.

Author:
Mark Spencer <markster@digium.com>
See also

Definition in file chan_mgcp.c.

#include "asterisk.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.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/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.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/causes.h"
#include "asterisk/dsp.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"

Include dependency graph for chan_mgcp.c:

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

Defines

#define CANREINVITE   1
#define DEFAULT_EXPIRY   120
#define DEFAULT_MGCP_CA_PORT   2727
#define DEFAULT_MGCP_GW_PORT   2427
#define DEFAULT_RETRANS   1000
#define INADDR_NONE   (in_addr_t)(-1)
#define IPTOS_MINCOST   0x02
#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)
static int __mgcp_xmit (struct mgcp_gateway *gw, char *data, int len)
static int add_header (struct mgcp_request *req, char *var, char *value)
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 *rtp)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Media Gateway Control Protocol (MGCP)",.load=load_module,.unload=unload_module,.reload=reload,)
 AST_MUTEX_DEFINE_STATIC (gatelock)
 gatelock: mutex for gateway/endpoint lists
 AST_MUTEX_DEFINE_STATIC (mgcp_reload_lock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 AST_MUTEX_DEFINE_STATIC (netlock)
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
static char * control2str (int ind)
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
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
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
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 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)
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 ---
static int mgcp_answer (struct ast_channel *ast)
static int mgcp_audit_endpoint (int fd, int argc, char *argv[])
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
static int mgcp_do_debug (int fd, int argc, char *argv[])
static int mgcp_do_reload (void)
 mgcp_do_reload: Reload module
static int mgcp_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static enum ast_rtp_get_result mgcp_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
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)
static int mgcp_no_debug (int fd, int argc, char *argv[])
static int mgcp_postrequest (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno)
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 int mgcp_reload (int fd, int argc, char *argv[])
static struct ast_channelmgcp_request (const char *type, int format, 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 *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
static int mgcp_show_endpoints (int fd, int argc, char *argv[])
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 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 (void)
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)
 Start the channel monitor thread.
static int retrans_pkt (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_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp *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 *rtp, int 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 in_addr __ourip
static char accountcode [AST_MAX_ACCOUNT_CODE] = ""
static int adsi = 0
static int amaflags = 0
static const char audit_endpoint_usage []
static struct sockaddr_in bindaddr
static int callreturn = 0
static int callwaiting = 0
static int cancallforward = 0
static int canreinvite = CANREINVITE
static int 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 const char debug_usage []
static struct ast_jb_conf default_jbconf
static int dtmfmode = 0
static int firstdigittimeout = 16000
static struct mgcp_gatewaygateways
static int gendigittimeout = 8000
static struct ast_jb_conf global_jbconf
static int immediate = 0
static struct io_contextio
static char language [MAX_LANGUAGE] = ""
static char mailbox [AST_MAX_EXTENSION]
static int matchdigittimeout = 3000
static char * mgcp_cxmodes []
static const char mgcp_reload_usage []
static int mgcp_reloading = 0
static struct ast_rtp_protocol mgcp_rtp
static const 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 char musicclass [MAX_MUSICCLASS] = ""
static int nat = 0
static const char no_debug_usage []
static int nonCodecCapability = AST_RTP_DTMF
static unsigned int oseq
static char ourhost [MAXHOSTNAMELEN]
static int ourport
static struct sched_contextsched
static const char show_endpoints_usage []
static int singlepath = 0
static int slowsequence = 0
static const char tdesc [] = "Media Gateway Control Protocol (MGCP)"
static int threewaycalling = 0
static int tos = 0
static int transfer = 0


Define Documentation

#define CANREINVITE   1
 

Definition at line 93 of file chan_mgcp.c.

Referenced by build_gateway().

#define DEFAULT_EXPIRY   120
 

Definition at line 91 of file chan_mgcp.c.

Referenced by reload_config().

#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.

#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 INADDR_NONE   (in_addr_t)(-1)
 

Definition at line 96 of file chan_mgcp.c.

Referenced by build_gateway().

#define IPTOS_MINCOST   0x02
 

Definition at line 81 of file chan_mgcp.c.

#define MAX_EXPIRY   3600
 

Definition at line 92 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 272 of file chan_mgcp.c.

Referenced by build_gateway(), and destroy_endpoint().

#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)
 

Definition at line 114 of file chan_mgcp.c.

Referenced by build_gateway(), mgcp_hangup(), mgcp_new(), and mgcp_ss().

#define MGCP_DTMF_INBAND   (1 << 1)
 

Definition at line 113 of file chan_mgcp.c.

Referenced by build_gateway(), mgcp_hangup(), mgcp_new(), mgcp_rtp_read(), mgcp_ss(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid().

#define MGCP_DTMF_RFC2833   (1 << 0)
 

Definition at line 112 of file chan_mgcp.c.

Referenced by build_gateway(), and mgcp_rtp_read().

#define MGCP_MAX_HEADERS   64
 

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

Definition at line 231 of file chan_mgcp.c.

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

#define MGCP_MAX_LINES   64
 

Definition at line 232 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_OFFHOOK   2
 

Definition at line 306 of file chan_mgcp.c.

Referenced by handle_hd_hf(), handle_request(), handle_response(), mgcp_call(), mgcp_hangup(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid().

#define MGCP_ONHOOK   1
 

Definition at line 305 of file chan_mgcp.c.

Referenced by build_gateway(), do_monitor(), handle_request(), handle_response(), mgcp_call(), mgcp_hangup(), mgcp_request(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid().

#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 283 of file chan_mgcp.c.

Referenced by build_gateway(), and mgcp_hangup().

#define MGCPDUMPER
 

Definition at line 90 of file chan_mgcp.c.

#define RESPONSE_TIMEOUT   30
 

in seconds

Definition at line 262 of file chan_mgcp.c.

Referenced by find_and_retrans().

#define SUB_ALT   1
 

Definition at line 275 of file chan_mgcp.c.

#define SUB_REAL   0
 

Definition at line 274 of file chan_mgcp.c.

#define TYPE_LINE   2
 

Definition at line 309 of file chan_mgcp.c.

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

#define TYPE_TRUNK   1
 

Definition at line 308 of file chan_mgcp.c.

Referenced by build_device(), and 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.

00140      {
00141    MGCP_CMD_EPCF,
00142    MGCP_CMD_CRCX,
00143    MGCP_CMD_MDCX,
00144    MGCP_CMD_DLCX,
00145    MGCP_CMD_RQNT,
00146    MGCP_CMD_NTFY,
00147    MGCP_CMD_AUEP,
00148    MGCP_CMD_AUCX,
00149    MGCP_CMD_RSIP
00150 };


Function Documentation

static char* __get_header struct mgcp_request req,
char *  name,
int *  start
[static]
 

Definition at line 1543 of file chan_mgcp.c.

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

Referenced by build_route(), copy_all_header(), copy_via_headers(), func_header_read(), get_header(), and handle_response_register().

01544 {
01545    int x;
01546    int len = strlen(name);
01547    char *r;
01548    for (x=*start;x<req->headers;x++) {
01549       if (!strncasecmp(req->header[x], name, len) && 
01550           (req->header[x][len] == ':')) {
01551          r = req->header[x] + len + 1;
01552          while(*r && (*r < 33))
01553             r++;
01554          *start = x+1;
01555          return r;
01556       }
01557    }
01558    /* Don't return NULL, so get_header is always a valid pointer */
01559    return "";
01560 }

static int __mgcp_xmit struct mgcp_gateway gw,
char *  data,
int  len
[static]
 

Definition at line 487 of file chan_mgcp.c.

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

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

00488 {
00489    int res;
00490    if (gw->addr.sin_addr.s_addr)
00491       res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in));
00492    else 
00493       res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in));
00494    if (res != len) {
00495       ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
00496    }
00497    return res;
00498 }

static int add_header struct mgcp_request req,
char *  var,
char *  value
[static]
 

Definition at line 1894 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 __transmit_response(), add_digit(), add_header_contentLength(), add_t38_sdp(), add_text(), add_vidupdate(), append_date(), append_maxforwards(), copy_all_header(), copy_header(), copy_via_headers(), reqprep(), respprep(), transmit_audit_endpoint(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_invite(), transmit_modify_request(), transmit_notify_request(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_attachment(), transmit_response_with_auth(), transmit_response_with_unsupported(), and transmit_state_notify().

01895 {
01896    if (req->len >= sizeof(req->data) - 4) {
01897       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
01898       return -1;
01899    }
01900    if (req->lines) {
01901       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
01902       return -1;
01903    }
01904    req->header[req->headers] = req->data + req->len;
01905    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
01906    req->len += strlen(req->header[req->headers]);
01907    if (req->headers < MGCP_MAX_HEADERS)
01908       req->headers++;
01909    else {
01910       ast_log(LOG_WARNING, "Out of header space\n");
01911       return -1;
01912    }
01913    return 0;   
01914 }

static int add_line struct mgcp_request req,
char *  line
[static]
 

Definition at line 1916 of file chan_mgcp.c.

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

Referenced by add_digit(), add_t38_sdp(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().

01917 {
01918    if (req->len >= sizeof(req->data) - 4) {
01919       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
01920       return -1;
01921    }
01922    if (!req->lines) {
01923       /* Add extra empty return */
01924       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
01925       req->len += strlen(req->data + req->len);
01926    }
01927    req->line[req->lines] = req->data + req->len;
01928    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
01929    req->len += strlen(req->line[req->lines]);
01930    if (req->lines < MGCP_MAX_LINES)
01931       req->lines++;
01932    else {
01933       ast_log(LOG_WARNING, "Out of line space\n");
01934       return -1;
01935    }
01936    return 0;   
01937 }

static int add_sdp struct mgcp_request resp,
struct mgcp_subchannel sub,
struct ast_rtp rtp
[static]
 

Definition at line 2018 of file chan_mgcp.c.

References AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_us(), ast_verbose(), mgcp_endpoint::capability, len, LOG_WARNING, mgcpdebug, mgcp_gateway::ourip, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, s, mgcp_endpoint::sub, and mgcp_subchannel::tmpdest.

Referenced by transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_attachment(), and transmit_response_with_sdp().

02019 {
02020    int len;
02021    int codec;
02022    char costr[80];
02023    struct sockaddr_in sin;
02024    char v[256];
02025    char s[256];
02026    char o[256];
02027    char c[256];
02028    char t[256];
02029    char m[256] = "";
02030    char a[1024] = "";
02031    int x;
02032    struct sockaddr_in dest;
02033    struct mgcp_endpoint *p = sub->parent;
02034    /* XXX We break with the "recommendation" and send our IP, in order that our
02035           peer doesn't have to ast_gethostbyname() us XXX */
02036    len = 0;
02037    if (!sub->rtp) {
02038       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
02039       return -1;
02040    }
02041    ast_rtp_get_us(sub->rtp, &sin);
02042    if (rtp) {
02043       ast_rtp_get_peer(rtp, &dest);
02044    } else {
02045       if (sub->tmpdest.sin_addr.s_addr) {
02046          dest.sin_addr = sub->tmpdest.sin_addr;
02047          dest.sin_port = sub->tmpdest.sin_port;
02048          /* Reset temporary destination */
02049          memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
02050       } else {
02051          dest.sin_addr = p->parent->ourip</