diff --git a/src/mme/sgsap-build.c b/src/mme/sgsap-build.c index c09472239..05a9c3228 100644 --- a/src/mme/sgsap-build.c +++ b/src/mme/sgsap-build.c @@ -192,3 +192,32 @@ ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue) return pkbuf; } + +ogs_pkbuf_t *sgsap_build_reset_ack(mme_vlr_t *vlr) +{ + ogs_tlv_t *root = NULL; + ogs_pkbuf_t *pkbuf = NULL; + + char mme_name[SGSAP_IE_MME_NAME_LEN+1]; + int mme_name_len = 0; + served_gummei_t *served_gummei = &mme_self()->served_gummei[0]; + + ogs_assert(vlr); + + mme_name_len = mme_name_build(mme_name, + served_gummei->mme_code[0], + served_gummei->mme_gid[0], + &served_gummei->plmn_id[0]); + root = ogs_tlv_add(NULL, SGSAP_IE_MME_NAME_TYPE, mme_name_len, 0, mme_name); + + pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN); + ogs_pkbuf_put_u8(pkbuf, SGSAP_RESET_ACK); + ogs_pkbuf_put(pkbuf, MAX_SDU_LEN-1); + + ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root, + pkbuf->data+1, MAX_SDU_LEN-1, OGS_TLV_MODE_T1_L1)); + + ogs_tlv_free_all(root); + + return pkbuf; +} diff --git a/src/mme/sgsap-build.h b/src/mme/sgsap-build.h index 6292d4de1..0914d7f14 100644 --- a/src/mme/sgsap-build.h +++ b/src/mme/sgsap-build.h @@ -31,6 +31,7 @@ ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue); ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue); ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue); ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue); +ogs_pkbuf_t *sgsap_build_reset_ack(mme_vlr_t *vlr); #ifdef __cplusplus } diff --git a/src/mme/sgsap-handler.c b/src/mme/sgsap-handler.c index 030754fb1..0addcd79d 100644 --- a/src/mme/sgsap-handler.c +++ b/src/mme/sgsap-handler.c @@ -18,6 +18,7 @@ */ #include "sgsap-types.h" +#include "sgsap-path.h" #include "mme-context.h" #include "mme-path.h" @@ -231,3 +232,13 @@ void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf) ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd); mme_send_delete_session_or_detach(mme_ue); } + +void sgsap_handle_reset_indication(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf) +{ + ogs_debug("[SGSAP] RESET-INDICATION"); + + ogs_assert(vlr); + ogs_assert(pkbuf); + + sgsap_send_reset_ack(vlr); +} diff --git a/src/mme/sgsap-handler.h b/src/mme/sgsap-handler.h index 1fc7f0c91..331bbfdc0 100644 --- a/src/mme/sgsap-handler.h +++ b/src/mme/sgsap-handler.h @@ -29,6 +29,7 @@ extern "C" { void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf); void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf); void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf); +void sgsap_handle_reset_indication(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf); #ifdef __cplusplus } diff --git a/src/mme/sgsap-path.c b/src/mme/sgsap-path.c index 17666fdfd..c2f8a4f78 100644 --- a/src/mme/sgsap-path.c +++ b/src/mme/sgsap-path.c @@ -177,3 +177,18 @@ int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue) return OGS_OK; } + +int sgsap_send_reset_ack(mme_vlr_t *vlr) +{ + int rv; + ogs_pkbuf_t *pkbuf = NULL; + ogs_assert(vlr); + + ogs_debug("[SGSAP] RESET-ACK"); + + pkbuf = sgsap_build_reset_ack(vlr); + rv = sgsap_send_to_vlr_with_sid(vlr, pkbuf, 0); + ogs_assert(rv == OGS_OK); + + return OGS_OK; +} diff --git a/src/mme/sgsap-path.h b/src/mme/sgsap-path.h index d729851af..0d26ea5ed 100644 --- a/src/mme/sgsap-path.h +++ b/src/mme/sgsap-path.h @@ -46,6 +46,7 @@ int sgsap_send_location_update_request(mme_ue_t *mme_ue); int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue); int sgsap_send_detach_indication(mme_ue_t *mme_ue); int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue); +int sgsap_send_reset_ack(mme_vlr_t *vlr); #ifdef __cplusplus } diff --git a/src/mme/sgsap-sm.c b/src/mme/sgsap-sm.c index 0e31d1e17..9dbc3eb5c 100644 --- a/src/mme/sgsap-sm.c +++ b/src/mme/sgsap-sm.c @@ -127,8 +127,14 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e) case SGSAP_IMSI_DETACH_ACK: sgsap_handle_detach_ack(vlr, pkbuf); break; + case SGSAP_RESET_INDICATION: + sgsap_handle_reset_indication(vlr, pkbuf); + + mme_vlr_free_node(vlr); + OGS_FSM_TRAN(s, sgsap_state_will_connect); + break; default: - ogs_warn("Not implemented(type:%d)", type); + ogs_warn("Unknown Message Type: [%d]", type); break; } break; diff --git a/tests/common/test-packet.c b/tests/common/test-packet.c index 4d19b1b3e..b77cc0f5e 100644 --- a/tests/common/test-packet.c +++ b/tests/common/test-packet.c @@ -3160,3 +3160,25 @@ int testsgsap_imsi_detach_ack(ogs_pkbuf_t **pkbuf, int i) return OGS_OK; } + +int testsgsap_reset_indication(ogs_pkbuf_t **pkbuf, int i) +{ + char *payload[TESTS1AP_MAX_MESSAGE] = { + "15021003766c7207 6578616d706c6503 6e6574", + "", + "", + + }; + uint16_t len[TESTS1AP_MAX_MESSAGE] = { + 19, + 0, + 0, + }; + char hexbuf[MAX_SDU_LEN]; + + *pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN); + ogs_pkbuf_put_data(*pkbuf, + OGS_HEX(payload[i], strlen(payload[i]), hexbuf), len[i]); + + return OGS_OK; +} diff --git a/tests/common/test-packet.h b/tests/common/test-packet.h index e259a01a8..6f401c7fc 100644 --- a/tests/common/test-packet.h +++ b/tests/common/test-packet.h @@ -134,6 +134,7 @@ int testgtpu_build_slacc_rs(ogs_pkbuf_t **sendbuf, int i); int testsgsap_location_update_accept(ogs_pkbuf_t **pkbuf, int i); int testsgsap_location_update_reject(ogs_pkbuf_t **pkbuf, int i); int testsgsap_imsi_detach_ack(ogs_pkbuf_t **pkbuf, int i); +int testsgsap_reset_indication(ogs_pkbuf_t **pkbuf, int i); #ifdef __cplusplus } diff --git a/tests/csfb/csfb-test.c b/tests/csfb/csfb-test.c index ead02c065..1e55f0b9f 100644 --- a/tests/csfb/csfb-test.c +++ b/tests/csfb/csfb-test.c @@ -797,6 +797,184 @@ static void test3_func(abts_case *tc, void *data) testenb_s1ap_close(s1ap); } +static void test4_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-Reset-Indication */ + rv = testsgsap_reset_indication(&sendbuf, 0); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testvlr_sgsap_send(sgsap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive SGsAP-Reset-ACK */ + recvbuf = testvlr_sgsap_read(sgsap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /********** 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_csfb(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -804,6 +982,7 @@ abts_suite *test_csfb(abts_suite *suite) abts_run_test(suite, test1_func, NULL); abts_run_test(suite, test2_func, NULL); abts_run_test(suite, test3_func, NULL); + abts_run_test(suite, test4_func, NULL); return suite; }