update it

This commit is contained in:
Sukchan Lee 2017-04-13 19:58:58 +09:00
parent c500842e6b
commit 4534e102ad
8 changed files with 158 additions and 146 deletions

View File

@ -16,6 +16,28 @@
#include "s1ap_build.h"
#include "s1ap_path.h"
static void event_emm_to_esm(mme_bearer_t *bearer,
nas_esm_message_container_t *bearer_message_container)
{
pkbuf_t *sendbuf = NULL;
event_t e;
d_assert(bearer, return, "Null param");
d_assert(bearer_message_container, return, "Null param");
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
sendbuf = pkbuf_alloc(NAS_HEADROOM, bearer_message_container->len);
d_assert(sendbuf, return, "Null param");
memcpy(sendbuf->payload,
bearer_message_container->data, bearer_message_container->len);
event_set(&e, MME_EVT_ESM_BEARER_MSG);
event_set_param1(&e, (c_uintptr_t)bearer->index);
event_set_param2(&e, (c_uintptr_t)sendbuf);
mme_event_send(&e);
}
void emm_handle_esm_message_container(
mme_ue_t *ue, nas_esm_message_container_t *esm_message_container)
{
@ -51,7 +73,7 @@ void emm_handle_esm_message_container(
ue->mme_ue_s1ap_id, bearer->pti);
}
mme_event_emm_to_esm(bearer, esm_message_container);
event_emm_to_esm(bearer, esm_message_container);
}
void emm_handle_attach_request(
@ -108,12 +130,17 @@ void emm_handle_attach_request(
void emm_handle_authentication_request(mme_ue_t *ue)
{
status_t rv;
mme_enb_t *enb = NULL;
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
nas_message_t message;
pkbuf_t *sendbuf = NULL;
nas_authentication_request_t *authentication_request =
&message.emm.authentication_request;
d_assert(ue, return, "Null param");
enb = ue->enb;
d_assert(ue->enb, return, "Null param");
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
@ -126,19 +153,26 @@ void emm_handle_authentication_request(mme_ue_t *ue)
authentication_request->authentication_parameter_autn.length =
AUTN_LEN;
d_assert(nas_plain_encode(&sendbuf, &message) == CORE_OK && sendbuf,,);
d_assert(nas_plain_encode(&emmbuf, &message) == CORE_OK && emmbuf,,);
mme_event_nas_to_s1ap(ue, sendbuf);
rv = s1ap_build_downlink_nas_transport(&s1apbuf, ue, emmbuf);
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(emmbuf); return, "s1ap build error");
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
}
void emm_handle_authentication_response(
mme_ue_t *ue, nas_authentication_response_t *authentication_response)
{
status_t rv;
mme_enb_t *enb = NULL;
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
nas_authentication_response_parameter_t *authentication_response_parameter =
&authentication_response->authentication_response_parameter;
nas_message_t message;
pkbuf_t *sendbuf = NULL;
nas_security_mode_command_t *security_mode_command =
&message.emm.security_mode_command;
nas_security_algorithms_t *selected_nas_security_algorithms =
@ -149,6 +183,8 @@ 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");
if (authentication_response_parameter->length != ue->xres_len ||
memcmp(authentication_response_parameter->res,
@ -196,17 +232,22 @@ void emm_handle_authentication_response(
mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_self()->selected_enc_algorithm,
ue->kasme, ue->knas_enc);
d_assert(nas_security_encode(&sendbuf, ue, &message) == CORE_OK &&
sendbuf,,);
mme_event_nas_to_s1ap(ue, sendbuf);
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);
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(emmbuf); return, "s1ap build error");
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
}
void emm_handle_lo_create_session(mme_bearer_t *bearer)
{
pkbuf_t *bearerbuf = NULL, *emmbuf = NULL, *s1apbuf = NULL;
status_t rv;
mme_ue_t *ue = NULL;
mme_enb_t *enb = NULL;
status_t rv;
pkbuf_t *esmbuf = NULL, *emmbuf = NULL, *s1apbuf = NULL;
d_assert(bearer, return, "Null param");
ue = bearer->ue;
@ -214,15 +255,18 @@ void emm_handle_lo_create_session(mme_bearer_t *bearer)
enb = ue->enb;
d_assert(ue->enb, return, "Null param");
rv = esm_build_activate_default_bearer_context(&bearerbuf, bearer);
d_assert(rv == CORE_OK, return, "bearer build error");
rv = esm_build_activate_default_bearer_context(&esmbuf, bearer);
d_assert(rv == CORE_OK && esmbuf,
return, "bearer build error");
rv = emm_build_attach_accept(&emmbuf, ue, bearerbuf);
d_assert(rv == CORE_OK, pkbuf_free(bearerbuf); return, "emm build error");
rv = emm_build_attach_accept(&emmbuf, ue, esmbuf);
d_assert(rv == CORE_OK && emmbuf,
pkbuf_free(esmbuf); return, "emm build error");
rv = s1ap_build_initial_context_setup_request(&s1apbuf, bearer, emmbuf);
d_assert(rv == CORE_OK, pkbuf_free(emmbuf); return, "emm build error");
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(emmbuf); return, "s1ap build error");
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,,);
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
}

View File

@ -6,6 +6,9 @@
#include "mme_context.h"
#include "mme_event.h"
#include "esm_build.h"
#include "s1ap_build.h"
#include "s1ap_path.h"
#include "mme_s11_build.h"
#include "mme_s11_path.h"
@ -22,6 +25,29 @@ void esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
#endif
}
void esm_handle_lo_information_request(mme_bearer_t *bearer)
{
status_t rv;
mme_ue_t *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");
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);
d_assert(rv == CORE_OK && s1apbuf,
pkbuf_free(esmbuf); return, "s1ap build error");
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
}
void esm_handle_information_response(mme_bearer_t *bearer,
nas_esm_information_response_t *esm_information_response)
{

View File

@ -11,6 +11,7 @@ extern "C" {
CORE_DECLARE(void) esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
nas_pdn_connectivity_request_t *pdn_connectivity_request);
CORE_DECLARE(void) esm_handle_lo_information_request(mme_bearer_t *bearer);
CORE_DECLARE(void) esm_handle_information_response(mme_bearer_t *bearer,
nas_esm_information_response_t *bearer_information_response);

View File

@ -57,13 +57,7 @@ void esm_state_operational(fsm_t *s, event_t *e)
{
case MME_EVT_ESM_BEARER_LO_INFO_REQ:
{
pkbuf_t *pkbuf = NULL;
status_t rv;
rv = esm_build_information_request(&pkbuf, bearer);
d_assert(rv == CORE_OK, break, "esm_build failed");
mme_event_nas_to_s1ap(ue, pkbuf);
esm_handle_lo_information_request(bearer);
d_info("[NAS] ESM information request : "
"UE[%s] <--- ESM[%d]", ue->imsi_bcd, bearer->pti);
break;

View File

@ -3,10 +3,6 @@
#include "core_debug.h"
#include "mme_event.h"
#include "s1ap_path.h"
#include "s1ap_message.h"
#include "nas_message.h"
#include "nas_security.h"
char* mme_event_get_name(event_t *e)
{
@ -53,109 +49,3 @@ char* mme_event_get_name(event_t *e)
return EVT_NAME_UNKNOWN;
}
void mme_event_s1ap_to_nas(mme_ue_t *ue, S1ap_NAS_PDU_t *nasPdu)
{
nas_esm_header_t *h = NULL;
pkbuf_t *sendbuf = NULL;
event_t e;
d_assert(ue, return, "Null param");
d_assert(nasPdu, return, "Null param");
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
sendbuf = pkbuf_alloc(NAS_HEADROOM, nasPdu->size);
d_assert(sendbuf, return, "Null param");
memcpy(sendbuf->payload, nasPdu->buf, nasPdu->size);
d_assert(nas_security_decode(ue, sendbuf) == CORE_OK,
pkbuf_free(sendbuf); return, "Can't decode NAS_PDU");
h = sendbuf->payload;
d_assert(h, pkbuf_free(sendbuf); return, "Null param");
if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_EMM)
{
event_set(&e, MME_EVT_EMM_UE_MSG);
event_set_param1(&e, (c_uintptr_t)ue->index);
event_set_param2(&e, (c_uintptr_t)sendbuf);
mme_event_send(&e);
}
else if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_ESM)
{
mme_bearer_t *bearer = mme_bearer_find_by_pti(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)sendbuf);
mme_event_send(&e);
}
else
d_error("Can't find ESM context(UE:%s, PTI:%d)",
ue->imsi_bcd, h->procedure_transaction_identity);
}
else
d_assert(0, pkbuf_free(sendbuf); return, "Unknown protocol:%d",
h->protocol_discriminator);
}
void mme_event_emm_to_esm(mme_bearer_t *bearer,
nas_esm_message_container_t *bearer_message_container)
{
pkbuf_t *sendbuf = NULL;
event_t e;
d_assert(bearer, return, "Null param");
d_assert(bearer_message_container, return, "Null param");
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
sendbuf = pkbuf_alloc(NAS_HEADROOM, bearer_message_container->len);
d_assert(sendbuf, return, "Null param");
memcpy(sendbuf->payload,
bearer_message_container->data, bearer_message_container->len);
event_set(&e, MME_EVT_ESM_BEARER_MSG);
event_set_param1(&e, (c_uintptr_t)bearer->index);
event_set_param2(&e, (c_uintptr_t)sendbuf);
mme_event_send(&e);
}
void mme_event_nas_to_s1ap(mme_ue_t *ue, pkbuf_t *pkbuf)
{
char buf[INET_ADDRSTRLEN];
int encoded;
s1ap_message_t message;
S1ap_DownlinkNASTransport_IEs_t *ies =
&message.s1ap_DownlinkNASTransport_IEs;
S1ap_NAS_PDU_t *nasPdu = &ies->nas_pdu;
pkbuf_t *sendbuf = NULL;
memset(&message, 0, sizeof(s1ap_message_t));
ies->mme_ue_s1ap_id = ue->mme_ue_s1ap_id;
ies->eNB_UE_S1AP_ID = ue->enb_ue_s1ap_id;
nasPdu->size = pkbuf->len;
nasPdu->buf = core_calloc(nasPdu->size, sizeof(c_uint8_t));
memcpy(nasPdu->buf, pkbuf->payload, nasPdu->size);
message.procedureCode = S1ap_ProcedureCode_id_downlinkNASTransport;
message.direction = S1AP_PDU_PR_initiatingMessage;
encoded = s1ap_encode_pdu(&sendbuf, &message);
s1ap_free_pdu(&message);
d_assert(sendbuf && encoded >= 0,,);
d_assert(s1ap_send_to_enb(ue->enb, sendbuf) == CORE_OK,,);
pkbuf_free(pkbuf);
d_assert(ue->enb,,);
d_info("[S1AP] downlinkNASTransport : "
"UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]",
ue->enb_ue_s1ap_id,
INET_NTOP(&ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
ue->enb->enb_id);
}

View File

@ -9,11 +9,6 @@ extern "C" {
#endif /* __cplusplus */
/* forward declaration */
typedef struct _mme_ue_t mme_ue_t;
typedef struct _mme_bearer_t mme_bearer_t;
typedef struct _nas_esm_message_container_t nas_esm_message_container_t;
typedef struct OCTET_STRING S1ap_NAS_PDU_t;
typedef enum {
MME_EVT_BASE = FSM_USER_SIG,
@ -40,11 +35,6 @@ typedef enum {
CORE_DECLARE(char*) mme_event_get_name(event_t *e);
CORE_DECLARE(void) mme_event_s1ap_to_nas(mme_ue_t *ue, S1ap_NAS_PDU_t *nasPdu);
CORE_DECLARE(void) mme_event_emm_to_esm(mme_bearer_t *bearer,
nas_esm_message_container_t *bearer_message_container);
CORE_DECLARE(void) mme_event_nas_to_s1ap(mme_ue_t *ue, pkbuf_t *pkbuf);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -108,6 +108,8 @@ 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)
{
char buf[INET_ADDRSTRLEN];
int encoded;
s1ap_message_t message;
S1ap_DownlinkNASTransport_IEs_t *ies =
@ -135,12 +137,20 @@ status_t s1ap_build_downlink_nas_transport(
d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,);
pkbuf_free(emmbuf);
d_info("[S1AP] downlinkNASTransport : "
"UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]",
ue->enb_ue_s1ap_id,
INET_NTOP(&ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
ue->enb->enb_id);
return CORE_OK;
}
status_t s1ap_build_initial_context_setup_request(
pkbuf_t **s1apbuf, mme_bearer_t *bearer, pkbuf_t *emmbuf)
{
char buf[INET_ADDRSTRLEN];
int encoded;
s1ap_message_t message;
S1ap_InitialContextSetupRequestIEs_t *ies =
@ -211,5 +221,11 @@ status_t s1ap_build_initial_context_setup_request(
d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,);
pkbuf_free(emmbuf);
d_info("[S1AP] Initial Context Setup Request : "
"UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]",
ue->enb_ue_s1ap_id,
INET_NTOP(&ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf),
ue->enb->enb_id);
return CORE_OK;
}

View File

@ -6,8 +6,59 @@
#include "s1ap_conv.h"
#include "s1ap_build.h"
#include "s1ap_handler.h"
#include "s1ap_path.h"
#include "nas_message.h"
#include "nas_security.h"
#include "s1ap_handler.h"
static void event_s1ap_to_nas(mme_ue_t *ue, S1ap_NAS_PDU_t *nasPdu)
{
nas_esm_header_t *h = NULL;
pkbuf_t *sendbuf = NULL;
event_t e;
d_assert(ue, return, "Null param");
d_assert(nasPdu, return, "Null param");
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
sendbuf = pkbuf_alloc(NAS_HEADROOM, nasPdu->size);
d_assert(sendbuf, return, "Null param");
memcpy(sendbuf->payload, nasPdu->buf, nasPdu->size);
d_assert(nas_security_decode(ue, sendbuf) == CORE_OK,
pkbuf_free(sendbuf); return, "Can't decode NAS_PDU");
h = sendbuf->payload;
d_assert(h, pkbuf_free(sendbuf); return, "Null param");
if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_EMM)
{
event_set(&e, MME_EVT_EMM_UE_MSG);
event_set_param1(&e, (c_uintptr_t)ue->index);
event_set_param2(&e, (c_uintptr_t)sendbuf);
mme_event_send(&e);
}
else if (h->protocol_discriminator == NAS_PROTOCOL_DISCRIMINATOR_ESM)
{
mme_bearer_t *bearer = mme_bearer_find_by_pti(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)sendbuf);
mme_event_send(&e);
}
else
d_error("Can't find ESM context(UE:%s, PTI:%d)",
ue->imsi_bcd, h->procedure_transaction_identity);
}
else
d_assert(0, pkbuf_free(sendbuf); return, "Unknown protocol:%d",
h->protocol_discriminator);
}
void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message)
{
@ -115,7 +166,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
enb->enb_id);
mme_event_s1ap_to_nas(ue, &ies->nas_pdu);
event_s1ap_to_nas(ue, &ies->nas_pdu);
}
void s1ap_handle_uplink_nas_transport(
@ -137,6 +188,6 @@ void s1ap_handle_uplink_nas_transport(
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
enb->enb_id);
mme_event_s1ap_to_nas(ue, &ies->nas_pdu);
event_s1ap_to_nas(ue, &ies->nas_pdu);
}