diff --git a/src/mme/emm_handler.c b/src/mme/emm_handler.c index 94108e5ffc..54694681fe 100644 --- a/src/mme/emm_handler.c +++ b/src/mme/emm_handler.c @@ -25,6 +25,8 @@ mme_ue_t *emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message) { mme_ue_t *mme_ue = NULL; + d_assert(enb_ue, return NULL, "Null param"); + switch(message->emm.h.message_type) { case NAS_ATTACH_REQUEST: @@ -68,6 +70,18 @@ mme_ue_t *emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message) guti.m_tmsi); mme_ue = mme_ue_find_by_guti(&guti); + if (!mme_ue) + { + d_warn("Cannot find mme_ue by " + "GUTI[G:%d,C:%d,M_TMSI:0x%x]\n", + guti.mme_gid, + guti.mme_code, + guti.m_tmsi); + } + else + { + mme_associate_ue_context(mme_ue, enb_ue); + } break; } default: @@ -203,27 +217,32 @@ void emm_handle_attach_request( d_info("[NAS] Attach request : UE_IMSI[%s] --> EMM", imsi_bcd); - if (mme_ue->security_context_available) + if (!mme_ue->security_context_available) { - if (enb_ue->mac_failed) + /* Initiate HSS Auth Process if No Security Context */ + mme_s6a_send_air(mme_ue); + } + else + { + /* if Security Context is Existed */ + if (!enb_ue->mac_failed) { + /* MAC verified */ + emm_handle_attach_accept(mme_ue); + } + else + { + /* Initiate Delete Session if MAC integrity Failed */ int delete_session_request_handled = 0; emm_handle_delete_session_request( mme_ue, &delete_session_request_handled); if (!delete_session_request_handled) { + /* Initiate HSS Auth Process if No Session */ mme_s6a_send_air(mme_ue); } } - else - { - emm_handle_attach_accept(mme_ue); - } - } - else - { - mme_s6a_send_air(mme_ue); } break; @@ -244,37 +263,43 @@ void emm_handle_attach_request( guti.mme_code, guti.m_tmsi); - /* FIXME :Check if GUTI was assigend from us */ - - /* FIXME :If not, forward the message to other MME */ - - /* FIXME : Find UE based on GUTI. - * The record with GUTI,IMSI should be - * stored in permanent DB - */ - - if (mme_ue->security_context_available) + if (memcmp(&guti, &mme_ue->guti, sizeof(guti_t)) == 0) { - if (enb_ue->mac_failed) + /* Known GUTI */ + if (!mme_ue->security_context_available) { - d_assert(0, return, "Not Implmeneted"); + /* Initiate HSS Auth Process if No Security Context */ + mme_s6a_send_air(mme_ue); } else { - if (memcmp(&guti, &mme_ue->guti, sizeof(guti_t)) != 0) + /* if Security Context is Existed */ + if (!enb_ue->mac_failed) { - emm_handle_identity_request(mme_ue); + /* MAC verified */ + emm_handle_attach_accept(mme_ue); } else { - emm_handle_attach_accept(mme_ue); + /* Initiate Delete Session if MAC integrity Failed */ + int delete_session_request_handled = 0; + + emm_handle_delete_session_request( + mme_ue, &delete_session_request_handled); + if (!delete_session_request_handled) + { + /* Initiate HSS Auth Process if No Session */ + mme_s6a_send_air(mme_ue); + } } } } else { - d_assert(0, return, "Not Implmeneted"); + /* Unknown GUTI */ + emm_handle_identity_request(mme_ue); } + break; } default: @@ -349,27 +374,32 @@ void emm_handle_identity_response( return; } - if (mme_ue->security_context_available) + if (!mme_ue->security_context_available) { - if (enb_ue->mac_failed) + /* Initiate HSS Auth Process if No Security Context */ + mme_s6a_send_air(mme_ue); + } + else + { + /* if Security Context is Existed */ + if (!enb_ue->mac_failed) { + /* MAC verified */ + emm_handle_attach_accept(mme_ue); + } + else + { + /* Initiate Delete Session if MAC integrity Failed */ int delete_session_request_handled = 0; emm_handle_delete_session_request( mme_ue, &delete_session_request_handled); if (!delete_session_request_handled) { + /* Initiate HSS Auth Process if No Session */ mme_s6a_send_air(mme_ue); } } - else - { - emm_handle_attach_accept(mme_ue); - } - } - else - { - mme_s6a_send_air(mme_ue); } } diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index 0ac0c9d67b..5fee3b0887 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -988,6 +988,12 @@ status_t mme_ue_remove(mme_ue_t *mme_ue) fsm_final(&mme_ue->sm, 0); fsm_clear(&mme_ue->sm); + /* Clear hash table */ + if (mme_ue->guti.m_tmsi != 0) + hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(guti_t), NULL); + if (mme_ue->imsi_len != 0) + hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, NULL); + mme_sess_remove_all(mme_ue); mme_pdn_remove_all(mme_ue); @@ -1077,6 +1083,13 @@ static status_t mme_ue_new_guti(mme_ue_t *mme_ue) d_assert(served_gummei->num_of_mme_code > 0, return CORE_ERROR, "Invalid param"); + if (mme_ue->guti.m_tmsi != 0) + { + /* MME has a VALID GUIT + * As such, we need to remove previous GUTI in hash table */ + hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(guti_t), NULL); + } + memset(&mme_ue->guti, 0, sizeof(guti_t)); /* FIXME : How to generate GUTI? @@ -1106,6 +1119,18 @@ status_t mme_ue_set_imsi(mme_ue_t *mme_ue, c_int8_t *imsi_bcd) return CORE_OK; } +status_t mme_associate_ue_context(mme_ue_t *mme_ue, enb_ue_t *enb_ue) +{ + d_assert(mme_ue, return CORE_ERROR, "Null param"); + d_assert(enb_ue, return CORE_ERROR, "Null param"); + + mme_ue->enb_ue = enb_ue; + enb_ue->mme_ue = mme_ue; + + return CORE_OK; +} + + #if 0 unsigned int mme_ue_count() { diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index a211b9cf55..03bcab73ff 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -282,13 +282,16 @@ CORE_DECLARE(mme_ue_t*) mme_ue_add(enb_ue_t *enb_ue); CORE_DECLARE(status_t) mme_ue_remove(mme_ue_t *mme_ue); CORE_DECLARE(status_t) mme_ue_remove_all(); -CORE_DECLARE(status_t) mme_ue_set_imsi( - mme_ue_t *mme_ue, c_int8_t *imsi_bcd); CORE_DECLARE(mme_ue_t*) mme_ue_find(index_t index); CORE_DECLARE(mme_ue_t*) mme_ue_find_by_imsi(c_uint8_t *imsi, int imsi_len); CORE_DECLARE(mme_ue_t*) mme_ue_find_by_imsi_bcd(c_int8_t *imsi_bcd); CORE_DECLARE(mme_ue_t*) mme_ue_find_by_guti(guti_t *guti); +CORE_DECLARE(status_t) mme_ue_set_imsi( + mme_ue_t *mme_ue, c_int8_t *imsi_bcd); +CORE_DECLARE(status_t) mme_associate_ue_context( + mme_ue_t *mme_ue, enb_ue_t *enb_ue); + CORE_DECLARE(hash_index_t *) mme_ue_first(); CORE_DECLARE(hash_index_t *) mme_ue_next(hash_index_t *hi); CORE_DECLARE(mme_ue_t *) mme_ue_this(hash_index_t *hi); diff --git a/src/mme/nas_security.c b/src/mme/nas_security.c index 016d044c17..d27fa46c64 100644 --- a/src/mme/nas_security.c +++ b/src/mme/nas_security.c @@ -243,7 +243,7 @@ status_t nas_security_decode(mme_ue_t *mme_ue, pkbuf_t *pkbuf, int *mac_failed) memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); if (h->message_authentication_code != mac32) { - d_error("NAS MAC verification failed(0x%x != 0x%x)", + d_warn("NAS MAC verification failed(0x%x != 0x%x)", ntohl(h->message_authentication_code), ntohl(mac32)); *mac_failed = 1; } diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index 855b046365..70160a51a0 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -212,8 +212,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message) } else { - mme_ue->enb_ue = enb_ue; - enb_ue->mme_ue = mme_ue; + mme_associate_ue_context(mme_ue, enb_ue); } } } diff --git a/test/nas_sm_test.c b/test/nas_sm_test.c index a4d2a0f099..3255e6a8e2 100644 --- a/test/nas_sm_test.c +++ b/test/nas_sm_test.c @@ -1,8 +1,8 @@ -#include #include "core_debug.h" #include "core_pkbuf.h" #include "core_lib.h" +#include #include "context.h" #include "mme_context.h" @@ -237,6 +237,16 @@ static void nas_sm_test1(abts_case *tc, void *data) rv = tests1ap_enb_send(sock, sendbuf); ABTS_INT_EQUAL(tc, CORE_OK, rv); + core_sleep(time_from_msec(300)); + + /* Send Initial-UE Message */ +#if 0 + rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+1); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); +#endif + /* eNB disonncect from MME */ rv = tests1ap_enb_close(sock); ABTS_INT_EQUAL(tc, CORE_OK, rv); @@ -419,14 +429,31 @@ static void nas_sm_test2(abts_case *tc, void *data) core_sleep(time_from_msec(300)); /* Send Initial-UE Message */ -#if 0 rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+1); ABTS_INT_EQUAL(tc, CORE_OK, rv); rv = tests1ap_enb_send(sock, sendbuf); ABTS_INT_EQUAL(tc, CORE_OK, rv); -#endif - core_sleep(time_from_msec(300)); + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + recvbuf->len = 223; + pkbuf_free(recvbuf); + + /* Send Initial-UE Message with MAC failed */ + rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+2); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive Authentication Request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + recvbuf->len = 60; + pkbuf_free(recvbuf); /* eNB disonncect from MME */ rv = tests1ap_enb_close(sock); @@ -544,6 +571,9 @@ static void nas_sm_test3(abts_case *tc, void *data) MONGOC_INSERT_NONE, doc, NULL, &error)); bson_destroy(doc); + mme_self()->mme_ue_s1ap_id = 33554631; + mme_self()->m_tmsi = 2; + d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_ERROR); /* eNB connects to MME */ @@ -566,7 +596,6 @@ static void nas_sm_test3(abts_case *tc, void *data) pkbuf_free(recvbuf); /* Send Initial-UE Message */ - mme_self()->mme_ue_s1ap_id = 33554631; rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex); ABTS_INT_EQUAL(tc, CORE_OK, rv); rv = tests1ap_enb_send(sock, sendbuf); diff --git a/test/tests1ap.c b/test/tests1ap.c index 686c54ff47..047497ac0b 100644 --- a/test/tests1ap.c +++ b/test/tests1ap.c @@ -121,7 +121,12 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i) "3254869104e060c0 4000050221d011d1 5c0a003103e5e034 9011035758a65d01" "00004300060000f1 105ba00064400800 00f1101079baf000 86400130", - "", + "000c40809c00" + "0005000800030001 00001a007372178c 3e3cff070741020b f600f11000020100" + "00000105e060c040 0100210204d011d1 271a808021100100 0010810600000000" + "830600000000000d 00000a005255f501 10225c0a003103e5 c03e1355f501aaaa" + "11035758a6200b60 1404ef65233b8878 d290400804026004 00021f025d0107e0" + "004300060055f501 1022006440080055 f5010019d0100086 400130", "", "000c406800000500 080002001f001a00 403f074172080910 10103254866202e0" @@ -133,7 +138,9 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i) "103254866205f0f0 000000000e023cd0 11d1270780000a00 000d00c100430006" "0000f1102b670064 40080000f1109d67 aa500086400130", - "", + "000c405300000500 080003001f00001a 002a2917bcba67c4 8207410108091010" + "103254866205f0f0 000000000e023cd0 11d1270780000a00 000d00c100430006" + "0000f1102b670064 40080000f1109d67 aa500086400130", "000c" "404c000005000800 020002001a002423 0741710809101010 3254767905f0f000" @@ -145,12 +152,12 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i) }; c_uint16_t len[TESTS1AP_MAX_MESSAGE] = { 92, - 0, + 161, 0, 108, 87, - 0, + 87, 80, 0,