diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index 5712180d0..62eefe290 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -60,10 +60,12 @@ status_t mme_context_init() list_init(&self.pgw_list); index_init(&mme_enb_pool, MAX_NUM_OF_ENB); + index_init(&mme_ue_pool, MAX_POOL_OF_UE); index_init(&enb_ue_pool, MAX_POOL_OF_UE); index_init(&mme_sess_pool, MAX_POOL_OF_SESS); index_init(&mme_bearer_pool, MAX_POOL_OF_BEARER); + pool_init(&self.m_tmsi, MAX_POOL_OF_UE); self.enb_sock_hash = hash_make(); self.enb_addr_hash = hash_make(); @@ -88,6 +90,14 @@ status_t mme_context_final() mme_enb_remove_all(); mme_ue_remove_all(); + if (pool_used(&self.m_tmsi)) + { + d_error("%d not freed in M-TMSI pool[%d] in MME-Context", + pool_used(&self.m_tmsi), pool_size(&self.m_tmsi)); + } + d_trace(5, "%d not freed in M-TMSI pool[%d] in MME-Context\n", + pool_used(&self.m_tmsi), pool_size(&self.m_tmsi)); + d_assert(self.enb_sock_hash, , "Null param"); hash_destroy(self.enb_sock_hash); d_assert(self.enb_addr_hash, , "Null param"); @@ -102,6 +112,7 @@ status_t mme_context_final() d_assert(self.guti_ue_hash, , "Null param"); hash_destroy(self.guti_ue_hash); + pool_final(&self.m_tmsi); index_final(&mme_bearer_pool); index_final(&mme_sess_pool); index_final(&mme_ue_pool); @@ -1859,8 +1870,11 @@ status_t mme_ue_remove(mme_ue_t *mme_ue) fsm_clear(&mme_ue->sm); /* Clear hash table */ - if (mme_ue->guti.m_tmsi != 0) + if (mme_ue->m_tmsi) + { hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(guti_t), NULL); + d_assert(mme_m_tmsi_free(mme_ue->m_tmsi) == CORE_OK,,); + } if (mme_ue->imsi_len != 0) hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, NULL); @@ -2114,23 +2128,23 @@ 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) + if (mme_ue->m_tmsi) { /* 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); + d_assert(mme_m_tmsi_free(mme_ue->m_tmsi) == CORE_OK,,); } memset(&mme_ue->guti, 0, sizeof(guti_t)); - /* FIXME : How to generate GUTI? - * At this point, I'll use first(0-index) Served GUMMEI in MME_CONTEXT */ memcpy(&mme_ue->guti.plmn_id, &served_gummei->plmn_id[0], PLMN_ID_LEN); mme_ue->guti.mme_gid = served_gummei->mme_gid[0]; mme_ue->guti.mme_code = served_gummei->mme_code[0]; - mme_ue->guti.m_tmsi = NEXT_ID(self.old_m_tmsi, 1, 0xffffffff); - + mme_ue->m_tmsi = mme_m_tmsi_alloc(); + d_assert(mme_ue->m_tmsi, return CORE_ERROR,); + mme_ue->guti.m_tmsi = *(mme_ue->m_tmsi); hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(guti_t), mme_ue); return CORE_OK; @@ -2688,27 +2702,30 @@ int mme_find_served_tai(tai_t *tai) status_t mme_m_tmsi_pool_generate() { status_t rv; - int i; + int i, j; d_trace(1, "M-TMSI Pool try to generate...\n"); for (i = 0; i < MAX_POOL_OF_UE; i++) { mme_m_tmsi_t *m_tmsi = NULL; + int conflict = 0; m_tmsi = &self.m_tmsi.pool[i]; rv = core_generate_random_bytes((c_uint8_t *)m_tmsi, sizeof(*m_tmsi)); d_assert(rv == CORE_OK, return CORE_ERROR, "Cannot generate random"); - + for (j = 0; j < i; j++) + { + if (*m_tmsi == self.m_tmsi.pool[j]) + { + conflict = 1; + break; + } + } + if (conflict == 1) continue; } + self.m_tmsi.size = i; d_trace(1, "M-TMSI Pool generate...done\n"); -#if 0 - for (i = 0; i < 10; i++) - { - printf("%x\n", self.m_tmsi.pool[i]); - } -#endif - return CORE_OK; } diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index 1928b1c5c..edc22a675 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -112,8 +112,8 @@ typedef struct _mme_context_t { /* Generator for unique identification */ c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */ - c_uint32_t old_m_tmsi; /* m_tmsi generator */ + /* M-TMSI Pool */ struct { int head, tail; int size, avail; @@ -207,6 +207,7 @@ struct _mme_ue_t { c_uint8_t imsi[MAX_IMSI_LEN]; int imsi_len; c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1]; + mme_m_tmsi_t *m_tmsi; guti_t guti; c_uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */ diff --git a/src/pgw/pgw_context.c b/src/pgw/pgw_context.c index 3cf577974..bc2db92ec 100644 --- a/src/pgw/pgw_context.c +++ b/src/pgw/pgw_context.c @@ -1651,7 +1651,7 @@ pgw_subnet_t *pgw_subnet_add( subnet->family = subnet->gw.family; subnet->prefixlen = atoi(mask_or_numbits); - pool_init(&subnet->pool, MAX_POOL_OF_UE); + pool_init(&subnet->pool, MAX_POOL_OF_SESS); list_append(&self.subnet_list, subnet); diff --git a/test/attach_test.c b/test/attach_test.c index 6277ffac7..1f60b7493 100644 --- a/test/attach_test.c +++ b/test/attach_test.c @@ -25,6 +25,9 @@ static void attach_test1(abts_case *tc, void *data) s1ap_message_t message; int i; int msgindex = 0; + enb_ue_t *enb_ue = NULL; + mme_ue_t *mme_ue = NULL; + c_uint32_t m_tmsi = 0; c_uint8_t tmp[MAX_SDU_LEN]; char *_authentication_request = @@ -281,12 +284,27 @@ static void attach_test1(abts_case *tc, void *data) pkbuf_free(recvbuf); #endif + /* Retreive M-TMSI */ + enb_ue = enb_ue_find_by_mme_ue_s1ap_id(16777373); + d_assert(enb_ue, goto out,); + mme_ue = enb_ue->mme_ue; + d_assert(mme_ue, goto out,); + m_tmsi = mme_ue->guti.m_tmsi; + /***************************************************************** * Attach Request : Known GUTI, Integrity Protected, MAC Matched * Send Initial-UE Message + Attach Request + PDN Connectivity */ core_sleep(time_from_msec(300)); rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+1); + /* Update M-TMSI */ + m_tmsi = htonl(m_tmsi); + memcpy(sendbuf->payload + 37, &m_tmsi, 4); + /* Update NAS MAC */ + void snow_3g_f9(c_uint8_t* key, c_uint32_t count, c_uint32_t fresh, + c_uint32_t dir, c_uint8_t *data, c_uint64_t length, c_uint8_t *out); + snow_3g_f9(mme_ue->knas_int, 7, 0, 0, + sendbuf->payload + 25, (109 << 3), sendbuf->payload+21); ABTS_INT_EQUAL(tc, CORE_OK, rv); rv = tests1ap_enb_send(sock, sendbuf); ABTS_INT_EQUAL(tc, CORE_OK, rv); @@ -402,6 +420,28 @@ static void attach_test1(abts_case *tc, void *data) /* eNB disonncect from SGW */ rv = testgtpu_enb_close(gtpu); ABTS_INT_EQUAL(tc, CORE_OK, rv); + + return; + +out: + /********** Remove Subscriber in Database */ + doc = BCON_NEW("imsi", BCON_UTF8("001010123456819")); + 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); + + core_sleep(time_from_msec(300)); + + /* eNB disonncect from MME */ + rv = tests1ap_enb_close(sock); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* eNB disonncect from SGW */ + rv = testgtpu_enb_close(gtpu); + ABTS_INT_EQUAL(tc, CORE_OK, rv); } /************************************************************** @@ -972,15 +1012,14 @@ static void attach_test3(abts_case *tc, void *data) ABTS_TRUE(tc, memcmp(recvbuf->payload+43, tmp+43, 3) == 0); pkbuf_free(recvbuf); + /* Retreive M-TMSI */ enb_ue = enb_ue_find_by_mme_ue_s1ap_id(33554632); d_assert(enb_ue, goto out,); mme_ue = enb_ue->mme_ue; d_assert(mme_ue, goto out,); m_tmsi = mme_ue->guti.m_tmsi; - /* Send UE Release Request */ - core_sleep(time_from_msec(300)); - + /* Send Initial UE Message + Attach Request */ rv = tests1ap_build_ue_context_release_request(&sendbuf, msgindex); ABTS_INT_EQUAL(tc, CORE_OK, rv); rv = tests1ap_enb_send(sock, sendbuf);