Commit 0aec555a authored by Cedric Roux's avatar Cedric Roux

- Some minor improvements when NAS is enabled

- Some formatting of header files

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4561 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 569d1c5f
//WARNING: Do not include this header directly. Use intertask_interface.h instead. //WARNING: Do not include this header directly. Use intertask_interface.h instead.
//MESSAGE_DEF(S1AP_SCTP_NEW_MESSAGE_IND, MESSAGE_PRIORITY_MED, S1apSctpNewMessageInd, s1apSctpNewMessageInd)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
MESSAGE_DEF(NAS_PAGING_IND, MESSAGE_PRIORITY_MED, nas_paging_ind_t, nas_paging_ind) MESSAGE_DEF(NAS_PAGING_IND, MESSAGE_PRIORITY_MED, nas_paging_ind_t, nas_paging_ind)
MESSAGE_DEF(NAS_CONNECTION_ESTABLISHMENT_IND, MESSAGE_PRIORITY_MED, nas_conn_est_ind_t, nas_conn_est_ind) MESSAGE_DEF(NAS_CONNECTION_ESTABLISHMENT_IND, MESSAGE_PRIORITY_MED, nas_conn_est_ind_t, nas_conn_est_ind)
MESSAGE_DEF(NAS_CONNECTION_ESTABLISHMENT_RSP, MESSAGE_PRIORITY_MED, nas_conn_est_rsp_t, nas_conn_est_rsp) MESSAGE_DEF(NAS_CONNECTION_ESTABLISHMENT_CNF, MESSAGE_PRIORITY_MED, nas_conn_est_cnf_t, nas_conn_est_cnf)
MESSAGE_DEF(NAS_CONNECTION_RELEASE_IND, MESSAGE_PRIORITY_MED, nas_conn_rel_ind_t, nas_conn_rel_ind) MESSAGE_DEF(NAS_CONNECTION_RELEASE_IND, MESSAGE_PRIORITY_MED, nas_conn_rel_ind_t, nas_conn_rel_ind)
MESSAGE_DEF(NAS_UPLINK_DATA_IND, MESSAGE_PRIORITY_MED, nas_ul_data_ind_t, nas_ul_data_ind) MESSAGE_DEF(NAS_UPLINK_DATA_IND, MESSAGE_PRIORITY_MED, nas_ul_data_ind_t, nas_ul_data_ind)
MESSAGE_DEF(NAS_DOWNLINK_DATA_REQ, MESSAGE_PRIORITY_MED, nas_dl_data_req_t, nas_dl_data_req) MESSAGE_DEF(NAS_DOWNLINK_DATA_REQ, MESSAGE_PRIORITY_MED, nas_dl_data_req_t, nas_dl_data_req)
...@@ -11,7 +11,13 @@ MESSAGE_DEF(NAS_NON_DELIVERY_IND, MESSAGE_PRIORITY_MED, nas_non_del_ ...@@ -11,7 +11,13 @@ MESSAGE_DEF(NAS_NON_DELIVERY_IND, MESSAGE_PRIORITY_MED, nas_non_del_
MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_REQ, MESSAGE_PRIORITY_MED, nas_rab_est_req_t, nas_rab_est_req) MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_REQ, MESSAGE_PRIORITY_MED, nas_rab_est_req_t, nas_rab_est_req)
MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_RESP, MESSAGE_PRIORITY_MED, nas_rab_est_rsp_t, nas_rab_est_rsp) MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_RESP, MESSAGE_PRIORITY_MED, nas_rab_est_rsp_t, nas_rab_est_rsp)
MESSAGE_DEF(NAS_RAB_RELEASE_REQ, MESSAGE_PRIORITY_MED, nas_rab_rel_req_t, nas_rab_rel_req) MESSAGE_DEF(NAS_RAB_RELEASE_REQ, MESSAGE_PRIORITY_MED, nas_rab_rel_req_t, nas_rab_rel_req)
MESSAGE_DEF(NAS_ATTACH_REQ, MESSAGE_PRIORITY_MED, nas_attach_req_t, nas_attach_req)
MESSAGE_DEF(NAS_ATTACH_ACCEPT, MESSAGE_PRIORITY_MED, nas_attach_accept_t, nas_attach_accept)
MESSAGE_DEF(NAS_AUTHENTICATION_REQ, MESSAGE_PRIORITY_MED, nas_auth_req_t, nas_auth_req) MESSAGE_DEF(NAS_AUTHENTICATION_REQ, MESSAGE_PRIORITY_MED, nas_auth_req_t, nas_auth_req)
MESSAGE_DEF(NAS_AUTHENTICATION_RESP, MESSAGE_PRIORITY_MED, nas_auth_resp_t, nas_auth_resp) MESSAGE_DEF(NAS_AUTHENTICATION_RESP, MESSAGE_PRIORITY_MED, nas_auth_resp_t, nas_auth_resp)
/* MME app -> NAS layer messages */
MESSAGE_DEF(NAS_BEARER_PARAM, MESSAGE_PRIORITY_MED, nas_bearer_param_t, nas_bearer_param)
#if defined(DISABLE_USE_NAS)
MESSAGE_DEF(NAS_ATTACH_REQ, MESSAGE_PRIORITY_MED, nas_attach_req_t, nas_attach_req)
MESSAGE_DEF(NAS_ATTACH_ACCEPT, MESSAGE_PRIORITY_MED, nas_attach_accept_t, nas_attach_accept)
#endif
\ No newline at end of file
...@@ -3,9 +3,11 @@ ...@@ -3,9 +3,11 @@
#ifndef NAS_MESSAGES_TYPES_H_ #ifndef NAS_MESSAGES_TYPES_H_
#define NAS_MESSAGES_TYPES_H_ #define NAS_MESSAGES_TYPES_H_
#define NAS_UL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_ind #define NAS_UL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_ind
#define NAS_DL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_req #define NAS_DL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_req
#define NAS_DL_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_cnf #define NAS_DL_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_cnf
#define NAS_CONN_EST_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_est_cnf
#define NAS_BEARER_PARAM(mSGpTR) (mSGpTR)->ittiMsg.nas_bearer_param
typedef struct { typedef struct {
...@@ -20,9 +22,38 @@ typedef struct { ...@@ -20,9 +22,38 @@ typedef struct {
s1ap_initial_ue_message_t transparent; s1ap_initial_ue_message_t transparent;
} nas_conn_est_ind_t; } nas_conn_est_ind_t;
typedef struct { typedef struct nas_conn_est_cnf_s {
uint32_t ue_id;
} nas_conn_est_rsp_t;
nas_establish_cnf_t nas_establish_cnf;
/* Transparent message from MME_APP to S1AP */
s1ap_initial_ctxt_setup_req_t transparent;
} nas_conn_est_cnf_t;
typedef struct nas_bearer_param_s {
unsigned eNB_ue_s1ap_id:24;
uint32_t mme_ue_s1ap_id;
/* Key eNB */
uint8_t keNB[32];
ambr_t ambr;
ambr_t apn_ambr;
/* EPS bearer ID */
unsigned ebi:4;
/* QoS */
qci_t qci;
priority_level_t prio_level;
pre_emp_vulnerability_t pre_emp_vulnerability;
pre_emp_capability_t pre_emp_capability;
/* S-GW TEID for user-plane */
uint32_t teid;
/* S-GW IP address for User-Plane */
ip_address_t s_gw_address;
} nas_bearer_param_t;
typedef struct { typedef struct {
...@@ -72,9 +103,4 @@ typedef struct { ...@@ -72,9 +103,4 @@ typedef struct {
char imsi[16]; char imsi[16];
} nas_auth_resp_t; } nas_auth_resp_t;
typedef struct {
s1ap_initial_ctxt_setup_req_t transparent;
} nas_attach_accept_t;
#endif /* NAS_MESSAGES_TYPES_H_ */ #endif /* NAS_MESSAGES_TYPES_H_ */
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind #define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind
#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req #define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req
#define SCTP_INIT(mSGpTR) (mSGpTR)->ittiMsg.sctpInit #define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctpInit
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association #define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
typedef struct sctp_data_req_s { typedef struct sctp_data_req_s {
......
...@@ -175,6 +175,7 @@ int mme_app_handle_authentication_info_answer(s6a_auth_info_ans_t *s6a_auth_info ...@@ -175,6 +175,7 @@ int mme_app_handle_authentication_info_answer(s6a_auth_info_ans_t *s6a_auth_info
return itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p); return itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p);
} }
#if defined(DISABLE_USE_NAS)
int mme_app_handle_attach_req(nas_attach_req_t *attach_req_p) int mme_app_handle_attach_req(nas_attach_req_t *attach_req_p)
{ {
/* An attach request has been received from NAS layer. /* An attach request has been received from NAS layer.
...@@ -283,3 +284,4 @@ request_auth: ...@@ -283,3 +284,4 @@ request_auth:
} }
return 0; return 0;
} }
#endif
...@@ -316,32 +316,29 @@ int mme_app_handle_create_sess_resp(SgwCreateSessionResponse *create_sess_resp_p ...@@ -316,32 +316,29 @@ int mme_app_handle_create_sess_resp(SgwCreateSessionResponse *create_sess_resp_p
{ {
uint8_t *keNB; uint8_t *keNB;
MessageDef *message_p; MessageDef *message_p;
nas_attach_accept_t *attach_accept_p;
message_p = itti_alloc_new_message(TASK_MME_APP, NAS_ATTACH_ACCEPT); message_p = itti_alloc_new_message(TASK_MME_APP, NAS_BEARER_PARAM);
attach_accept_p = &message_p->ittiMsg.nas_attach_accept;
derive_keNB(ue_context_p->vector_in_use->kasme, 156, &keNB); derive_keNB(ue_context_p->vector_in_use->kasme, 156, &keNB);
memcpy(attach_accept_p->transparent.keNB, keNB, 32); memcpy(NAS_BEARER_PARAM(message_p).keNB, keNB, 32);
free(keNB); free(keNB);
attach_accept_p->transparent.eNB_ue_s1ap_id = ue_context_p->eNB_ue_s1ap_id; NAS_BEARER_PARAM(message_p).eNB_ue_s1ap_id = ue_context_p->eNB_ue_s1ap_id;
attach_accept_p->transparent.mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id; NAS_BEARER_PARAM(message_p).mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
attach_accept_p->transparent.ebi = bearer_id; NAS_BEARER_PARAM(message_p).ebi = bearer_id;
attach_accept_p->transparent.qci = current_bearer_p->qci; NAS_BEARER_PARAM(message_p).qci = current_bearer_p->qci;
attach_accept_p->transparent.prio_level = current_bearer_p->prio_level; NAS_BEARER_PARAM(message_p).prio_level = current_bearer_p->prio_level;
attach_accept_p->transparent.pre_emp_vulnerability = current_bearer_p->pre_emp_vulnerability; NAS_BEARER_PARAM(message_p).pre_emp_vulnerability = current_bearer_p->pre_emp_vulnerability;
attach_accept_p->transparent.pre_emp_capability = current_bearer_p->pre_emp_capability; NAS_BEARER_PARAM(message_p).pre_emp_capability = current_bearer_p->pre_emp_capability;
attach_accept_p->transparent.teid = current_bearer_p->s_gw_teid; NAS_BEARER_PARAM(message_p).teid = current_bearer_p->s_gw_teid;
memcpy(&attach_accept_p->transparent.s_gw_address, memcpy(&NAS_BEARER_PARAM(message_p).s_gw_address,
&current_bearer_p->s_gw_address, sizeof(ip_address_t)); &current_bearer_p->s_gw_address, sizeof(ip_address_t));
memcpy(&attach_accept_p->transparent.ambr, &ue_context_p->subscribed_ambr, memcpy(&NAS_BEARER_PARAM(message_p).ambr, &ue_context_p->subscribed_ambr,
sizeof(ambr_t)); sizeof(ambr_t));
return itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p); return itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p);
......
...@@ -57,7 +57,9 @@ extern mme_app_desc_t mme_app_desc; ...@@ -57,7 +57,9 @@ extern mme_app_desc_t mme_app_desc;
int mme_app_create_bearer(s6a_update_location_ans_t *ula_p); int mme_app_create_bearer(s6a_update_location_ans_t *ula_p);
#if defined(DISABLE_USE_NAS)
int mme_app_handle_attach_req(nas_attach_req_t *attach_req_p); int mme_app_handle_attach_req(nas_attach_req_t *attach_req_p);
#endif
int mme_app_handle_create_sess_resp(SgwCreateSessionResponse *create_sess_resp_p); int mme_app_handle_create_sess_resp(SgwCreateSessionResponse *create_sess_resp_p);
......
...@@ -68,19 +68,26 @@ void *mme_app_thread(void *args) ...@@ -68,19 +68,26 @@ void *mme_app_thread(void *args)
*/ */
mme_app_handle_authentication_info_answer(&received_message_p->ittiMsg.s6a_auth_info_ans); mme_app_handle_authentication_info_answer(&received_message_p->ittiMsg.s6a_auth_info_ans);
} break; } break;
case S6A_UPDATE_LOCATION_ANS: { case S6A_UPDATE_LOCATION_ANS: {
/* We received the update location answer message from HSS -> Handle it */ /* We received the update location answer message from HSS -> Handle it */
mme_app_create_bearer(&received_message_p->ittiMsg.s6a_update_location_ans); mme_app_create_bearer(&received_message_p->ittiMsg.s6a_update_location_ans);
} break; } break;
case SGW_CREATE_SESSION_RESPONSE: { case SGW_CREATE_SESSION_RESPONSE: {
mme_app_handle_create_sess_resp(&received_message_p->ittiMsg.sgwCreateSessionResponse); mme_app_handle_create_sess_resp(&received_message_p->ittiMsg.sgwCreateSessionResponse);
} break; } break;
case NAS_AUTHENTICATION_RESP: { case NAS_AUTHENTICATION_RESP: {
mme_app_handle_nas_auth_resp(&received_message_p->ittiMsg.nas_auth_resp); mme_app_handle_nas_auth_resp(&received_message_p->ittiMsg.nas_auth_resp);
} break; } break;
#if defined(DISABLE_USE_NAS)
case NAS_ATTACH_REQ: { case NAS_ATTACH_REQ: {
mme_app_handle_attach_req(&received_message_p->ittiMsg.nas_attach_req); mme_app_handle_attach_req(&received_message_p->ittiMsg.nas_attach_req);
} break; } break;
#endif
case TIMER_HAS_EXPIRED: { case TIMER_HAS_EXPIRED: {
/* Check if it is the statistic timer */ /* Check if it is the statistic timer */
if (received_message_p->ittiMsg.timer_has_expired.timer_id == if (received_message_p->ittiMsg.timer_has_expired.timer_id ==
......
/***************************************************************************** /*****************************************************************************
Eurecom OpenAirInterface 3 Eurecom OpenAirInterface 3
Copyright(c) 2012 Eurecom Copyright(c) 2012 Eurecom
Source nas_message.h Source nas_message.h
Version 0.1 Version 0.1
Date 2012/26/09 Date 2012/26/09
Product NAS stack Product NAS stack
Subsystem Application Programming Interface Subsystem Application Programming Interface
Author Frederic Maurel Author Frederic Maurel
Description Defines the layer 3 messages supported by the NAS sublayer Description Defines the layer 3 messages supported by the NAS sublayer
protocol and functions used to encode and decode protocol and functions used to encode and decode
*****************************************************************************/ *****************************************************************************/
#ifndef __NAS_MESSAGE_H__ #ifndef __NAS_MESSAGE_H__
...@@ -29,7 +29,7 @@ Description Defines the layer 3 messages supported by the NAS sublayer ...@@ -29,7 +29,7 @@ Description Defines the layer 3 messages supported by the NAS sublayer
/********************* G L O B A L C O N S T A N T S *******************/ /********************* G L O B A L C O N S T A N T S *******************/
/****************************************************************************/ /****************************************************************************/
#define NAS_MESSAGE_SECURITY_HEADER_SIZE 6 #define NAS_MESSAGE_SECURITY_HEADER_SIZE 6
/****************************************************************************/ /****************************************************************************/
/************************ G L O B A L T Y P E S ************************/ /************************ G L O B A L T Y P E S ************************/
...@@ -51,8 +51,8 @@ typedef struct { ...@@ -51,8 +51,8 @@ typedef struct {
/* Structure of plain NAS message */ /* Structure of plain NAS message */
typedef union { typedef union {
EMM_msg emm; /* EPS Mobility Management messages */ EMM_msg emm; /* EPS Mobility Management messages */
ESM_msg esm; /* EPS Session Management messages */ ESM_msg esm; /* EPS Session Management messages */
} nas_message_plain_t; } nas_message_plain_t;
/* Structure of security protected NAS message */ /* Structure of security protected NAS message */
...@@ -78,12 +78,14 @@ typedef union { ...@@ -78,12 +78,14 @@ typedef union {
/****************** E X P O R T E D F U N C T I O N S ******************/ /****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/ /****************************************************************************/
int nas_message_encrypt(const char* inbuf, char* outbuf, const nas_message_security_header_t* header, int length); int nas_message_encrypt(const char *inbuf, char *outbuf,
const nas_message_security_header_t *header, int length);
int nas_message_decrypt(const char* inbuf, char* outbuf, nas_message_security_header_t* header, int length); int nas_message_decrypt(const char *inbuf, char *outbuf,
nas_message_security_header_t *header, int length);
int nas_message_decode(const char* buffer, nas_message_t* msg, int length); int nas_message_decode(const char *buffer, nas_message_t *msg, int length);
int nas_message_encode(char* buffer, const nas_message_t* msg, int length); int nas_message_encode(char *buffer, const nas_message_t *msg, int length);
#endif /* __NAS_MESSAGE_H__*/ #endif /* __NAS_MESSAGE_H__*/
/***************************************************************************** /*****************************************************************************
Eurecom OpenAirInterface 3 Eurecom OpenAirInterface 3
Copyright(c) 2012 Eurecom Copyright(c) 2012 Eurecom
Source emm_msg.c Source emm_msg.c
Version 0.1 Version 0.1
Date 2012/09/27 Date 2012/09/27
Product NAS stack Product NAS stack
Subsystem EPS Mobility Management Subsystem EPS Mobility Management
Author Frederic Maurel, Sebastien Roux Author Frederic Maurel, Sebastien Roux
Description Defines EPS Mobility Management messages Description Defines EPS Mobility Management messages
*****************************************************************************/ *****************************************************************************/
...@@ -33,8 +33,10 @@ Description Defines EPS Mobility Management messages ...@@ -33,8 +33,10 @@ Description Defines EPS Mobility Management messages
/******************* L O C A L D E F I N I T I O N S *******************/ /******************* L O C A L D E F I N I T I O N S *******************/
/****************************************************************************/ /****************************************************************************/
static int _emm_msg_decode_header(emm_msg_header_t *header, const uint8_t *buffer, uint32_t len); static int _emm_msg_decode_header(emm_msg_header_t *header,
static int _emm_msg_encode_header(const emm_msg_header_t *header, uint8_t *buffer, uint32_t len); const uint8_t *buffer, uint32_t len);
static int _emm_msg_encode_header(const emm_msg_header_t *header,
uint8_t *buffer, uint32_t len);
/****************************************************************************/ /****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/ /****************** E X P O R T E D F U N C T I O N S ******************/
...@@ -42,20 +44,20 @@ static int _emm_msg_encode_header(const emm_msg_header_t *header, uint8_t *buffe ...@@ -42,20 +44,20 @@ static int _emm_msg_encode_header(const emm_msg_header_t *header, uint8_t *buffe
/**************************************************************************** /****************************************************************************
** ** ** **
** Name: emm_msg_decode() ** ** Name: emm_msg_decode() **
** ** ** **
** Description: Decode EPS Mobility Management messages ** ** Description: Decode EPS Mobility Management messages **
** ** ** **
** Inputs: buffer: Pointer to the buffer containing the EMM ** ** Inputs: buffer: Pointer to the buffer containing the EMM **
** message data ** ** message data **
** len: Number of bytes that should be decoded ** ** len: Number of bytes that should be decoded **
** Others: None ** ** Others: None **
** ** ** **
** Outputs: msg: The EMM message structure to be filled ** ** Outputs: msg: The EMM message structure to be filled **
** Return: The number of bytes in the buffer if data ** ** Return: The number of bytes in the buffer if data **
** have been successfully decoded; ** ** have been successfully decoded; **
** A negative error code otherwise. ** ** A negative error code otherwise. **
** Others: None ** ** Others: None **
** ** ** **
***************************************************************************/ ***************************************************************************/
int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
...@@ -78,19 +80,21 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -78,19 +80,21 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
LOG_TRACE(INFO, "EMM-MSG - Message Type %02x", msg->header.message_type); LOG_TRACE(INFO, "EMM-MSG - Message Type %02x", msg->header.message_type);
switch(msg->header.message_type) switch(msg->header.message_type) {
{
case EMM_INFORMATION: case EMM_INFORMATION:
decode_result = decode_emm_information(&msg->emm_information, buffer, len); decode_result = decode_emm_information(&msg->emm_information, buffer, len);
break; break;
case UPLINK_NAS_TRANSPORT: case UPLINK_NAS_TRANSPORT:
decode_result = decode_uplink_nas_transport(&msg->uplink_nas_transport, buffer, len); decode_result = decode_uplink_nas_transport(&msg->uplink_nas_transport, buffer,
len);
break; break;
case AUTHENTICATION_REJECT: case AUTHENTICATION_REJECT:
decode_result = decode_authentication_reject(&msg->authentication_reject, buffer, len); decode_result = decode_authentication_reject(&msg->authentication_reject,
buffer, len);
break; break;
case AUTHENTICATION_FAILURE: case AUTHENTICATION_FAILURE:
decode_result = decode_authentication_failure(&msg->authentication_failure, buffer, len); decode_result = decode_authentication_failure(&msg->authentication_failure,
buffer, len);
break; break;
case DETACH_ACCEPT: case DETACH_ACCEPT:
decode_result = decode_detach_accept(&msg->detach_accept, buffer, len); decode_result = decode_detach_accept(&msg->detach_accept, buffer, len);
...@@ -99,10 +103,12 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -99,10 +103,12 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
decode_result = decode_service_reject(&msg->service_reject, buffer, len); decode_result = decode_service_reject(&msg->service_reject, buffer, len);
break; break;
case AUTHENTICATION_REQUEST: case AUTHENTICATION_REQUEST:
decode_result = decode_authentication_request(&msg->authentication_request, buffer, len); decode_result = decode_authentication_request(&msg->authentication_request,
buffer, len);
break; break;
case TRACKING_AREA_UPDATE_REQUEST: case TRACKING_AREA_UPDATE_REQUEST:
decode_result = decode_tracking_area_update_request(&msg->tracking_area_update_request, buffer, len); decode_result = decode_tracking_area_update_request(
&msg->tracking_area_update_request, buffer, len);
break; break;
case ATTACH_REQUEST: case ATTACH_REQUEST:
decode_result = decode_attach_request(&msg->attach_request, buffer, len); decode_result = decode_attach_request(&msg->attach_request, buffer, len);
...@@ -117,19 +123,23 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -117,19 +123,23 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
decode_result = decode_identity_request(&msg->identity_request, buffer, len); decode_result = decode_identity_request(&msg->identity_request, buffer, len);
break; break;
case GUTI_REALLOCATION_COMMAND: case GUTI_REALLOCATION_COMMAND:
decode_result = decode_guti_reallocation_command(&msg->guti_reallocation_command, buffer, len); decode_result = decode_guti_reallocation_command(&msg->guti_reallocation_command,
buffer, len);
break; break;
case TRACKING_AREA_UPDATE_REJECT: case TRACKING_AREA_UPDATE_REJECT:
decode_result = decode_tracking_area_update_reject(&msg->tracking_area_update_reject, buffer, len); decode_result = decode_tracking_area_update_reject(
&msg->tracking_area_update_reject, buffer, len);
break; break;
case ATTACH_ACCEPT: case ATTACH_ACCEPT:
decode_result = decode_attach_accept(&msg->attach_accept, buffer, len); decode_result = decode_attach_accept(&msg->attach_accept, buffer, len);
break; break;
case SECURITY_MODE_COMPLETE: case SECURITY_MODE_COMPLETE:
decode_result = decode_security_mode_complete(&msg->security_mode_complete, buffer, len); decode_result = decode_security_mode_complete(&msg->security_mode_complete,
buffer, len);
break; break;
case TRACKING_AREA_UPDATE_ACCEPT: case TRACKING_AREA_UPDATE_ACCEPT:
decode_result = decode_tracking_area_update_accept(&msg->tracking_area_update_accept, buffer, len); decode_result = decode_tracking_area_update_accept(
&msg->tracking_area_update_accept, buffer, len);
break; break;
case ATTACH_REJECT: case ATTACH_REJECT:
decode_result = decode_attach_reject(&msg->attach_reject, buffer, len); decode_result = decode_attach_reject(&msg->attach_reject, buffer, len);
...@@ -138,62 +148,70 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -138,62 +148,70 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
decode_result = decode_attach_complete(&msg->attach_complete, buffer, len); decode_result = decode_attach_complete(&msg->attach_complete, buffer, len);
break; break;
case TRACKING_AREA_UPDATE_COMPLETE: case TRACKING_AREA_UPDATE_COMPLETE:
decode_result = decode_tracking_area_update_complete(&msg->tracking_area_update_complete, buffer, len); decode_result = decode_tracking_area_update_complete(
&msg->tracking_area_update_complete, buffer, len);
break; break;
case CS_SERVICE_NOTIFICATION: case CS_SERVICE_NOTIFICATION:
decode_result = decode_cs_service_notification(&msg->cs_service_notification, buffer, len); decode_result = decode_cs_service_notification(&msg->cs_service_notification,
buffer, len);
break; break;
case SECURITY_MODE_REJECT: case SECURITY_MODE_REJECT:
decode_result = decode_security_mode_reject(&msg->security_mode_reject, buffer, len); decode_result = decode_security_mode_reject(&msg->security_mode_reject, buffer,
len);
break; break;
case DETACH_REQUEST: case DETACH_REQUEST:
decode_result = decode_detach_request(&msg->detach_request, buffer, len); decode_result = decode_detach_request(&msg->detach_request, buffer, len);
break; break;
case GUTI_REALLOCATION_COMPLETE: case GUTI_REALLOCATION_COMPLETE:
decode_result = decode_guti_reallocation_complete(&msg->guti_reallocation_complete, buffer, len); decode_result = decode_guti_reallocation_complete(
&msg->guti_reallocation_complete, buffer, len);
break; break;
case SECURITY_MODE_COMMAND: case SECURITY_MODE_COMMAND:
decode_result = decode_security_mode_command(&msg->security_mode_command, buffer, len); decode_result = decode_security_mode_command(&msg->security_mode_command,
buffer, len);
break; break;
case DOWNLINK_NAS_TRANSPORT: case DOWNLINK_NAS_TRANSPORT:
decode_result = decode_downlink_nas_transport(&msg->downlink_nas_transport, buffer, len); decode_result = decode_downlink_nas_transport(&msg->downlink_nas_transport,
buffer, len);
break; break;
case EXTENDED_SERVICE_REQUEST: case EXTENDED_SERVICE_REQUEST:
decode_result = decode_extended_service_request(&msg->extended_service_request, buffer, len); decode_result = decode_extended_service_request(&msg->extended_service_request,
buffer, len);
break; break;
case AUTHENTICATION_RESPONSE: case AUTHENTICATION_RESPONSE:
decode_result = decode_authentication_response(&msg->authentication_response, buffer, len); decode_result = decode_authentication_response(&msg->authentication_response,
buffer, len);
break; break;
default: default:
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x",
msg->header.message_type); msg->header.message_type);
decode_result = TLV_DECODE_WRONG_MESSAGE_TYPE; decode_result = TLV_DECODE_WRONG_MESSAGE_TYPE;
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
} }
if (decode_result < 0) { if (decode_result < 0) {
LOG_TRACE(ERROR, "EMM-MSG - Failed to decode L3 EMM message 0x%x " LOG_TRACE(ERROR, "EMM-MSG - Failed to decode L3 EMM message 0x%x "
"(%d)", msg->header.message_type, decode_result); "(%d)", msg->header.message_type, decode_result);
LOG_FUNC_RETURN (decode_result); LOG_FUNC_RETURN (decode_result);
} }
LOG_FUNC_RETURN (header_result + decode_result); LOG_FUNC_RETURN (header_result + decode_result);
} }
/**************************************************************************** /****************************************************************************
** ** ** **
** Name: emm_msg_encode() ** ** Name: emm_msg_encode() **
** ** ** **
** Description: Encode EPS Mobility Management messages ** ** Description: Encode EPS Mobility Management messages **
** ** ** **
** Inputs: msg: The EMM message structure to encode ** ** Inputs: msg: The EMM message structure to encode **
** length: Maximal capacity of the output buffer ** ** length: Maximal capacity of the output buffer **
** Others: None ** ** Others: None **
** ** ** **
** Outputs: buffer: Pointer to the encoded data buffer ** ** Outputs: buffer: Pointer to the encoded data buffer **
** Return: The number of bytes in the buffer if data ** ** Return: The number of bytes in the buffer if data **
** have been successfully encoded; ** ** have been successfully encoded; **
** A negative error code otherwise. ** ** A negative error code otherwise. **
** Others: None ** ** Others: None **
** ** ** **
***************************************************************************/ ***************************************************************************/
int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
...@@ -206,27 +224,29 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -206,27 +224,29 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
/* First encode the EMM message header */ /* First encode the EMM message header */
header_result = _emm_msg_encode_header(&msg->header, buffer, len); header_result = _emm_msg_encode_header(&msg->header, buffer, len);
if (header_result < 0) { if (header_result < 0) {
LOG_TRACE(ERROR, "EMM-MSG - Failed to encode EMM message header " LOG_TRACE(ERROR, "EMM-MSG - Failed to encode EMM message header "
"(%d)", header_result); "(%d)", header_result);
LOG_FUNC_RETURN(header_result); LOG_FUNC_RETURN(header_result);
} }
buffer += header_result; buffer += header_result;
len -= header_result; len -= header_result;
switch(msg->header.message_type) switch(msg->header.message_type) {
{
case EMM_INFORMATION: case EMM_INFORMATION:
encode_result = encode_emm_information(&msg->emm_information, buffer, len); encode_result = encode_emm_information(&msg->emm_information, buffer, len);
break; break;
case UPLINK_NAS_TRANSPORT: case UPLINK_NAS_TRANSPORT:
encode_result = encode_uplink_nas_transport(&msg->uplink_nas_transport, buffer, len); encode_result = encode_uplink_nas_transport(&msg->uplink_nas_transport, buffer,
len);
break; break;
case AUTHENTICATION_REJECT: case AUTHENTICATION_REJECT:
encode_result = encode_authentication_reject(&msg->authentication_reject, buffer, len); encode_result = encode_authentication_reject(&msg->authentication_reject,
buffer, len);
break; break;
case AUTHENTICATION_FAILURE: case AUTHENTICATION_FAILURE:
encode_result = encode_authentication_failure(&msg->authentication_failure, buffer, len); encode_result = encode_authentication_failure(&msg->authentication_failure,
buffer, len);
break; break;
case DETACH_ACCEPT: case DETACH_ACCEPT:
encode_result = encode_detach_accept(&msg->detach_accept, buffer, len); encode_result = encode_detach_accept(&msg->detach_accept, buffer, len);
...@@ -235,10 +255,12 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -235,10 +255,12 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
encode_result = encode_service_reject(&msg->service_reject, buffer, len); encode_result = encode_service_reject(&msg->service_reject, buffer, len);
break; break;
case AUTHENTICATION_REQUEST: case AUTHENTICATION_REQUEST:
encode_result = encode_authentication_request(&msg->authentication_request, buffer, len); encode_result = encode_authentication_request(&msg->authentication_request,
buffer, len);
break; break;
case TRACKING_AREA_UPDATE_REQUEST: case TRACKING_AREA_UPDATE_REQUEST:
encode_result = encode_tracking_area_update_request(&msg->tracking_area_update_request, buffer, len); encode_result = encode_tracking_area_update_request(
&msg->tracking_area_update_request, buffer, len);
break; break;
case ATTACH_REQUEST: case ATTACH_REQUEST:
encode_result = encode_attach_request(&msg->attach_request, buffer, len); encode_result = encode_attach_request(&msg->attach_request, buffer, len);
...@@ -253,19 +275,23 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -253,19 +275,23 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
encode_result = encode_identity_request(&msg->identity_request, buffer, len); encode_result = encode_identity_request(&msg->identity_request, buffer, len);
break; break;
case GUTI_REALLOCATION_COMMAND: case GUTI_REALLOCATION_COMMAND:
encode_result = encode_guti_reallocation_command(&msg->guti_reallocation_command, buffer, len); encode_result = encode_guti_reallocation_command(&msg->guti_reallocation_command,
buffer, len);
break; break;
case TRACKING_AREA_UPDATE_REJECT: case TRACKING_AREA_UPDATE_REJECT:
encode_result = encode_tracking_area_update_reject(&msg->tracking_area_update_reject, buffer, len); encode_result = encode_tracking_area_update_reject(
&msg->tracking_area_update_reject, buffer, len);
break; break;
case ATTACH_ACCEPT: case ATTACH_ACCEPT:
encode_result = encode_attach_accept(&msg->attach_accept, buffer, len); encode_result = encode_attach_accept(&msg->attach_accept, buffer, len);
break; break;
case SECURITY_MODE_COMPLETE: case SECURITY_MODE_COMPLETE:
encode_result = encode_security_mode_complete(&msg->security_mode_complete, buffer, len); encode_result = encode_security_mode_complete(&msg->security_mode_complete,
buffer, len);
break; break;
case TRACKING_AREA_UPDATE_ACCEPT: case TRACKING_AREA_UPDATE_ACCEPT:
encode_result = encode_tracking_area_update_accept(&msg->tracking_area_update_accept, buffer, len); encode_result = encode_tracking_area_update_accept(
&msg->tracking_area_update_accept, buffer, len);
break; break;
case ATTACH_REJECT: case ATTACH_REJECT:
encode_result = encode_attach_reject(&msg->attach_reject, buffer, len); encode_result = encode_attach_reject(&msg->attach_reject, buffer, len);
...@@ -274,45 +300,53 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -274,45 +300,53 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
encode_result = encode_attach_complete(&msg->attach_complete, buffer, len); encode_result = encode_attach_complete(&msg->attach_complete, buffer, len);
break; break;
case TRACKING_AREA_UPDATE_COMPLETE: case TRACKING_AREA_UPDATE_COMPLETE:
encode_result = encode_tracking_area_update_complete(&msg->tracking_area_update_complete, buffer, len); encode_result = encode_tracking_area_update_complete(
&msg->tracking_area_update_complete, buffer, len);
break; break;
case CS_SERVICE_NOTIFICATION: case CS_SERVICE_NOTIFICATION:
encode_result = encode_cs_service_notification(&msg->cs_service_notification, buffer, len); encode_result = encode_cs_service_notification(&msg->cs_service_notification,
buffer, len);
break; break;
case SECURITY_MODE_REJECT: case SECURITY_MODE_REJECT:
encode_result = encode_security_mode_reject(&msg->security_mode_reject, buffer, len); encode_result = encode_security_mode_reject(&msg->security_mode_reject, buffer,
len);
break; break;
case DETACH_REQUEST: case DETACH_REQUEST:
encode_result = encode_detach_request(&msg->detach_request, buffer, len); encode_result = encode_detach_request(&msg->detach_request, buffer, len);
break; break;
case GUTI_REALLOCATION_COMPLETE: case GUTI_REALLOCATION_COMPLETE:
encode_result = encode_guti_reallocation_complete(&msg->guti_reallocation_complete, buffer, len); encode_result = encode_guti_reallocation_complete(
&msg->guti_reallocation_complete, buffer, len);
break; break;
case SECURITY_MODE_COMMAND: case SECURITY_MODE_COMMAND:
encode_result = encode_security_mode_command(&msg->security_mode_command, buffer, len); encode_result = encode_security_mode_command(&msg->security_mode_command,
buffer, len);
break; break;
case DOWNLINK_NAS_TRANSPORT: case DOWNLINK_NAS_TRANSPORT:
encode_result = encode_downlink_nas_transport(&msg->downlink_nas_transport, buffer, len); encode_result = encode_downlink_nas_transport(&msg->downlink_nas_transport,
buffer, len);
break; break;
case EXTENDED_SERVICE_REQUEST: case EXTENDED_SERVICE_REQUEST:
encode_result = encode_extended_service_request(&msg->extended_service_request, buffer, len); encode_result = encode_extended_service_request(&msg->extended_service_request,
buffer, len);
break; break;
case AUTHENTICATION_RESPONSE: case AUTHENTICATION_RESPONSE:
encode_result = encode_authentication_response(&msg->authentication_response, buffer, len); encode_result = encode_authentication_response(&msg->authentication_response,
buffer, len);
break; break;
case SERVICE_REQUEST: case SERVICE_REQUEST:
encode_result = encode_service_request(&msg->service_request, buffer, len); encode_result = encode_service_request(&msg->service_request, buffer, len);
break; break;
default: default:
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x",
msg->header.message_type); msg->header.message_type);
encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE; encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE;
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
} }
if (encode_result < 0) { if (encode_result < 0) {
LOG_TRACE(ERROR, "EMM-MSG - Failed to encode L3 EMM message 0x%x " LOG_TRACE(ERROR, "EMM-MSG - Failed to encode L3 EMM message 0x%x "
"(%d)", msg->header.message_type, encode_result); "(%d)", msg->header.message_type, encode_result);
} }
LOG_FUNC_RETURN (header_result + encode_result); LOG_FUNC_RETURN (header_result + encode_result);
} }
...@@ -323,43 +357,43 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -323,43 +357,43 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
/**************************************************************************** /****************************************************************************
** ** ** **
** Name: _emm_msg_decode_header() ** ** Name: _emm_msg_decode_header() **
** ** ** **
** Description: Decode header of EPS Mobility Management message. ** ** Description: Decode header of EPS Mobility Management message. **
** The protocol discriminator and the security header type ** ** The protocol discriminator and the security header type **
** have already been decoded. ** ** have already been decoded. **
** ** ** **
** Inputs: buffer: Pointer to the buffer containing the EMM ** ** Inputs: buffer: Pointer to the buffer containing the EMM **
** message ** ** message **
** len: Number of bytes that should be decoded ** ** len: Number of bytes that should be decoded **
** Others: None ** ** Others: None **
** ** ** **
** Outputs: header: The EMM message header to be filled ** ** Outputs: header: The EMM message header to be filled **
** Return: The size of the header if data have been ** ** Return: The size of the header if data have been **
** successfully decoded; ** ** successfully decoded; **
** A negative error code otherwise. ** ** A negative error code otherwise. **
** Others: None ** ** Others: None **
** ** ** **
***************************************************************************/ ***************************************************************************/
static int _emm_msg_decode_header(emm_msg_header_t *header, static int _emm_msg_decode_header(emm_msg_header_t *header,
const uint8_t *buffer, uint32_t len) const uint8_t *buffer, uint32_t len)
{ {
int size = 0; int size = 0;
/* Check the buffer length */ /* Check the buffer length */
if (len < sizeof(emm_msg_header_t)) { if (len < sizeof(emm_msg_header_t)) {
return (TLV_DECODE_BUFFER_TOO_SHORT); return (TLV_DECODE_BUFFER_TOO_SHORT);
} }
/* Decode the security header type and the protocol discriminator */ /* Decode the security header type and the protocol discriminator */
DECODE_U8(buffer + size, *(uint8_t*)(header), size); DECODE_U8(buffer + size, *(uint8_t *)(header), size);
/* Decode the message type */ /* Decode the message type */
DECODE_U8(buffer + size, header->message_type, size); DECODE_U8(buffer + size, header->message_type, size);
/* Check the protocol discriminator */ /* Check the protocol discriminator */
if (header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) { if (header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) {
LOG_TRACE(ERROR, "ESM-MSG - Unexpected protocol discriminator: 0x%x", LOG_TRACE(ERROR, "ESM-MSG - Unexpected protocol discriminator: 0x%x",
header->protocol_discriminator); header->protocol_discriminator);
return (TLV_DECODE_PROTOCOL_NOT_SUPPORTED); return (TLV_DECODE_PROTOCOL_NOT_SUPPORTED);
} }
return (size); return (size);
...@@ -367,40 +401,40 @@ static int _emm_msg_decode_header(emm_msg_header_t *header, ...@@ -367,40 +401,40 @@ static int _emm_msg_decode_header(emm_msg_header_t *header,
/**************************************************************************** /****************************************************************************
** ** ** **
** Name: _emm_msg_encode_header() ** ** Name: _emm_msg_encode_header() **
** ** ** **
** The protocol discriminator and the security header type ** ** The protocol discriminator and the security header type **
** have already been encoded. ** ** have already been encoded. **
** ** ** **
** Inputs: header: The EMM message header to encode ** ** Inputs: header: The EMM message header to encode **
** len: Maximal capacity of the output buffer ** ** len: Maximal capacity of the output buffer **
** Others: None ** ** Others: None **
** ** ** **
** Outputs: buffer: Pointer to the encoded data buffer ** ** Outputs: buffer: Pointer to the encoded data buffer **
** Return: The number of bytes in the buffer if data ** ** Return: The number of bytes in the buffer if data **
** have been successfully encoded; ** ** have been successfully encoded; **
** A negative error code otherwise. ** ** A negative error code otherwise. **
** Others: None ** ** Others: None **
** ** ** **
***************************************************************************/ ***************************************************************************/
static int _emm_msg_encode_header(const emm_msg_header_t *header, static int _emm_msg_encode_header(const emm_msg_header_t *header,
uint8_t *buffer, uint32_t len) uint8_t *buffer, uint32_t len)
{ {
int size = 0; int size = 0;
/* Check the buffer length */ /* Check the buffer length */
if (len < sizeof(emm_msg_header_t)) { if (len < sizeof(emm_msg_header_t)) {
return (TLV_ENCODE_BUFFER_TOO_SHORT); return (TLV_ENCODE_BUFFER_TOO_SHORT);
} }
/* Check the protocol discriminator */ /* Check the protocol discriminator */
if (header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) { if (header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) {
LOG_TRACE(ERROR, "ESM-MSG - Unexpected protocol discriminator: 0x%x", LOG_TRACE(ERROR, "ESM-MSG - Unexpected protocol discriminator: 0x%x",
header->protocol_discriminator); header->protocol_discriminator);
return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED); return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED);
} }
/* Encode the security header type and the protocol discriminator */ /* Encode the security header type and the protocol discriminator */
ENCODE_U8(buffer + size, *(uint8_t*)(header), size); ENCODE_U8(buffer + size, *(uint8_t *)(header), size);
/* Encode the message type */ /* Encode the message type */
ENCODE_U8(buffer + size, header->message_type, size); ENCODE_U8(buffer + size, header->message_type, size);
......
...@@ -1080,17 +1080,22 @@ static int _emm_as_send(const emm_as_t *msg) ...@@ -1080,17 +1080,22 @@ static int _emm_as_send(const emm_as_t *msg)
#if defined(EPC_BUILD) && defined(NAS_MME) #if defined(EPC_BUILD) && defined(NAS_MME)
switch (as_msg.msgID) { switch (as_msg.msgID) {
case AS_DL_INFO_TRANSFER_REQ: { case AS_DL_INFO_TRANSFER_REQ: {
int ret; nas_itti_dl_data_req(as_msg.msg.dl_info_transfer_req.UEid,
as_msg.msg.dl_info_transfer_req.nasMsg.data,
as_msg.msg.dl_info_transfer_req.nasMsg.length);
} break;
case AS_NAS_ESTABLISH_RSP: {
/* The attach procedure succeeded wihtin MME.
* This message should trigger an S1AP initial context setup
* request.
* NOTE: we support only one bearer per message...
*/
// nas_itti_establish_cnf(as_msg.msg.nas_establish_cnf.errCode,
// as_msg.msg.nas_establish_cnf.nasMsg.data,
// as_msg.msg.nas_establish_cnf.nasMsg.length);
} break;
ret = nas_itti_dl_data_req(as_msg.msg.dl_info_transfer_req.UEid,
as_msg.msg.dl_info_transfer_req.nasMsg.data,
as_msg.msg.dl_info_transfer_req.nasMsg.length);
if (ret != -1) {
LOG_FUNC_RETURN (RETURNok);
}
}
break;
default: default:
break; break;
} }
...@@ -1610,10 +1615,11 @@ static int _emm_as_security_rej(const emm_as_security_t *msg, ...@@ -1610,10 +1615,11 @@ static int _emm_as_security_rej(const emm_as_security_t *msg,
static int _emm_as_establish_cnf(const emm_as_establish_t *msg, static int _emm_as_establish_cnf(const emm_as_establish_t *msg,
nas_establish_rsp_t *as_msg) nas_establish_rsp_t *as_msg)
{ {
LOG_FUNC_IN; EMM_msg *emm_msg;
int size = 0; int size = 0;
LOG_FUNC_IN;
LOG_TRACE(INFO, "EMMAS-SAP - Send AS connection establish response"); LOG_TRACE(INFO, "EMMAS-SAP - Send AS connection establish response");
nas_message_t nas_msg; nas_message_t nas_msg;
...@@ -1628,7 +1634,7 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, ...@@ -1628,7 +1634,7 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg,
as_msg->s_tmsi.m_tmsi = msg->UEid.guti->m_tmsi; as_msg->s_tmsi.m_tmsi = msg->UEid.guti->m_tmsi;
/* Setup the NAS security header */ /* Setup the NAS security header */
EMM_msg *emm_msg = _emm_as_set_header(&nas_msg, &msg->sctx); emm_msg = _emm_as_set_header(&nas_msg, &msg->sctx);
/* Setup the initial NAS information message */ /* Setup the initial NAS information message */
if (emm_msg != NULL) switch (msg->NASinfo) { if (emm_msg != NULL) switch (msg->NASinfo) {
......
...@@ -354,12 +354,13 @@ emm_fsm_state_t emm_fsm_get_status(unsigned int ueid, void *ctx) ...@@ -354,12 +354,13 @@ emm_fsm_state_t emm_fsm_get_status(unsigned int ueid, void *ctx)
***************************************************************************/ ***************************************************************************/
int emm_fsm_process(const emm_reg_t *evt) int emm_fsm_process(const emm_reg_t *evt)
{ {
int rc;
emm_fsm_state_t status; emm_fsm_state_t status;
emm_reg_primitive_t primitive;
LOG_FUNC_IN; LOG_FUNC_IN;
int rc; primitive = evt->primitive;
emm_reg_primitive_t primitive = evt->primitive;
#ifdef NAS_UE #ifdef NAS_UE
status = _emm_fsm_status[0]; status = _emm_fsm_status[0];
......
...@@ -44,3 +44,17 @@ int nas_itti_dl_data_req(const uint32_t ue_id, void * const data, ...@@ -44,3 +44,17 @@ int nas_itti_dl_data_req(const uint32_t ue_id, void * const data,
return itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p); return itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p);
} }
void nas_itti_establish_cnf(const nas_error_code_t error_code, void * const data,
const uint32_t length)
{
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS, NAS_CONNECTION_ESTABLISHMENT_CNF);
NAS_CONN_EST_CNF(message_p).nas_establish_cnf.nasMsg.data = data;
NAS_CONN_EST_CNF(message_p).nas_establish_cnf.nasMsg.length = length;
NAS_CONN_EST_CNF(message_p).nas_establish_cnf.errCode = error_code;
itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p);
}
...@@ -34,4 +34,7 @@ ...@@ -34,4 +34,7 @@
int nas_itti_dl_data_req(const uint32_t ue_id, void * const data, int nas_itti_dl_data_req(const uint32_t ue_id, void * const data,
const uint32_t length); const uint32_t length);
void nas_itti_establish_cnf(const nas_error_code_t error_code, void * const data,
const uint32_t length);
#endif /* NAS_ITTI_MESSAGING_H_ */ #endif /* NAS_ITTI_MESSAGING_H_ */
...@@ -62,6 +62,7 @@ next_message: ...@@ -62,6 +62,7 @@ next_message:
#endif #endif
} break; } break;
#if defined(DISABLE_USE_NAS)
case NAS_ATTACH_ACCEPT: { case NAS_ATTACH_ACCEPT: {
itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, received_message_p); itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, received_message_p);
goto next_message; goto next_message;
...@@ -81,6 +82,7 @@ next_message: ...@@ -81,6 +82,7 @@ next_message:
itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p); itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p);
} break; } break;
#endif
case NAS_UPLINK_DATA_IND: { case NAS_UPLINK_DATA_IND: {
nas_proc_ul_transfer_ind(NAS_UL_DATA_IND(received_message_p).UEid, nas_proc_ul_transfer_ind(NAS_UL_DATA_IND(received_message_p).UEid,
......
...@@ -140,12 +140,29 @@ void *s1ap_mme_thread(void *args) ...@@ -140,12 +140,29 @@ void *s1ap_mme_thread(void *args)
/* New message received from NAS task. /* New message received from NAS task.
* This corresponds to a S1AP downlink nas transport message. * This corresponds to a S1AP downlink nas transport message.
*/ */
s1ap_generate_downlink_nas_transport(&NAS_DL_DATA_REQ(received_message_p)); s1ap_generate_downlink_nas_transport(NAS_DL_DATA_REQ(received_message_p).UEid,
NAS_DL_DATA_REQ(received_message_p).nasMsg.data,
NAS_DL_DATA_REQ(received_message_p).nasMsg.length);
} break; } break;
#if defined(DISABLE_USE_NAS)
case NAS_ATTACH_ACCEPT: { case NAS_ATTACH_ACCEPT: {
s1ap_handle_attach_accepted(&received_message_p->ittiMsg.nas_attach_accept); s1ap_handle_attach_accepted(&received_message_p->ittiMsg.nas_attach_accept);
} break; } break;
#else
case NAS_CONNECTION_ESTABLISHMENT_CNF: {
if (AS_TERMINATED_NAS == NAS_CONN_EST_CNF(received_message_p).nas_establish_cnf.errCode) {
/* Attach rejected by NAS -> send result via
* DL info transfer message
*/
s1ap_generate_downlink_nas_transport(NAS_CONN_EST_CNF(received_message_p).ue_id,
NAS_CONN_EST_CNF(received_message_p).nas_establish_cnf.nasMsg.data,
NAS_CONN_EST_CNF(received_message_p).nas_establish_cnf.nasMsg.length);
} else {
s1ap_handle_conn_est_cnf(&NAS_CONN_EST_CNF(received_message_p));
}
} break;
#endif
case TIMER_HAS_EXPIRED: { case TIMER_HAS_EXPIRED: {
s1ap_handle_timer_expiry(&received_message_p->ittiMsg.timer_has_expired); s1ap_handle_timer_expiry(&received_message_p->ittiMsg.timer_has_expired);
......
...@@ -191,7 +191,7 @@ int s1ap_mme_handle_uplink_nas_transport(uint32_t assoc_id, uint32_t stream, ...@@ -191,7 +191,7 @@ int s1ap_mme_handle_uplink_nas_transport(uint32_t assoc_id, uint32_t stream,
//TODO: forward NAS PDU to NAS //TODO: forward NAS PDU to NAS
#if defined(DISABLE_USE_NAS) #if defined(DISABLE_USE_NAS)
DevMessage("TODO: forward NAS PDU to NAS\n"); DevMessage("Can't go further (TODO)\n");
#else #else
s1ap_mme_itti_nas_uplink_ind(uplinkNASTransport_p->mme_ue_s1ap_id, uplinkNASTransport_p->nas_pdu.buf, s1ap_mme_itti_nas_uplink_ind(uplinkNASTransport_p->mme_ue_s1ap_id, uplinkNASTransport_p->nas_pdu.buf,
uplinkNASTransport_p->nas_pdu.size); uplinkNASTransport_p->nas_pdu.size);
...@@ -212,15 +212,14 @@ int s1ap_mme_handle_nas_non_delivery(uint32_t assoc_id, uint32_t stream, ...@@ -212,15 +212,14 @@ int s1ap_mme_handle_nas_non_delivery(uint32_t assoc_id, uint32_t stream,
return 0; return 0;
} }
int s1ap_generate_downlink_nas_transport(nas_dl_data_req_t *nas_dl_data_req_p) int s1ap_generate_downlink_nas_transport(const uint32_t ue_id, void * const data,
const uint32_t size)
{ {
ue_description_t *ue_ref; ue_description_t *ue_ref;
uint8_t *buffer_p; uint8_t *buffer_p;
uint32_t length; uint32_t length;
DevAssert(nas_dl_data_req_p != NULL); if ((ue_ref = s1ap_is_ue_mme_id_in_list(ue_id)) == NULL) {
if ((ue_ref = s1ap_is_ue_mme_id_in_list(nas_dl_data_req_p->UEid)) == NULL) {
/* If the UE-associated logical S1-connection is not established, /* If the UE-associated logical S1-connection is not established,
* the MME shall allocate a unique MME UE S1AP ID to be used for the UE. * the MME shall allocate a unique MME UE S1AP ID to be used for the UE.
*/ */
...@@ -245,9 +244,10 @@ int s1ap_generate_downlink_nas_transport(nas_dl_data_req_t *nas_dl_data_req_p) ...@@ -245,9 +244,10 @@ int s1ap_generate_downlink_nas_transport(nas_dl_data_req_t *nas_dl_data_req_p)
/* Setting UE informations with the ones fount in ue_ref */ /* Setting UE informations with the ones fount in ue_ref */
downlinkNasTransport->mme_ue_s1ap_id = ue_ref->mme_ue_s1ap_id; downlinkNasTransport->mme_ue_s1ap_id = ue_ref->mme_ue_s1ap_id;
downlinkNasTransport->eNB_UE_S1AP_ID = ue_ref->eNB_ue_s1ap_id; downlinkNasTransport->eNB_UE_S1AP_ID = ue_ref->eNB_ue_s1ap_id;
OCTET_STRING_fromBuf(&downlinkNasTransport->nas_pdu,
(char*)nas_dl_data_req_p->nasMsg.data, /* Fill in the NAS pdu */
nas_dl_data_req_p->nasMsg.length); OCTET_STRING_fromBuf(&downlinkNasTransport->nas_pdu, (char*)data, size);
if (s1ap_mme_encode_pdu(&message, &buffer_p, &length) < 0) { if (s1ap_mme_encode_pdu(&message, &buffer_p, &length) < 0) {
// TODO: handle something // TODO: handle something
return -1; return -1;
...@@ -261,6 +261,7 @@ int s1ap_generate_downlink_nas_transport(nas_dl_data_req_t *nas_dl_data_req_p) ...@@ -261,6 +261,7 @@ int s1ap_generate_downlink_nas_transport(nas_dl_data_req_t *nas_dl_data_req_p)
return 0; return 0;
} }
#if defined(DISABLE_USE_NAS)
int s1ap_handle_attach_accepted(nas_attach_accept_t *attach_accept_p) int s1ap_handle_attach_accepted(nas_attach_accept_t *attach_accept_p)
{ {
/* We received create session response from S-GW on S11 interface abstraction. /* We received create session response from S-GW on S11 interface abstraction.
...@@ -387,3 +388,131 @@ int s1ap_handle_attach_accepted(nas_attach_accept_t *attach_accept_p) ...@@ -387,3 +388,131 @@ int s1ap_handle_attach_accepted(nas_attach_accept_t *attach_accept_p)
return s1ap_mme_itti_send_sctp_request(buffer_p, length, ue_ref->eNB->sctp_assoc_id, return s1ap_mme_itti_send_sctp_request(buffer_p, length, ue_ref->eNB->sctp_assoc_id,
ue_ref->sctp_stream_send); ue_ref->sctp_stream_send);
} }
#else
void s1ap_handle_conn_est_cnf(nas_conn_est_cnf_t *nas_conn_est_cnf_p)
{
/* We received create session response from S-GW on S11 interface abstraction.
* At least one bearer has been established. We can now send s1ap initial context setup request
* message to eNB.
*/
uint8_t supportedAlgorithms[] = { 0x00, 0x02 };
uint8_t offset = 0;
uint8_t *buffer_p;
uint32_t length;
ue_description_t *ue_ref = NULL;
s1ap_message message;
s1ap_initial_ctxt_setup_req_t *initial_p;
S1ap_InitialContextSetupRequestIEs_t *initialContextSetupRequest_p;
S1ap_E_RABToBeSetupItemCtxtSUReq_t e_RABToBeSetup;
DevAssert(nas_conn_est_cnf_p != NULL);
initial_p = &nas_conn_est_cnf_p->transparent;
if ((ue_ref = s1ap_is_ue_mme_id_in_list(initial_p->mme_ue_s1ap_id)) == NULL) {
S1AP_DEBUG("This mme ue s1ap id (%08x) is not attached to any UE context\n",
initial_p->mme_ue_s1ap_id);
DevParam(initial_p->mme_ue_s1ap_id, 0, 0);
}
/* Start the outcome response timer.
* When time is reached, MME consider that procedure outcome has failed.
*/
// timer_setup(mme_config.s1ap_config.outcome_drop_timer_sec, 0, TASK_S1AP, INSTANCE_DEFAULT,
// TIMER_ONE_SHOT,
// NULL,
// &ue_ref->outcome_response_timer_id);
/* Insert the timer in the MAP of mme_ue_s1ap_id <-> timer_id */
// s1ap_timer_insert(ue_ref->mme_ue_s1ap_id, ue_ref->outcome_response_timer_id);
memset(&message, 0, sizeof(s1ap_message));
memset(&e_RABToBeSetup, 0, sizeof(S1ap_E_RABToBeSetupItemCtxtSUReq_t));
message.procedureCode = S1ap_ProcedureCode_id_InitialContextSetup;
message.direction = S1AP_PDU_PR_initiatingMessage;
initialContextSetupRequest_p = &message.msg.s1ap_InitialContextSetupRequestIEs;
initialContextSetupRequest_p->mme_ue_s1ap_id = (unsigned long)ue_ref->mme_ue_s1ap_id;
initialContextSetupRequest_p->eNB_UE_S1AP_ID = (unsigned long)ue_ref->eNB_ue_s1ap_id;
/* uEaggregateMaximumBitrateDL and uEaggregateMaximumBitrateUL expressed in term of bits/sec */
initialContextSetupRequest_p->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL = initial_p->ambr.br_dl;
initialContextSetupRequest_p->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL = initial_p->ambr.br_ul;
e_RABToBeSetup.e_RAB_ID = initial_p->ebi;
e_RABToBeSetup.e_RABlevelQoSParameters.qCI = initial_p->qci;
e_RABToBeSetup.e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel
= initial_p->prio_level; //No priority
e_RABToBeSetup.e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability
= initial_p->pre_emp_capability;
e_RABToBeSetup.e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability
= initial_p->pre_emp_vulnerability;
/* Set the GTP-TEID. This is the S1-U S-GW TEID */
INT32_TO_OCTET_STRING(initial_p->teid, &e_RABToBeSetup.gTP_TEID);
/* S-GW IP address(es) for user-plane */
if ((initial_p->s_gw_address.pdn_type == IPv4) ||
(initial_p->s_gw_address.pdn_type == IPv4_AND_v6))
{
e_RABToBeSetup.transportLayerAddress.buf = calloc(4, sizeof(uint8_t));
/* Only IPv4 supported */
memcpy(e_RABToBeSetup.transportLayerAddress.buf,
initial_p->s_gw_address.address.ipv4_address,
4);
offset += 4;
e_RABToBeSetup.transportLayerAddress.size = 4;
e_RABToBeSetup.transportLayerAddress.bits_unused = 0;
}
if ((initial_p->s_gw_address.pdn_type == IPv6) ||
(initial_p->s_gw_address.pdn_type == IPv4_AND_v6))
{
if (offset == 0) {
/* Both IPv4 and IPv6 provided */
/* TODO: check memory allocation */
e_RABToBeSetup.transportLayerAddress.buf = calloc(16, sizeof(uint8_t));
} else {
/* Only IPv6 supported */
/* TODO: check memory allocation */
e_RABToBeSetup.transportLayerAddress.buf
= realloc(e_RABToBeSetup.transportLayerAddress.buf, (16 + offset) * sizeof(uint8_t));
}
memcpy(&e_RABToBeSetup.transportLayerAddress.buf[offset],
initial_p->s_gw_address.address.ipv6_address,
16);
e_RABToBeSetup.transportLayerAddress.size = 16 + offset;
e_RABToBeSetup.transportLayerAddress.bits_unused = 0;
}
ASN_SEQUENCE_ADD(&initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq,
&e_RABToBeSetup);
initialContextSetupRequest_p->ueSecurityCapabilities.encryptionAlgorithms.buf =
(uint8_t *)supportedAlgorithms;
initialContextSetupRequest_p->ueSecurityCapabilities.encryptionAlgorithms.size = 2;
initialContextSetupRequest_p->ueSecurityCapabilities.encryptionAlgorithms.bits_unused
= 0;
initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms.buf
= (uint8_t *)supportedAlgorithms;
initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms.size
= 2;
initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms.bits_unused
= 0;
initialContextSetupRequest_p->securityKey.buf = initial_p->keNB; /* 256 bits length */
initialContextSetupRequest_p->securityKey.size = 32;
initialContextSetupRequest_p->securityKey.bits_unused = 0;
if (s1ap_mme_encode_pdu(&message, &buffer_p, &length) < 0) {
// TODO: handle something
DevMessage("Failed to encode initial context setup request message\n");
}
s1ap_mme_itti_send_sctp_request(buffer_p, length, ue_ref->eNB->sctp_assoc_id,
ue_ref->sctp_stream_send);
}
#endif
...@@ -64,8 +64,12 @@ int s1ap_mme_handle_uplink_nas_transport(uint32_t assocId, uint32_t stream, ...@@ -64,8 +64,12 @@ int s1ap_mme_handle_uplink_nas_transport(uint32_t assocId, uint32_t stream,
int s1ap_mme_handle_nas_non_delivery(uint32_t assocId, uint32_t stream, int s1ap_mme_handle_nas_non_delivery(uint32_t assocId, uint32_t stream,
struct s1ap_message_s *message); struct s1ap_message_s *message);
#if defined(DISABLE_USE_NAS)
int s1ap_handle_attach_accepted(nas_attach_accept_t *attach_accept_p); int s1ap_handle_attach_accepted(nas_attach_accept_t *attach_accept_p);
#else
void s1ap_handle_conn_est_cnf(nas_conn_est_cnf_t *nas_conn_est_cnf_p);
#endif
int s1ap_generate_downlink_nas_transport(nas_dl_data_req_t *nas_dl_data_req); int s1ap_generate_downlink_nas_transport(const uint32_t ue_id, void * const data,
const uint32_t size);
#endif /* S1AP_MME_NAS_PROCEDURES_H_ */ #endif /* S1AP_MME_NAS_PROCEDURES_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment