summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c96
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c22
3 files changed, 89 insertions, 32 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 6f7c8dd..90f3c80 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -281,6 +281,9 @@ struct gsm_network {
struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue;
+ /* nitb related control */
+ int avoid_tmsi;
+
/* control interface */
struct ctrl_handle *ctrl;
};
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 29ab2ba..02ffe58 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -67,7 +67,7 @@
void *tall_locop_ctx;
void *tall_authciphop_ctx;
-int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi);
+static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn);
static int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
uint8_t pdisc, uint8_t msg_type);
static void schedule_reject(struct gsm_subscriber_connection *conn);
@@ -294,6 +294,42 @@ static void allocate_loc_updating_req(struct gsm_subscriber_connection *conn)
struct gsm_loc_updating_operation);
}
+static int finish_lu(struct gsm_subscriber_connection *conn)
+{
+ int rc = 0;
+ int avoid_tmsi = conn->bts->network->avoid_tmsi;
+
+ /* We're all good */
+ if (avoid_tmsi) {
+ conn->subscr->tmsi = GSM_RESERVED_TMSI;
+ db_sync_subscriber(conn->subscr);
+ } else {
+ db_subscriber_alloc_tmsi(conn->subscr);
+ }
+
+ rc = gsm0408_loc_upd_acc(conn);
+ if (conn->bts->network->send_mm_info) {
+ /* send MM INFO with network name */
+ rc = gsm48_tx_mm_info(conn);
+ }
+
+ /* call subscr_update after putting the loc_upd_acc
+ * in the transmit queue, since S_SUBSCR_ATTACHED might
+ * trigger further action like SMS delivery */
+ subscr_update(conn->subscr, conn->bts,
+ GSM_SUBSCRIBER_UPDATE_ATTACHED);
+
+ /*
+ * The gsm0408_loc_upd_acc sends a MI with the TMSI. The
+ * MS needs to respond with a TMSI REALLOCATION COMPLETE
+ * (even if the TMSI is the same).
+ */
+ if (avoid_tmsi)
+ release_loc_updating_req(conn, 1);
+
+ return rc;
+}
+
static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event,
struct msgb *msg, void *data, void *param)
{
@@ -312,25 +348,7 @@ static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event,
case GSM_SECURITY_NOAVAIL:
case GSM_SECURITY_SUCCEEDED:
- /* We're all good */
- db_subscriber_alloc_tmsi(conn->subscr);
- rc = gsm0408_loc_upd_acc(conn, conn->subscr->tmsi);
- if (conn->bts->network->send_mm_info) {
- /* send MM INFO with network name */
- rc = gsm48_tx_mm_info(conn);
- }
-
- /* call subscr_update after putting the loc_upd_acc
- * in the transmit queue, since S_SUBSCR_ATTACHED might
- * trigger further action like SMS delivery */
- subscr_update(conn->subscr, conn->bts,
- GSM_SUBSCRIBER_UPDATE_ATTACHED);
-
- /*
- * The gsm0408_loc_upd_acc sends a MI with the TMSI. The
- * MS needs to respond with a TMSI REALLOCATION COMPLETE
- * (even if the TMSI is the same).
- */
+ rc = finish_lu(conn);
break;
default:
@@ -434,7 +452,7 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
}
/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
-int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi)
+static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn)
{
struct gsm_bts *bts = conn->bts;
struct msgb *msg = gsm48_msgb_alloc();
@@ -452,8 +470,16 @@ int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi)
gsm48_generate_lai(lai, bts->network->country_code,
bts->network->network_code, bts->location_area_code);
- mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
- gsm48_generate_mid_from_tmsi(mid, tmsi);
+ if (conn->subscr->tmsi == GSM_RESERVED_TMSI) {
+ uint8_t mi[10];
+ int len;
+ len = gsm48_generate_mid_from_imsi(mi, conn->subscr->imsi);
+ mid = msgb_put(msg, len);
+ memcpy(mid, mi, len);
+ } else {
+ mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
+ gsm48_generate_mid_from_tmsi(mid, conn->subscr->tmsi);
+ }
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
@@ -946,29 +972,35 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
GSM48_REJECT_INCORRECT_MESSAGE);
}
+ gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
mi_type = mi[0] & GSM_MI_TYPE_MASK;
- if (mi_type != GSM_MI_TYPE_TMSI) {
- DEBUGPC(DMM, "mi_type is not TMSI: %d\n", mi_type);
+
+ if (mi_type == GSM_MI_TYPE_IMSI) {
+ DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
+ req->cm_service_type, mi_type, mi_string);
+ subscr = subscr_get_by_imsi(bts->network->subscr_group,
+ mi_string);
+ } else if (mi_type == GSM_MI_TYPE_TMSI) {
+ DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
+ req->cm_service_type, mi_type, mi_string);
+ subscr = subscr_get_by_tmsi(bts->network->subscr_group,
+ tmsi_from_string(mi_string));
+ } else {
+ DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
return gsm48_tx_mm_serv_rej(conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
- DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
- req->cm_service_type, mi_type, mi_string);
-
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
- tmsi_from_string(mi_string));
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
if (!subscr)
return gsm48_tx_mm_serv_rej(conn,
- GSM48_REJECT_IMSI_UNKNOWN_IN_HLR);
+ GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
if (!conn->subscr)
conn->subscr = subscr;
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index 6cf51a3..1515aea 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -1037,12 +1037,32 @@ DEFUN(cfg_nitb_no_subscr_create, cfg_nitb_no_subscr_create_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_nitb_assign_tmsi, cfg_nitb_assign_tmsi_cmd,
+ "assign-tmsi",
+ "Assign TMSI during Location Updating.\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ gsmnet->avoid_tmsi = 0;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_nitb_no_assign_tmsi, cfg_nitb_no_assign_tmsi_cmd,
+ "no assign-tmsi",
+ NO_STR "Assign TMSI during Location Updating.\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ gsmnet->avoid_tmsi = 1;
+ return CMD_SUCCESS;
+}
+
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);
+ vty_out(vty, " %sassign-tmsi%s",
+ gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1096,6 +1116,8 @@ int bsc_vty_init_extra(void)
install_node(&nitb_node, config_write_nitb);
install_element(NITB_NODE, &cfg_nitb_subscr_create_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);
return 0;
}