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
This commit is contained in:
parent
c13599dc69
commit
c7f1787c18
80
src/hlr.c
80
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 @@ osmo_hlr_subscriber_update_notify(struct hlr_subscriber *subscr)
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ static int rx_send_auth_info(struct osmo_gsup_conn *conn,
|
|||
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 @@ static int rx_upd_loc_req(struct osmo_gsup_conn *conn,
|
|||
}
|
||||
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 @@ static int rx_check_imei_req(struct osmo_gsup_conn *conn, const struct osmo_gsup
|
|||
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);
|
||||
|
|
|
@ -56,6 +56,11 @@ struct hlr {
|
|||
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;
|
||||
|
|
|
@ -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 @@ static int config_write_hlr(struct vty *vty)
|
|||
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 @@ DEFUN(cfg_no_store_imei, cfg_no_store_imei_cmd,
|
|||
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 @@ void hlr_vty_init(const struct log_info *cat)
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ OsmoHLR(config-hlr)# list
|
|||
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
|
||||
|
|
|
@ -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
|
||||
...
|
Loading…
Reference in New Issue