aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_mgcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_mgcp.c')
-rwxr-xr-xchannels/chan_mgcp.c117
1 files changed, 60 insertions, 57 deletions
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index 22058c775..102c28b14 100755
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -686,8 +686,7 @@ static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
if (gettimeofday(&tv, NULL) < 0) {
/* This shouldn't ever happen, but let's be sure */
ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
- }
- else {
+ } else {
msg->expire = tv.tv_sec * 1000 + tv.tv_usec / 1000 + DEFAULT_RETRANS;
if (gw->retransid == -1)
@@ -862,8 +861,9 @@ static int mgcp_hangup(struct ast_channel *ast)
struct mgcp_subchannel *sub = ast->pvt->pvt;
struct mgcp_endpoint *p = sub->parent;
- if (option_debug)
+ if (option_debug) {
ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name);
+ }
if (!ast->pvt->pvt) {
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
return 0;
@@ -872,14 +872,14 @@ static int mgcp_hangup(struct ast_channel *ast)
ast_log(LOG_DEBUG, "Invalid magic. MGCP subchannel freed up already.\n");
return 0;
}
+ ast_mutex_lock(&sub->lock);
if (mgcpdebug) {
ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name);
}
- if ((p->dtmfmode & MGCP_DTMF_INBAND) && (p->dsp != NULL)){
+ if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) {
/* SC: check whether other channel is active. */
- if (!sub->next->owner)
- {
+ if (!sub->next->owner) {
if (mgcpdebug) {
ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name);
}
@@ -887,7 +887,6 @@ static int mgcp_hangup(struct ast_channel *ast)
p->dsp = NULL;
}
}
- ast_mutex_lock(&sub->lock);
sub->owner = NULL;
if (strlen(sub->cxident)) {
@@ -967,7 +966,7 @@ static int mgcp_show_endpoints(int fd, int argc, char *argv[])
e = g->endpoints;
ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), g->addr.sin_addr) : ast_inet_ntoa(iabuf, sizeof(iabuf), g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static");
while(e) {
- // JS: Don't show wilcard endpoint
+ /* JS: Don't show wilcard endpoint */
if (strcmp(e->name, g->wcardep) !=0)
ast_cli(fd, " -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle");
hasendpoints = 1;
@@ -1078,7 +1077,11 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
{
/* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
struct ast_frame *f;
+ static struct ast_frame null_frame = { AST_FRAME_NULL, };
f = ast_rtp_read(sub->rtp);
+ /* Don't send RFC2833 if we're not supposed to */
+ if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833))
+ return &null_frame;
if (sub->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
@@ -1089,7 +1092,7 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
ast_set_write_format(sub->owner, sub->owner->writeformat);
}
/* Courtesy fearnor aka alex@pilosoft.com */
- if (sub->parent->dtmfmode & MGCP_DTMF_INBAND) {
+ if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
#if 0
ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n");
#endif
@@ -1103,18 +1106,12 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
static struct ast_frame *mgcp_read(struct ast_channel *ast)
{
- struct ast_frame *fr;
+ struct ast_frame *f;
struct mgcp_subchannel *sub = ast->pvt->pvt;
- static struct ast_frame null_frame = { AST_FRAME_NULL, };
ast_mutex_lock(&sub->lock);
- fr = mgcp_rtp_read(sub);
- if (!(sub->parent->dtmfmode & MGCP_DTMF_RFC2833)) {
- if (fr && (fr->frametype == AST_FRAME_DTMF)) {
- fr = &null_frame;
- }
- }
+ f = mgcp_rtp_read(sub);
ast_mutex_unlock(&sub->lock);
- return fr;
+ return f;
}
static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
@@ -1313,7 +1310,8 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state)
return tmp;
}
-static char* get_sdp_by_line(char* line, char *name, int nameLen) {
+static char* get_sdp_by_line(char* line, char *name, int nameLen)
+{
if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
char* r = line + nameLen + 1;
while (*r && (*r < 33)) ++r;
@@ -1323,7 +1321,8 @@ static char* get_sdp_by_line(char* line, char *name, int nameLen) {
return "";
}
-static char *get_sdp(struct mgcp_request *req, char *name) {
+static char *get_sdp(struct mgcp_request *req, char *name)
+{
int x;
int len = strlen(name);
char *r;
@@ -1335,12 +1334,13 @@ static char *get_sdp(struct mgcp_request *req, char *name) {
return "";
}
-static void sdpLineNum_iterator_init(int* iterator) {
+static void sdpLineNum_iterator_init(int* iterator)
+{
*iterator = 0;
}
-static char* get_sdp_iterate(int* iterator,
- struct mgcp_request *req, char *name) {
+static char* get_sdp_iterate(int* iterator, struct mgcp_request *req, char *name)
+{
int len = strlen(name);
char *r;
while (*iterator < req->lines) {
@@ -1658,7 +1658,7 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
#if 0
printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
#endif
- // Scan through the RTP payload types specified in a "m=" line:
+ /* Scan through the RTP payload types specified in a "m=" line: */
ast_rtp_pt_clear(sub->rtp);
codecs = m + len;
while(strlen(codecs)) {
@@ -1670,18 +1670,18 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
codecs += len;
}
- // Next, scan through each "a=rtpmap:" line, noting each
- // specified RTP payload type (with corresponding MIME subtype):
+ /* Next, scan through each "a=rtpmap:" line, noting each
+ specified RTP payload type (with corresponding MIME subtype): */
sdpLineNum_iterator_init(&iterator);
while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
char* mimeSubtype = strdup(a); // ensures we have enough space
if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
- // Note: should really look at the 'freq' and '#chans' params too
+ /* Note: should really look at the 'freq' and '#chans' params too */
ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype);
free(mimeSubtype);
}
- // Now gather all of the codecs that were asked for:
+ /* Now gather all of the codecs that were asked for: */
ast_rtp_get_current_formats(sub->rtp,
&peercapability, &peerNonCodecCapability);
p->capability = capability & peercapability;
@@ -1696,7 +1696,6 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
return -1;
}
return 0;
-
}
static int add_header(struct mgcp_request *req, char *var, char *value)
@@ -1712,9 +1711,9 @@ static int add_header(struct mgcp_request *req, char *var, char *value)
req->header[req->headers] = req->data + req->len;
snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
req->len += strlen(req->header[req->headers]);
- if (req->headers < MGCP_MAX_HEADERS)
+ if (req->headers < MGCP_MAX_HEADERS) {
req->headers++;
- else {
+ } else {
ast_log(LOG_WARNING, "Out of header space\n");
return -1;
}
@@ -1735,9 +1734,9 @@ static int add_line(struct mgcp_request *req, char *line)
req->line[req->lines] = req->data + req->len;
snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
req->len += strlen(req->line[req->lines]);
- if (req->lines < MGCP_MAX_LINES)
+ if (req->lines < MGCP_MAX_LINES) {
req->lines++;
- else {
+ } else {
ast_log(LOG_WARNING, "Out of line space\n");
return -1;
}
@@ -1785,7 +1784,7 @@ static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *ver
static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
{
- memset(resp, 0, sizeof(*resp));
+ memset(resp, 0, sizeof(struct mgcp_request));
init_resp(resp, msg, req, msgrest);
return 0;
}
@@ -1947,7 +1946,7 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
add_header(&resp, "X", sub->txident);
add_header(&resp, "I", sub->cxident);
/*add_header(&resp, "S", "");*/
- ast_rtp_offered_from_local(rtp, 0);
+ ast_rtp_offered_from_local(sub->rtp, 0);
add_sdp(&resp, sub, rtp);
/* SC: fill in new fields */
resp.cmd = MGCP_CMD_MDCX;
@@ -1981,7 +1980,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
/* SC: X header should not be sent. kept for compatibility */
add_header(&resp, "X", sub->txident);
/*add_header(&resp, "S", "");*/
- ast_rtp_offered_from_local(rtp, 1);
+ ast_rtp_offered_from_local(sub->rtp, 1);
add_sdp(&resp, sub, rtp);
/* SC: fill in new fields */
resp.cmd = MGCP_CMD_CRCX;
@@ -2115,7 +2114,7 @@ static int transmit_audit_endpoint(struct mgcp_endpoint *p)
struct mgcp_request resp;
reqprep(&resp, p, "AUEP");
/* SC: removed unknown param VS */
- //add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");
+ /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/
add_header(&resp, "F", "A");
/* SC: fill in new fields */
resp.cmd = MGCP_CMD_AUEP;
@@ -2411,7 +2410,7 @@ static void start_rtp(struct mgcp_subchannel *sub)
sub->rtp = NULL;
}
/* Allocate the RTP now */
- sub->rtp = ast_rtp_new(sched, io, 1, 0);
+ sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
if (sub->rtp && sub->owner)
sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
if (sub->rtp)
@@ -2860,7 +2859,7 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) {
ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name);
}
- // JS: For RSIP on wildcard we reset all endpoints
+ /* JS: For RSIP on wildcard we reset all endpoints */
if (!strcmp(p->name, p->parent->wcardep)) {
/* Reset all endpoints */
struct mgcp_endpoint *tmp_ep;
@@ -2868,7 +2867,7 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
g = p->parent;
tmp_ep = g->endpoints;
while (tmp_ep) {
- //if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/*") != 0)) {
+ /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/
if (strcmp(tmp_ep->name, g->wcardep) != 0) {
struct mgcp_subchannel *tmp_sub, *first_sub;
if (option_verbose > 2) {
@@ -2879,7 +2878,7 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
tmp_sub = tmp_ep->sub;
while (tmp_sub) {
if (tmp_sub->owner)
- ast_softhangup(sub->owner, AST_SOFTHANGUP_DEV);
+ ast_softhangup(tmp_sub->owner, AST_SOFTHANGUP_DEV);
tmp_sub = tmp_sub->next;
if (tmp_sub == first_sub)
break;
@@ -2928,7 +2927,9 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
return -1;
}
/* do not let * confrnce two down channels */
- if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) return -1;
+ if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) {
+ return -1;
+ }
if (p->callwaiting || p->transfer || p->threewaycalling) {
if (option_verbose > 2) {
@@ -3046,9 +3047,13 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
} else {
/* SC: verbose level check */
if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed\n",
- p->name, p->parent->name, sub->id);
+ ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n",
+ p->name, p->parent->name, sub->id);
}
+ /* Instruct the other side to remove the connection since it apparently *
+ * still thinks the channel is active. *
+ * For Cisco IAD2421 /BAK/ */
+ transmit_connection_del(sub);
}
}
if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) {
@@ -3081,11 +3086,9 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
if (strstr(p->curtone, "wt") && (ev[0] == 'A')) {
memset(p->curtone, 0, sizeof(p->curtone));
}
- }
- else if (!strcasecmp(ev, "T")) {
+ } else if (!strcasecmp(ev, "T")) {
/* Digit timeout -- unimportant */
- }
- else if (!strcasecmp(ev, "ping")) {
+ } else if (!strcasecmp(ev, "ping")) {
/* ping -- unimportant */
} else {
ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
@@ -3140,7 +3143,7 @@ static int mgcpsock_read(int *id, int fd, short events, void *ignore)
int ident;
char iabuf[INET_ADDRSTRLEN];
len = sizeof(sin);
- memset(&req, 0, sizeof(req));
+ memset(&req, 0, sizeof(struct mgcp_request));
res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
if (res < 0) {
if (errno != ECONNREFUSED)
@@ -3150,8 +3153,8 @@ static int mgcpsock_read(int *id, int fd, short events, void *ignore)
req.data[res] = '\0';
req.len = res;
if (mgcpdebug) {
- ast_verbose("MGCP read: \n%s\nfrom %s:%d", req.data, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
- }
+ ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
+ }
parse(&req);
if (req.headers < 1) {
/* Must have at least one header */
@@ -3257,10 +3260,10 @@ static void *do_monitor(void *data)
/* Lock the network interface */
ast_mutex_lock(&netlock);
+#if 0
/* XXX THIS IS COMPLETELY HOSED */
/* The gateway goes into a state of panic */
/* If the vmwi indicator is sent while it is reseting interfaces */
-#if 0
lastpass = thispass;
thispass = time(NULL);
g = gateways;
@@ -3385,8 +3388,9 @@ static struct ast_channel *mgcp_request(char *type, int format, void *data)
return NULL;
}
tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN);
- if (!tmpc)
+ if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
+ }
restart_monitor();
return tmpc;
}
@@ -3516,8 +3520,6 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
adsi = ast_true(v->value);
} else if (!strcasecmp(v->name, "callreturn")) {
callreturn = ast_true(v->value);
- } else if (!strcasecmp(v->name, "immediate")) {
- immediate = ast_true(v->value);
} else if (!strcasecmp(v->name, "callwaiting")) {
callwaiting = ast_true(v->value);
} else if (!strcasecmp(v->name, "slowsequence")) {
@@ -3555,7 +3557,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
e->needaudit = 1;
}
strncpy(gw->wcardep, v->value, sizeof(gw->wcardep)-1);
- //strncpy(e->name, "aaln/*", sizeof(e->name) - 1);
+ /*strncpy(e->name, "aaln/" "*", sizeof(e->name) - 1);*/
/* XXX Should we really check for uniqueness?? XXX */
strncpy(e->context, context, sizeof(e->context) - 1);
strncpy(e->callerid, callerid, sizeof(e->callerid) - 1);
@@ -3748,6 +3750,8 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
}
return NULL;
}
+ gw->defaddr.sin_family = AF_INET;
+ gw->addr.sin_family = AF_INET;
if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port))
gw->defaddr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port))
@@ -4226,4 +4230,3 @@ char *description()
{
return desc;
}
-