aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp/mgcp_protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_protocol.c')
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c83
1 files changed, 47 insertions, 36 deletions
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index 0681c1038..db8354abf 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -320,16 +320,18 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
char sdp_record[4096];
int len;
int nchars;
+ char osmux_extension[strlen("\nX-Osmux: 255") + 1];
if (!addr)
addr = endp->cfg->source_addr;
- len = snprintf(sdp_record, sizeof(sdp_record),
- "I: %u%s\n\n",
- endp->ci,
- endp->cfg->osmux && endp->osmux.enable ?
- "\nX-Osmux: On" : "");
+ if (endp->osmux.state == OSMUX_STATE_ACTIVATING)
+ sprintf(osmux_extension, "\nX-Osmux: %u", endp->osmux.cid);
+ else
+ osmux_extension[0] = '\0';
+ len = snprintf(sdp_record, sizeof(sdp_record),
+ "I: %u%s\n\n", endp->ci, osmux_extension);
if (len < 0)
return NULL;
@@ -347,7 +349,7 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
static void send_dummy(struct mgcp_endpoint *endp)
{
- if (endp->osmux.enable)
+ if (endp->osmux.state != OSMUX_STATE_DISABLED)
osmux_send_dummy(endp);
else
mgcp_send_dummy(endp);
@@ -879,7 +881,22 @@ uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,
return rtp->rate * f * rtp->frame_duration_num / rtp->frame_duration_den;
}
-static int mgcp_osmux_setup(struct mgcp_endpoint *endp)
+static int mgcp_parse_osmux_cid(const char *line)
+{
+ uint32_t osmux_cid;
+
+ sscanf(line + 2, "Osmux: %u", &osmux_cid);
+ if (osmux_cid > OSMUX_CID_MAX) {
+ LOGP(DMGCP, LOGL_ERROR, "Osmux ID too large: %u > %u\n",
+ osmux_cid, OSMUX_CID_MAX);
+ return -1;
+ }
+ LOGP(DMGCP, LOGL_DEBUG, "bsc-nat offered Osmux CID %u\n", osmux_cid);
+
+ return osmux_cid;
+}
+
+static int mgcp_osmux_setup(struct mgcp_endpoint *endp, const char *line)
{
if (!endp->cfg->osmux_init) {
if (osmux_init(OSMUX_ROLE_BSC, endp->cfg) < 0) {
@@ -889,12 +906,7 @@ static int mgcp_osmux_setup(struct mgcp_endpoint *endp)
LOGP(DMGCP, LOGL_NOTICE, "OSMUX socket has been set up\n");
}
- if (osmux_enable_endpoint(endp, OSMUX_ROLE_BSC) < 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Could not activate Osmux in endpoint %d\n",
- ENDPOINT_NUMBER(endp));
- }
- return 0;
+ return mgcp_parse_osmux_cid(line);
}
static struct msgb *handle_create_con(struct mgcp_parse_data *p)
@@ -907,7 +919,7 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p)
const char *callid = NULL;
const char *mode = NULL;
char *line;
- int have_sdp = 0;
+ int have_sdp = 0, osmux_cid = -1;
if (p->found != 0)
return create_err_response(NULL, 510, "CRCX", p->trans);
@@ -928,8 +940,14 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p)
mode = (const char *) line + 3;
break;
case 'X':
- if (strcmp("Osmux: on", line + 2) == 0)
- mgcp_osmux_setup(endp);
+ /* Osmux is not enabled in this bsc, ignore it so the
+ * bsc-nat knows that we don't want to use Osmux.
+ */
+ if (!p->endp->cfg->osmux)
+ break;
+
+ if (strncmp("Osmux: ", line + 2, strlen("Osmux: ")) == 0)
+ osmux_cid = mgcp_osmux_setup(endp, line);
break;
case '\0':
have_sdp = 1;
@@ -993,6 +1011,15 @@ mgcp_header_done:
if (endp->ci == CI_UNUSED)
goto error2;
+ /* Annotate Osmux circuit ID and set it to activating state until this
+ * is fully set up from the dummy load.
+ */
+ endp->osmux.state = OSMUX_STATE_DISABLED;
+ if (osmux_cid >= 0) {
+ endp->osmux.cid = osmux_cid;
+ endp->osmux.state = OSMUX_STATE_ACTIVATING;
+ }
+
endp->allocated = 1;
/* set up RTP media parameters */
@@ -1057,7 +1084,7 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
{
struct mgcp_endpoint *endp = p->endp;
int error_code = 500;
- int silent = 0, osmux = 0;
+ int silent = 0;
int have_sdp = 0;
char *line;
const char *local_options = NULL;
@@ -1096,10 +1123,6 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
}
endp->orig_mode = endp->conn_mode;
break;
- case 'X':
- if (strcmp("Osmux: on", line + 2) == 0)
- osmux = 1;
- break;
case 'Z':
silent = strcmp("noanswer", line + 3) == 0;
break;
@@ -1118,21 +1141,6 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
}
}
- /* Re-enable Osmux if we receive a MDCX, we have to set up a new
- * RTP flow: this generates a randomly allocated RTP SSRC and sequence
- * number.
- */
- if (osmux) {
- if (osmux_enable_endpoint(endp, OSMUX_ROLE_BSC) < 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Could not update osmux in endpoint %d\n",
- ENDPOINT_NUMBER(endp));
- }
- LOGP(DMGCP, LOGL_NOTICE,
- "Re-enabling osmux in endpoint %d, we got updated\n",
- ENDPOINT_NUMBER(endp));
- }
-
set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
local_options);
@@ -1528,6 +1536,9 @@ void mgcp_release_endp(struct mgcp_endpoint *endp)
endp->conn_mode = endp->orig_mode = MGCP_CONN_NONE;
+ if (endp->osmux.state == OSMUX_STATE_ENABLED)
+ osmux_disable_endpoint(endp);
+
memset(&endp->taps, 0, sizeof(endp->taps));
}