aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-02-18 22:20:46 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-03-08 01:01:43 +0100
commit6d804b1a7e375213cb4b3e437c2b9b8c68872164 (patch)
tree226c66c67e1d2181e545cb21f83234b90b051a99 /openbsc/src/libmsc
parentabf53d87b6648f2d42562c5699e9035afd92e608 (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.c29
-rw-r--r--openbsc/src/libmsc/gsm_subscriber.c30
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c14
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;
}