Harald Welte has submitted this change and it was merged. ( 
https://gerrit.osmocom.org/13713 )

Change subject: Create subscribers on demand
......................................................................

Create subscribers on demand

Add a new vty option and allow to optionally generate a random msisdn,
as well as setting the default NAM:

subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|both)

Thanks to Vadim for the random MSISDN patch [1], which was squashed into
this one.

[1] Change-Id: I475c71f9902950fa7498855a616e1ec231fad6ac

Depends on: Idc74f4d94ad44b9fc1b6d43178f5f33d551ebfb1 (libosmocore)
Change-Id: I0c9fe93f5c24b5e9fefb513c4d049fb7ebd47ecd
Related: OS#2542
---
M src/hlr.c
M src/hlr.h
M src/hlr_vty.c
M tests/test_nodes.vty
A tests/test_subscr_create_on_demand.vty
5 files changed, 186 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  osmith: Looks good to me, but someone else must approve
  Harald Welte: Looks good to me, approved



diff --git a/src/hlr.c b/src/hlr.c
index 0bea590..694ba14 100644
--- a/src/hlr.c
+++ b/src/hlr.c
@@ -34,6 +34,8 @@
 #include <osmocom/ctrl/control_vty.h>
 #include <osmocom/gsm/apn.h>
 #include <osmocom/gsm/gsm48_ie.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>

 #include "db.h"
 #include "hlr.h"
@@ -148,6 +150,78 @@
        }
 }

+static int generate_new_msisdn(char *msisdn, const char *imsi, unsigned int 
len)
+{
+       int i, j, rc;
+       uint8_t rand_buf[GSM23003_MSISDN_MAX_DIGITS];
+
+       OSMO_ASSERT(len <= sizeof(rand_buf));
+
+       /* Generate a random unique MSISDN (with retry) */
+       for (i = 0; i < 10; i++) {
+               /* Get a random number (with retry) */
+               for (j = 0; j < 10; j++) {
+                       rc = osmo_get_rand_id(rand_buf, len);
+                       if (!rc)
+                               break;
+               }
+               if (rc) {
+                       LOGP(DMAIN, LOGL_ERROR, "IMSI='%s': Failed to generate 
new MSISDN, random number generator"
+                                               " failed (rc=%d)\n", imsi, rc);
+                       return rc;
+               }
+
+               /* Shift 0x00 ... 0xff range to 30 ... 39 (ASCII numbers) */
+               for (j = 0; j < len; j++)
+                       msisdn[j] = 48 + (rand_buf[j] % 10);
+               msisdn[j] = '\0';
+
+               /* Ensure there is no subscriber with such MSISDN */
+               if (db_subscr_exists_by_msisdn(g_hlr->dbc, msisdn) == -ENOENT)
+                       return 0;
+       }
+
+       /* Failure */
+       LOGP(DMAIN, LOGL_ERROR, "IMSI='%s': Failed to generate a new MSISDN, 
consider increasing "
+                               "the length for the automatically assigned 
MSISDNs "
+                               "(see 'subscriber-create-on-demand' 
command)\n", imsi);
+       return -1;
+}
+
+static int subscr_create_on_demand(const char *imsi)
+{
+       char msisdn[GSM23003_MSISDN_MAX_DIGITS + 1];
+       int rc;
+       unsigned int rand_msisdn_len = 
g_hlr->subscr_create_on_demand_rand_msisdn_len;
+
+       if (!g_hlr->subscr_create_on_demand)
+               return -1;
+       if (db_subscr_exists_by_imsi(g_hlr->dbc, imsi) == 0)
+               return -1;
+       if (rand_msisdn_len && generate_new_msisdn(msisdn, imsi, 
rand_msisdn_len) != 0)
+               return -1;
+
+       LOGP(DMAIN, LOGL_INFO, "IMSI='%s': Creating subscriber on demand\n", 
imsi);
+       rc = db_subscr_create(g_hlr->dbc, imsi, 
g_hlr->subscr_create_on_demand_flags);
+       if (rc) {
+               LOGP(DMAIN, LOGL_ERROR, "Failed to create subscriber on demand 
(rc=%d): IMSI='%s'\n", rc, imsi);
+               return rc;
+       }
+
+       if (!rand_msisdn_len)
+               return 0;
+
+       /* Update MSISDN of the new (just allocated) subscriber */
+       rc = db_subscr_update_msisdn_by_imsi(g_hlr->dbc, imsi, msisdn);
+       if (rc) {
+               LOGP(DMAIN, LOGL_ERROR, "IMSI='%s': Failed to assign 
MSISDN='%s' (rc=%d)\n", imsi, msisdn, rc);
+               return rc;
+       }
+       LOGP(DMAIN, LOGL_INFO, "IMSI='%s': Successfully assigned 
MSISDN='%s'\n", imsi, msisdn);
+
+       return 0;
+}
+
 /***********************************************************************
  * Send Auth Info handling
  ***********************************************************************/
@@ -161,6 +235,8 @@
        struct msgb *msg_out;
        int rc;

+       subscr_create_on_demand(gsup->imsi);
+
        /* initialize return message structure */
        memset(&gsup_out, 0, sizeof(gsup_out));
        memcpy(&gsup_out.imsi, &gsup->imsi, sizeof(gsup_out.imsi));
@@ -291,6 +367,8 @@
        }
        llist_add(&luop->list, &g_lu_ops);

+       subscr_create_on_demand(gsup->imsi);
+
        /* Roughly follwing "Process Update_Location_HLR" of TS 09.02 */

        /* check if subscriber is known at all */
@@ -415,6 +493,8 @@
                return -1;
        }

+       subscr_create_on_demand(gsup->imsi);
+
        /* Save in DB if desired */
        if (g_hlr->store_imei) {
                LOGP(DAUC, LOGL_DEBUG, "IMSI='%s': storing IMEI = %s\n", 
gsup->imsi, imei);
diff --git a/src/hlr.h b/src/hlr.h
index e2e96a4..18c4a1d 100644
--- a/src/hlr.h
+++ b/src/hlr.h
@@ -56,6 +56,11 @@
        struct llist_head ss_sessions;

        bool store_imei;
+
+       bool subscr_create_on_demand;
+       /* Bitmask of DB_SUBSCR_FLAG_* */
+       uint8_t subscr_create_on_demand_flags;
+       unsigned int subscr_create_on_demand_rand_msisdn_len;
 };

 extern struct hlr *g_hlr;
diff --git a/src/hlr_vty.c b/src/hlr_vty.c
index e4cc4be..e6567cc 100644
--- a/src/hlr_vty.c
+++ b/src/hlr_vty.c
@@ -33,6 +33,7 @@
 #include <osmocom/vty/misc.h>
 #include <osmocom/abis/ipa.h>

+#include "db.h"
 #include "hlr.h"
 #include "hlr_vty.h"
 #include "hlr_vty_subscr.h"
@@ -76,6 +77,23 @@
                vty_out(vty, " store-imei%s", VTY_NEWLINE);
        if (g_hlr->db_file_path && strcmp(g_hlr->db_file_path, 
HLR_DEFAULT_DB_FILE_PATH))
                vty_out(vty, " database %s%s", g_hlr->db_file_path, 
VTY_NEWLINE);
+       if (g_hlr->subscr_create_on_demand) {
+               const char *flags_str = "none";
+               uint8_t flags = g_hlr->subscr_create_on_demand_flags;
+               unsigned int rand_msisdn_len = 
g_hlr->subscr_create_on_demand_rand_msisdn_len;
+
+               if ((flags & DB_SUBSCR_FLAG_NAM_CS) && (flags & 
DB_SUBSCR_FLAG_NAM_PS))
+                       flags_str = "cs+ps";
+               else if (flags & DB_SUBSCR_FLAG_NAM_CS)
+                       flags_str = "cs";
+               else if (flags & DB_SUBSCR_FLAG_NAM_PS)
+                       flags_str = "ps";
+
+               if (rand_msisdn_len)
+                       vty_out(vty, " subscriber-create-on-demand %i %s%s", 
rand_msisdn_len, flags_str, VTY_NEWLINE);
+               else
+                       vty_out(vty, " subscriber-create-on-demand no-msisdn 
%s%s", flags_str, VTY_NEWLINE);
+       }
        return CMD_SUCCESS;
 }

@@ -336,6 +354,42 @@
        return CMD_SUCCESS;
 }

+DEFUN(cfg_subscr_create_on_demand, cfg_subscr_create_on_demand_cmd,
+       "subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|cs+ps)",
+       "Make a new record when a subscriber is first seen.\n"
+       "Do not automatically assign MSISDN.\n"
+       "Length of an automatically assigned MSISDN.\n"
+       "Do not allow any NAM (Network Access Mode) by default.\n"
+       "Allow access to circuit switched NAM by default.\n"
+       "Allow access to packet switched NAM by default.\n"
+       "Allow access to circuit and packet switched NAM by default.\n")
+{
+       unsigned int rand_msisdn_len = 0;
+       uint8_t flags = 0x00;
+
+       if (strcmp(argv[0], "no-msisdn") != 0)
+               rand_msisdn_len = atoi(argv[0]);
+
+       if (strstr(argv[1], "cs"))
+               flags |= DB_SUBSCR_FLAG_NAM_CS;
+       if (strstr(argv[1], "ps"))
+               flags |= DB_SUBSCR_FLAG_NAM_PS;
+
+       g_hlr->subscr_create_on_demand = true;
+       g_hlr->subscr_create_on_demand_rand_msisdn_len = rand_msisdn_len;
+       g_hlr->subscr_create_on_demand_flags = flags;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_subscr_create_on_demand, cfg_no_subscr_create_on_demand_cmd,
+       "no subscriber-create-on-demand",
+       "Do not make a new record when a subscriber is first seen.\n")
+{
+       g_hlr->subscr_create_on_demand = false;
+       return CMD_SUCCESS;
+}
+
 /***********************************************************************
  * Common Code
  ***********************************************************************/
@@ -404,6 +458,8 @@
        install_element(HLR_NODE, &cfg_ncss_guard_timeout_cmd);
        install_element(HLR_NODE, &cfg_store_imei_cmd);
        install_element(HLR_NODE, &cfg_no_store_imei_cmd);
+       install_element(HLR_NODE, &cfg_subscr_create_on_demand_cmd);
+       install_element(HLR_NODE, &cfg_no_subscr_create_on_demand_cmd);

        hlr_vty_subscriber_init();
 }
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index a4e53db..bf2afaf 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -86,6 +86,8 @@
   ncss-guard-timeout <0-255>
   store-imei
   no store-imei
+  subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|cs+ps)
+  no subscriber-create-on-demand

 OsmoHLR(config-hlr)# gsup
 OsmoHLR(config-hlr-gsup)# list
diff --git a/tests/test_subscr_create_on_demand.vty 
b/tests/test_subscr_create_on_demand.vty
new file mode 100644
index 0000000..fb587ae
--- /dev/null
+++ b/tests/test_subscr_create_on_demand.vty
@@ -0,0 +1,43 @@
+OsmoHLR> enable
+OsmoHLR# configure terminal
+OsmoHLR(config)# hlr
+
+OsmoHLR(config-hlr)# subscriber-create-on-demand no-msisdn none
+OsmoHLR(config-hlr)# show running-config
+...
+hlr
+...
+ subscriber-create-on-demand no-msisdn none
+...
+
+OsmoHLR(config-hlr)# subscriber-create-on-demand 3 none
+OsmoHLR(config-hlr)# show running-config
+...
+hlr
+...
+ subscriber-create-on-demand 3 none
+...
+
+OsmoHLR(config-hlr)# subscriber-create-on-demand 4 cs
+OsmoHLR(config-hlr)# show running-config
+...
+hlr
+...
+ subscriber-create-on-demand 4 cs
+...
+
+OsmoHLR(config-hlr)# subscriber-create-on-demand 5 ps
+OsmoHLR(config-hlr)# show running-config
+...
+hlr
+...
+ subscriber-create-on-demand 5 ps
+...
+
+OsmoHLR(config-hlr)# subscriber-create-on-demand 6 cs+ps
+OsmoHLR(config-hlr)# show running-config
+...
+hlr
+...
+ subscriber-create-on-demand 6 cs+ps
+...

--
To view, visit https://gerrit.osmocom.org/13713
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I0c9fe93f5c24b5e9fefb513c4d049fb7ebd47ecd
Gerrit-Change-Number: 13713
Gerrit-PatchSet: 8
Gerrit-Owner: Vadim Yanitskiy <[email protected]>
Gerrit-Assignee: Vadim Yanitskiy <[email protected]>
Gerrit-Reviewer: Harald Welte <[email protected]>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Pau Espin Pedrol <[email protected]>
Gerrit-Reviewer: Vadim Yanitskiy <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>

Reply via email to