diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-03-10 02:14:00 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-03-16 15:32:34 +0100 |
commit | 33513ae19a8aa5a800813fe464b4c5b4a474eb91 (patch) | |
tree | c1d69c35199e1a47290f6bc3391adc70f13680b4 | |
parent | c1ebe963f44006fe8b60304dcceeb22c5d14c2e3 (diff) |
allow CM Service Request on already open connection
Change-Id: I3c4687aafe495e60b1568e6505dbf847adab37f1
-rw-r--r-- | openbsc/src/libmsc/gsm_04_08.c | 63 | ||||
-rw-r--r-- | openbsc/tests/msc_vlr/msc_vlr_test_reject_concurrency.c | 28 |
2 files changed, 78 insertions, 13 deletions
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 68ac3cf86..8b7d3bdd1 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -598,6 +598,49 @@ int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn) return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ); } +#define CONN_REUSE 1 +#if CONN_REUSE +static int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref); +static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum vlr_proc_arq_result result); + +int cm_serv_conn_reuse(struct gsm_subscriber_connection *conn, + const uint8_t *mi_lv) +{ + struct vlr_subscr *vsub; + uint8_t mi_type; + char mi_string[GSM48_MI_SIZE]; + uint32_t tmsi; + + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]); + mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; + + switch (mi_type) { + case GSM_MI_TYPE_IMSI: + vsub = vlr_subscr_find_by_imsi(conn->network->vlr, mi_string); + break; + case GSM_MI_TYPE_TMSI: + tmsi = osmo_load32be(mi_lv+2); + vsub = vlr_subscr_find_by_tmsi(conn->network->vlr, tmsi); + break; + case GSM_MI_TYPE_IMEI: + /* TODO: IMEI (emergency call) */ + default: + vsub = NULL; + break; + } + + if (!vsub) { + msc_vlr_tx_cm_serv_rej(conn, VLR_PR_ARQ_RES_ILLEGAL_SUBSCR); + return -EINVAL; + } + + DEBUGP(DMM, "%s: re-using already accepted connection\n", + vlr_subscr_name(vsub)); + conn->received_cm_service_request = true; + return conn->network->vlr->ops.tx_cm_serv_acc(conn); +} +#endif + /* * Handle CM Service Requests * a) Verify that the packet is long enough to contain the information @@ -664,14 +707,26 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms } osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len)); + memcpy(conn->classmark.classmark2, classmark2, classmark2_len); + conn->classmark.classmark2_len = classmark2_len; + +#if CONN_REUSE + if (conn->conn_fsm) { + if (msc_subscr_conn_is_accepted(conn)) + return cm_serv_conn_reuse(conn, mi-1); + LOGP(DMM, LOGL_ERROR, "%s: connection already in use\n", + vlr_subscr_name(conn->vsub)); + msc_vlr_tx_cm_serv_rej(conn, VLR_PR_ARQ_RES_UNKNOWN_ERROR); + return -EINVAL; + } +#endif rc = msc_create_conn_fsm(conn, mi_string); - if (rc) + if (rc) { + msc_vlr_tx_cm_serv_rej(conn, VLR_PR_ARQ_RES_UNKNOWN_ERROR); /* logging already happened in msc_create_conn_fsm() */ return rc; - - memcpy(conn->classmark.classmark2, classmark2, classmark2_len); - conn->classmark.classmark2_len = classmark2_len; + } #if BEFORE_MSCSPLIT /* see mail on openbsc@ 9 Feb 2016 22:30:15 +0100 diff --git a/openbsc/tests/msc_vlr/msc_vlr_test_reject_concurrency.c b/openbsc/tests/msc_vlr/msc_vlr_test_reject_concurrency.c index 52757fea4..bace73ba3 100644 --- a/openbsc/tests/msc_vlr/msc_vlr_test_reject_concurrency.c +++ b/openbsc/tests/msc_vlr/msc_vlr_test_reject_concurrency.c @@ -164,7 +164,7 @@ void _paging_resp_part1() EXPECT_CONN_COUNT(1); } -void _paging_resp_part2() +void _paging_resp_part2(int expect_conn_count) { btw("MS replies with CP-ACK for received SMS"); ms_sends_msg("8904"); @@ -175,8 +175,8 @@ void _paging_resp_part2() ms_sends_msg("890106020041020000"); VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); + btw("SMS is done"); + EXPECT_CONN_COUNT(expect_conn_count); } void test_reject_lu_during_lu() @@ -242,10 +242,15 @@ void test_reject_lu_during_cm() _normal_lu(); _normal_cm_service_req(); - btw("An erratic LU request on the same conn results in conn termination"); + btw("A LU request on an open conn is dropped silently"); + /* TODO: accept periodic LU on an already open conn? */ lu_result_sent = RES_NONE; ms_sends_msg("050802008168000130089910070000006402"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); + EXPECT_CONN_COUNT(1); + + BTW("subscriber detaches"); + ms_sends_msg("050130089910070000006402"); EXPECT_CONN_COUNT(0); clear_vlr(); @@ -303,7 +308,7 @@ void test_reject_paging_resp_during_paging_resp() BTW("MS sends another erratic Paging Response which is dropped silently"); ms_sends_msg("06270703305882089910070000006402"); - _paging_resp_part2(); + _paging_resp_part2(0); clear_vlr(); comment_end(); @@ -323,7 +328,7 @@ void test_reject_lu_during_paging_resp() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); EXPECT_CONN_COUNT(1); - _paging_resp_part2(); + _paging_resp_part2(0); clear_vlr(); comment_end(); @@ -337,13 +342,18 @@ void test_reject_cm_during_paging_resp() _page(); _paging_resp_part1(); - BTW("MS sends erratic CM Service Request, which is dropped silently"); + BTW("CM Service Request during open connection is accepted"); cm_service_result_sent = RES_NONE; ms_sends_msg("05247803305886089910070000006402"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); + VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); EXPECT_CONN_COUNT(1); + VERBOSE_ASSERT(g_conn->received_cm_service_request, == true, "%d"); + + _paging_resp_part2(1); - _paging_resp_part2(); + BTW("subscriber detaches"); + ms_sends_msg("050130089910070000006402"); + EXPECT_CONN_COUNT(0); clear_vlr(); comment_end(); |