update it
This commit is contained in:
parent
44a55c5a1e
commit
aabea210f6
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,,);
|
||||
|
|
12
src/mme/sm.h
12
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue