aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-11-06 13:16:26 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-11-07 13:34:43 +0100
commite2f34d588c710db809da6bcfc9a85f3f09468201 (patch)
treebb1442325b68c04239bd2a2d1dc03a1a49b16cc0
parent93fda87cf88be8508a1075b9995d9efe0088b4c0 (diff)
nat: Inject a a=fmtp:%d to force the right AMR code
This assumes that AMR is used and/or the mode-set is ignored for other codecs by the remote end.
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c27
-rw-r--r--openbsc/tests/bsc-nat/bsc_data.c6
2 files changed, 27 insertions, 6 deletions
diff --git a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
index 668ddd653..d78dc91bc 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
@@ -563,12 +563,18 @@ struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char
static const char *ip_str = "c=IN IP4 ";
static const char *aud_str = "m=audio ";
+ static const char *fmt_str = "a=fmtp: ";
char buf[128];
char *running, *token;
struct msgb *output;
- if (length > 4096 - 128) {
+ /* keep state to add the a=fmtp line */
+ int found_fmtp = 0;
+ int payload = -1;
+ int cr = 1;
+
+ if (length > 4096 - 256) {
LOGP(DMGCP, LOGL_ERROR, "Input is too long.\n");
return NULL;
}
@@ -584,7 +590,7 @@ struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char
output->l3h = output->l2h;
for (token = strsep(&running, "\n"); running; token = strsep(&running, "\n")) {
int len = strlen(token);
- int cr = len > 0 && token[len - 1] == '\r';
+ cr = len > 0 && token[len - 1] == '\r';
if (strncmp(crcx_str, token, (sizeof crcx_str) - 1) == 0) {
patch_mgcp(output, "CRCX", token, endpoint, len, cr);
@@ -607,7 +613,6 @@ struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char
output->l3h[0] = '\n';
}
} else if (strncmp(aud_str, token, (sizeof aud_str) - 1) == 0) {
- int payload;
if (sscanf(token, "m=audio %*d RTP/AVP %d", &payload) != 1) {
LOGP(DMGCP, LOGL_ERROR, "Could not parsed audio line.\n");
msgb_free(output);
@@ -620,13 +625,29 @@ struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char
output->l3h = msgb_put(output, strlen(buf));
memcpy(output->l3h, buf, strlen(buf));
+ } else if (strncmp(fmt_str, token, (sizeof fmt_str) - 1) == 0) {
+ found_fmtp = 1;
+ goto copy;
} else {
+copy:
output->l3h = msgb_put(output, len + 1);
memcpy(output->l3h, token, len);
output->l3h[len] = '\n';
}
}
+ /*
+ * the above code made sure that we have 128 bytes lefts. So we can
+ * safely append another line.
+ */
+ if (!found_fmtp && payload != -1) {
+ snprintf(buf, sizeof(buf) - 1, "a=fmtp:%d mode-set=2%s",
+ payload, cr ? "\r\n" : "\n");
+ buf[sizeof(buf) - 1] = '\0';
+ output->l3h = msgb_put(output, strlen(buf));
+ memcpy(output->l3h, buf, strlen(buf));
+ }
+
return output;
}
diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c
index 96dda7f7d..fe0051a59 100644
--- a/openbsc/tests/bsc-nat/bsc_data.c
+++ b/openbsc/tests/bsc-nat/bsc_data.c
@@ -158,7 +158,7 @@ static const char crcx_patched[] = "CRCX 23265295 1e@mgw MGCP 1.0\r\nC: 394b0439
/* patch the ip and port */
static const char crcx_resp[] = "200 23265295\r\nI: 1\r\n\r\nv=0\r\nc=IN IP4 172.16.18.2\r\nm=audio 4002 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\n";
-static const char crcx_resp_patched[] = "200 23265295\r\nI: 1\r\n\r\nv=0\r\nc=IN IP4 10.0.0.1\r\nm=audio 999 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\n";
+static const char crcx_resp_patched[] = "200 23265295\r\nI: 1\r\n\r\nv=0\r\nc=IN IP4 10.0.0.1\r\nm=audio 999 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\na=fmtp:98 mode-set=2\r\n";
/* patch the ip and port */
static const char mdcx[] = "MDCX 23330829 8@mgw MGCP 1.0\r\nC: 394b0439fb\r\nI: 1\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 1049380491 0 IN IP4 172.16.18.2\r\ns=-\r\nc=IN IP4 172.16.18.2\r\nt=0 0\r\nm=audio 4410 RTP/AVP 126\r\na=rtpmap:126 AMR/8000/1\r\na=fmtp:126 mode-set=2;start-mode=0\r\na=ptime:20\r\na=recvonly\r\nm=image 4412 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n";
@@ -166,11 +166,11 @@ static const char mdcx_patched[] = "MDCX 23330829 1e@mgw MGCP 1.0\r\nC: 394b0439
static const char mdcx_resp[] = "200 23330829\r\n\r\nv=0\r\nc=IN IP4 172.16.18.2\r\nm=audio 4002 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\n";
-static const char mdcx_resp_patched[] = "200 23330829\r\n\r\nv=0\r\nc=IN IP4 10.0.0.23\r\nm=audio 5555 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\n";
+static const char mdcx_resp_patched[] = "200 23330829\r\n\r\nv=0\r\nc=IN IP4 10.0.0.23\r\nm=audio 5555 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\na=fmtp:98 mode-set=2\r\n";
/* different line ending */
static const char mdcx_resp2[] = "200 33330829\n\nv=0\nc=IN IP4 172.16.18.2\nm=audio 4002 RTP/AVP 98\na=rtpmap:98 AMR/8000\n";
-static const char mdcx_resp_patched2[] = "200 33330829\n\nv=0\nc=IN IP4 10.0.0.23\nm=audio 5555 RTP/AVP 98\na=rtpmap:98 AMR/8000\n";
+static const char mdcx_resp_patched2[] = "200 33330829\n\nv=0\nc=IN IP4 10.0.0.23\nm=audio 5555 RTP/AVP 98\na=rtpmap:98 AMR/8000\na=fmtp:98 mode-set=2\n";
struct mgcp_patch_test {
const char *orig;