From aabea210f605770d3e8dc0484d99b38c997b5a15 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Mon, 6 Mar 2017 17:55:50 +0900 Subject: [PATCH] update it --- lib/3gpp/3gpp_message.h | 1 + lib/nas/nas_decoder.c | 10 ++- lib/nas/nas_ies.c | 20 ++--- lib/nas/nas_ies.h | 4 +- lib/s6a/freeDiameter/Makefile.am | 2 +- lib/s6a/freeDiameter/extension.h | 2 + src/hss/init.c | 1 - src/mme/context.h | 9 ++- src/mme/enb_s1ap_sm.c | 124 ++++++++++++++++--------------- src/mme/init.c | 15 ++-- src/mme/mme_sm.c | 7 +- src/mme/s1ap_path.c | 20 ++--- src/mme/s1ap_path.h | 2 +- src/mme/s6a_sm.c | 57 ++++++++++++-- src/mme/sm.h | 12 --- src/mme/ue_emm_sm.c | 49 ++++++++++-- 16 files changed, 205 insertions(+), 130 deletions(-) diff --git a/lib/3gpp/3gpp_message.h b/lib/3gpp/3gpp_message.h index ed8706ca0e..01f68cd002 100644 --- a/lib/3gpp/3gpp_message.h +++ b/lib/3gpp/3gpp_message.h @@ -14,6 +14,7 @@ extern "C" { #define MAX_RAND_LEN 16 #define MAX_AUTN_LEN 16 #define MAX_RES_LEN 16 +#define MAX_KASME_LEN 32 #ifdef __cplusplus } diff --git a/lib/nas/nas_decoder.c b/lib/nas/nas_decoder.c index f75e752ef5..9c6f427e55 100644 --- a/lib/nas/nas_decoder.c +++ b/lib/nas/nas_decoder.c @@ -364,14 +364,14 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf) decoded += size; break; case NAS_ATTACH_ACCEPT: - d_error("Not implemented(0x%x)", message->h.message_type); - return CORE_ERROR; + break; case NAS_ATTACH_COMPLETE: size = nas_decode_attach_complete(message, pkbuf); d_assert(size >= CORE_OK, return CORE_ERROR, "decode error"); decoded += size; break; case NAS_ATTACH_REJECT: + break; case NAS_DETACH_REQUEST: case NAS_DETACH_ACCEPT: case NAS_TRACKING_AREA_UPDATE_REQUEST: @@ -382,15 +382,17 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf) case NAS_SERVICE_REJECT: case NAS_GUTI_REALLOCATION_COMMAND: case NAS_GUTI_REALLOCATION_COMPLETE: + d_error("Not implemented(0x%x)", message->h.message_type); + return CORE_ERROR; case NAS_AUTHENTICATION_REQUEST: + break; case NAS_AUTHENTICATION_RESPONSE: size = nas_decode_authentication_response(message, pkbuf); d_assert(size >= CORE_OK, return CORE_ERROR, "decode error"); decoded += size; break; case NAS_AUTHENTICATION_REJECT: - d_error("Not implemented(0x%x)", message->h.message_type); - return CORE_ERROR; + break; case NAS_AUTHENTICATION_FAILURE: size = nas_decode_authentication_failure(message, pkbuf); d_assert(size >= CORE_OK, return CORE_ERROR, "decode error"); diff --git a/lib/nas/nas_ies.c b/lib/nas/nas_ies.c index 4301dabf4f..df8a5bf9a7 100644 --- a/lib/nas/nas_ies.c +++ b/lib/nas/nas_ies.c @@ -247,15 +247,15 @@ c_int32_t nas_encode_authentication_parameter_autn(pkbuf_t *pkbuf, nas_authentication_parameter_autn_t *authentication_parameter_autn) { c_uint16_t size = 0; - nas_authentication_parameter_autn_t *source = pkbuf->payload; - authentication_parameter_autn->length = source->length; + d_assert(authentication_parameter_autn, return -1, "Null param"); + size = authentication_parameter_autn->length + - sizeof(authentication_parameter_autn->length); - + sizeof(authentication_parameter_autn->length); d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1, "pkbuf_header error"); - memcpy(authentication_parameter_autn, pkbuf->payload - size, size); + + memcpy(pkbuf->payload - size, authentication_parameter_autn, size); return size; } @@ -840,15 +840,15 @@ c_int32_t nas_encode_ue_security_capability( pkbuf_t *pkbuf, nas_ue_security_capability_t *ue_security_capability) { c_uint16_t size = 0; - nas_ue_security_capability_t *source = pkbuf->payload; - ue_security_capability->length = source->length; + d_assert(ue_security_capability, return -1, "Null param"); + size = ue_security_capability->length + - sizeof(ue_security_capability->length); - + sizeof(ue_security_capability->length); d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1, "pkbuf_header error"); - memcpy(ue_security_capability, pkbuf->payload - size, size); + + memcpy(pkbuf->payload - size, ue_security_capability, size); return size; } diff --git a/lib/nas/nas_ies.h b/lib/nas/nas_ies.h index 109202c03d..079738c426 100644 --- a/lib/nas/nas_ies.h +++ b/lib/nas/nas_ies.h @@ -240,7 +240,7 @@ CORE_DECLARE(c_int32_t) nas_decode_authentication_failure_parameter( * M LV 17 */ typedef struct _nas_authentication_parameter_autn_t { c_uint8_t length; - c_uint8_t authentication_parameter_autn[MAX_AUTN_LEN]; + c_uint8_t autn[MAX_AUTN_LEN]; } nas_authentication_parameter_autn_t; CORE_DECLARE(c_int32_t) nas_encode_authentication_parameter_autn(pkbuf_t *pkbuf, @@ -250,7 +250,7 @@ CORE_DECLARE(c_int32_t) nas_encode_authentication_parameter_autn(pkbuf_t *pkbuf, * See subclause 10.5.3.1 in 3GPP TS 24.008 [13]. * M V 16 */ typedef struct _nas_authentication_parameter_rand_t { - c_uint8_t authentication_parameter_rand[MAX_RAND_LEN]; + c_uint8_t rand[MAX_RAND_LEN]; } nas_authentication_parameter_rand_t; CORE_DECLARE(c_int32_t) nas_encode_authentication_parameter_rand(pkbuf_t *pkbuf, diff --git a/lib/s6a/freeDiameter/Makefile.am b/lib/s6a/freeDiameter/Makefile.am index 04f7e110e5..cc6fdff089 100644 --- a/lib/s6a/freeDiameter/Makefile.am +++ b/lib/s6a/freeDiameter/Makefile.am @@ -6,7 +6,7 @@ libs6afreeDiameter_la_SOURCES = \ extension.h nodist_libs6afreeDiameter_la_SOURCES = \ - dict_nas_mipv6.c dict_s6a.c + dict_nas_mipv6.c dict_s6a.c libapp_sip.c AM_CPPFLAGS = \ -I$(top_srcdir)/lib/s6a diff --git a/lib/s6a/freeDiameter/extension.h b/lib/s6a/freeDiameter/extension.h index 3eb605a39f..686cd1a910 100644 --- a/lib/s6a/freeDiameter/extension.h +++ b/lib/s6a/freeDiameter/extension.h @@ -65,6 +65,8 @@ int fd_ext_ ## _function(int major, int minor, char * conffile) { \ return (_function)(conffile); \ } +int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp ); + #ifdef __cplusplus } #endif diff --git a/src/hss/init.c b/src/hss/init.c index 182ef2f204..06c3a03ea3 100644 --- a/src/hss/init.c +++ b/src/hss/init.c @@ -11,7 +11,6 @@ #define MAX_SQN_LEN 6 #define MAX_AK_LEN 6 -#define MAX_KASME_LEN 32 static struct disp_hdl *hdl_fb = NULL; /* handler for fallback cb */ static struct disp_hdl *hdl_air = NULL; /* handler for Auth-Info-Request cb */ diff --git a/src/mme/context.h b/src/mme/context.h index a9964d219a..893d53a9ee 100644 --- a/src/mme/context.h +++ b/src/mme/context.h @@ -35,6 +35,9 @@ typedef struct _mme_ctx_t { c_uint16_t enb_s1ap_port; c_uint32_t enb_local_addr; /** Network byte order */ + msgq_id queue_id; + tm_service_t tm_service; + c_uint32_t mme_ue_s1ap_id; plmn_id_t plmn_id; @@ -63,12 +66,16 @@ typedef struct _enb_ctx_t { typedef struct _ue_ctx_t { lnode_t node; /**< A node of list_t */ + ue_emm_sm_t emm_sm; + 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+1]; c_uint8_t imsi_len; - ue_emm_sm_t emm_sm; + c_uint8_t xres[MAX_RES_LEN]; + c_uint8_t xres_len; + c_uint8_t kasme[MAX_KASME_LEN]; rab_list_t rab_list; diff --git a/src/mme/enb_s1ap_sm.c b/src/mme/enb_s1ap_sm.c index 1e0d40b7b1..ee664dcba1 100644 --- a/src/mme/enb_s1ap_sm.c +++ b/src/mme/enb_s1ap_sm.c @@ -10,7 +10,9 @@ #include "context.h" #include "event.h" -static status_t enb_s1ap_handle_s1setuprequest( +static void enb_s1ap_handle_s1_setup_request( + enb_ctx_t *enb, s1ap_message_t *message); +static void enb_s1ap_handle_initial_ue_message( enb_ctx_t *enb, s1ap_message_t *message); void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e) @@ -71,60 +73,12 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e) { case S1ap_ProcedureCode_id_S1Setup : { - enb_s1ap_handle_s1setuprequest(enb, &message); + enb_s1ap_handle_s1_setup_request(enb, &message); break; } case S1ap_ProcedureCode_id_initialUEMessage : { - 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, break, "Null param"); - - nasPdu = &ies->nas_pdu; - d_assert(nasPdu, break, "Null param"); - - sendbuf = pkbuf_alloc(0, nasPdu->size); - d_assert(sendbuf, break, "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, break, "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; - ue->emm_sm.queue_id = s->queue_id; - ue->emm_sm.tm_service = s->tm_service; - - 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); - - event_send(s->queue_id, &e); + enb_s1ap_handle_initial_ue_message(enb, &message); break; } default: @@ -197,7 +151,8 @@ void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e) } } -status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message_t *message) +static void enb_s1ap_handle_s1_setup_request( + enb_ctx_t *enb, s1ap_message_t *message) { char buf[INET_ADDRSTRLEN]; @@ -205,12 +160,12 @@ status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message_t *message) pkbuf_t *sendbuf = NULL; c_uint32_t enb_id; - d_assert(enb, return CORE_ERROR, "Null param"); - d_assert(enb->s1ap_sock, return CORE_ERROR, "Null param"); - d_assert(message, return CORE_ERROR, "Null param"); + d_assert(enb, return, "Null param"); + d_assert(enb->s1ap_sock, return, "Null param"); + d_assert(message, return, "Null param"); ies = &message->s1ap_S1SetupRequestIEs; - d_assert(ies, return CORE_ERROR, "Null param"); + d_assert(ies, return, "Null param"); s1ap_ENB_ID_to_uint32(&ies->global_ENB_ID.eNB_ID, &enb_id); @@ -234,11 +189,58 @@ status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message_t *message) enb->enb_id = enb_id; d_assert(s1ap_build_setup_rsp(&sendbuf) == CORE_OK, - return CORE_ERROR, "build error"); - d_assert(s1ap_send_to_enb(enb, sendbuf) == CORE_OK, - return CORE_ERROR, "send error"); + return, "build error"); + d_assert(s1ap_send_to_enb(enb, sendbuf) == CORE_OK, , "send error"); pkbuf_free(sendbuf); - - return CORE_OK; +} + +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); + + event_send(mme_self()->queue_id, &e); } diff --git a/src/mme/init.c b/src/mme/init.c index 258e024b97..74757cb1d6 100644 --- a/src/mme/init.c +++ b/src/mme/init.c @@ -42,20 +42,19 @@ void mme_terminate(void) void *THREAD_FUNC mme_sm_main(void *data) { event_t event; - msgq_id queue_id; mme_sm_t mme_sm; c_time_t prev_tm, now_tm; int r; memset(&event, 0, sizeof(event_t)); - queue_id = event_create(); - d_assert(queue_id, return NULL, "MME event queue creation failed"); + mme_self()->queue_id = event_create(); + d_assert(mme_self()->queue_id, return NULL, + "MME event queue creation failed"); fsm_create(&mme_sm.fsm, mme_state_initial, mme_state_final); d_assert(&mme_sm.fsm, return NULL, "MME state machine creation failed"); - mme_sm.queue_id = queue_id; - tm_service_init(&mme_sm.tm_service); + tm_service_init(&mme_self()->tm_service); fsm_init((fsm_t*)&mme_sm, 0); @@ -63,7 +62,7 @@ void *THREAD_FUNC mme_sm_main(void *data) while ((!thread_should_stop())) { - r = event_timedrecv(queue_id, &event, EVENT_WAIT_TIMEOUT); + r = event_timedrecv(mme_self()->queue_id, &event, EVENT_WAIT_TIMEOUT); d_assert(r != CORE_ERROR, continue, "While receiving a event message, error occurs"); @@ -73,7 +72,7 @@ void *THREAD_FUNC mme_sm_main(void *data) /* if the gap is over 10 ms, execute preriodic jobs */ if (now_tm - prev_tm > EVENT_WAIT_TIMEOUT) { - event_timer_execute(&mme_sm.tm_service); + event_timer_execute(&mme_self()->tm_service); prev_tm = now_tm; } @@ -89,7 +88,7 @@ void *THREAD_FUNC mme_sm_main(void *data) fsm_final((fsm_t*)&mme_sm, 0); fsm_clear((fsm_t*)&mme_sm); - event_delete(queue_id); + event_delete(mme_self()->queue_id); return NULL; } diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index f037dda1d9..af4930e5d9 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -30,13 +30,12 @@ void mme_state_operational(mme_sm_t *s, event_t *e) sm_trace(1, e); d_assert(s, return, "Null param"); - d_assert(s->queue_id, return, "Null param"); switch (event_get(e)) { case FSM_ENTRY_SIG: { - rv = s1ap_open(s->queue_id); + rv = s1ap_open(); if (rv != CORE_OK) { d_error("Can't establish S1AP path"); @@ -67,7 +66,7 @@ void mme_state_operational(mme_sm_t *s, event_t *e) enb_ctx_t *enb = mme_ctx_enb_find_by_sock(sock); if (!enb) { - rc = net_register_sock(sock, _s1ap_recv_cb, (void*)s->queue_id); + rc = net_register_sock(sock, _s1ap_recv_cb, NULL); d_assert(rc == 0, break, "register _s1ap_recv_cb failed"); enb_ctx_t *enb = mme_ctx_enb_add(); @@ -77,8 +76,6 @@ void mme_state_operational(mme_sm_t *s, event_t *e) fsm_create((fsm_t*)&enb->s1ap_sm, enb_s1ap_state_initial, enb_s1ap_state_final); enb->s1ap_sm.ctx = enb; - enb->s1ap_sm.queue_id = s->queue_id; - enb->s1ap_sm.tm_service = s->tm_service; fsm_init((fsm_t*)&enb->s1ap_sm, 0); } else diff --git a/src/mme/s1ap_path.c b/src/mme/s1ap_path.c index 9324b52398..5c1f752fa0 100644 --- a/src/mme/s1ap_path.c +++ b/src/mme/s1ap_path.c @@ -7,11 +7,12 @@ #include "s1ap_message.h" #include "event.h" +#include "context.h" #include "s1ap_path.h" static int _s1ap_accept_cb(net_sock_t *net_sock, void *data); -status_t s1ap_open(msgq_id queue_id) +status_t s1ap_open(void) { char buf[INET_ADDRSTRLEN]; int rc; @@ -28,7 +29,7 @@ status_t s1ap_open(msgq_id queue_id) } rc = net_register_sock( - mme_self()->enb_s1ap_sock, _s1ap_accept_cb, (void *)queue_id); + mme_self()->enb_s1ap_sock, _s1ap_accept_cb, NULL); if (rc != 0) { d_error("Can't establish S1-ENB path(%d:%s)", @@ -61,10 +62,8 @@ static int _s1ap_accept_cb(net_sock_t *net_sock, void *data) char buf[INET_ADDRSTRLEN]; ssize_t r; net_sock_t *remote_sock; - msgq_id queue_id = (msgq_id)data; d_assert(net_sock, return -1, "Null param"); - d_assert(queue_id, return -1, "Null param"); r = net_accept(&remote_sock, net_sock, 0); if (r > 0) @@ -75,7 +74,7 @@ static int _s1ap_accept_cb(net_sock_t *net_sock, void *data) event_t e; event_set(&e, EVT_LO_ENB_S1AP_ACCEPT); event_set_param1(&e, (c_uintptr_t)remote_sock); - event_send(queue_id, &e); + event_send(mme_self()->queue_id, &e); } else { @@ -85,13 +84,12 @@ static int _s1ap_accept_cb(net_sock_t *net_sock, void *data) return r; } -static status_t s1ap_recv(net_sock_t *net_sock, pkbuf_t *pkbuf, msgq_id queue_id) +static status_t s1ap_recv(net_sock_t *net_sock, pkbuf_t *pkbuf) { event_t e; d_assert(net_sock, return CORE_ERROR, "Null param"); d_assert(pkbuf, return CORE_ERROR, "Null param"); - d_assert(queue_id, return -1, "Null param"); d_trace(1, "S1AP_PDU is received from eNB-Inf\n"); d_trace_hex(1, pkbuf->payload, pkbuf->len); @@ -100,7 +98,7 @@ static status_t s1ap_recv(net_sock_t *net_sock, pkbuf_t *pkbuf, msgq_id queue_id event_set_param1(&e, (c_uintptr_t)net_sock); event_set_param2(&e, (c_uintptr_t)pkbuf); - return event_send(queue_id, &e); + return event_send(mme_self()->queue_id, &e); } int _s1ap_recv_cb(net_sock_t *net_sock, void *data) @@ -108,10 +106,8 @@ int _s1ap_recv_cb(net_sock_t *net_sock, void *data) status_t rv; pkbuf_t *pkbuf; ssize_t r; - msgq_id queue_id = (msgq_id)data; d_assert(net_sock, return -1, "Null param"); - d_assert(queue_id, return -1, "Null param"); pkbuf = pkbuf_alloc(0, MESSAGE_SDU_SIZE); d_assert(pkbuf, return -1, "Can't allocate pkbufuf"); @@ -146,7 +142,7 @@ int _s1ap_recv_cb(net_sock_t *net_sock, void *data) event_set(&e, EVT_LO_ENB_S1AP_CONNREFUSED); event_set_param1(&e, (c_uintptr_t)net_sock); - event_send(queue_id, &e); + event_send(mme_self()->queue_id, &e); return -1; } @@ -154,7 +150,7 @@ int _s1ap_recv_cb(net_sock_t *net_sock, void *data) { pkbuf->len = r; - rv = s1ap_recv(net_sock, pkbuf, queue_id); + rv = s1ap_recv(net_sock, pkbuf); if (rv == CORE_ERROR) { pkbuf_free(pkbuf); diff --git a/src/mme/s1ap_path.h b/src/mme/s1ap_path.h index 17e0d52a88..ac56af98c3 100644 --- a/src/mme/s1ap_path.h +++ b/src/mme/s1ap_path.h @@ -11,7 +11,7 @@ extern "C" { #endif /* __cplusplus */ -CORE_DECLARE(status_t) s1ap_open(msgq_id queue_id); +CORE_DECLARE(status_t) s1ap_open(); CORE_DECLARE(status_t) s1ap_close(); CORE_DECLARE(status_t) s1ap_send(net_sock_t *s, pkbuf_t *pkb); diff --git a/src/mme/s6a_sm.c b/src/mme/s6a_sm.c index a65bd2cf2a..5abf464eac 100644 --- a/src/mme/s6a_sm.c +++ b/src/mme/s6a_sm.c @@ -3,6 +3,8 @@ #include "core_debug.h" #include "core_pool.h" +#include "context.h" +#include "nas_message.h" #include "s6a_lib.h" #include "s6a_sm.h" @@ -126,11 +128,18 @@ static void s6a_aia_cb(void *data, struct msg **msg) struct timespec ts; struct session *sess; struct avp *avp; + struct avp *avpch1, *avpch2; struct avp_hdr *hdr; unsigned long dur; int error = 0; int new; + ue_ctx_t *ue = NULL; + nas_message_t message; + pkbuf_t *sendbuf = NULL; + event_t e; + nas_authentication_request_t *authentication_request = + &message.emm.authentication_request; CHECK_SYS_DO(clock_gettime(CLOCK_REALTIME, &ts), return); @@ -155,16 +164,50 @@ static void s6a_aia_cb(void *data, struct msg **msg) goto out; } - /* Value of Origin-Host */ - d_assert(fd_msg_search_avp(*msg, s6a_origin_host, &avp) == 0 && avp, + memset(&message, 0, sizeof(message)); + message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + message.h.message_type = NAS_AUTHENTICATION_REQUEST; + + d_assert(fd_msg_search_avp(*msg, s6a_authentication_info, &avp) == 0 && avp, error++; goto out,); d_assert(fd_msg_avp_hdr(avp, &hdr) == 0 && hdr, error++; goto out,); - - /* Value of Origin-Realm */ - d_assert(fd_msg_search_avp(*msg, s6a_origin_realm, &avp) == 0 && avp, + d_assert(fd_avp_search_avp(avp, s6a_e_utran_vector, &avpch1) == 0 && avp, error++; goto out,); - d_assert(fd_msg_avp_hdr(avp, &hdr) == 0 && hdr, error++; goto out,); - + d_assert(fd_msg_avp_hdr(avpch1, &hdr) == 0 && hdr, error++; goto out,); + + d_assert(fd_avp_search_avp(avpch1, s6a_xres, &avpch2) == 0 && avp, + error++; goto out,); + d_assert(fd_msg_avp_hdr(avpch2, &hdr) == 0 && hdr, error++; goto out,); + memcpy(ue->xres, hdr->avp_value->os.data, hdr->avp_value->os.len); + ue->xres_len = hdr->avp_value->os.len; + + d_assert(fd_avp_search_avp(avpch1, s6a_kasme, &avpch2) == 0 && avp, + error++; goto out,); + d_assert(fd_msg_avp_hdr(avpch2, &hdr) == 0 && hdr, error++; goto out,); + memcpy(ue->kasme, hdr->avp_value->os.data, hdr->avp_value->os.len); + + d_assert(fd_avp_search_avp(avpch1, s6a_rand, &avpch2) == 0 && avp, + error++; goto out,); + d_assert(fd_msg_avp_hdr(avpch2, &hdr) == 0 && hdr, error++; goto out,); + memcpy(authentication_request->authentication_parameter_rand.rand, + hdr->avp_value->os.data, hdr->avp_value->os.len); + + d_assert(fd_avp_search_avp(avpch1, s6a_autn, &avpch2) == 0 && avp, + error++; goto out,); + d_assert(fd_msg_avp_hdr(avpch2, &hdr) == 0 && hdr, error++; goto out,); + authentication_request->authentication_parameter_autn.length = + hdr->avp_value->os.len; + memcpy(authentication_request->authentication_parameter_autn.autn, + hdr->avp_value->os.data, hdr->avp_value->os.len); + + d_assert(nas_encode_pdu(&sendbuf, &message) == CORE_OK && sendbuf, + error++; goto out,); + + event_set(&e, EVT_MSG_UE_EMM); + event_set_param1(&e, (c_uintptr_t)ue); + event_set_param2(&e, (c_uintptr_t)sendbuf); + + event_send(mme_self()->queue_id, &e); out: /* Free the message */ d_assert(pthread_mutex_lock(&s6a_config->stats_lock) == 0,,); diff --git a/src/mme/sm.h b/src/mme/sm.h index d221459fb4..651cdcf644 100644 --- a/src/mme/sm.h +++ b/src/mme/sm.h @@ -11,12 +11,8 @@ extern "C" { #endif /* __cplusplus */ typedef struct _mme_sm_t { - fsm_t fsm; void *ctx; - msgq_id queue_id; - tm_service_t tm_service; - } mme_sm_t; void mme_state_initial(mme_sm_t *s, event_t *e); @@ -25,12 +21,8 @@ void mme_state_operational(mme_sm_t *s, event_t *e); void mme_state_exception(mme_sm_t *s, event_t *e); typedef struct _enb_s1ap_sm_t { - fsm_t fsm; void *ctx; - msgq_id queue_id; - tm_service_t tm_service; - } enb_s1ap_sm_t; void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e); @@ -39,12 +31,8 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e); void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e); typedef struct _ue_emm_sm_t { - fsm_t fsm; void *ctx; - msgq_id queue_id; - tm_service_t tm_service; - } ue_emm_sm_t; void ue_emm_state_initial(ue_emm_sm_t *s, event_t *e); diff --git a/src/mme/ue_emm_sm.c b/src/mme/ue_emm_sm.c index bbc2a9d0e3..868a8d92f9 100644 --- a/src/mme/ue_emm_sm.c +++ b/src/mme/ue_emm_sm.c @@ -2,15 +2,20 @@ #include "core_debug.h" +#include "s1ap_message.h" #include "nas_message.h" -#include "nas_conv.h" -#include "s6a_sm.h" #include "sm.h" #include "context.h" #include "event.h" -static void ue_emm_handle_attachrequest(ue_ctx_t *ue, nas_message_t *message); +#include "nas_conv.h" +#include "s6a_sm.h" +#include "s1ap_path.h" + +static void ue_emm_handle_attach_request(ue_ctx_t *ue, nas_message_t *message); +static void ue_emm_handle_authentication_request( + ue_ctx_t *ue, pkbuf_t *recvbuf); void ue_emm_state_initial(ue_emm_sm_t *s, event_t *e) { @@ -66,7 +71,12 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e) { case NAS_ATTACH_REQUEST: { - ue_emm_handle_attachrequest(ue, &message); + ue_emm_handle_attach_request(ue, &message); + break; + } + case NAS_AUTHENTICATION_REQUEST: + { + ue_emm_handle_authentication_request(ue, recvbuf); break; } default: @@ -113,7 +123,7 @@ void ue_emm_state_exception(ue_emm_sm_t *s, event_t *e) } } -static void ue_emm_handle_attachrequest(ue_ctx_t *ue, nas_message_t *message) +static void ue_emm_handle_attach_request(ue_ctx_t *ue, nas_message_t *message) { nas_attach_request_t *attach_request = &message->emm.attach_request; nas_eps_mobile_identity_t *eps_mobile_identity = @@ -152,3 +162,32 @@ static void ue_emm_handle_attachrequest(ue_ctx_t *ue, nas_message_t *message) } } } + +static void ue_emm_handle_authentication_request(ue_ctx_t *ue, pkbuf_t *recvbuf) +{ + 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 = recvbuf->len; + nasPdu->buf = core_calloc(nasPdu->size, sizeof(c_uint8_t)); + memcpy(nasPdu->buf, recvbuf->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(encoded >= 0, , "encode failed"); + + d_assert(s1ap_send_to_enb(ue->enb, sendbuf) == CORE_OK, , "send error"); + pkbuf_free(recvbuf); +}