From 1ba0730a7109b06e4043e7b17c11d8d2c34358c5 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 27 Jan 2015 10:27:53 +0100 Subject: nitb: Allow the network to decide if a subscriber should be created --- openbsc/include/openbsc/gsm_data.h | 1 + openbsc/src/libbsc/net_init.c | 2 ++ openbsc/src/libmsc/gsm_04_08.c | 29 ++++++++++++++++++++--------- 3 files changed, 23 insertions(+), 9 deletions(-) (limited to 'openbsc') diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index b278309f7..f78f24419 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -278,6 +278,7 @@ struct gsm_network { struct osmo_bsc_data *bsc_data; /* subscriber related features */ + int create_subscriber; 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 5bb8ae2b6..568a0b85e 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -46,7 +46,9 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod net->bsc_data->auto_off_timeout = -1; net->bsc_data->network = net; INIT_LLIST_HEAD(&net->bsc_data->mscs); + net->subscr_group->net = net; + net->create_subscriber = 1; 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 cd3db9c77..941090c8d 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -269,7 +269,7 @@ static int authorize_subscriber(struct gsm_loc_updating_operation *loc, } } -static void release_loc_updating_req(struct gsm_subscriber_connection *conn) +static void release_loc_updating_req(struct gsm_subscriber_connection *conn, int release) { if (!conn->loc_operation) return; @@ -280,14 +280,15 @@ static void release_loc_updating_req(struct gsm_subscriber_connection *conn) osmo_timer_del(&conn->loc_operation->updating_timer); talloc_free(conn->loc_operation); conn->loc_operation = NULL; - msc_release_connection(conn); + if (release) + msc_release_connection(conn); } static void allocate_loc_updating_req(struct gsm_subscriber_connection *conn) { if (conn->loc_operation) LOGP(DMM, LOGL_ERROR, "Connection already had operation.\n"); - release_loc_updating_req(conn); + release_loc_updating_req(conn, 0); conn->loc_operation = talloc_zero(tall_locop_ctx, struct gsm_loc_updating_operation); @@ -301,7 +302,7 @@ static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event, switch (event) { case GSM_SECURITY_AUTH_FAILED: - release_loc_updating_req(conn); + release_loc_updating_req(conn, 1); break; case GSM_SECURITY_ALREADY: @@ -362,7 +363,7 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus * Cancel any outstanding location updating request * operation taking place on the subscriber connection. */ - release_loc_updating_req(conn); + release_loc_updating_req(conn, 1); /* We might need to cancel the paging response or such. */ if (conn->sec_operation && conn->sec_operation->cb) { @@ -500,10 +501,15 @@ 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) + if (!conn->subscr && net->create_subscriber) conn->subscr = subscr_create_subscriber( net->subscr_group, mi_string); } + if (!conn->subscr && conn->loc_operation) { + gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + release_loc_updating_req(conn, 1); + return 0; + } if (conn->loc_operation) conn->loc_operation->waiting_for_imsi = 0; break; @@ -532,7 +538,7 @@ static void loc_upd_rej_cb(void *data) LOGP(DMM, LOGL_DEBUG, "Location Updating Request procedure timedout.\n"); gsm0408_loc_upd_rej(conn, bts->network->reject_cause); - release_loc_updating_req(conn); + release_loc_updating_req(conn, 1); } static void schedule_reject(struct gsm_subscriber_connection *conn) @@ -613,10 +619,15 @@ 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) { + if (!subscr && bts->network->create_subscriber) { subscr = subscr_create_subscriber( bts->network->subscr_group, mi_string); } + if (!subscr) { + gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + release_loc_updating_req(conn, 0); + return 0; + } break; case GSM_MI_TYPE_TMSI: DEBUGPC(DMM, "\n"); @@ -1109,7 +1120,7 @@ static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *m conn->subscr ? subscr_name(conn->subscr) : "unknown subscriber"); - release_loc_updating_req(conn); + release_loc_updating_req(conn, 1); break; case GSM48_MT_MM_IMSI_DETACH_IND: rc = gsm48_rx_mm_imsi_detach_ind(conn, msg); -- cgit v1.2.3