diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 9d29d26c3..19144e3dd 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -285,6 +285,7 @@ struct bsc_nat { uint8_t mgcp_msg[4096]; int mgcp_length; int mgcp_ipa; + int sdp_ensure_amr_mode_set; /* msc things */ struct llist_head dests; @@ -421,7 +422,7 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat); struct nat_sccp_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number); struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip, - int port, int osmux, int *payload_type); + int port, int osmux, int *payload_type, int mode_set); void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg); void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc); diff --git a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c index 97593031c..5a024dbc4 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c +++ b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c @@ -552,7 +552,8 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, sccp->bsc_endp, nat->mgcp_cfg->source_addr, mgcp_endp->bts_end.local_port, osmux_cid, - &mgcp_endp->net_end.codec.payload_type); + &mgcp_endp->net_end.codec.payload_type, + nat->sdp_ensure_amr_mode_set); if (!bsc_msg) { LOGP(DMGCP, LOGL_ERROR, "Failed to patch the msg.\n"); return MGCP_POLICY_CONT; @@ -746,7 +747,8 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg) output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), -1, bsc->nat->mgcp_cfg->source_addr, endp->net_end.local_port, -1, - &endp->bts_end.codec.payload_type); + &endp->bts_end.codec.payload_type, + bsc->nat->sdp_ensure_amr_mode_set); if (!output) { LOGP(DMGCP, LOGL_ERROR, "Failed to rewrite MGCP msg.\n"); return; @@ -813,7 +815,7 @@ static void patch_mgcp(struct msgb *output, const char *op, const char *tok, /* we need to replace some strings... */ struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char *ip, int port, int osmux_cid, - int *payload_type) + int *payload_type, int ensure_mode_set) { static const char crcx_str[] = "CRCX "; static const char dlcx_str[] = "DLCX "; @@ -898,7 +900,7 @@ copy: * the above code made sure that we have 128 bytes lefts. So we can * safely append another line. */ - if (!found_fmtp && payload != -1) { + if (ensure_mode_set && !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'; diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 93a91450c..5c3b696e2 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -1526,6 +1526,9 @@ int main(int argc, char **argv) return -5; } + /* We need to add mode-set for amr codecs */ + nat->sdp_ensure_amr_mode_set = 1; + vty_info.copyright = openbsc_copyright; vty_init(&vty_info); logging_vty_add_cmds(&log_info); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c index 2b7db2ee8..9e66cdc28 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c @@ -156,6 +156,8 @@ static int config_write_nat(struct vty *vty) write_pgroup_lst(vty, pgroup); if (_nat->mgcp_ipa) vty_out(vty, " use-msc-ipa-for-mgcp%s", VTY_NEWLINE); + vty_out(vty, " %ssdp-ensure-amr-mode-set%s", + _nat->sdp_ensure_amr_mode_set ? "" : "no ", VTY_NEWLINE); return CMD_SUCCESS; } @@ -773,6 +775,24 @@ DEFUN(cfg_nat_use_ipa_for_mgcp, return CMD_SUCCESS; } +DEFUN(cfg_nat_sdp_amr_mode_set, + cfg_nat_sdp_amr_mode_set_cmd, + "sdp-ensure-amr-mode-set", + "Ensure that SDP records include a mode-set\n") +{ + _nat->sdp_ensure_amr_mode_set = 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_nat_no_sdp_amr_mode_set, + cfg_nat_no_sdp_amr_mode_set_cmd, + "no sdp-ensure-amr-mode-set", + NO_STR "Ensure that SDP records include a mode-set\n") +{ + _nat->sdp_ensure_amr_mode_set = 0; + return CMD_SUCCESS; +} + /* per BSC configuration */ DEFUN(cfg_bsc, cfg_bsc_cmd, "bsc BSC_NR", "BSC configuration\n" "Identifier of the BSC\n") @@ -1274,6 +1294,9 @@ int bsc_nat_vty_init(struct bsc_nat *nat) install_element(NAT_NODE, &cfg_nat_prefix_trie_cmd); install_element(NAT_NODE, &cfg_nat_no_prefix_trie_cmd); + install_element(NAT_NODE, &cfg_nat_sdp_amr_mode_set_cmd); + install_element(NAT_NODE, &cfg_nat_no_sdp_amr_mode_set_cmd); + install_element(NAT_NODE, &cfg_nat_pgroup_cmd); install_element(NAT_NODE, &cfg_nat_no_pgroup_cmd); install_node(&pgroup_node, config_write_pgroup); diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c index d1f8ebc0d..3f1f527c0 100644 --- a/openbsc/tests/bsc-nat/bsc_data.c +++ b/openbsc/tests/bsc-nat/bsc_data.c @@ -171,6 +171,7 @@ static const char mdcx_resp_patched[] = "200 23330829\r\n\r\nv=0\r\nc=IN IP4 10. /* 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\na=fmtp:98 mode-set=2\n"; +static const char mdcx_resp_patched2_noamr[] = "200 33330829\n\nv=0\nc=IN IP4 10.0.0.23\nm=audio 5555 RTP/AVP 98\na=rtpmap:98 AMR/8000\n"; struct mgcp_patch_test { const char *orig; @@ -178,6 +179,7 @@ struct mgcp_patch_test { const char *ip; const int port; const int payload_type; + const int ensure_mode_set; }; static const struct mgcp_patch_test mgcp_messages[] = { @@ -186,6 +188,7 @@ static const struct mgcp_patch_test mgcp_messages[] = { .patch = crcx_patched, .ip = "0.0.0.0", .port = 2323, + .ensure_mode_set = 1, }, { .orig = crcx_resp, @@ -193,6 +196,7 @@ static const struct mgcp_patch_test mgcp_messages[] = { .ip = "10.0.0.1", .port = 999, .payload_type = 98, + .ensure_mode_set = 1, }, { .orig = mdcx, @@ -200,6 +204,7 @@ static const struct mgcp_patch_test mgcp_messages[] = { .ip = "10.0.0.23", .port = 6666, .payload_type = 126, + .ensure_mode_set = 1, }, { .orig = mdcx_resp, @@ -207,6 +212,7 @@ static const struct mgcp_patch_test mgcp_messages[] = { .ip = "10.0.0.23", .port = 5555, .payload_type = 98, + .ensure_mode_set = 1, }, { .orig = mdcx_resp2, @@ -214,6 +220,15 @@ static const struct mgcp_patch_test mgcp_messages[] = { .ip = "10.0.0.23", .port = 5555, .payload_type = 98, + .ensure_mode_set = 1, + }, + { + .orig = mdcx_resp2, + .patch = mdcx_resp_patched2_noamr, + .ip = "10.0.0.23", + .port = 5555, + .payload_type = 98, + .ensure_mode_set = 0, }, }; diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index 245b081e1..5b01cc3cd 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -625,12 +625,13 @@ static void test_mgcp_rewrite(void) const char *ip = mgcp_messages[i].ip; const int port = mgcp_messages[i].port; const int expected_payload_type = mgcp_messages[i].payload_type; + const int ensure_mode_set = mgcp_messages[i].ensure_mode_set; int payload_type = -1; char *input = strdup(orig); output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, - ip, port, -1, &payload_type); + ip, port, -1, &payload_type, ensure_mode_set); if (payload_type != -1) { fprintf(stderr, "Found media payload type %d in SDP data\n", diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index fb4ca7d1a..3581b67c9 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -588,6 +588,23 @@ class TestVTYNAT(TestVTYGenericBSC): res = self.vty.command("number-rewrite rewrite.cfg") res = self.vty.command("no number-rewrite") + def testEnsureNoEnsureModeSet(self): + self.vty.enable() + res = self.vty.command("configure terminal") + res = self.vty.command("nat") + + # Ensure the default + res = self.vty.command("show running-config") + self.assert_(res.find('\n sdp-ensure-amr-mode-set') > 0) + + self.vty.command("sdp-ensure-amr-mode-set") + res = self.vty.command("show running-config") + self.assert_(res.find('\n sdp-ensure-amr-mode-set') > 0) + + self.vty.command("no sdp-ensure-amr-mode-set") + res = self.vty.command("show running-config") + self.assert_(res.find('\n no sdp-ensure-amr-mode-set') > 0) + def testRewritePostNoRewrite(self): self.vty.enable() self.vty.command("configure terminal")