aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-08-30 22:01:42 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-09-13 23:04:42 +0200
commit3001bc649ca7287c6caa1f5031c5a50af97c8974 (patch)
treefd29adbcc211057018c187f5e10866b6432de63c
parent9b45dc7eda8e31b8b46ea99bc7c0cd6ce17fb844 (diff)
Iu: allow configuring AMR rates
-rw-r--r--include/osmocom/msc/ran_msg_iu.h6
-rw-r--r--src/libmsc/msc_vty.c66
-rw-r--r--src/libmsc/ran_msg_iu.c18
-rw-r--r--tests/test_nodes.vty16
4 files changed, 103 insertions, 3 deletions
diff --git a/include/osmocom/msc/ran_msg_iu.h b/include/osmocom/msc/ran_msg_iu.h
index 7da1d5754..ebf376cf3 100644
--- a/include/osmocom/msc/ran_msg_iu.h
+++ b/include/osmocom/msc/ran_msg_iu.h
@@ -24,8 +24,7 @@
#include <osmocom/msc/ran_msg.h>
#include <osmocom/msc/paging.h>
-
-struct sccp_ran_inst;
+#include <osmocom/msc/sccp_ran.h>
int ran_iu_decode_l2(struct ran_dec *ran_dec_iu, struct msgb *ranap);
struct msgb *ran_iu_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg);
@@ -36,3 +35,6 @@ struct msgb *ranap_make_reset_msg(const struct sccp_ran_inst *sri, enum reset_ms
struct msgb *ranap_make_paging_msg(const struct sccp_ran_inst *sri, const struct gsm0808_cell_id *page_cell_id,
const char *imsi, uint32_t tmsi, enum paging_cause cause);
const char *ranap_msg_name(const struct sccp_ran_inst *sri, const struct msgb *l2);
+
+extern const int g_ranap_rab_modes_default;
+extern int g_ranap_rab_modes;
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 70b3b6bb1..9b27f102c 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -45,6 +45,8 @@
#ifdef BUILD_IU
#include <osmocom/ranap/iu_client.h>
+#include <osmocom/ranap/ranap_msg_factory.h>
+#include <osmocom/msc/ran_msg_iu.h>
#endif
#include <osmocom/msc/vty.h>
@@ -530,6 +532,53 @@ DEFUN(cfg_msc_cs7_instance_iu,
#endif
}
+#if BUILD_IU
+static const struct value_string rab_mode_strs[] = {
+ { OSMO_RANAP_RAB_MODE_AMR_4_75, "4k75" },
+ { OSMO_RANAP_RAB_MODE_AMR_5_15, "5k15" },
+ { OSMO_RANAP_RAB_MODE_AMR_5_90, "5k90" },
+ { OSMO_RANAP_RAB_MODE_AMR_6_70, "6k70" },
+ { OSMO_RANAP_RAB_MODE_AMR_7_40, "7k40" },
+ { OSMO_RANAP_RAB_MODE_AMR_7_95, "7k95" },
+ { OSMO_RANAP_RAB_MODE_AMR_10_2, "10k2" },
+ { OSMO_RANAP_RAB_MODE_AMR_12_2, "12k2" },
+ { OSMO_RANAP_RAB_MODE_AMR_SID, "SID" },
+ {}
+};
+#endif
+
+DEFUN(cfg_msc_iu_rab_modes,
+ cfg_msc_iu_rab_modes_cmd,
+ "iu global rab-modes .LIST",
+ "UTRAN related\n"
+ "Applies to all attached RNCs\n" /* future: also allow individual settings per CGI */
+ "Set RAB modes (AMR rates) to request from RNC in RAB Assignment\n"
+ "List of RAB modes. The full list would be '4k75 5k15 5k90 6k70 7k40 7k95 10k2 12k2 SID'\n")
+{
+#if BUILD_IU
+ int i;
+ int modes = 0;
+ for (i = 0; i < argc; i++) {
+ const char *arg = argv[i];
+ int val = get_string_value(rab_mode_strs, arg);
+
+ if (val < 0) {
+ vty_out(vty, "%% Error: unknown RAB mode: '%s'%s", arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ modes |= (1 << val);
+ }
+
+ g_ranap_rab_modes = modes;
+ return CMD_SUCCESS;
+#else
+ vty_out(vty, "WARNING: 'iu * rab-modes' without effect: built without Iu support%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+#endif
+}
+
DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
"auth-tuple-max-reuse-count <-1-2147483647>",
"Configure authentication tuple re-use\n"
@@ -777,6 +826,19 @@ static int config_write_msc(struct vty *vty)
#if BUILD_IU
vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
VTY_NEWLINE);
+
+ if (g_ranap_rab_modes != g_ranap_rab_modes_default) {
+ int i;
+
+ vty_out(vty, " iu global rab-modes");
+
+ for (i = 0; i < OSMO_RANAP_RAB_MODE_COUNT; i++) {
+ if ((g_ranap_rab_modes & (1 << i)) == 0)
+ continue;
+ vty_out(vty, " %s", get_value_string(rab_mode_strs, i));
+ }
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
#endif
if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
@@ -2060,6 +2122,9 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
+
+ install_element(MSC_NODE, &cfg_msc_iu_rab_modes_cmd);
+
install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
@@ -2081,6 +2146,7 @@ void msc_vty_init(struct gsm_network *msc_network)
#ifdef BUILD_IU
ranap_iu_vty_init(MSC_NODE, (enum ranap_nsap_addr_enc*)&msc_network->iu.rab_assign_addr_enc);
#endif
+
sgs_vty_init();
smsc_vty_init(msc_network);
asci_vty_init(msc_network);
diff --git a/src/libmsc/ran_msg_iu.c b/src/libmsc/ran_msg_iu.c
index 13c43fe0a..66aef56d2 100644
--- a/src/libmsc/ran_msg_iu.c
+++ b/src/libmsc/ran_msg_iu.c
@@ -344,6 +344,22 @@ static struct msgb *ran_iu_wrap_dtap(struct msgb *dtap)
return an_apdu;
}
+const int g_ranap_rab_modes_default = (1 << OSMO_RANAP_RAB_MODE_AMR_12_2) | (1 << OSMO_RANAP_RAB_MODE_AMR_SID);
+
+/* HACK: a single set of AMR rates to add to RAB Assignment Request.
+ * A proper implementation would pick rates according to the codec filter results, to allow matching rates in both call
+ * legs.
+ * This is a quick hack to be able to quickly test supported AMR rates in 3G femto cells, without having to resolve the
+ * lack of AMR rates in struct ran_assignment_command: this is not trivial, because it needs to encompass
+ * - 2G: rates communicated in predefined sets as explained in gsm0808_speech_codec_defaults; see
+ * gsm0808_speech_codec_from_chan_type().
+ * - 3G: individual SDUs per AMR rate.
+ * - AMR-WB: rates not present in 2G signalling.
+ *
+ * Bitmask composed from enum osmo_ranap_rab_mode.
+ */
+int g_ranap_rab_modes = g_ranap_rab_modes_default;
+
static struct msgb *ran_iu_make_rab_assignment(struct osmo_fsm_inst *caller_fi, const struct ran_assignment_command *ac)
{
struct msgb *msg;
@@ -371,7 +387,7 @@ static struct msgb *ran_iu_make_rab_assignment(struct osmo_fsm_inst *caller_fi,
LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "RAB Assignment: rab_id=%d, rtp=" OSMO_SOCKADDR_STR_FMT ", use_x213_nsap=%d\n",
rab_id, OSMO_SOCKADDR_STR_FMT_ARGS(ac->cn_rtp), use_x213_nsap);
- msg = ranap_new_msg_rab_assign_voice(rab_id, cn_rtp_ip, ac->cn_rtp->port, use_x213_nsap);
+ msg = ranap_new_msg_rab_assign_voice_2(rab_id, cn_rtp_ip, ac->cn_rtp->port, use_x213_nsap, g_ranap_rab_modes);
msg->l2h = msg->data;
return msg;
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index a1c443589..9eaffa5d4 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -63,6 +63,7 @@ OsmoMSC(config-msc)# list
check-imei-rqd (0|1|early)
cs7-instance-a <0-15>
cs7-instance-iu <0-15>
+ iu global rab-modes .LIST
emergency-call route-to-msisdn MSISDN
sms-over-gsup
no sms-over-gsup
@@ -107,6 +108,21 @@ OsmoMSC(config-msc)# mncc internal
OsmoMSC(config-msc)# show running-config
... ! mncc external
+OsmoMSC(config-msc)# iu?
+ iu UTRAN related
+OsmoMSC(config-msc)# iu ?
+ global Applies to all attached RNCs
+...
+OsmoMSC(config-msc)# iu global ?
+ rab-modes Set RAB modes (AMR rates) to request from RNC in RAB Assignment
+OsmoMSC(config-msc)# iu global rab-modes ?
+ LIST List of RAB modes. The full list would be '4k75 5k15 5k90 6k70 7k40 7k95 10k2 12k2 SID'
+OsmoMSC(config-msc)# iu global rab-modes 4k75 5k15 5k90 6k70 7k40 7k95 10k2 12k2 SID
+OsmoMSC(config-msc)# show running-config
+...
+ iu global rab-modes 4k75 5k15 5k90 6k70 7k40 7k95 10k2 12k2 SID
+...
+
OsmoMSC(config-msc)# exit
OsmoMSC(config)# mncc-int
OsmoMSC(config-mncc-int)# list