Split ue_context into two context(enb_ue_t, mme_ue_t)
This commit is contained in:
parent
b95e40a851
commit
65b5378c91
|
@ -66,6 +66,13 @@ typedef struct _e_cgi_t {
|
|||
c_uint32_t cell_id; /* 28 bit */
|
||||
} __attribute__ ((packed)) e_cgi_t;
|
||||
|
||||
typedef struct _guti_t {
|
||||
plmn_id_t plmn_id;
|
||||
c_uint16_t mme_gid;
|
||||
c_uint8_t mme_code;
|
||||
c_uint32_t m_tmsi;
|
||||
} __attribute__ ((packed)) guti_t;
|
||||
|
||||
/**************************************************
|
||||
* 8.14 PDN Address Allocation (PAA) */
|
||||
#define PAA_IPV4_LEN 5
|
||||
|
|
|
@ -25,6 +25,7 @@ status_t emm_build_attach_accept(
|
|||
&attach_accept->eps_network_feature_support;
|
||||
|
||||
d_assert(ue, return CORE_ERROR, "Null param");
|
||||
d_assert(ue->enb_ue, return CORE_ERROR, "Null param");
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.h.security_header_type =
|
||||
|
@ -41,7 +42,7 @@ status_t emm_build_attach_accept(
|
|||
tai_list->length = 6;
|
||||
tai_list->type = 2;
|
||||
tai_list->num = 0; /* +1 = 1 elements */
|
||||
memcpy(&tai_list->type2.tai[0], &ue->tai, sizeof(tai_t));
|
||||
memcpy(&tai_list->type2.tai[0], &ue->enb_ue->tai, sizeof(tai_t));
|
||||
|
||||
attach_accept->esm_message_container.data = esmbuf->payload;
|
||||
attach_accept->esm_message_container.len = esmbuf->len;
|
||||
|
|
|
@ -141,16 +141,19 @@ void emm_handle_attach_request(
|
|||
}
|
||||
}
|
||||
|
||||
void emm_handle_identity_request(mme_ue_t *ue)
|
||||
void emm_handle_identity_request(mme_ue_t *mme_ue)
|
||||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
nas_message_t message;
|
||||
nas_identity_request_t *identity_request =
|
||||
&message.emm.identity_request;
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
ue = mme_ue->enb_ue;
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
d_assert(ue->enb, return, "Null param");
|
||||
|
@ -202,16 +205,19 @@ void emm_handle_identity_response(
|
|||
|
||||
}
|
||||
|
||||
void emm_handle_authentication_request(mme_ue_t *ue)
|
||||
void emm_handle_authentication_request(mme_ue_t *mme_ue)
|
||||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
nas_message_t message;
|
||||
nas_authentication_request_t *authentication_request =
|
||||
&message.emm.authentication_request;
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
ue = mme_ue->enb_ue;
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
d_assert(ue->enb, return, "Null param");
|
||||
|
@ -221,9 +227,9 @@ void emm_handle_authentication_request(mme_ue_t *ue)
|
|||
message.emm.h.message_type = NAS_AUTHENTICATION_REQUEST;
|
||||
|
||||
memcpy(authentication_request->authentication_parameter_rand.rand,
|
||||
ue->rand, RAND_LEN);
|
||||
mme_ue->rand, RAND_LEN);
|
||||
memcpy(authentication_request->authentication_parameter_autn.autn,
|
||||
ue->autn, AUTN_LEN);
|
||||
mme_ue->autn, AUTN_LEN);
|
||||
authentication_request->authentication_parameter_autn.length =
|
||||
AUTN_LEN;
|
||||
|
||||
|
@ -241,6 +247,7 @@ void emm_handle_authentication_response(
|
|||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
nas_authentication_response_parameter_t *authentication_response_parameter =
|
||||
|
@ -257,8 +264,10 @@ void emm_handle_authentication_response(
|
|||
&security_mode_command->replayed_ue_security_capabilities;
|
||||
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
d_assert(ue->enb, return, "Null param");
|
||||
enb_ue = ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
if (authentication_response_parameter->length != ue->xres_len ||
|
||||
memcmp(authentication_response_parameter->res,
|
||||
|
@ -313,7 +322,7 @@ void emm_handle_authentication_response(
|
|||
rv = nas_security_encode(&emmbuf, ue, &message);
|
||||
d_assert(rv == CORE_OK && emmbuf, return, "emm build error");
|
||||
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, ue, emmbuf);
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, enb_ue, emmbuf);
|
||||
d_assert(rv == CORE_OK && s1apbuf,
|
||||
pkbuf_free(emmbuf); return, "s1ap build error");
|
||||
|
||||
|
@ -324,14 +333,17 @@ void emm_handle_create_session_response(mme_bearer_t *bearer)
|
|||
{
|
||||
status_t rv;
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
mme_enb_t *enb = NULL;
|
||||
pkbuf_t *esmbuf = NULL, *emmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
d_assert(bearer, return, "Null param");
|
||||
ue = bearer->ue;
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
d_assert(ue->enb, return, "Null param");
|
||||
enb_ue = ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
rv = esm_build_activate_default_bearer_context(&esmbuf, bearer);
|
||||
d_assert(rv == CORE_OK && esmbuf,
|
||||
|
@ -358,6 +370,7 @@ void emm_handle_attach_complete(
|
|||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
nas_message_t message;
|
||||
|
@ -371,7 +384,9 @@ void emm_handle_attach_complete(
|
|||
time_exp_lt(&time_exp, time_now());
|
||||
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
enb_ue = ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
emm_handle_esm_message_container(
|
||||
|
@ -414,7 +429,7 @@ void emm_handle_attach_complete(
|
|||
rv = nas_security_encode(&emmbuf, ue, &message);
|
||||
d_assert(rv == CORE_OK && emmbuf, return, "emm build error");
|
||||
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, ue, emmbuf);
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, enb_ue, emmbuf);
|
||||
d_assert(rv == CORE_OK && s1apbuf,
|
||||
pkbuf_free(emmbuf); return, "s1ap build error");
|
||||
|
||||
|
@ -434,6 +449,7 @@ void emm_handle_detach_request(
|
|||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
nas_message_t message;
|
||||
|
@ -445,7 +461,9 @@ void emm_handle_detach_request(
|
|||
*/
|
||||
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
enb_ue = ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
switch (detach_type->detach_type)
|
||||
|
@ -484,7 +502,7 @@ void emm_handle_detach_request(
|
|||
rv = nas_security_encode(&emmbuf, ue, &message);
|
||||
d_assert(rv == CORE_OK && emmbuf, return, "emm build error");
|
||||
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, ue, emmbuf);
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, enb_ue, emmbuf);
|
||||
d_assert(rv == CORE_OK && s1apbuf,
|
||||
pkbuf_free(emmbuf); return, "s1ap build error");
|
||||
|
||||
|
@ -493,3 +511,98 @@ void emm_handle_detach_request(
|
|||
|
||||
/* initiate s1 ue context release */
|
||||
}
|
||||
|
||||
mme_ue_t *emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message)
|
||||
{
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
switch(message->emm.h.message_type)
|
||||
{
|
||||
case NAS_ATTACH_REQUEST:
|
||||
{
|
||||
nas_attach_request_t *attach_request =
|
||||
&message->emm.attach_request;
|
||||
|
||||
nas_eps_mobile_identity_t *eps_mobile_identity =
|
||||
&attach_request->eps_mobile_identity;
|
||||
|
||||
switch(eps_mobile_identity->imsi.type)
|
||||
{
|
||||
case NAS_EPS_MOBILE_IDENTITY_IMSI:
|
||||
{
|
||||
c_uint8_t imsi[MAX_IMSI_LEN];
|
||||
int imsi_len = 0;
|
||||
c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1];
|
||||
|
||||
nas_imsi_to_bcd(
|
||||
&eps_mobile_identity->imsi, eps_mobile_identity->length,
|
||||
imsi_bcd);
|
||||
core_bcd_to_buffer(imsi_bcd, imsi, &imsi_len);
|
||||
|
||||
d_trace(3,"Search mme_ue by UE_IMSI[%s]\n", imsi_bcd);
|
||||
|
||||
/* Find mme_ue_context by IMSI */
|
||||
mme_ue = mme_ue_find_by_imsi(imsi, imsi_len);
|
||||
|
||||
/* If not found , create one */
|
||||
if (!mme_ue)
|
||||
{
|
||||
mme_ue = mme_ue_add(enb_ue);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NAS_EPS_MOBILE_IDENTITY_GUTI:
|
||||
{
|
||||
nas_eps_mobile_identity_guti_t *nas_guti = NULL;
|
||||
nas_guti = &eps_mobile_identity->guti;
|
||||
guti_t guti;
|
||||
|
||||
guti.plmn_id = nas_guti->plmn_id;
|
||||
guti.mme_gid = nas_guti->mme_gid;
|
||||
guti.mme_code = nas_guti->mme_code;
|
||||
guti.m_tmsi = nas_guti->m_tmsi;
|
||||
|
||||
d_trace(3,"Search mme_ue by GUTI[G:%d,C:%d,M_TMSI:0x%x]\n",
|
||||
guti.mme_gid,
|
||||
guti.mme_code,
|
||||
guti.m_tmsi);
|
||||
printf("Search mme_ue by GUTI[G:%d,C:%d,M_TMSI:0x%x]\n",
|
||||
guti.mme_gid,
|
||||
guti.mme_code,
|
||||
guti.m_tmsi);
|
||||
|
||||
mme_ue = mme_ue_find_by_guti(&guti);
|
||||
if (!mme_ue)
|
||||
{
|
||||
mme_ue = mme_ue_add(enb_ue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("Uknown message imsi type =%d\n",
|
||||
eps_mobile_identity->imsi.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NAS_DETACH_REQUEST:
|
||||
{
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
case NAS_TRACKING_AREA_UPDATE_REQUEST:
|
||||
{
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mme_ue;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ CORE_DECLARE(void) emm_handle_identity_response(
|
|||
mme_ue_t *ue, nas_identity_response_t *identity_response);
|
||||
CORE_DECLARE(void) emm_handle_detach_request(
|
||||
mme_ue_t *ue, nas_detach_request_from_ue_t *detach_request);
|
||||
CORE_DECLARE(mme_ue_t*) emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -32,19 +32,22 @@ void esm_handle_s6a_update_location(mme_bearer_t *bearer)
|
|||
{
|
||||
status_t rv;
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
mme_enb_t *enb = NULL;
|
||||
pkbuf_t *esmbuf = NULL, *s1apbuf = NULL;
|
||||
|
||||
d_assert(bearer, return, "Null param");
|
||||
ue = bearer->ue;
|
||||
d_assert(ue, return, "Null param");
|
||||
enb = ue->enb;
|
||||
d_assert(ue->enb, return, "Null param");
|
||||
enb_ue = ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
rv = esm_build_information_request(&esmbuf, bearer);
|
||||
d_assert(rv == CORE_OK && esmbuf, return, "esm_build failed");
|
||||
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, ue, esmbuf);
|
||||
rv = s1ap_build_downlink_nas_transport(&s1apbuf, enb_ue, esmbuf);
|
||||
d_assert(rv == CORE_OK && s1apbuf,
|
||||
pkbuf_free(esmbuf); return, "s1ap build error");
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ pool_declare(mme_sgw_pool, mme_sgw_t, MAX_NUM_OF_SGW);
|
|||
|
||||
index_declare(mme_enb_pool, mme_enb_t, MAX_NUM_OF_ENB);
|
||||
index_declare(mme_ue_pool, mme_ue_t, MAX_NUM_OF_UE);
|
||||
index_declare(enb_ue_pool, enb_ue_t, MAX_NUM_OF_UE);
|
||||
index_declare(mme_bearer_pool, mme_bearer_t, MAX_NUM_OF_UE_BEARER);
|
||||
pool_declare(mme_pdn_pool, pdn_t, MAX_NUM_OF_UE_PDN);
|
||||
|
||||
|
@ -53,12 +54,15 @@ status_t mme_context_init()
|
|||
list_init(&self.enb_list);
|
||||
|
||||
index_init(&mme_ue_pool, MAX_NUM_OF_UE);
|
||||
index_init(&enb_ue_pool, MAX_NUM_OF_UE);
|
||||
index_init(&mme_bearer_pool, MAX_NUM_OF_UE_BEARER);
|
||||
pool_init(&mme_pdn_pool, MAX_NUM_OF_UE_PDN);
|
||||
|
||||
self.mme_addr = inet_addr(g_mme_ip_addr);
|
||||
|
||||
self.mme_ue_s1ap_id_hash = hash_make();
|
||||
self.imsi_hash = hash_make();
|
||||
self.guti_hash = hash_make();
|
||||
|
||||
self.s1ap_addr = self.mme_addr;
|
||||
self.s1ap_port = S1AP_SCTP_PORT;
|
||||
|
@ -107,9 +111,16 @@ status_t mme_context_final()
|
|||
d_assert(self.mme_ue_s1ap_id_hash, , "Null param");
|
||||
hash_destroy(self.mme_ue_s1ap_id_hash);
|
||||
|
||||
d_assert(self.imsi_hash, , "Null param");
|
||||
hash_destroy(self.imsi_hash);
|
||||
|
||||
d_assert(self.guti_hash, , "Null param");
|
||||
hash_destroy(self.guti_hash);
|
||||
|
||||
pool_final(&mme_pdn_pool);
|
||||
index_final(&mme_bearer_pool);
|
||||
index_final(&mme_ue_pool);
|
||||
index_final(&enb_ue_pool);
|
||||
|
||||
index_final(&mme_enb_pool);
|
||||
pool_final(&mme_sgw_pool);
|
||||
|
@ -224,7 +235,7 @@ status_t mme_enb_remove(mme_enb_t *enb)
|
|||
fsm_final(&enb->sm, 0);
|
||||
fsm_clear(&enb->sm);
|
||||
|
||||
mme_ue_remove_in_enb(enb);
|
||||
enb_ue_remove_in_enb(enb);
|
||||
|
||||
net_unregister_sock(enb->s1ap_sock);
|
||||
net_close(enb->s1ap_sock);
|
||||
|
@ -300,19 +311,21 @@ mme_enb_t* mme_enb_next(mme_enb_t *enb)
|
|||
return list_next(enb);
|
||||
}
|
||||
|
||||
mme_ue_t* mme_ue_add(mme_enb_t *enb)
|
||||
/** enb_ue_context handling function */
|
||||
enb_ue_t* enb_ue_add(mme_enb_t *enb)
|
||||
{
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return NULL, "Null param");
|
||||
d_assert(enb, return NULL, "Null param");
|
||||
|
||||
index_alloc(&mme_ue_pool, &ue);
|
||||
index_alloc(&enb_ue_pool, &ue);
|
||||
d_assert(ue, return NULL, "Null param");
|
||||
|
||||
ue->mme_ue_s1ap_id = NEXT_ID(self.mme_ue_s1ap_id, 1, 0xffffffff);
|
||||
hash_set(self.mme_ue_s1ap_id_hash, &ue->mme_ue_s1ap_id,
|
||||
sizeof(ue->mme_ue_s1ap_id), ue);
|
||||
#if 0
|
||||
ue->mme_s11_teid = ue->index;
|
||||
ue->mme_s11_addr = mme_self()->s11_addr;
|
||||
|
||||
|
@ -320,10 +333,135 @@ mme_ue_t* mme_ue_add(mme_enb_t *enb)
|
|||
|
||||
list_init(&ue->pdn_list);
|
||||
list_init(&ue->bearer_list);
|
||||
#endif
|
||||
list_append(&enb->ue_list, ue);
|
||||
|
||||
ue->enb = enb;
|
||||
|
||||
#if 0
|
||||
fsm_create(&ue->sm, enbue_state_initial, enbue_state_final);
|
||||
fsm_init(&ue->sm, 0);
|
||||
#endif
|
||||
|
||||
return ue;
|
||||
|
||||
}
|
||||
|
||||
unsigned int enb_ue_count()
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return 0, "Null param");
|
||||
return hash_count(self.mme_ue_s1ap_id_hash);
|
||||
}
|
||||
|
||||
status_t enb_ue_remove(enb_ue_t *ue)
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return CORE_ERROR, "Null param");
|
||||
d_assert(ue, return CORE_ERROR, "Null param");
|
||||
d_assert(ue->enb, return CORE_ERROR, "Null param");
|
||||
|
||||
#if 0
|
||||
fsm_final(&ue->sm, 0);
|
||||
fsm_clear(&ue->sm);
|
||||
|
||||
mme_bearer_remove_all(ue);
|
||||
mme_pdn_remove_all(ue);
|
||||
#endif
|
||||
|
||||
list_remove(&ue->enb->ue_list, ue);
|
||||
hash_set(self.mme_ue_s1ap_id_hash, &ue->mme_ue_s1ap_id,
|
||||
sizeof(ue->mme_ue_s1ap_id), NULL);
|
||||
|
||||
index_free(&enb_ue_pool, ue);
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t enb_ue_remove_in_enb(mme_enb_t *enb)
|
||||
{
|
||||
enb_ue_t *ue = NULL, *next_ue = NULL;
|
||||
|
||||
ue = enb_ue_first_in_enb(enb);
|
||||
while (ue)
|
||||
{
|
||||
next_ue = enb_ue_next_in_enb(ue);
|
||||
|
||||
enb_ue_remove(ue);
|
||||
|
||||
ue = next_ue;
|
||||
}
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
||||
enb_ue_t* enb_ue_find(index_t index)
|
||||
{
|
||||
d_assert(index, return NULL, "Invalid Index");
|
||||
return index_find(&enb_ue_pool, index);
|
||||
}
|
||||
|
||||
enb_ue_t* enb_ue_find_by_enb_ue_s1ap_id(
|
||||
mme_enb_t *enb, c_uint32_t enb_ue_s1ap_id)
|
||||
{
|
||||
enb_ue_t *ue = NULL;
|
||||
|
||||
ue = enb_ue_first_in_enb(enb);
|
||||
while (ue)
|
||||
{
|
||||
if (enb_ue_s1ap_id == ue->enb_ue_s1ap_id)
|
||||
break;
|
||||
|
||||
ue = enb_ue_next_in_enb(ue);
|
||||
}
|
||||
|
||||
return ue;
|
||||
}
|
||||
|
||||
enb_ue_t* enb_ue_find_by_mme_ue_s1ap_id(c_uint32_t mme_ue_s1ap_id)
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return NULL, "Null param");
|
||||
return hash_get(self.mme_ue_s1ap_id_hash,
|
||||
&mme_ue_s1ap_id, sizeof(mme_ue_s1ap_id));
|
||||
}
|
||||
|
||||
enb_ue_t* enb_ue_first_in_enb(mme_enb_t *enb)
|
||||
{
|
||||
return list_first(&enb->ue_list);
|
||||
}
|
||||
|
||||
enb_ue_t* enb_ue_next_in_enb(enb_ue_t *ue)
|
||||
{
|
||||
return list_next(ue);
|
||||
}
|
||||
|
||||
mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
|
||||
{
|
||||
mme_ue_t *ue = NULL;
|
||||
|
||||
#if 0
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return NULL, "Null param");
|
||||
#endif
|
||||
d_assert(enb_ue, return NULL, "Null param");
|
||||
|
||||
index_alloc(&mme_ue_pool, &ue);
|
||||
d_assert(ue, return NULL, "Null param");
|
||||
|
||||
#if 0
|
||||
ue->mme_ue_s1ap_id = NEXT_ID(self.mme_ue_s1ap_id, 1, 0xffffffff);
|
||||
hash_set(self.mme_ue_s1ap_id_hash, &ue->mme_ue_s1ap_id,
|
||||
sizeof(ue->mme_ue_s1ap_id), ue);
|
||||
#endif
|
||||
ue->mme_s11_teid = ue->index;
|
||||
ue->mme_s11_addr = mme_self()->s11_addr;
|
||||
|
||||
ue->ebi = MIN_EPS_BEARER_ID - 1; /* Setup EBI Generator */
|
||||
|
||||
list_init(&ue->pdn_list);
|
||||
list_init(&ue->bearer_list);
|
||||
//list_append(&enb->ue_list, ue);
|
||||
|
||||
ue->enb_ue = enb_ue;
|
||||
enb_ue->mme_ue = ue;
|
||||
|
||||
fsm_create(&ue->sm, emm_state_initial, emm_state_final);
|
||||
fsm_init(&ue->sm, 0);
|
||||
|
||||
|
@ -332,9 +470,9 @@ mme_ue_t* mme_ue_add(mme_enb_t *enb)
|
|||
|
||||
status_t mme_ue_remove(mme_ue_t *ue)
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return CORE_ERROR, "Null param");
|
||||
//d_assert(self.mme_ue_s1ap_id_hash, return CORE_ERROR, "Null param");
|
||||
d_assert(ue, return CORE_ERROR, "Null param");
|
||||
d_assert(ue->enb, return CORE_ERROR, "Null param");
|
||||
//d_assert(ue->enb, return CORE_ERROR, "Null param");
|
||||
|
||||
fsm_final(&ue->sm, 0);
|
||||
fsm_clear(&ue->sm);
|
||||
|
@ -342,9 +480,11 @@ status_t mme_ue_remove(mme_ue_t *ue)
|
|||
mme_bearer_remove_all(ue);
|
||||
mme_pdn_remove_all(ue);
|
||||
|
||||
#if 0
|
||||
list_remove(&ue->enb->ue_list, ue);
|
||||
hash_set(self.mme_ue_s1ap_id_hash, &ue->mme_ue_s1ap_id,
|
||||
sizeof(ue->mme_ue_s1ap_id), NULL);
|
||||
#endif
|
||||
|
||||
index_free(&mme_ue_pool, ue);
|
||||
|
||||
|
@ -371,18 +511,54 @@ mme_ue_t* mme_ue_find(index_t index)
|
|||
return index_find(&mme_ue_pool, index);
|
||||
}
|
||||
|
||||
#if 0
|
||||
mme_ue_t* mme_ue_find_by_mme_ue_s1ap_id(c_uint32_t mme_ue_s1ap_id)
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return NULL, "Null param");
|
||||
return hash_get(self.mme_ue_s1ap_id_hash,
|
||||
&mme_ue_s1ap_id, sizeof(mme_ue_s1ap_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
mme_ue_t* mme_ue_find_by_teid(c_uint32_t teid)
|
||||
{
|
||||
return mme_ue_find(teid);
|
||||
}
|
||||
|
||||
mme_ue_t* mme_ue_find_by_imsi(c_uint8_t *imsi, int imsi_len)
|
||||
{
|
||||
mme_ue_t *iter = NULL;
|
||||
|
||||
#if 0
|
||||
d_assert(imsi && imsi_len, return NULL, "Invalid Param");
|
||||
|
||||
for (iter = list_first(&self.mme_ue_list); iter; iter = list_next(iter))
|
||||
{
|
||||
if (!memcmp(iter->imsi,imsi, imsi_len))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
mme_ue_t* mme_ue_find_by_guti(guti_t *guti)
|
||||
{
|
||||
mme_ue_t *iter = NULL;
|
||||
|
||||
#if 0
|
||||
d_assert(imsi && imsi_len, return NULL, "Invalid Param");
|
||||
|
||||
for (iter = list_first(&self.mme_ue_list); iter; iter = list_next(iter))
|
||||
{
|
||||
if (!memcmp(iter->imsi,imsi, imsi_len))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
hash_index_t *mme_ue_first()
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return NULL, "Null param");
|
||||
|
@ -400,6 +576,7 @@ mme_ue_t *mme_ue_this(hash_index_t *hi)
|
|||
return hash_this_val(hi);
|
||||
}
|
||||
|
||||
#if 0
|
||||
unsigned int mme_ue_count()
|
||||
{
|
||||
d_assert(self.mme_ue_s1ap_id_hash, return 0, "Null param");
|
||||
|
@ -449,6 +626,7 @@ mme_ue_t* mme_ue_next_in_enb(mme_ue_t *ue)
|
|||
{
|
||||
return list_next(ue);
|
||||
}
|
||||
#endif
|
||||
|
||||
mme_bearer_t* mme_bearer_add(mme_ue_t *ue, c_uint8_t pti)
|
||||
{
|
||||
|
|
|
@ -75,6 +75,8 @@ typedef struct _mme_context_t {
|
|||
list_t enb_list;
|
||||
|
||||
hash_t *mme_ue_s1ap_id_hash; /* hash table for MME-UE-S1AP-ID */
|
||||
hash_t *imsi_hash; /* hash table (IMSI : MME_UE) */
|
||||
hash_t *guti_hash; /* hash table (GUTI : MME_UE) */
|
||||
} mme_context_t;
|
||||
|
||||
typedef struct _mme_sgw_t {
|
||||
|
@ -94,7 +96,10 @@ typedef struct _mme_enb_t {
|
|||
|
||||
} mme_enb_t;
|
||||
|
||||
typedef struct _mme_ue_t {
|
||||
typedef struct _enb_ue_t enb_ue_t;
|
||||
typedef struct _mme_ue_t mme_ue_t;
|
||||
|
||||
struct _enb_ue_t {
|
||||
lnode_t node; /**< A node of list_t */
|
||||
index_t index; /**< An index of this node */
|
||||
fsm_t sm;
|
||||
|
@ -104,13 +109,44 @@ typedef struct _mme_ue_t {
|
|||
/* UE identity */
|
||||
c_uint32_t enb_ue_s1ap_id; /** eNB-UE-S1AP-ID received from eNB */
|
||||
c_uint32_t mme_ue_s1ap_id; /** MME-UE-S1AP-ID received from MME */
|
||||
c_uint8_t imsi[MAX_IMSI_LEN];
|
||||
int imsi_len;
|
||||
c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1];
|
||||
|
||||
/* UE Info */
|
||||
tai_t tai;
|
||||
e_cgi_t e_cgi;
|
||||
|
||||
/* S_TMSI */
|
||||
//s_tmsi_t s_smti;
|
||||
|
||||
/* mme_ue_context */
|
||||
mme_ue_t *mme_ue;
|
||||
|
||||
/* Connected enodeB */
|
||||
mme_enb_t *enb;
|
||||
|
||||
};
|
||||
|
||||
struct _mme_ue_t {
|
||||
lnode_t node; /**< A node of list_t */
|
||||
index_t index; /**< An index of this node */
|
||||
fsm_t sm;
|
||||
|
||||
/* State Machine */
|
||||
|
||||
/* UE identity */
|
||||
#if 0
|
||||
c_uint32_t enb_ue_s1ap_id; /** eNB-UE-S1AP-ID received from eNB */
|
||||
c_uint32_t mme_ue_s1ap_id; /** MME-UE-S1AP-ID received from MME */
|
||||
#endif
|
||||
c_uint8_t imsi[MAX_IMSI_LEN];
|
||||
int imsi_len;
|
||||
c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1];
|
||||
guti_t guti;
|
||||
|
||||
/* UE Info */
|
||||
#if 0
|
||||
tai_t tai;
|
||||
e_cgi_t e_cgi;
|
||||
#endif
|
||||
plmn_id_t visited_plmn_id;
|
||||
|
||||
/* Security Context */
|
||||
|
@ -153,8 +189,9 @@ typedef struct _mme_ue_t {
|
|||
c_uint8_t ebi; /* EPS Bearer ID generator */
|
||||
list_t bearer_list;
|
||||
|
||||
mme_enb_t *enb;
|
||||
} mme_ue_t;
|
||||
/* enb ue context */
|
||||
enb_ue_t *enb_ue;
|
||||
};
|
||||
|
||||
typedef struct _mme_bearer_t {
|
||||
lnode_t node; /**< A node of list_t */
|
||||
|
@ -201,7 +238,7 @@ CORE_DECLARE(mme_enb_t*) mme_enb_find_by_enb_id(c_uint32_t enb_id);
|
|||
CORE_DECLARE(mme_enb_t*) mme_enb_first(void);
|
||||
CORE_DECLARE(mme_enb_t*) mme_enb_next(mme_enb_t *enb);
|
||||
|
||||
CORE_DECLARE(mme_ue_t*) mme_ue_add(mme_enb_t *enb);
|
||||
CORE_DECLARE(mme_ue_t*) mme_ue_add(enb_ue_t *enb_ue);
|
||||
CORE_DECLARE(status_t) mme_ue_remove(mme_ue_t *ue);
|
||||
CORE_DECLARE(status_t) mme_ue_remove_all();
|
||||
CORE_DECLARE(mme_ue_t*) mme_ue_find(index_t index);
|
||||
|
@ -217,6 +254,8 @@ CORE_DECLARE(mme_ue_t*) mme_ue_find_by_enb_ue_s1ap_id(
|
|||
mme_enb_t *enb, c_uint32_t enb_ue_s1ap_id);
|
||||
CORE_DECLARE(mme_ue_t*) mme_ue_first_in_enb(mme_enb_t *enb);
|
||||
CORE_DECLARE(mme_ue_t*) mme_ue_next_in_enb(mme_ue_t *ue);
|
||||
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_guti(guti_t *guti);
|
||||
|
||||
CORE_DECLARE(mme_bearer_t*) mme_bearer_add(mme_ue_t *ue, c_uint8_t pti);
|
||||
CORE_DECLARE(status_t) mme_bearer_remove(mme_bearer_t *bearer);
|
||||
|
@ -234,6 +273,17 @@ CORE_DECLARE(pdn_t*) mme_pdn_find_by_apn(mme_ue_t *ue, c_int8_t *apn);
|
|||
CORE_DECLARE(pdn_t*) mme_pdn_first(mme_ue_t *ue);
|
||||
CORE_DECLARE(pdn_t*) mme_pdn_next(pdn_t *pdn);
|
||||
|
||||
CORE_DECLARE(enb_ue_t*) enb_ue_add(mme_enb_t *enb);
|
||||
CORE_DECLARE(unsigned int) enb_ue_count();
|
||||
CORE_DECLARE(status_t) enb_ue_remove(enb_ue_t *ue);
|
||||
CORE_DECLARE(status_t) enb_ue_remove_in_enb(mme_enb_t *enb);
|
||||
CORE_DECLARE(enb_ue_t*) enb_ue_find(index_t index);
|
||||
CORE_DECLARE(enb_ue_t*) enb_ue_find_by_enb_ue_s1ap_id(mme_enb_t *enb,
|
||||
c_uint32_t enb_ue_s1ap_id);
|
||||
CORE_DECLARE(enb_ue_t*) enb_ue_find_by_mme_ue_s1ap_id(c_uint32_t mme_ue_s1ap_id);
|
||||
CORE_DECLARE(enb_ue_t*) enb_ue_first_in_enb(mme_enb_t *enb);
|
||||
CORE_DECLARE(enb_ue_t*) enb_ue_next_in_enb(enb_ue_t *ue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
|
@ -32,6 +32,7 @@ status_t mme_s11_build_create_session_request(pkbuf_t **pkbuf, mme_bearer_t *bea
|
|||
d_assert(sgw, return CORE_ERROR, "Null param");
|
||||
ue = bearer->ue;
|
||||
d_assert(ue, return CORE_ERROR, "Null param");
|
||||
d_assert(ue->enb_ue, return CORE_ERROR, "Null param");
|
||||
|
||||
memset(>p_message, 0, sizeof(gtp_message_t));
|
||||
|
||||
|
@ -48,10 +49,10 @@ status_t mme_s11_build_create_session_request(pkbuf_t **pkbuf, mme_bearer_t *bea
|
|||
memset(&uli, 0, sizeof(gtp_uli_t));
|
||||
uli.flags.e_cgi = 1;
|
||||
uli.flags.tai = 1;
|
||||
memcpy(&uli.tai.plmn_id, &ue->tai.plmn_id, sizeof(uli.tai.plmn_id));
|
||||
uli.tai.tac = ue->tai.tac;
|
||||
memcpy(&uli.e_cgi.plmn_id, &ue->e_cgi.plmn_id, sizeof(uli.tai.plmn_id));
|
||||
uli.e_cgi.cell_id = ue->e_cgi.cell_id;
|
||||
memcpy(&uli.tai.plmn_id, &ue->enb_ue->tai.plmn_id, sizeof(uli.tai.plmn_id));
|
||||
uli.tai.tac = ue->enb_ue->tai.tac;
|
||||
memcpy(&uli.e_cgi.plmn_id, &ue->enb_ue->e_cgi.plmn_id, sizeof(uli.tai.plmn_id));
|
||||
uli.e_cgi.cell_id = ue->enb_ue->e_cgi.cell_id;
|
||||
req->user_location_information.presence = 1;
|
||||
gtp_build_uli(&req->user_location_information, &uli,
|
||||
uli_buf, GTP_MAX_ULI_LEN);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nas_security.h"
|
||||
#include "mme_s11_path.h"
|
||||
#include "mme_s11_handler.h"
|
||||
#include "emm_handler.h"
|
||||
|
||||
void mme_state_initial(fsm_t *s, event_t *e)
|
||||
{
|
||||
|
@ -145,6 +146,42 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
break;
|
||||
}
|
||||
case MME_EVT_EMM_UE_MSG:
|
||||
{
|
||||
nas_message_t message;
|
||||
index_t index = event_get_param1(e);
|
||||
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param2(e);
|
||||
//int mac_failed = event_get_param3(e);
|
||||
enb_ue_t *ue = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
ue = enb_ue_find(index);
|
||||
d_assert(ue, break, "No ENB UE context");
|
||||
|
||||
d_assert(pkbuf, break, "Null param");
|
||||
d_assert(nas_emm_decode(&message, pkbuf) == CORE_OK,
|
||||
pkbuf_free(pkbuf); break, "Can't decode NAS_EMM");
|
||||
|
||||
mme_ue = ue->mme_ue;
|
||||
if (mme_ue == NULL)
|
||||
{
|
||||
/* Find MME UE by NAS message or create if needed */
|
||||
mme_ue = emm_find_ue_by_message(ue, &message);
|
||||
}
|
||||
|
||||
d_assert(mme_ue, pkbuf_free(pkbuf);break, "No MME UE context");
|
||||
d_assert(FSM_STATE(&mme_ue->sm), pkbuf_free(pkbuf);break,
|
||||
"No EMM State Machine");
|
||||
|
||||
/* Set event */
|
||||
event_set_param1(e, (c_uintptr_t)mme_ue->index);/* mme_ue index */
|
||||
event_set_param3(e, (c_uintptr_t)&message);
|
||||
|
||||
fsm_dispatch(&mme_ue->sm, (fsm_event_t*)e);
|
||||
|
||||
pkbuf_free(pkbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
case MME_EVT_EMM_UE_FROM_S6A:
|
||||
case MME_EVT_EMM_UE_FROM_S11:
|
||||
case MME_EVT_EMM_BEARER_FROM_S11:
|
||||
|
|
|
@ -110,7 +110,7 @@ status_t nas_security_encode(
|
|||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t nas_security_decode(mme_ue_t *ue, pkbuf_t *pkbuf)
|
||||
status_t nas_security_decode(mme_ue_t *ue, pkbuf_t *pkbuf, int *mac_failed)
|
||||
{
|
||||
c_int32_t hsize = 0;
|
||||
|
||||
|
@ -123,6 +123,7 @@ status_t nas_security_decode(mme_ue_t *ue, pkbuf_t *pkbuf)
|
|||
d_assert(ue, return CORE_ERROR, "Null param");
|
||||
d_assert(pkbuf, return CORE_ERROR, "Null param");
|
||||
d_assert(pkbuf->payload, return CORE_ERROR, "Null param");
|
||||
d_assert(mac_failed, return CORE_ERROR, "Null param");
|
||||
|
||||
h = pkbuf->payload;
|
||||
switch(h->security_header_type)
|
||||
|
@ -203,10 +204,15 @@ status_t nas_security_decode(mme_ue_t *ue, pkbuf_t *pkbuf)
|
|||
memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE);
|
||||
if (h->message_authentication_code != mac32)
|
||||
{
|
||||
#if 0
|
||||
d_error("NAS MAC verification failed");
|
||||
d_assert(pkbuf_header(pkbuf, hsize-1) == CORE_OK,
|
||||
return CORE_ERROR, "pkbuf_header error");
|
||||
return CORE_ERROR;
|
||||
#else
|
||||
d_warn("NAS MAC verification failed");
|
||||
*mac_failed = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ extern "C" {
|
|||
CORE_DECLARE(status_t) nas_security_encode(
|
||||
pkbuf_t **pkbuf, mme_ue_t *ue, nas_message_t *message);
|
||||
CORE_DECLARE(status_t) nas_security_decode(
|
||||
mme_ue_t *ue, pkbuf_t *pkbuf);
|
||||
mme_ue_t *ue, pkbuf_t *pkbuf, int *mac_failed);
|
||||
|
||||
CORE_DECLARE(void) nas_mac_calculate(c_uint8_t algorithm_identity,
|
||||
c_uint8_t *knas_int, c_uint32_t count, c_uint8_t bearer,
|
||||
|
|
|
@ -107,7 +107,7 @@ status_t s1ap_build_setup_failure(pkbuf_t **pkbuf, S1ap_Cause_t cause)
|
|||
}
|
||||
|
||||
status_t s1ap_build_downlink_nas_transport(
|
||||
pkbuf_t **s1apbuf, mme_ue_t *ue, pkbuf_t *emmbuf)
|
||||
pkbuf_t **s1apbuf, enb_ue_t *ue, pkbuf_t *emmbuf)
|
||||
{
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
|
@ -159,12 +159,15 @@ status_t s1ap_build_initial_context_setup_request(
|
|||
S1ap_E_RABToBeSetupItemCtxtSUReq_t *e_rab = NULL;
|
||||
struct S1ap_GBR_QosInformation *gbrQosInformation = NULL; /* OPTIONAL */
|
||||
S1ap_NAS_PDU_t *nasPdu = NULL;
|
||||
mme_ue_t *ue = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
pdn_t *pdn = NULL;
|
||||
|
||||
d_assert(emmbuf, return CORE_ERROR, "Null param");
|
||||
d_assert(bearer, return CORE_ERROR, "Null param");
|
||||
ue = bearer->ue;
|
||||
mme_ue = bearer->ue;
|
||||
d_assert(mme_ue, return CORE_ERROR, "Null param");
|
||||
ue = mme_ue->enb_ue;
|
||||
d_assert(ue, return CORE_ERROR, "Null param");
|
||||
pdn = bearer->pdn;
|
||||
d_assert(pdn, return CORE_ERROR, "Null param");
|
||||
|
@ -176,10 +179,10 @@ status_t s1ap_build_initial_context_setup_request(
|
|||
|
||||
asn_uint642INTEGER(
|
||||
&ies->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
|
||||
ue->max_bandwidth_ul);
|
||||
mme_ue->max_bandwidth_ul);
|
||||
asn_uint642INTEGER(
|
||||
&ies->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
|
||||
ue->max_bandwidth_dl);
|
||||
mme_ue->max_bandwidth_dl);
|
||||
|
||||
e_rab = (S1ap_E_RABToBeSetupItemCtxtSUReq_t *)
|
||||
core_calloc(1, sizeof(S1ap_E_RABToBeSetupItemCtxtSUReq_t));
|
||||
|
@ -224,7 +227,7 @@ status_t s1ap_build_initial_context_setup_request(
|
|||
sizeof(c_uint8_t));
|
||||
ies->ueSecurityCapabilities.encryptionAlgorithms.bits_unused = 0;
|
||||
ies->ueSecurityCapabilities.encryptionAlgorithms.buf[0] =
|
||||
ue->ue_network_capability.eea;
|
||||
mme_ue->ue_network_capability.eea;
|
||||
|
||||
ies->ueSecurityCapabilities.integrityProtectionAlgorithms.size = 2;
|
||||
ies->ueSecurityCapabilities.integrityProtectionAlgorithms.buf =
|
||||
|
@ -232,13 +235,13 @@ status_t s1ap_build_initial_context_setup_request(
|
|||
integrityProtectionAlgorithms.size, sizeof(c_uint8_t));
|
||||
ies->ueSecurityCapabilities.integrityProtectionAlgorithms.bits_unused = 0;
|
||||
ies->ueSecurityCapabilities.integrityProtectionAlgorithms.buf[0] =
|
||||
(ue->ue_network_capability.eia << 1);
|
||||
(mme_ue->ue_network_capability.eia << 1);
|
||||
|
||||
ies->securityKey.size = SHA256_DIGEST_SIZE;
|
||||
ies->securityKey.buf =
|
||||
core_calloc(ies->securityKey.size, sizeof(c_uint8_t));
|
||||
ies->securityKey.bits_unused = 0;
|
||||
memcpy(ies->securityKey.buf, ue->kenb, ies->securityKey.size);
|
||||
memcpy(ies->securityKey.buf, mme_ue->kenb, ies->securityKey.size);
|
||||
|
||||
message.procedureCode = S1ap_ProcedureCode_id_InitialContextSetup;
|
||||
message.direction = S1AP_PDU_PR_initiatingMessage;
|
||||
|
|
|
@ -12,7 +12,7 @@ CORE_DECLARE(status_t) s1ap_build_setup_rsp(pkbuf_t **pkbuf);
|
|||
CORE_DECLARE(status_t) s1ap_build_setup_failure(
|
||||
pkbuf_t **pkbuf, S1ap_Cause_t cause);
|
||||
CORE_DECLARE(status_t) s1ap_build_downlink_nas_transport(
|
||||
pkbuf_t **s1apbuf, mme_ue_t *ue, pkbuf_t *emmbuf);
|
||||
pkbuf_t **s1apbuf, enb_ue_t *ue, pkbuf_t *emmbuf);
|
||||
CORE_DECLARE(status_t) s1ap_build_initial_context_setup_request(
|
||||
pkbuf_t **s1apbuf, mme_bearer_t *bearer, pkbuf_t *emmbuf);
|
||||
|
||||
|
|
|
@ -12,11 +12,12 @@
|
|||
|
||||
#include "s1ap_handler.h"
|
||||
|
||||
static void event_s1ap_to_nas(mme_ue_t *ue, S1ap_NAS_PDU_t *nasPdu)
|
||||
static void event_s1ap_to_nas(enb_ue_t *ue, S1ap_NAS_PDU_t *nasPdu)
|
||||
{
|
||||
nas_esm_header_t *h = NULL;
|
||||
pkbuf_t *nasbuf = NULL;
|
||||
event_t e;
|
||||
int mac_failed = 0;
|
||||
|
||||
d_assert(ue, return, "Null param");
|
||||
d_assert(nasPdu, return, "Null param");
|
||||
|
@ -27,8 +28,34 @@ static void event_s1ap_to_nas(mme_ue_t *ue, S1ap_NAS_PDU_t *nasPdu)
|
|||
d_assert(nasbuf, return, "Null param");
|
||||
memcpy(nasbuf->payload, nasPdu->buf, nasPdu->size);
|
||||
|
||||
d_assert(nas_security_decode(ue, nasbuf) == CORE_OK,
|
||||
pkbuf_free(nasbuf); return, "Can't decode NAS_PDU");
|
||||
if (ue->mme_ue)
|
||||
{
|
||||
d_assert(nas_security_decode(ue->mme_ue, nasbuf,
|
||||
&mac_failed) == CORE_OK,
|
||||
pkbuf_free(nasbuf);return,
|
||||
"nas_security_decode failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME */
|
||||
c_uint32_t hsize = sizeof(nas_security_header_t);
|
||||
nas_security_header_t *sh = NULL;
|
||||
|
||||
sh = nasbuf->payload;
|
||||
switch(sh->security_header_type)
|
||||
{
|
||||
case NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE:
|
||||
case NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
mac_failed = 1;
|
||||
d_warn("Security Protected (securiry header type:0x%x)",
|
||||
sh->security_header_type);
|
||||
pkbuf_header(nasbuf, -hsize);
|
||||
}
|
||||
}
|
||||
|
||||
h = nasbuf->payload;
|
||||
d_assert(h, pkbuf_free(nasbuf); return, "Null param");
|
||||
|
@ -37,22 +64,34 @@ static void event_s1ap_to_nas(mme_ue_t *ue, S1ap_NAS_PDU_t *nasPdu)
|
|||
event_set(&e, MME_EVT_EMM_UE_MSG);
|
||||
event_set_param1(&e, (c_uintptr_t)ue->index);
|
||||
event_set_param2(&e, (c_uintptr_t)nasbuf);
|
||||
event_set_param3(&e, (c_uintptr_t)mac_failed);
|
||||
mme_event_send(&e);
|
||||
}
|
||||
else if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_ESM)
|
||||
{
|
||||
mme_bearer_t *bearer = mme_bearer_find_by_pti(ue,
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_ue_t *mme_ue = ue->mme_ue;
|
||||
|
||||
if (!mme_ue)
|
||||
{
|
||||
d_error("No mme_ue exists");
|
||||
pkbuf_free(nasbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
bearer = mme_bearer_find_by_pti(mme_ue,
|
||||
h->procedure_transaction_identity);
|
||||
if (bearer)
|
||||
{
|
||||
event_set(&e, MME_EVT_ESM_BEARER_MSG);
|
||||
event_set_param1(&e, (c_uintptr_t)bearer->index);
|
||||
event_set_param2(&e, (c_uintptr_t)nasbuf);
|
||||
event_set_param3(&e, (c_uintptr_t)mac_failed);
|
||||
mme_event_send(&e);
|
||||
}
|
||||
else
|
||||
d_error("Can't find ESM context(UE:%s, PTI:%d)",
|
||||
ue->imsi_bcd, h->procedure_transaction_identity);
|
||||
mme_ue->imsi_bcd, h->procedure_transaction_identity);
|
||||
}
|
||||
else
|
||||
d_assert(0, pkbuf_free(nasbuf); return, "Unknown protocol:%d",
|
||||
|
@ -111,7 +150,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
|
|||
{
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
S1ap_InitialUEMessage_IEs_t *ies = NULL;
|
||||
S1ap_TAI_t *tai = NULL;
|
||||
S1ap_PLMNidentity_t *pLMNidentity = NULL;
|
||||
|
@ -138,10 +177,10 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
|
|||
cell_ID = &eutran_cgi->cell_ID;
|
||||
d_assert(cell_ID, return,);
|
||||
|
||||
ue = mme_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
if (!ue)
|
||||
{
|
||||
ue = mme_ue_add(enb);
|
||||
ue = enb_ue_add(enb);
|
||||
d_assert(ue, return, "Null param");
|
||||
|
||||
ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID;
|
||||
|
@ -160,7 +199,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
|
|||
memcpy(&ue->e_cgi.cell_id, cell_ID->buf, sizeof(ue->e_cgi.cell_id));
|
||||
ue->e_cgi.cell_id = (ntohl(ue->e_cgi.cell_id) >> 4);
|
||||
|
||||
d_assert(enb->s1ap_sock, mme_ue_remove(ue); return,);
|
||||
d_assert(enb->s1ap_sock, enb_ue_remove(ue); return,);
|
||||
d_info("[S1AP] InitialUEMessage : UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]",
|
||||
ue->enb_ue_s1ap_id,
|
||||
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
|
||||
|
@ -174,13 +213,13 @@ void s1ap_handle_uplink_nas_transport(
|
|||
{
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
S1ap_UplinkNASTransport_IEs_t *ies = NULL;
|
||||
|
||||
ies = &message->s1ap_UplinkNASTransport_IEs;
|
||||
d_assert(ies, return, "Null param");
|
||||
|
||||
ue = mme_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
d_assert(ue, return, "Null param");
|
||||
|
||||
d_info("[S1AP] uplinkNASTransport : UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]",
|
||||
|
@ -196,13 +235,13 @@ void s1ap_handle_ue_capability_info_indication(
|
|||
{
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
S1ap_UECapabilityInfoIndicationIEs_t *ies = NULL;
|
||||
|
||||
ies = &message->s1ap_UECapabilityInfoIndicationIEs;
|
||||
d_assert(ies, return, "Null param");
|
||||
|
||||
ue = mme_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
d_assert(ue, return, "No UE Context[%d]", ies->eNB_UE_S1AP_ID);
|
||||
|
||||
d_info("[S1AP] UE Capability Info Indication : "
|
||||
|
@ -218,13 +257,13 @@ void s1ap_handle_initial_context_setup_response(
|
|||
char buf[INET_ADDRSTRLEN];
|
||||
int i = 0;
|
||||
|
||||
mme_ue_t *ue = NULL;
|
||||
enb_ue_t *ue = NULL;
|
||||
S1ap_InitialContextSetupResponseIEs_t *ies = NULL;
|
||||
|
||||
ies = &message->s1ap_InitialContextSetupResponseIEs;
|
||||
d_assert(ies, return, "Null param");
|
||||
|
||||
ue = mme_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
|
||||
d_assert(ue, return, "No UE Context[%d]", ies->eNB_UE_S1AP_ID);
|
||||
|
||||
d_info("[S1AP] Initial Context Setup Response : "
|
||||
|
@ -239,13 +278,14 @@ void s1ap_handle_initial_context_setup_response(
|
|||
{
|
||||
event_t e;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_ue_t *mme_ue = ue->mme_ue;
|
||||
S1ap_E_RABSetupItemCtxtSURes_t *e_rab = NULL;
|
||||
|
||||
e_rab = (S1ap_E_RABSetupItemCtxtSURes_t *)
|
||||
ies->e_RABSetupListCtxtSURes.s1ap_E_RABSetupItemCtxtSURes.array[i];
|
||||
d_assert(e_rab, return, "Null param");
|
||||
|
||||
bearer = mme_bearer_find_by_ebi(ue, e_rab->e_RAB_ID);
|
||||
bearer = mme_bearer_find_by_ebi(mme_ue, e_rab->e_RAB_ID);
|
||||
d_assert(bearer, return, "Null param");
|
||||
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
||||
sizeof(bearer->enb_s1u_teid));
|
||||
|
|
Loading…
Reference in New Issue