open5gs/src/mme/enb_s1ap_sm.c

247 lines
6.5 KiB
C
Raw Normal View History

2017-02-13 05:41:20 +00:00
#define TRACE_MODULE _enb_s1_sm
2017-03-05 07:49:57 +00:00
2017-02-13 05:41:20 +00:00
#include "core_debug.h"
2017-02-20 10:46:58 +00:00
#include "s1ap_build.h"
2017-02-13 05:41:20 +00:00
#include "s1ap_conv.h"
#include "s1ap_path.h"
2017-03-05 07:49:57 +00:00
#include "sm.h"
#include "context.h"
#include "event.h"
2017-03-06 08:55:50 +00:00
static void enb_s1ap_handle_s1_setup_request(
enb_ctx_t *enb, s1ap_message_t *message);
static void enb_s1ap_handle_initial_ue_message(
2017-03-06 00:07:59 +00:00
enb_ctx_t *enb, s1ap_message_t *message);
2017-02-13 05:41:20 +00:00
2017-03-05 04:03:11 +00:00
void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e)
2017-02-13 05:41:20 +00:00
{
d_assert(s, return, "Null param");
sm_trace(1, e);
2017-03-05 02:30:40 +00:00
FSM_TRAN(s, &enb_s1ap_state_operational);
2017-02-13 05:41:20 +00:00
}
2017-03-05 04:03:11 +00:00
void enb_s1ap_state_final(enb_s1ap_sm_t *s, event_t *e)
2017-02-13 05:41:20 +00:00
{
d_assert(s, return, "Null param");
sm_trace(1, e);
}
2017-03-05 04:03:11 +00:00
void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e)
2017-02-13 05:41:20 +00:00
{
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
enb_ctx_t *enb = s->ctx;
d_assert(enb, return, "Null param");
sm_trace(1, e);
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
break;
}
case FSM_EXIT_SIG:
{
break;
}
2017-03-05 08:07:43 +00:00
case EVT_MSG_ENB_S1AP:
2017-02-13 05:41:20 +00:00
{
2017-03-06 00:07:59 +00:00
s1ap_message_t message;
2017-02-13 05:41:20 +00:00
status_t rv;
2017-03-05 08:05:30 +00:00
pkbuf_t *recvbuf = (pkbuf_t *)event_get_param2(e);
2017-03-05 09:09:34 +00:00
d_assert(recvbuf, break, "Null param");
2017-02-13 05:41:20 +00:00
rv = s1ap_decode_pdu(&message, recvbuf);
if (rv != CORE_OK)
{
2017-03-05 09:09:34 +00:00
d_error("Can't parse S1AP_PDU");
2017-02-13 05:41:20 +00:00
break;
}
switch(message.direction)
{
case S1AP_PDU_PR_initiatingMessage :
{
switch(message.procedureCode)
{
case S1ap_ProcedureCode_id_S1Setup :
{
2017-03-06 08:55:50 +00:00
enb_s1ap_handle_s1_setup_request(enb, &message);
2017-02-13 05:41:20 +00:00
break;
}
2017-03-05 07:49:57 +00:00
case S1ap_ProcedureCode_id_initialUEMessage :
{
2017-03-06 08:55:50 +00:00
enb_s1ap_handle_initial_ue_message(enb, &message);
2017-03-05 07:49:57 +00:00
break;
}
2017-02-13 05:41:20 +00:00
default:
{
d_warn("Not implemented(choice:%d, proc:%d",
message.direction, message.procedureCode);
break;
}
}
2017-03-05 08:36:16 +00:00
2017-02-13 05:41:20 +00:00
break;
}
case S1AP_PDU_PR_successfulOutcome :
{
switch(message.procedureCode)
{
default:
{
d_warn("Not implemented(choice:%d, proc:%d",
message.direction, message.procedureCode);
break;
}
}
break;
}
case S1AP_PDU_PR_unsuccessfulOutcome :
default:
{
d_warn("Not implemented(choice:%d, proc:%d",
message.direction, message.procedureCode);
break;
}
}
s1ap_free_pdu(&message);
2017-03-05 08:36:16 +00:00
pkbuf_free(recvbuf);
2017-02-13 05:41:20 +00:00
break;
}
default:
{
d_error("Unknown event %s", event_get_name(e));
break;
}
}
}
2017-03-05 04:03:11 +00:00
void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e)
2017-02-13 05:41:20 +00:00
{
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
sm_trace(1, e);
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
break;
}
case FSM_EXIT_SIG:
{
break;
}
default:
{
d_error("Unknown event %s", event_get_name(e));
break;
}
}
}
2017-03-06 08:55:50 +00:00
static void enb_s1ap_handle_s1_setup_request(
enb_ctx_t *enb, s1ap_message_t *message)
2017-02-13 05:41:20 +00:00
{
char buf[INET_ADDRSTRLEN];
S1ap_S1SetupRequestIEs_t *ies = NULL;
pkbuf_t *sendbuf = NULL;
2017-02-13 11:10:05 +00:00
c_uint32_t enb_id;
2017-02-13 05:41:20 +00:00
2017-03-06 08:55:50 +00:00
d_assert(enb, return, "Null param");
d_assert(enb->s1ap_sock, return, "Null param");
d_assert(message, return, "Null param");
2017-02-13 05:41:20 +00:00
2017-03-05 02:46:42 +00:00
ies = &message->s1ap_S1SetupRequestIEs;
2017-03-06 08:55:50 +00:00
d_assert(ies, return, "Null param");
2017-02-13 05:41:20 +00:00
2017-03-05 02:29:15 +00:00
s1ap_ENB_ID_to_uint32(&ies->global_ENB_ID.eNB_ID, &enb_id);
2017-03-05 02:46:42 +00:00
#if 0 /* FIXME : does it needed? */
2017-03-05 04:03:11 +00:00
if (mme_ctx_enb_find_by_enb_id(enb_id))
2017-02-13 11:10:05 +00:00
{
S1ap_Cause_t cause;
d_error("eNB-id[0x%x] duplicated from [%s]", enb_id,
2017-03-05 04:03:11 +00:00
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf));
2017-02-13 11:10:05 +00:00
cause.present = S1ap_Cause_PR_protocol;
cause.choice.protocol =
S1ap_CauseProtocol_message_not_compatible_with_receiver_state;
rv = s1ap_build_setup_failure(&sendbuf, cause);
}
2017-03-05 02:46:42 +00:00
#endif
2017-02-13 11:10:05 +00:00
2017-03-05 07:49:57 +00:00
d_info("eNB[0x%x] sends S1-Setup-Request from [%s]", enb_id,
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf));
2017-02-13 05:41:20 +00:00
2017-03-05 07:49:57 +00:00
enb->enb_id = enb_id;
2017-02-13 05:41:20 +00:00
2017-03-05 07:49:57 +00:00
d_assert(s1ap_build_setup_rsp(&sendbuf) == CORE_OK,
2017-03-06 08:55:50 +00:00
return, "build error");
d_assert(s1ap_send_to_enb(enb, sendbuf) == CORE_OK, , "send error");
2017-02-13 05:41:20 +00:00
pkbuf_free(sendbuf);
2017-03-06 08:55:50 +00:00
}
static void enb_s1ap_handle_initial_ue_message(
enb_ctx_t *enb, s1ap_message_t *message)
{
ue_ctx_t *ue = NULL;
S1ap_InitialUEMessage_IEs_t *ies = NULL;
S1ap_NAS_PDU_t *nasPdu = NULL;
event_t e;
pkbuf_t *sendbuf = NULL;
ies = &message->s1ap_InitialUEMessage_IEs;
d_assert(ies, return, "Null param");
nasPdu = &ies->nas_pdu;
d_assert(nasPdu, return, "Null param");
sendbuf = pkbuf_alloc(0, nasPdu->size);
d_assert(sendbuf, return, "Null param");
memcpy(sendbuf->payload, nasPdu->buf, nasPdu->size);
ue = mme_ctx_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
if (!ue)
{
ue = mme_ctx_ue_add(enb);
d_assert(ue, pkbuf_free(sendbuf);return, "Null param");
ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID;
}
else
{
d_warn("Duplicated: eNB[0x%x] sends "
"Initial-UE Message[eNB-UE-S1AP-ID(%d)]",
enb->enb_id, ue->enb_ue_s1ap_id);
}
d_info("eNB[0x%x] sends Initial-UE Message[eNB-UE-S1AP-ID(%d)]",
enb->enb_id, ue->enb_ue_s1ap_id);
fsm_create((fsm_t*)&ue->emm_sm,
ue_emm_state_initial, ue_emm_state_final);
ue->emm_sm.ctx = ue;
fsm_init((fsm_t*)&ue->emm_sm, 0);
event_set(&e, EVT_MSG_UE_EMM);
event_set_param1(&e, (c_uintptr_t)ue);
event_set_param2(&e, (c_uintptr_t)sendbuf);
2017-02-13 05:41:20 +00:00
2017-03-06 08:55:50 +00:00
event_send(mme_self()->queue_id, &e);
2017-02-13 05:41:20 +00:00
}