diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 3 | ||||
-rw-r--r-- | openbsc/src/libmsc/gsm_04_08.c | 94 | ||||
-rw-r--r-- | openbsc/src/libmsc/vty_interface_layer3.c | 22 |
3 files changed, 88 insertions, 31 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 6f7c8dd2a..90f3c800d 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 e380d948b..02ffe580b 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,24 +972,30 @@ 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) diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 6cf51a33f..3c33ffcd7 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, " %suse-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; } |