diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-02-18 22:20:46 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-03-08 01:01:43 +0100 |
commit | 6d804b1a7e375213cb4b3e437c2b9b8c68872164 (patch) | |
tree | 226c66c67e1d2181e545cb21f83234b90b051a99 /openbsc/src/libmsc | |
parent | abf53d87b6648f2d42562c5699e9035afd92e608 (diff) |
add struct bsc_subscr, separating libbsc from gsm_subscriber
In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will
not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC
subscriber: struct bsc_subscr.
Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no
longer have a backpointer to gsm_network (used to be via subscr->group).
Create a separate logging filter for the new BSC subscriber. The implementation
of adjusting the filter context is added in libbsc to not introduce
bsc_subscr_get/_put() dependencies to libcommon.
During Paging Response, fetch a bsc_subscr from the mobile identity, like we do
for the gsm_subscriber. It looks like a duplication now, but will make sense
for the VLR as well as for future MSC split patches.
Naming: it was requested to not name the new struct bsc_sub, because 'sub' is
too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function
prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to
match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast
to type, relatively short, unambiguous, and the naming is consistent.
Add bsc_subscr unit test.
Related: OS#1592, OS#1594
Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e
Diffstat (limited to 'openbsc/src/libmsc')
-rw-r--r-- | openbsc/src/libmsc/gsm_04_08.c | 29 | ||||
-rw-r--r-- | openbsc/src/libmsc/gsm_subscriber.c | 30 | ||||
-rw-r--r-- | openbsc/src/libmsc/vty_interface_layer3.c | 14 |
3 files changed, 62 insertions, 11 deletions
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index fff902d7a..c910d7192 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1433,6 +1433,8 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m uint8_t mi_type; char mi_string[GSM48_MI_SIZE]; struct gsm_subscriber *subscr = NULL; + struct bsc_subscr *bsub; + uint32_t tmsi; int rc = 0; resp = (struct gsm48_pag_resp *) &gh->data[0]; @@ -1443,8 +1445,8 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(conn->network->subscr_group, - tmsi_from_string(mi_string)); + tmsi = tmsi_from_string(mi_string); + subscr = subscr_get_by_tmsi(conn->network->subscr_group, tmsi); break; case GSM_MI_TYPE_IMSI: subscr = subscr_get_by_imsi(conn->network->subscr_group, @@ -1457,6 +1459,19 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m /* FIXME: request id? close channel? */ return -EINVAL; } + + if (!conn->subscr) { + conn->subscr = subscr; + } else if (conn->subscr != subscr) { + LOGP(DRR, LOGL_ERROR, "<- Channel already owned by someone else?\n"); + subscr_put(subscr); + return -EINVAL; + } else { + DEBUGP(DRR, "<- Channel already owned by us\n"); + subscr_put(subscr); + subscr = conn->subscr; + } + log_set_context(LOG_CTX_VLR_SUBSCR, subscr); DEBUGP(DRR, "<- Channel was requested by %s\n", subscr->name && strlen(subscr->name) ? subscr->name : subscr->imsi); @@ -1465,10 +1480,18 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m memcpy(subscr->equipment.classmark2, classmark2_lv+1, *classmark2_lv); db_sync_equipment(&subscr->equipment); + /* TODO MSC split -- creating a BSC subscriber directly from MSC data + * structures in RAM. At some point the MSC will send a message to the + * BSC instead. */ + bsub = bsc_subscr_find_or_create_by_imsi(conn->network->bsc_subscribers, + subscr->imsi); + bsub->tmsi = subscr->tmsi; + bsub->lac = subscr->lac; + /* We received a paging */ conn->expire_timer_stopped = 1; - rc = gsm48_handle_paging_resp(conn, msg, subscr); + rc = gsm48_handle_paging_resp(conn, msg, bsub); return rc; } diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c index 568f1c5d0..1a03cf76e 100644 --- a/openbsc/src/libmsc/gsm_subscriber.c +++ b/openbsc/src/libmsc/gsm_subscriber.c @@ -82,8 +82,11 @@ static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, struct gsm_subscriber_connection *conn = data; struct gsm_subscriber *subscr = param; struct paging_signal_data sig_data; + struct bsc_subscr *bsub; + struct gsm_network *net; - OSMO_ASSERT(subscr->is_paging); + OSMO_ASSERT(subscr && subscr->is_paging); + net = subscr->group->net; /* * Stop paging on all other BTS. E.g. if this is @@ -91,7 +94,16 @@ static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, * timeout soon as well. Let's just stop everything * and forget we wanted to page. */ - paging_request_stop(NULL, subscr, NULL, NULL); + + /* TODO MSC split -- creating a BSC subscriber directly from MSC data + * structures in RAM. At some point the MSC will send a message to the + * BSC instead. */ + bsub = bsc_subscr_find_or_create_by_imsi(net->bsc_subscribers, + subscr->imsi); + bsub->tmsi = subscr->tmsi; + bsub->lac = subscr->lac; + paging_request_stop(&net->bts_list, NULL, bsub, NULL, NULL); + bsc_subscr_put(bsub); /* Inform parts of the system we don't know */ sig_data.subscr = subscr; @@ -169,13 +181,23 @@ struct subscr_request *subscr_request_channel(struct gsm_subscriber *subscr, { int rc; struct subscr_request *request; + struct bsc_subscr *bsub; + struct gsm_network *net = subscr->group->net; /* Start paging.. we know it is async so we can do it before */ if (!subscr->is_paging) { LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet.\n", subscr_name(subscr)); - rc = paging_request(subscr->group->net, subscr, channel_type, - subscr_paging_cb, subscr); + /* TODO MSC split -- creating a BSC subscriber directly from + * MSC data structures in RAM. At some point the MSC will send + * a message to the BSC instead. */ + bsub = bsc_subscr_find_or_create_by_imsi(net->bsc_subscribers, + subscr->imsi); + bsub->tmsi = subscr->tmsi; + bsub->lac = subscr->lac; + rc = paging_request(net, bsub, channel_type, subscr_paging_cb, + subscr); + bsc_subscr_put(bsub); if (rc <= 0) { LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n", subscr_name(subscr), rc); diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index cd5dfb723..1bc9372a6 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -34,6 +34,7 @@ #include <osmocom/core/linuxlist.h> #include <openbsc/gsm_data.h> #include <openbsc/gsm_subscriber.h> +#include <openbsc/bsc_subscriber.h> #include <openbsc/silent_call.h> #include <openbsc/gsm_04_11.h> #include <osmocom/abis/e1_input.h> @@ -1034,21 +1035,26 @@ DEFUN(logging_fltr_imsi, LOGGING_STR FILTER_STR "Filter log messages by IMSI\n" "IMSI to be used as filter\n") { - struct gsm_subscriber *subscr; + struct gsm_subscriber *vlr_subscr; + struct bsc_subscr *bsc_subscr; struct gsm_network *gsmnet = gsmnet_from_vty(vty); struct log_target *tgt = osmo_log_vty2tgt(vty); + const char *imsi = argv[0]; if (!tgt) return CMD_WARNING; - subscr = subscr_get_by_imsi(gsmnet->subscr_group, argv[0]); - if (!subscr) { + vlr_subscr = subscr_get_by_imsi(gsmnet->subscr_group, imsi); + bsc_subscr = bsc_subscr_find_by_imsi(gsmnet->bsc_subscribers, imsi); + + if (!vlr_subscr && !bsc_subscr) { vty_out(vty, "%%no subscriber with IMSI(%s)%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - log_set_imsi_filter(tgt, subscr); + log_set_filter_vlr_subscr(tgt, vlr_subscr); + log_set_filter_bsc_subscr(tgt, bsc_subscr); return CMD_SUCCESS; } |