aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gsm_data.h8
-rw-r--r--openbsc/src/libbsc/net_init.c2
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c57
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c31
4 files changed, 84 insertions, 14 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 6d7aba358..e9ec92cdf 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -208,6 +208,12 @@ enum gsm_auth_policy {
#define GSM_T3113_DEFAULT 60
#define GSM_T3122_DEFAULT 10
+enum {
+ SUBSCR_DONT_CREATE,
+ SUBSCR_CREATE_FULL_SERVICE,
+ SUBSCR_CREATE_LMTD_SERVICE,
+};
+
struct gsm_network {
/* global parameters */
uint16_t country_code;
@@ -282,7 +288,7 @@ struct gsm_network {
struct osmo_bsc_data *bsc_data;
/* subscriber related features */
- int create_subscriber;
+ int create_subscriber_mode;
struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue;
diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c
index 568a0b85e..64ac7cd6b 100644
--- a/openbsc/src/libbsc/net_init.c
+++ b/openbsc/src/libbsc/net_init.c
@@ -48,7 +48,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
INIT_LLIST_HEAD(&net->bsc_data->mscs);
net->subscr_group->net = net;
- net->create_subscriber = 1;
+ net->create_subscriber_mode = SUBSCR_CREATE_FULL_SERVICE;
net->country_code = country_code;
net->network_code = network_code;
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index d907f7d04..3eafe4ca3 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -119,12 +119,56 @@ static void reject_trap(struct ctrl_handle *ctrl, const char *imsi)
}
cmd->id = "0";
- cmd->variable = talloc_asprintf(cmd, "subscriber-reject-v1");
+ cmd->variable = talloc_strdup(cmd, "subscriber-reject-v1");
cmd->reply = talloc_strdup(cmd, imsi);
ctrl_cmd_send_to_all(ctrl, cmd);
talloc_free(cmd);
}
+static void send_trap(struct ctrl_handle *ctrl, const char *var, const char *value)
+{
+ struct ctrl_cmd *cmd;
+
+ cmd = ctrl_cmd_create(NULL, CTRL_TYPE_TRAP);
+ if (!cmd) {
+ LOGP(DCTRL, LOGL_ERROR, "Failed to create TRAP command.\n");
+ return;
+ }
+
+ cmd->id = "0";
+ cmd->variable = talloc_strdup(cmd, var);
+ cmd->reply = talloc_strdup(cmd, value);
+ ctrl_cmd_send_to_all(ctrl, cmd);
+ talloc_free(cmd);
+}
+
+static struct gsm_subscriber *maybe_create(struct gsm_network *net, const char *imsi)
+{
+ struct gsm_subscriber *subscr;
+
+ switch (net->create_subscriber_mode) {
+ case SUBSCR_DONT_CREATE:
+ return NULL;
+ case SUBSCR_CREATE_FULL_SERVICE:
+ subscr = subscr_create_subscriber(net->subscr_group, imsi);
+ subscr->limited_service = 0;
+ subscr->authorized = 1;
+ db_sync_subscriber(subscr);
+ send_trap(net->ctrl, "subscriber-created-full-v1", imsi);
+ return subscr;
+ case SUBSCR_CREATE_LMTD_SERVICE:
+ subscr = subscr_create_subscriber(net->subscr_group, imsi);
+ subscr->limited_service = 1;
+ subscr->authorized = 1;
+ db_sync_subscriber(subscr);
+ send_trap(net->ctrl, "subscriber-created-limited-v1", imsi);
+ return subscr;
+ default:
+ LOGP(DMM, LOGL_ERROR, "Unknown mode %d\n", net->create_subscriber_mode);
+ return NULL;
+ }
+}
+
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
{
net->mncc_recv(net, msg);
@@ -547,9 +591,8 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *ms
if (!conn->subscr) {
conn->subscr = subscr_get_by_imsi(net->subscr_group,
mi_string);
- if (!conn->subscr && net->create_subscriber)
- conn->subscr = subscr_create_subscriber(
- net->subscr_group, mi_string);
+ if (!conn->subscr)
+ conn->subscr = maybe_create(net, mi_string);
}
if (!conn->subscr && conn->loc_operation) {
reject_trap(net->ctrl, mi_string);
@@ -659,10 +702,8 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
/* look up subscriber based on IMSI, create if not found */
subscr = subscr_get_by_imsi(bts->network->subscr_group, mi_string);
- if (!subscr && bts->network->create_subscriber) {
- subscr = subscr_create_subscriber(
- bts->network->subscr_group, mi_string);
- }
+ if (!subscr)
+ subscr = maybe_create(bts->network, mi_string);
if (!subscr) {
reject_trap(bts->network->ctrl, mi_string);
gsm0408_loc_upd_rej(conn, bts->network->reject_cause);
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index 790fedf39..9f15b8a8b 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -1036,7 +1036,20 @@ DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd,
"Make a new record when a subscriber is first seen.\n")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
- gsmnet->create_subscriber = 1;
+ gsmnet->create_subscriber_mode = SUBSCR_CREATE_FULL_SERVICE;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_nitb_subscr_create_od, cfg_nitb_subscr_create_od_cmd,
+ "subscriber-create-on-demand (full-service|limited-service)",
+ "Make a new record when a subscriber is first seen.\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
+ if (argv[0][0] == 'f')
+ gsmnet->create_subscriber_mode = SUBSCR_CREATE_FULL_SERVICE;
+ else
+ gsmnet->create_subscriber_mode = SUBSCR_CREATE_LMTD_SERVICE;
return CMD_SUCCESS;
}
@@ -1045,7 +1058,7 @@ DEFUN(cfg_nitb_no_subscr_create, cfg_nitb_no_subscr_create_cmd,
NO_STR "Make a new record when a subscriber is first seen.\n")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
- gsmnet->create_subscriber = 0;
+ gsmnet->create_subscriber_mode = SUBSCR_DONT_CREATE;
return CMD_SUCCESS;
}
@@ -1071,8 +1084,17 @@ static int config_write_nitb(struct vty *vty)
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
vty_out(vty, "nitb%s", VTY_NEWLINE);
- vty_out(vty, " %ssubscriber-create-on-demand%s",
- gsmnet->create_subscriber ? "" : "no ", VTY_NEWLINE);
+ switch (gsmnet->create_subscriber_mode) {
+ case SUBSCR_CREATE_FULL_SERVICE:
+ vty_out(vty, " subscriber-create-on-demand full-service%s", VTY_NEWLINE);
+ break;
+ case SUBSCR_CREATE_LMTD_SERVICE:
+ vty_out(vty, " subscriber-create-on-demand limited-service%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, " no subscriber-create-on-demand%s", VTY_NEWLINE);
+ break;
+ }
vty_out(vty, " %sassign-tmsi%s",
gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE);
return CMD_SUCCESS;
@@ -1127,6 +1149,7 @@ int bsc_vty_init_extra(void)
install_element(CONFIG_NODE, &cfg_nitb_cmd);
install_node(&nitb_node, config_write_nitb);
install_element(NITB_NODE, &cfg_nitb_subscr_create_cmd);
+ install_element(NITB_NODE, &cfg_nitb_subscr_create_od_cmd);
install_element(NITB_NODE, &cfg_nitb_no_subscr_create_cmd);
install_element(NITB_NODE, &cfg_nitb_assign_tmsi_cmd);
install_element(NITB_NODE, &cfg_nitb_no_assign_tmsi_cmd);