diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h index a7f1db7ca..5c46f4979 100644 --- a/include/osmocom/msc/vty.h +++ b/include/osmocom/msc/vty.h @@ -30,6 +30,7 @@ enum bsc_vty_node { GCR_NODE, VGC_NODE, VBC_NODE, + CODECS_NODE, }; int bsc_vty_init_extra(void); diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index 1f389f455..bc03d897a 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -69,6 +69,7 @@ #include #include #include +#include static struct gsm_network *gsmnet = NULL; @@ -78,6 +79,12 @@ static struct cmd_node net_node = { 1, }; +static struct cmd_node codecs_node = { + CODECS_NODE, + "%s(config-codecs)# ", + 1, +}; + #define VSUB_USE_VTY "VTY" #define NETWORK_STR "Configure the GSM network\n" @@ -758,6 +765,145 @@ DEFUN(show_nri, show_nri_cmd, return CMD_SUCCESS; } +DEFUN(cfg_codecs, cfg_codecs_cmd, + "codecs (a|iu)", + "Configure allowed codecs and order of preference\n" + "Configure codecs on GERAN (2G). For AMR codecs, the 'mode-set' instructs the 2G RAN to support specific AMR" + " rates." + " The octet-align has no effect on the 2G RAN side: on AoIP, osmo-msc always uses a fixed octet-align mode," + " see ." + " Make sure that an entry matching the AoIP octet-align mode is present; optionally offer AMR alignment" + " conversion to the other call leg by adding another entry in mismatching octet-align mode." + " For TrFO between TCH/H channels with AMR-FR used on TCH/F and 3G, consider that AMR-HR does not support" + " mode-set 6 nor 7.\n" + "Configure (inner) AMR codecs on UTRAN. Towards 3G RAN, osmo-msc *always* uses VND.3GPP.IUFP. The codecs" + " configured here need to be AMR or AMR-WB, corresponding to the AMR payload within the IUFP header." + " The 'mode-set' instructs the 3G RAN to support specific AMR rates." + " 'octet-align' has no effect on the 3G RAN, but simply offers AMR alignment conversion to the other call leg.\n") +{ + enum osmo_rat_type rat; + vty->node = CODECS_NODE; + if (!strcmp(argv[0], "a")) + rat = OSMO_RAT_GERAN_A; + else + rat = OSMO_RAT_UTRAN_IU; + vty->index = &msc_ran_infra[rat]; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_codecs_clear, cfg_codecs_clear_cmd, + "clear", + "Clear all codecs from the list -- this breaks voice calls, you should add new entries after this.\n", + CMD_ATTR_IMMEDIATE) +{ + struct ran_infra *dst = vty->index; + dst->codecs = (struct sdp_audio_codecs){}; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_codecs_entry, cfg_codecs_entry_cmd, + "(add|no) CODEC_STR", + "Add a codec entry\n" + "Delete a codec entry\n" + "A string like [:][#]," + " for example: AMR:octet-align=1;mode-set=0,2,4,7#112." + " For AMR fmtp option details, see RFC 4867 8.1." + " The '#112' payload type number is the default payload type number used for the codec," + " which may end up being chosen differently in specific calls when osmo-msc needs to avoid duplicates," + " or when the other call leg asks for a different payload type number for the same codec.\n", + CMD_ATTR_IMMEDIATE) +{ + struct ran_infra *dst = vty->index; + const char *add_del = argv[0]; + const char *codec_str = argv[1]; + struct sdp_audio_codec c; + struct sdp_audio_codec *exists; + const struct codec_mapping *m; + bool ok; + + if (sdp_audio_codec_from_str(&c, codec_str)) + return CMD_WARNING; + + /* make sure this is a known codec */ + ok = false; + codec_mapping_foreach (m) { + if (sdp_audio_codec_cmp(&m->sdp, &c, true, false)) + continue; + ok = true; + break; + } + + if (!ok) { + vty_out(vty, "%% Error: unsupported codec '%s'. See 'do show codecs supported' command.%s", codec_str, VTY_NEWLINE); + return CMD_WARNING; + } + + exists = sdp_audio_codecs_by_descr(&dst->codecs, &c); + + if (!strcmp("add", add_del)) { + if (exists) { + vty_out(vty, "%% Codec already present in the list: %s%s", sdp_audio_codec_to_str(exists), + VTY_NEWLINE); + return CMD_WARNING; + } + + if (!sdp_audio_codecs_add_copy(&dst->codecs, &c, false, false)) { + vty_out(vty, "%% Error: failed to add codec '%s' -- too many entries?%s", codec_str, VTY_NEWLINE); + return CMD_WARNING; + } + } else { + /* "del" */ + if (!exists) { + vty_out(vty, "%% Codec not present in the list: %s%s", codec_str, VTY_NEWLINE); + return CMD_WARNING; + } + sdp_audio_codecs_remove(&dst->codecs, exists); + } + return CMD_SUCCESS; +} + +static void config_write_codecs_for_rat(struct vty *vty, enum osmo_rat_type rat) +{ + const struct sdp_audio_codec *c; + char buf[128]; + vty_out(vty, "codecs %s%s", rat == OSMO_RAT_GERAN_A ? "a" : "iu", VTY_NEWLINE); + vty_out(vty, " clear%s", VTY_NEWLINE); + sdp_audio_codecs_foreach (c, &msc_ran_infra[rat].codecs) { + sdp_audio_codec_to_str_buf(buf, sizeof(buf), c); + vty_out(vty, " %s%s", buf, VTY_NEWLINE); + } +} + +static int config_write_codecs(struct vty *vty) +{ + config_write_codecs_for_rat(vty, OSMO_RAT_GERAN_A); + config_write_codecs_for_rat(vty, OSMO_RAT_UTRAN_IU); + return 0; +} + +DEFUN(show_codecs, show_codecs_cmd, + "show codecs [(a|iu|supported)]\n", + SHOW_STR "Show codecs listings\n" + "Show codecs currently allowed on 2G AoIP calls.\n" + "Show codecs currently allowed on 3G CS calls.\n" + "List all codecs that osmo-msc supports, in general.\n" + ) +{ + if (!argc) + config_write_codecs(vty); + else if (!strcmp("a", argv[0])) + config_write_codecs_for_rat(vty, OSMO_RAT_GERAN_A); + else if (!strcmp("iu", argv[0])) + config_write_codecs_for_rat(vty, OSMO_RAT_UTRAN_IU); + else { + const struct codec_mapping *m; + vty_out(vty, "Supported codecs are:%s", VTY_NEWLINE); + codec_mapping_foreach (m) + vty_out(vty, " %s%s", sdp_audio_codec_to_str(&m->sdp), VTY_NEWLINE); + } + return CMD_SUCCESS; +} + static int config_write_msc(struct vty *vty) { vty_out(vty, "msc%s", VTY_NEWLINE); @@ -2072,6 +2218,11 @@ void msc_vty_init(struct gsm_network *msc_network) install_element(MSC_NODE, &cfg_msc_nri_add_cmd); install_element(MSC_NODE, &cfg_msc_nri_del_cmd); + install_element(CONFIG_NODE, &cfg_codecs_cmd); + install_node(&codecs_node, config_write_codecs); + install_element(CODECS_NODE, &cfg_codecs_clear_cmd); + install_element(CODECS_NODE, &cfg_codecs_entry_cmd); + neighbor_ident_vty_init(msc_network); /* Timer configuration commands (generic osmo_tdef API) */ @@ -2097,6 +2248,7 @@ void msc_vty_init(struct gsm_network *msc_network) install_element_ve(&show_msc_conn_cmd); install_element_ve(&show_msc_transaction_cmd); install_element_ve(&show_nri_cmd); + install_element_ve(&show_codecs_cmd); install_element_ve(&sms_send_pend_cmd); install_element_ve(&sms_delete_expired_cmd); diff --git a/tests/codecs.vty b/tests/codecs.vty new file mode 100644 index 000000000..94d91697b --- /dev/null +++ b/tests/codecs.vty @@ -0,0 +1,296 @@ +OsmoMSC> show codecs? + codecs Show codecs listings + +OsmoMSC> show codecs ? + [a] Show codecs currently allowed on 2G AoIP calls. + [iu] Show codecs currently allowed on 3G CS calls. + [supported] List all codecs that osmo-msc supports, in general. + +OsmoMSC> show codecs a +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 + +OsmoMSC> show codecs iu +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC> show codecs supported +Supported codecs are: + PCMU#0 + GSM#3 + PCMA#8 + G729#18 + GSM-EFR#110 + GSM-HR-08#111 + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#112 + AMR:octet-align=1;mode-set=0,2,4#112 + AMR:octet-align=1;mode-set=0,2,4#112 + AMR:mode-set=0,2,4,7#112 + AMR:mode-set=7#112 + AMR:mode-set=0,2,4#112 + AMR:mode-set=0,2,4#112 + AMR-WB/16000:octet-align=1#113 + VND.3GPP.IUFP/16000#96 + CLEARMODE#120 + +OsmoMSC> show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC> enable +OsmoMSC# show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC# configure terminal + +OsmoMSC(config)# do show codecs? + codecs Show codecs listings +OsmoMSC(config)# do show codecs ? + [a] Show codecs currently allowed on 2G AoIP calls. + [iu] Show codecs currently allowed on 3G CS calls. + [supported] List all codecs that osmo-msc supports, in general. + +OsmoMSC(config)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config)# codecs? + codecs Configure allowed codecs and order of preference +OsmoMSC(config)# codecs ? + a Configure codecs on GERAN (2G). For AMR codecs, the 'mode-set' instructs the 2G RAN to support specific AMR rates. The octet-align has no effect on the 2G RAN side: on AoIP, osmo-msc always uses a fixed octet-align mode, see . Make sure that an entry matching the AoIP octet-align mode is present; optionally offer AMR alignment conversion to the other call leg by adding another entry in mismatching octet-align mode. For TrFO between TCH/H channels with AMR-FR used on TCH/F and 3G, consider that AMR-HR does not support mode-set 6 nor 7. + iu Configure (inner) AMR codecs on UTRAN. Towards 3G RAN, osmo-msc *always* uses VND.3GPP.IUFP. The codecs configured here need to be AMR or AMR-WB, corresponding to the AMR payload within the IUFP header. The 'mode-set' instructs the 3G RAN to support specific AMR rates. 'octet-align' has no effect on the 3G RAN, but simply offers AMR alignment conversion to the other call leg. + +OsmoMSC(config)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config)# codecs a +OsmoMSC(config-codecs)# list +... + clear + (add|no) CODEC_STR +OsmoMSC(config-codecs)# ? +... + clear Clear all codecs from the list -- this breaks voice calls, you should add new entries after this. + add Add a codec entry + no Delete a codec entry + +OsmoMSC(config-codecs)# ### Remove an entry. (1) affects only 'codecs a'. (2) does not affect the 'octet-align=1' entry +OsmoMSC(config-codecs)# no AMR:mode-set=7 +OsmoMSC(config-codecs)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 +OsmoMSC(config-codecs)# ### Also remove the octet-align=1 variant +OsmoMSC(config-codecs)# no AMR:octet-align=1;mode-set=7 +OsmoMSC(config-codecs)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config-codecs)# ### Remove nonexisting entry +OsmoMSC(config-codecs)# no AMR:mode-set=7 +% Codec not present in the list: AMR:mode-set=7 + +OsmoMSC(config-codecs)# clear +OsmoMSC(config-codecs)# do show codecs +codecs a + clear +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config-codecs)# add AMR:mode-set=1 +% Error: unsupported codec 'AMR:mode-set=1'. See 'do show codecs supported' command. + +OsmoMSC(config-codecs)# do show codecs +codecs a + clear +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config-codecs)# add AMR:octet-align=1;mode-set=0,2,4,7#98 +OsmoMSC(config-codecs)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#98 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config-codecs)# add AMR:octet-align=1;mode-set=0,2,4,7#112 +% Codec already present in the list: AMR:octet-align=1;mode-set=0,2,4,7#98 + +OsmoMSC(config-codecs)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#98 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config-codecs)# add AMR:mode-set=0,2,4,7#98 +OsmoMSC(config-codecs)# do show codecs +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#98 + AMR:mode-set=0,2,4,7#98 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 + +OsmoMSC(config-codecs)# ### The AMR octet-align and mode-set fmtp are handled logically, in any order: +OsmoMSC(config-codecs)# add AMR:mode-set=0,2,4,7;octet-align=1#112 +% Codec already present in the list: AMR:octet-align=1;mode-set=0,2,4,7#98 diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty index 5e4b793b1..69a1efb17 100644 --- a/tests/test_nodes.vty +++ b/tests/test_nodes.vty @@ -4,6 +4,7 @@ OsmoMSC(config)# list ... network msc + codecs (a|iu) sgs smsc asci @@ -112,6 +113,15 @@ msc ... ! mncc external OsmoMSC(config-msc)# exit + +OsmoMSC(config)# codecs? + codecs Configure allowed codecs and order of preference +OsmoMSC(config)# codecs ? + a Configure codecs on GERAN (2G). For AMR codecs, the 'mode-set' instructs the 2G RAN to support specific AMR rates. The octet-align has no effect on the 2G RAN side: on AoIP, osmo-msc always uses a fixed octet-align mode, see . Make sure that an entry matching the AoIP octet-align mode is present; optionally offer AMR alignment conversion to the other call leg by adding another entry in mismatching octet-align mode. For TrFO between TCH/H channels with AMR-FR used on TCH/F and 3G, consider that AMR-HR does not support mode-set 6 nor 7. + iu Configure (inner) AMR codecs on UTRAN. Towards 3G RAN, osmo-msc *always* uses VND.3GPP.IUFP. The codecs configured here need to be AMR or AMR-WB, corresponding to the AMR payload within the IUFP header. The 'mode-set' instructs the 3G RAN to support specific AMR rates. 'octet-align' has no effect on the 3G RAN, but simply offers AMR alignment conversion to the other call leg. +OsmoMSC(config)# codecs a +OsmoMSC(config-codecs)# exit + OsmoMSC(config)# mncc-int OsmoMSC(config-mncc-int)# list ... @@ -191,6 +201,26 @@ smsc asci disable gcr +codecs a + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + GSM-EFR#110 + GSM#3 + GSM-HR-08#111 +codecs iu + clear + AMR:octet-align=1;mode-set=0,2,4,7#112 + AMR:octet-align=1;mode-set=7#114 + AMR:octet-align=1;mode-set=0,2,4#115 + AMR:mode-set=0,2,4,7#116 + AMR:mode-set=7#117 + AMR:mode-set=0,2,4#118 + AMR-WB/16000:octet-align=1#113 end OsmoMSC# configure terminal