From de59488e2e36628fa9a48c297c277717b7fb3788 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 11 Jul 2019 18:14:32 +0900 Subject: [PATCH] [CSFB] MT-Active-Mode (Not Done) --- src/mme/emm-build.c | 31 ++++ src/mme/emm-build.h | 2 + src/mme/nas-path.c | 19 +++ src/mme/nas-path.h | 23 ++- src/mme/sgsap-handler.c | 5 +- tests/Makefile.am | 2 +- tests/csfb/abts-main.c | 2 + tests/csfb/mt-active-test.c | 302 ++++++++++++++++++++++++++++++++++++ 8 files changed, 370 insertions(+), 16 deletions(-) create mode 100644 tests/csfb/mt-active-test.c diff --git a/src/mme/emm-build.c b/src/mme/emm-build.c index 3fa62fc97..d4106e806 100644 --- a/src/mme/emm-build.c +++ b/src/mme/emm-build.c @@ -512,3 +512,34 @@ int emm_build_service_reject(ogs_pkbuf_t **emmbuf, nas_emm_cause_t emm_cause, return OGS_OK; } + +int emm_build_cs_service_notification(ogs_pkbuf_t **emmbuf, mme_ue_t *mme_ue) +{ + nas_message_t message; + nas_cs_service_notification_t *cs_service_notification = + &message.emm.cs_service_notification; + nas_paging_identity_t *paging_identity = + &cs_service_notification->paging_identity; + + ogs_assert(mme_ue); + + memset(&message, 0, sizeof(message)); + message.h.security_header_type = + NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; + message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + + message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + message.emm.h.message_type = NAS_CS_SERVICE_NOTIFICATION; + + /* FIXME : Does it right to use TMSI */ + paging_identity->identity = NAS_PAGING_IDENTITY_TMSI; + ogs_debug(" Paging Identity[%d]", paging_identity->identity); + + /* FIXME : What optional filed should be included in this message? */ + + ogs_assert(nas_security_encode(emmbuf, mme_ue, &message) == OGS_OK && + *emmbuf); + + return OGS_OK; +} + diff --git a/src/mme/emm-build.h b/src/mme/emm-build.h index 33cc42953..2109046d5 100644 --- a/src/mme/emm-build.h +++ b/src/mme/emm-build.h @@ -50,6 +50,8 @@ int emm_build_tau_reject(ogs_pkbuf_t **emmbuf, int emm_build_service_reject(ogs_pkbuf_t **emmbuf, nas_emm_cause_t emm_cause, mme_ue_t *mme_ue); +int emm_build_cs_service_notification(ogs_pkbuf_t **emmbuf, mme_ue_t *mme_ue); + #ifdef __cplusplus } #endif diff --git a/src/mme/nas-path.c b/src/mme/nas-path.c index 1df38bd19..23e3bb8a6 100644 --- a/src/mme/nas-path.c +++ b/src/mme/nas-path.c @@ -446,3 +446,22 @@ int nas_send_service_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause) return OGS_OK; } + +int nas_send_cs_service_notification(mme_ue_t *mme_ue) +{ + int rv; + ogs_pkbuf_t *emmbuf = NULL; + + ogs_assert(mme_ue); + + ogs_debug("[EMM] CS Service Notification"); + ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd); + + rv = emm_build_cs_service_notification(&emmbuf, mme_ue); + ogs_assert(rv == OGS_OK && emmbuf); + + rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf); + ogs_assert(rv == OGS_OK); + + return OGS_OK; +} diff --git a/src/mme/nas-path.h b/src/mme/nas-path.h index 7ae3bf241..2fcb67c35 100644 --- a/src/mme/nas-path.h +++ b/src/mme/nas-path.h @@ -27,24 +27,19 @@ int nas_send_detach_accept(mme_ue_t *mme_ue); int nas_send_pdn_connectivity_reject( mme_sess_t *sess, nas_esm_cause_t esm_cause); int nas_send_esm_information_request(mme_bearer_t *bearer); -int nas_send_activate_default_bearer_context_request( - mme_bearer_t *bearer); -int nas_send_activate_dedicated_bearer_context_request( - mme_bearer_t *bearer); -int nas_send_activate_all_dedicated_bearers( - mme_bearer_t *default_bearer); +int nas_send_activate_default_bearer_context_request(mme_bearer_t *bearer); +int nas_send_activate_dedicated_bearer_context_request(mme_bearer_t *bearer); +int nas_send_activate_all_dedicated_bearers(mme_bearer_t *default_bearer); int nas_send_modify_bearer_context_request( mme_bearer_t *bearer, int qos_presence, int tft_presence); -int nas_send_deactivate_bearer_context_request( - mme_bearer_t *bearer); +int nas_send_deactivate_bearer_context_request(mme_bearer_t *bearer); -int nas_send_tau_accept( - mme_ue_t *mme_ue, S1AP_ProcedureCode_t procedureCode); -int nas_send_tau_reject( - mme_ue_t *mme_ue, nas_esm_cause_t emm_cause); +int nas_send_tau_accept(mme_ue_t *mme_ue, S1AP_ProcedureCode_t procedureCode); +int nas_send_tau_reject(mme_ue_t *mme_ue, nas_esm_cause_t emm_cause); -int nas_send_service_reject( - mme_ue_t *mme_ue, nas_emm_cause_t emm_cause); +int nas_send_service_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause); + +int nas_send_cs_service_notification(mme_ue_t *mme_ue); #ifdef __cplusplus } diff --git a/src/mme/sgsap-handler.c b/src/mme/sgsap-handler.c index 83f8935f2..64698a78e 100644 --- a/src/mme/sgsap-handler.c +++ b/src/mme/sgsap-handler.c @@ -317,7 +317,10 @@ void sgsap_handle_paging_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf) plmn_id_hexdump(&lai->nas_plmn_id), lai->lac); } - s1ap_send_paging(mme_ue, S1AP_CNDomain_cs); + if (ECM_IDLE(mme_ue)) + s1ap_send_paging(mme_ue, S1AP_CNDomain_cs); + else + nas_send_cs_service_notification(mme_ue); } void sgsap_handle_reset_indication(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf) diff --git a/tests/Makefile.am b/tests/Makefile.am index 4866d4ed4..0a021037f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -44,7 +44,7 @@ testcsfb_SOURCES = \ common/test-app.h \ csfb/abts-main.c csfb/test-app.c \ csfb/mo-idle-test.c csfb/mt-idle-test.c \ - csfb/mo-active-test.c \ + csfb/mo-active-test.c csfb/mt-active-test.c \ $(NULL) testcsfb_LDADD = $(top_srcdir)/src/libepc.la diff --git a/tests/csfb/abts-main.c b/tests/csfb/abts-main.c index 626ac4220..a978e7778 100644 --- a/tests/csfb/abts-main.c +++ b/tests/csfb/abts-main.c @@ -32,6 +32,7 @@ abts_suite *test_mo_idle(abts_suite *suite); abts_suite *test_mt_idle(abts_suite *suite); abts_suite *test_mo_active(abts_suite *suite); +abts_suite *test_mt_active(abts_suite *suite); const struct testlist { abts_suite *(*func)(abts_suite *suite); @@ -39,6 +40,7 @@ const struct testlist { {test_mo_idle}, {test_mt_idle}, {test_mo_active}, + {test_mt_active}, {NULL}, }; diff --git a/tests/csfb/mt-active-test.c b/tests/csfb/mt-active-test.c new file mode 100644 index 000000000..a6a82751c --- /dev/null +++ b/tests/csfb/mt-active-test.c @@ -0,0 +1,302 @@ + +#include + +#include "core/abts.h" + +#include "app/context.h" +#include "mme/mme-context.h" +#include "mme/s1ap-build.h" +#include "asn1c/s1ap-message.h" + +#include "test-packet.h" + +extern ogs_socknode_t *sgsap; + +static void test1_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *s1ap; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + s1ap_message_t message; + int i; + int msgindex = 18; + enb_ue_t *enb_ue = NULL; + mme_ue_t *mme_ue = NULL; + uint32_t m_tmsi = 0; + + mongoc_collection_t *collection = NULL; + bson_t *doc = NULL; + int64_t count = 0; + bson_error_t error; + const char *json = + "{" + "\"_id\" : { \"$oid\" : \"310014158b8861d7605378c6\" }, " + "\"imsi\" : \"262420000118139\", " + "\"pdn\" : [" + "{" + "\"apn\" : \"internet\", " + "\"_id\" : { \"$oid\" : \"310014158b8861d7605378c7\" }, " + "\"ambr\" : {" + "\"uplink\" : { \"$numberLong\" : \"1000000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1000000\" } " + "}," + "\"qos\" : { " + "\"qci\" : 9, " + "\"arp\" : { " + "\"priority_level\" : 8," + "\"pre_emption_vulnerability\" : 0, " + "\"pre_emption_capability\" : 0" + "} " + "}, " + "\"type\" : 2" + "}" + "]," + "\"ambr\" : { " + "\"uplink\" : { \"$numberLong\" : \"1000000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1000000\" } " + "}," + "\"subscribed_rau_tau_timer\" : 12," + "\"network_access_mode\" : 2, " + "\"subscriber_status\" : 0, " + "\"access_restriction_data\" : 32, " + "\"security\" : { " + "\"k\" : \"70D49A71DD1A2B806A25ABE0EF749F1E\", " + "\"opc\" : \"6F1BF53D624B3A43AF6592854E2444C7\", " + "\"amf\" : \"8000\", " + "\"sqn\" : { \"$numberLong\" : \"2374\" }, " + "\"rand\" : \"aa266700bc2887354e9f87368d5d0ae7\" " + "}, " + "\"__v\" : 0 " + "}"; + + /* eNB connects to MME */ + s1ap = testenb_s1ap_client("127.0.0.1"); + ABTS_PTR_NOTNULL(tc, s1ap); + + /* Send S1-Setup Reqeust */ + rv = tests1ap_build_setup_req( + &sendbuf, S1AP_ENB_ID_PR_macroENB_ID, 0x0019b0, 7, 901, 70, 2); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive S1-Setup Response */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + rv = s1ap_decode_pdu(&message, recvbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + s1ap_free_pdu(&message); + ogs_pkbuf_free(recvbuf); + + collection = mongoc_client_get_collection( + context_self()->db.client, + context_self()->db.name, "subscribers"); + ABTS_PTR_NOTNULL(tc, collection); + + /********** Insert Subscriber in Database */ + doc = bson_new_from_json((const uint8_t *)json, -1, &error);; + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_insert(collection, + MONGOC_INSERT_NONE, doc, NULL, &error)); + bson_destroy(doc); + + doc = BCON_NEW("imsi", BCON_UTF8("262420000118139")); + ABTS_PTR_NOTNULL(tc, doc); + do { + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + } while (count == 0); + bson_destroy(doc); + + /* Send Attach Request */ + mme_self()->mme_ue_s1ap_id = 0; + rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Identity-Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Identity Response */ + rv = tests1ap_build_identity_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Authentication Response */ + rv = tests1ap_build_authentication_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Security mode Complete */ + rv = tests1ap_build_security_mode_complete(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send ESM Information Response */ + rv = tests1ap_build_esm_information_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive SGsAP-Location-Update-Request */ + recvbuf = testvlr_sgsap_read(sgsap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send SGsAP-Location-Update-Accept */ + rv = testsgsap_location_update_accept(&sendbuf, 0); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testvlr_sgsap_send(sgsap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Initial Context Setup Response */ + rv = tests1ap_build_initial_context_setup_response(&sendbuf, + 1, 1, 5, 0x00460003, "127.0.0.5"); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + rv = tests1ap_build_attach_complete(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive SGsAP TMSI-REALLOCATION-COMPLETE */ + recvbuf = testvlr_sgsap_read(sgsap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Retreive M-TMSI */ + enb_ue = enb_ue_find_by_mme_ue_s1ap_id(1); + ogs_assert(enb_ue); + mme_ue = enb_ue->mme_ue; + ogs_assert(mme_ue); + m_tmsi = mme_ue->guti.m_tmsi; + + /* Send UE Context Release Request */ + rv = tests1ap_build_ue_context_release_request(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE Context Release Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send UE Context Release Complete */ + rv = tests1ap_build_ue_context_release_complete(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send SGsAP-Paging-Request */ + rv = testsgsap_paging_request(&sendbuf, 0); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testvlr_sgsap_send(sgsap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive S1AP Paging */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Extended Service Request */ + rv = tests1ap_build_extended_service_request(&sendbuf, msgindex, + 1, m_tmsi, 4, mme_ue->knas_int); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Service Request */ + recvbuf = testvlr_sgsap_read(sgsap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive Initial Context Setup Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Initial Context Setup Response */ + rv = tests1ap_build_initial_context_setup_response(&sendbuf, + 2, 2, 5, 0x00470003, "127.0.0.5"); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send UE Context Release Request */ + rv = tests1ap_build_ue_context_release_request(&sendbuf, msgindex+1); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE Context Release Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send UE Context Release Complete */ + rv = tests1ap_build_ue_context_release_complete(&sendbuf, msgindex+1); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + doc = BCON_NEW("imsi", BCON_UTF8("262420000118139")); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + bson_destroy(doc); + + mongoc_collection_destroy(collection); + + /* eNB disonncect from MME */ + testenb_s1ap_close(s1ap); +} + +abts_suite *test_mt_active(abts_suite *suite) +{ + suite = ADD_SUITE(suite) + + abts_run_test(suite, test1_func, NULL); + + return suite; +}