diff options
author | Harald Welte <laforge@osmocom.org> | 2020-06-21 18:00:23 +0200 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2020-08-17 13:04:03 +0200 |
commit | 210aa95d4967748a5899a2070db8e3e703a92e2a (patch) | |
tree | c517fc6ade6fa03bf51addebfeb845a29cfe1f38 | |
parent | fe12b70ce5db384d56adc011292346c511ed9446 (diff) |
Implement support for receiving BSSMAP CommonID from MSC
The MSC may at any time send a BSSMAP CommonID message via a
SCCP connection to inform us of the IMSI of the subscriber. Let's
make use of that information by associating a related bsc_subscr
and updating the identity of the bsc_subscr_conn_fsm for improved
logging / filtering.
Closes: OS#2969
Change-Id: I52c43fb940f0db796adf4c0adb2260321c721c39
-rw-r--r-- | include/osmocom/bsc/bsc_msc_data.h | 1 | ||||
-rw-r--r-- | include/osmocom/bsc/bsc_subscr_conn_fsm.h | 2 | ||||
-rw-r--r-- | src/osmo-bsc/bsc_subscr_conn_fsm.c | 17 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_bssap.c | 32 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_msc.c | 1 |
5 files changed, 52 insertions, 1 deletions
diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h index b1fe14d2f..43ace2532 100644 --- a/include/osmocom/bsc/bsc_msc_data.h +++ b/include/osmocom/bsc/bsc_msc_data.h @@ -64,6 +64,7 @@ enum { MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD, MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST, MSC_CTR_BSSMAP_RX_DT1_CONFUSION, + MSC_CTR_BSSMAP_RX_DT1_COMMON_ID, MSC_CTR_BSSMAP_RX_DT1_UNKNOWN, MSC_CTR_BSSMAP_RX_DT1_DTAP, MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR, diff --git a/include/osmocom/bsc/bsc_subscr_conn_fsm.h b/include/osmocom/bsc/bsc_subscr_conn_fsm.h index 78937353f..354c5ee93 100644 --- a/include/osmocom/bsc/bsc_subscr_conn_fsm.h +++ b/include/osmocom/bsc/bsc_subscr_conn_fsm.h @@ -14,6 +14,8 @@ enum gscon_fsm_event { GSCON_EV_A_CLEAR_CMD, /* MSC SCCP disconnect indication */ GSCON_EV_A_DISC_IND, + /* MSC has sent a BSSMAP COMMON ID */ + GSCON_EV_A_COMMON_ID_IND, GSCON_EV_ASSIGNMENT_START, GSCON_EV_ASSIGNMENT_END, diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c index 6a35c755d..bd0b53468 100644 --- a/src/osmo-bsc/bsc_subscr_conn_fsm.c +++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c @@ -73,6 +73,7 @@ static const struct value_string gscon_fsm_event_names[] = { {GSCON_EV_A_CONN_CFM, "MO-CONNECT.cfm"}, {GSCON_EV_A_CLEAR_CMD, "CLEAR_CMD"}, {GSCON_EV_A_DISC_IND, "DISCONNET.ind"}, + {GSCON_EV_A_COMMON_ID_IND, "COMMON_ID.ind"}, {GSCON_EV_ASSIGNMENT_START, "ASSIGNMENT_START"}, {GSCON_EV_ASSIGNMENT_END, "ASSIGNMENT_END"}, {GSCON_EV_HANDOVER_START, "HANDOVER_START"}, @@ -759,6 +760,7 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d { struct gsm_subscriber_connection *conn = fi->priv; const struct gscon_clear_cmd_data *ccd; + struct osmo_mobile_identity *mi_imsi; /* Regular allstate event processing */ switch (event) { @@ -805,6 +807,18 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d break; case GSCON_EV_LCLS_FAIL: break; + case GSCON_EV_A_COMMON_ID_IND: + OSMO_ASSERT(data); + mi_imsi = data; + if (!conn->bsub) + conn->bsub = bsc_subscr_find_or_create_by_imsi(conn->network->bsc_subscribers, mi_imsi->imsi); + else { + /* we already have a bsc_subscr associated; maybe that subscriber has no IMSI yet? */ + if (!conn->bsub->imsi[0]) + bsc_subscr_set_imsi(conn->bsub, mi_imsi->imsi); + } + gscon_update_id(conn); + break; default: OSMO_ASSERT(false); break; @@ -898,7 +912,8 @@ static struct osmo_fsm gscon_fsm = { .name = "SUBSCR_CONN", .states = gscon_fsm_states, .num_states = ARRAY_SIZE(gscon_fsm_states), - .allstate_event_mask = S(GSCON_EV_A_DISC_IND) | S(GSCON_EV_A_CLEAR_CMD) | S(GSCON_EV_RSL_CONN_FAIL) | + .allstate_event_mask = S(GSCON_EV_A_DISC_IND) | S(GSCON_EV_A_CLEAR_CMD) | S(GSCON_EV_A_COMMON_ID_IND) | + S(GSCON_EV_RSL_CONN_FAIL) | S(GSCON_EV_LCLS_FAIL) | S(GSCON_EV_FORGET_LCHAN) | S(GSCON_EV_FORGET_MGW_ENDPOINT), diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index bf38d107d..a253b01f1 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -1073,6 +1073,34 @@ static int bssmap_handle_confusion(struct gsm_subscriber_connection *conn, return 0; } +/* Common ID; 3GPP TS 48.008 3.2.1.68 */ +static int bssmap_handle_common_id(struct gsm_subscriber_connection *conn, + struct msgb *msg, unsigned int length) +{ + struct tlv_parsed tp; + struct osmo_mobile_identity mi_imsi; + + osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1); + + /* Check for the mandatory elements */ + if (!TLVP_PRESENT(&tp, GSM0808_IE_IMSI)) { + LOGPFSML(conn->fi, LOGL_ERROR, + "CommonID: missing mandatory IMSI IE: %s\n", + osmo_hexdump(msg->l4h, length)); + return -EINVAL; + } + + if (osmo_mobile_identity_decode(&mi_imsi, TLVP_VAL(&tp, GSM0808_IE_IMSI), TLVP_LEN(&tp, GSM0808_IE_IMSI), false) + || mi_imsi.type != GSM_MI_TYPE_IMSI) { + LOGPFSML(conn->fi, LOGL_ERROR, "CommonID: could not parse IMSI\n"); + return -EINVAL; + } + + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_COMMON_ID_IND, &mi_imsi); + + return 0; +} + static int bssmap_rcvmsg_udt(struct bsc_msc_data *msc, struct msgb *msg, unsigned int length) { @@ -1153,6 +1181,10 @@ static int bssmap_rcvmsg_dt1(struct gsm_subscriber_connection *conn, rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_CONFUSION]); ret = bssmap_handle_confusion(conn, msg, length); break; + case BSS_MAP_MSG_COMMON_ID: + rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_COMMON_ID]); + ret = bssmap_handle_common_id(conn, msg, length); + break; default: rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_UNKNOWN]); LOGP(DMSC, LOGL_NOTICE, "Unimplemented msg type: %s\n", diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c index 5e02b4a39..b1bb24530 100644 --- a/src/osmo-bsc/osmo_bsc_msc.c +++ b/src/osmo-bsc/osmo_bsc_msc.c @@ -58,6 +58,7 @@ static const struct rate_ctr_desc msc_ctr_description[] = { [MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD] = {"bssmap:rx:dt1:handover:cmd", "Number of received BSSMAP DT1 HANDOVER CMD messages"}, [MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST] = {"bssmap:rx:dt1:classmark:rqst", "Number of received BSSMAP DT1 CLASSMARK RQST messages"}, [MSC_CTR_BSSMAP_RX_DT1_CONFUSION] = {"bssmap:rx:dt1:confusion", "Number of received BSSMAP DT1 CONFUSION messages"}, + [MSC_CTR_BSSMAP_RX_DT1_COMMON_ID] = {"bssmap:rx:dt1:common_id", "Number of received BSSMAP DT1 COMMON ID messages"}, [MSC_CTR_BSSMAP_RX_DT1_UNKNOWN] = {"bssmap:rx:dt1:err_unknown", "Number of received BSSMAP unknown DT1 messages"}, [MSC_CTR_BSSMAP_RX_DT1_DTAP] = {"bssmap:rx:dt1:dtap:good", "Number of received BSSMAP DTAP messages"}, [MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR] = {"bssmap:rx:dt1:dtap:error", "Number of received BSSMAP DTAP messages with errors"}, |