aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2020-05-27 00:04:26 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2020-06-19 03:58:13 +0200
commit9aac5c2d215d6309445801d1f3cd954933942615 (patch)
tree8cd996b3f5582565c08eaddce0ed2e75d23788cd /src
parent46d526a3dff7527ba23fde1df3d6243e7edf6486 (diff)
add rudimentary NRI support for MSC pooling
This patch served for a manual testing counterpart for osmo-bsc to implement MSC pooling. This enables a basic MSC pooling setup, but for a production setup, osmo-msc would still lack various features related to unloading subscribers to another MSC as explained in 3GPP TS 23.236. Change-Id: Iafe0878a0a2c8669080d757b34a398ea75fced36
Diffstat (limited to 'src')
-rw-r--r--src/libmsc/msc_vty.c77
-rw-r--r--src/libvlr/vlr.c12
2 files changed, 89 insertions, 0 deletions
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index a92609d7f..29deb5e82 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -33,6 +33,7 @@
#include <osmocom/gsm/protocol/gsm_08_58.h>
#include <osmocom/gsm/protocol/gsm_04_14.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/sigtran/sccp_helpers.h>
@@ -657,6 +658,76 @@ DEFUN(cfg_msc_osmux,
return CMD_SUCCESS;
}
+#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
+DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd,
+ "nri bitlen <0-15>",
+ NRI_STR
+ "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n"
+ "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n")
+{
+ gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
+#define NRI_ARGS_TO_STR_FMT "%s%s%s"
+#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
+#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
+ "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
+ " first value; if omitted, apply only the first value.\n"
+
+DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd,
+ "nri add <0-32767> [<0-32767>]",
+ NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ const char *message;
+ int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.nri_bitlen);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd,
+ "nri del <0-32767> [<0-32767>]",
+ NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ const char *message;
+ int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
+static void msc_write_nri(struct vty *vty)
+{
+ struct osmo_nri_range *r;
+
+ llist_for_each_entry(r, &gsmnet->vlr->cfg.nri_ranges->entries, entry) {
+ if (osmo_nri_range_validate(r, 255))
+ vty_out(vty, " %% INVALID RANGE:");
+ vty_out(vty, " nri add %d", r->first);
+ if (r->first != r->last)
+ vty_out(vty, " %d", r->last);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+}
+
+DEFUN(show_nri, show_nri_cmd,
+ "show nri",
+ SHOW_STR NRI_STR)
+{
+ msc_write_nri(vty);
+ return CMD_SUCCESS;
+}
+
static int config_write_msc(struct vty *vty)
{
vty_out(vty, "msc%s", VTY_NEWLINE);
@@ -722,6 +793,8 @@ static int config_write_msc(struct vty *vty)
/* Timer introspection commands (generic osmo_tdef API) */
osmo_tdef_vty_groups_write(vty, " ");
+ msc_write_nri(vty);
+
return CMD_SUCCESS;
}
@@ -2002,6 +2075,9 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
install_element(MSC_NODE, &cfg_msc_osmux_cmd);
install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
+ install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd);
+ install_element(MSC_NODE, &cfg_msc_nri_add_cmd);
+ install_element(MSC_NODE, &cfg_msc_nri_del_cmd);
neighbor_ident_vty_init(msc_network);
@@ -2023,6 +2099,7 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element_ve(&show_bsc_cmd);
install_element_ve(&show_msc_conn_cmd);
install_element_ve(&show_msc_transaction_cmd);
+ install_element_ve(&show_nri_cmd);
install_element_ve(&sms_send_pend_cmd);
install_element_ve(&sms_delete_expired_cmd);
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
index 3a44d3090..33d6331c0 100644
--- a/src/libvlr/vlr.c
+++ b/src/libvlr/vlr.c
@@ -25,6 +25,7 @@
#include <osmocom/core/timer.h>
#include <osmocom/core/tdef.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/gsm/gsm48.h>
@@ -329,6 +330,15 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
LOGP(DDB, LOGL_ERROR, "osmo_get_rand_id() failed: %s\n", strerror(-rc));
return rc;
}
+
+ if (!llist_empty(&vlr->cfg.nri_ranges->entries)) {
+ int16_t nri_v;
+ osmo_tmsi_nri_v_limit_by_ranges(&tmsi, vlr->cfg.nri_ranges, vlr->cfg.nri_bitlen);
+ osmo_tmsi_nri_v_get(&nri_v, tmsi, vlr->cfg.nri_bitlen);
+ LOGP(DVLR, LOGL_DEBUG, "New NRI from range [%s] = 0x%x --> TMSI 0x%08x\n",
+ osmo_nri_ranges_to_str_c(OTC_SELECT, vlr->cfg.nri_ranges), nri_v, tmsi);
+ }
+
/* throw the dice again, if the TSMI doesn't fit */
if (tmsi == GSM_RESERVED_TMSI)
continue;
@@ -1246,6 +1256,8 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
/* defaults */
vlr->cfg.assign_tmsi = true;
+ vlr->cfg.nri_bitlen = OSMO_NRI_BITLEN_DEFAULT;
+ vlr->cfg.nri_ranges = osmo_nri_ranges_alloc(vlr);
/* reset shared timer definitions */
osmo_tdefs_reset(msc_tdefs_vlr);