Commit ed72ec9e authored by nepes's avatar nepes

Preliminary extensions for Remote UE Report support based on Release 14

parent 6849e297
...@@ -1520,6 +1520,8 @@ set(libnas_esm_msg_OBJS ...@@ -1520,6 +1520,8 @@ set(libnas_esm_msg_OBJS
${NAS_SRC}COMMON/ESM/MSG/PdnConnectivityRequest.c ${NAS_SRC}COMMON/ESM/MSG/PdnConnectivityRequest.c
${NAS_SRC}COMMON/ESM/MSG/PdnDisconnectReject.c ${NAS_SRC}COMMON/ESM/MSG/PdnDisconnectReject.c
${NAS_SRC}COMMON/ESM/MSG/PdnDisconnectRequest.c ${NAS_SRC}COMMON/ESM/MSG/PdnDisconnectRequest.c
${NAS_SRC}COMMON/ESM/MSG/RemoteUEReport.c
${NAS_SRC}COMMON/ESM/MSG/RemoteUEReportResponse.c
) )
set(libnas_ies_OBJS set(libnas_ies_OBJS
...@@ -1601,6 +1603,9 @@ set(libnas_ies_OBJS ...@@ -1601,6 +1603,9 @@ set(libnas_ies_OBJS
${NAS_SRC}COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.c ${NAS_SRC}COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.c
${NAS_SRC}COMMON/IES/UeSecurityCapability.c ${NAS_SRC}COMMON/IES/UeSecurityCapability.c
${NAS_SRC}COMMON/IES/VoiceDomainPreferenceAndUeUsageSetting.c ${NAS_SRC}COMMON/IES/VoiceDomainPreferenceAndUeUsageSetting.c
${NAS_SRC}COMMON/IES/RemoteUserID.c
${NAS_SRC}COMMON/IES/RemoteUEContext.c
${NAS_SRC}COMMON/IES/PKMFAddress.c
) )
set (libnas_utils_OBJS set (libnas_utils_OBJS
...@@ -1679,6 +1684,7 @@ if(NAS_UE) ...@@ -1679,6 +1684,7 @@ if(NAS_UE)
${NAS_SRC}UE/ESM/EsmStatusHdl.c ${NAS_SRC}UE/ESM/EsmStatusHdl.c
${NAS_SRC}UE/ESM/PdnConnectivity.c ${NAS_SRC}UE/ESM/PdnConnectivity.c
${NAS_SRC}UE/ESM/PdnDisconnect.c ${NAS_SRC}UE/ESM/PdnDisconnect.c
${NAS_SRC}UE/ESM/RemoteUeReport.c
) )
set(libnas_ue_esm_sap_OBJS set(libnas_ue_esm_sap_OBJS
${NAS_SRC}UE/ESM/SAP/esm_recv.c ${NAS_SRC}UE/ESM/SAP/esm_recv.c
......
...@@ -111,6 +111,8 @@ typedef enum { ...@@ -111,6 +111,8 @@ typedef enum {
ESM_MSG_ESM_INFORMATION_REQUEST, ESM_MSG_ESM_INFORMATION_REQUEST,
ESM_MSG_ESM_INFORMATION_RESPONSE, ESM_MSG_ESM_INFORMATION_RESPONSE,
ESM_MSG_ESM_STATUS, ESM_MSG_ESM_STATUS,
ESM_MSG_REMOTE_UE_REPORT,
ESM_MSG_REMOTE_UE_REPORT_RESPONSE,
} esm_message_ids_t; } esm_message_ids_t;
typedef struct nas_raw_msg_s { typedef struct nas_raw_msg_s {
......
...@@ -72,3 +72,5 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstab ...@@ -72,3 +72,5 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstab
MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind) MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind)
MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf) MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf)
MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind)
MESSAGE_DEF(NAS_REMOTE_UE_REPORT, MESSAGE_PRIORITY_MED, NasRemoteUeReport, nas_remote_ue_report)
...@@ -80,6 +80,7 @@ ...@@ -80,6 +80,7 @@
#define NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_release_ind #define NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_release_ind
#define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf #define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
#define NAS_REMOTE_UE_REPORT(mSGpTR) (mSGpTR)->ittiMsg.nas_remote_ue_report
//-------------------------------------------------------------------------------------------// //-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s { typedef struct RrcStateInd_s {
...@@ -400,4 +401,9 @@ typedef nas_release_ind_t NasConnReleaseInd; ...@@ -400,4 +401,9 @@ typedef nas_release_ind_t NasConnReleaseInd;
typedef ul_info_transfer_cnf_t NasUlDataCnf; typedef ul_info_transfer_cnf_t NasUlDataCnf;
typedef dl_info_transfer_ind_t NasDlDataInd; typedef dl_info_transfer_ind_t NasDlDataInd;
typedef struct NasRemoteUeReport_s {
int dummy;
} NasRemoteUeReport;
#endif /* RRC_MESSAGES_TYPES_H_ */ #endif /* RRC_MESSAGES_TYPES_H_ */
...@@ -2371,7 +2371,12 @@ rrc_ue_decode_dcch( ...@@ -2371,7 +2371,12 @@ rrc_ue_decode_dcch(
rrc_ue_generate_SidelinkUEInformation(ctxt_pP, eNB_indexP, destinationInfoList, NULL, SL_TRANSMIT_NON_RELAY_ONE_TO_ONE); rrc_ue_generate_SidelinkUEInformation(ctxt_pP, eNB_indexP, destinationInfoList, NULL, SL_TRANSMIT_NON_RELAY_ONE_TO_ONE);
send_ue_information ++; send_ue_information ++;
} }
//For Remote UE Report
#if defined(ENABLE_ITTI)
msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_REMOTE_UE_REPORT);
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
#endif
break; break;
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
...@@ -2385,7 +2390,6 @@ rrc_ue_decode_dcch( ...@@ -2385,7 +2390,6 @@ rrc_ue_decode_dcch(
NAS_CONN_RELEASE_IND(msg_p).cause = NAS_CONN_RELEASE_IND(msg_p).cause =
dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause; dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause;
} }
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
#if ENABLE_RAL #if ENABLE_RAL
msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_CONNECTION_RELEASE_IND); msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_CONNECTION_RELEASE_IND);
...@@ -5717,6 +5721,8 @@ void *rrc_control_socket_thread_fct(void *arg) ...@@ -5717,6 +5721,8 @@ void *rrc_control_socket_thread_fct(void *arg)
ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf;
LOG_UI(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); LOG_UI(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type);
LOG_UI(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); LOG_UI(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id);
//
} }
break; break;
......
...@@ -266,7 +266,7 @@ extern log_t *g_log; ...@@ -266,7 +266,7 @@ extern log_t *g_log;
#endif #endif
#endif #endif
/*--- INCLUDES ---------------------------------------------------------------*/ /*--- INCLUDES ---------------------------------------------------------------*/
# include "log_if.h" #include "log_if.h"
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
int logInit (void); int logInit (void);
void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
......
/*
* RemoteUEReport.c
*
* Created on: Jun 5, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "RemoteUEReport.h"
#include "PKMFAddress.h"
int decode_remote_ue_report(remote_ue_report_msg *remoteuereport, uint8_t *buffer, uint32_t len)
{
uint32_t decoded = 0;
int decoded_result = 0;
// Check if we got a NULL pointer and if buffer length is >= minimum length expected for the message.
CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, REMOTE_UE_REPORT_RESPONSE_MINIMUM_LENGTH, len);
if ((decoded_result = decode_pkmf_address(&remoteuereport->pkmfaddress, 0, buffer + decoded, len - decoded)) < 0)
return decoded_result;
else
decoded += decoded_result;
return decoded;
}
int encode_remote_ue_report(remote_ue_report_msg *remoteuereport, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
int encode_result = 0;
/* Checking IEI and pointer */
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, REMOTE_UE_REPORT_RESPONSE_MINIMUM_LENGTH, len);
remoteuereport->pkmfaddress.pkmfipv4address = 0;
if ((encode_result = encode_pkmf_address(&remoteuereport->pkmfaddress, 0, buffer + encoded, len - encoded)) < 0)//Return in case of error
return encode_result;
else
encoded += encode_result;
return encoded;
}
/*
* RemoteUEReport.h
*
* Created on: Jun 5, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ProtocolDiscriminator.h"
#include "EpsBearerIdentity.h"
#include "ProcedureTransactionIdentity.h"
#include "PKMFAddress.h"
#ifndef OPENAIR3_NAS_COMMON_ESM_MSG_REMOTEUEREPORT_H_
#define OPENAIR3_NAS_COMMON_ESM_MSG_REMOTEUEREPORT_H_
/* Minimum length macro. Formed by minimum length of each mandatory field */
#define REMOTE_UE_REPORT_RESPONSE_MINIMUM_LENGTH (0)
typedef struct remote_ue_report_msg_tag {
/* Mandatory fields */
ProtocolDiscriminator protocoldiscriminator:4;
EpsBearerIdentity epsbeareridentity:4;
ProcedureTransactionIdentity proceduretransactionidentity;
/* Optional fields */
pkmf_address_t pkmfaddress;
//RemoteUEContext remoteuecontext;
} remote_ue_report_msg;
int decode_remote_ue_report(remote_ue_report_msg *remoteuereport, uint8_t *buffer, uint32_t len);
int encode_remote_ue_report(remote_ue_report_msg *remoteuereport, uint8_t *buffer, uint32_t len);
#endif /* OPENAIR3_NAS_COMMON_ESM_MSG_REMOTEUEREPORT_H_ */
/*
* RemoteUEReportResponse.c
*
* Created on: Jun 7, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "RemoteUEReportResponse.h"
int decode_remote_ue_report_response(remote_ue_report_response_msg *remoteuereportresponse, uint8_t *buffer, uint32_t len)
{
uint32_t decoded = 0;
// Check if we got a NULL pointer and if buffer length is >= minimum length expected for the message.
CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, REMOTE_UE_REPORT_RESPONSE_MINIMUM_LENGTH, len);
/* Decoding mandatory fields */
return decoded;
}
int encode_remote_ue_report_response(remote_ue_report_response_msg *remoteuereportresponse, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
/* Checking IEI and pointer */
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, REMOTE_UE_REPORT_RESPONSE_MINIMUM_LENGTH, len);
return encoded;
}
/*
* RemoteUEReportResponse.h
*
* Created on: Jun 7, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ProtocolDiscriminator.h"
#include "EpsBearerIdentity.h"
#include "ProcedureTransactionIdentity.h"
#ifndef OPENAIR3_NAS_COMMON_ESM_MSG_REMOTEUEREPORTRESPONSE_H_
#define OPENAIR3_NAS_COMMON_ESM_MSG_REMOTEUEREPORTRESPONSE_H_
/* Minimum length macro. Formed by minimum length of each mandatory field */
#define REMOTE_UE_REPORT_RESPONSE_MINIMUM_LENGTH (0)
/* Maximum length macro. Formed by minimum length of each mandatory field */
#define REMOTE_UE_REPORT_RESPONSE_MAXIMUM_LENGTH (0)
typedef struct remote_ue_report_response_msg_tag {
/* Mandatory fields */
ProtocolDiscriminator protocoldiscriminator:4;
EpsBearerIdentity epsbeareridentity:4;
ProcedureTransactionIdentity proceduretransactionidentity;
} remote_ue_report_response_msg;
int decode_remote_ue_report_response(remote_ue_report_response_msg *remoteuereportresponse, uint8_t *buffer, uint32_t len);
int encode_remote_ue_report_response(remote_ue_report_response_msg *remoteuereportresponse, uint8_t *buffer, uint32_t len);
#endif /* OPENAIR3_NAS_COMMON_ESM_MSG_REMOTEUEREPORTRESPONSE_H_ */
...@@ -200,6 +200,14 @@ int esm_msg_decode(ESM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -200,6 +200,14 @@ int esm_msg_decode(ESM_msg *msg, uint8_t *buffer, uint32_t len)
decode_result = decode_esm_status(&msg->esm_status, buffer, len); decode_result = decode_esm_status(&msg->esm_status, buffer, len);
break; break;
case REMOTE_UE_REPORT:
decode_result = decode_esm_status(&msg->remote_ue_report, buffer, len);
break;
case REMOTE_UE_REPORT_RESPONSE:
decode_result = decode_esm_status(&msg->remote_ue_report_response, buffer, len);
break;
default: default:
LOG_TRACE(ERROR, "ESM-MSG - Unexpected message type: 0x%x", LOG_TRACE(ERROR, "ESM-MSG - Unexpected message type: 0x%x",
msg->header.message_type); msg->header.message_type);
...@@ -360,6 +368,14 @@ int esm_msg_encode(ESM_msg *msg, uint8_t *buffer, uint32_t len) ...@@ -360,6 +368,14 @@ int esm_msg_encode(ESM_msg *msg, uint8_t *buffer, uint32_t len)
encode_result = encode_esm_status(&msg->esm_status, buffer, len); encode_result = encode_esm_status(&msg->esm_status, buffer, len);
break; break;
case REMOTE_UE_REPORT:
encode_result = encode_esm_status(&msg->remote_ue_report, buffer, len);
break;
case REMOTE_UE_REPORT_RESPONSE:
encode_result = encode_esm_status(&msg->remote_ue_report_response, buffer, len);
break;
default: default:
LOG_TRACE(ERROR, "ESM-MSG - Unexpected message type: 0x%x", LOG_TRACE(ERROR, "ESM-MSG - Unexpected message type: 0x%x",
msg->header.message_type); msg->header.message_type);
......
...@@ -63,6 +63,8 @@ Description Defines EPS Session Management messages and functions used ...@@ -63,6 +63,8 @@ Description Defines EPS Session Management messages and functions used
#include "EsmInformationRequest.h" #include "EsmInformationRequest.h"
#include "EsmInformationResponse.h" #include "EsmInformationResponse.h"
#include "EsmStatus.h" #include "EsmStatus.h"
#include "RemoteUEReport.h"
#include "RemoteUEReportResponse.h"
#include <stdint.h> #include <stdint.h>
...@@ -102,6 +104,8 @@ typedef union { ...@@ -102,6 +104,8 @@ typedef union {
esm_information_request_msg esm_information_request; esm_information_request_msg esm_information_request;
esm_information_response_msg esm_information_response; esm_information_response_msg esm_information_response;
esm_status_msg esm_status; esm_status_msg esm_status;
remote_ue_report_msg remote_ue_report;
remote_ue_report_response_msg remote_ue_report_response;
} ESM_msg; } ESM_msg;
......
...@@ -72,7 +72,8 @@ Description Defines identifiers of the EPS Session Management messages ...@@ -72,7 +72,8 @@ Description Defines identifiers of the EPS Session Management messages
# define ESM_INFORMATION_REQUEST 0b11011001 /* 217 = 0xd9 */ # define ESM_INFORMATION_REQUEST 0b11011001 /* 217 = 0xd9 */
# define ESM_INFORMATION_RESPONSE 0b11011010 /* 218 = 0xda */ # define ESM_INFORMATION_RESPONSE 0b11011010 /* 218 = 0xda */
# define ESM_STATUS 0b11101000 /* 232 = 0xe8 */ # define ESM_STATUS 0b11101000 /* 232 = 0xe8 */
# define REMOTE_UE_REPORT 0b11101001 /* 233 = 0xe9 */
# define REMOTE_UE_REPORT_RESPONSE 0b11101010 /* 234 = 0xea */
/****************************************************************************/ /****************************************************************************/
/************************ G L O B A L T Y P E S ************************/ /************************ G L O B A L T Y P E S ************************/
/****************************************************************************/ /****************************************************************************/
......
/*
* PKMFAddress.c
*
* Created on: Jun 11, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "PKMFAddress.h"
//static int encode_pkmf_address(pkmf_address_t *pkmfaddress, uint8_t iei, uint8_t *buffer, uint32_t len);
//static int decode_pkmf_address(pkmf_address_t *pkmfaddress, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_pkmf_address(
pkmf_address_t *pkmfaddress,
uint8_t iei,
uint8_t *buffer,
uint32_t len)
{
int decoded = 0;
uint8_t ielen = 0;
if (iei > 0)
{
CHECK_IEI_DECODER (iei, *buffer);
decoded++;
}
DECODE_U8 (buffer + decoded, ielen, decoded);
memset (pkmfaddress, 0, sizeof (pkmf_address_t));
//OAILOG_TRACE (LOG_NAS_EMM, "decode_pkmf_address = %d\n", ielen);
CHECK_LENGTH_DECODER (len - decoded, ielen);
pkmfaddress->spare = (*(buffer + decoded) >> 3) & 0x1;
pkmfaddress->addresstype = *(buffer + decoded) & 0x1;
decoded++;
if (iei > 1)
{
pkmfaddress->pkmfipv4address = *(buffer + decoded ) & 0xf;
decoded++;
}
//OAILOG_TRACE (LOG_NAS_EMM, "PKMFAddress decoded=%u\n", decoded);
if ((ielen + 2) != decoded) {
decoded = ielen + 1 + (iei > 0 ? 1 : 0) /* Size of header for this IE */ ;
//OAILOG_TRACE (LOG_NAS_EMM, "PKMFAddress then decoded=%u\n", decoded);
}
return decoded;
}
int encode_pkmf_address(
pkmf_address_t *pkmfaddress,
uint8_t iei,
uint8_t *buffer,
uint32_t len)
{
uint8_t *lenPtr;
uint32_t encoded = 0;
if (iei > 0)
{
*buffer = iei;
encoded++;
lenPtr = (buffer + encoded);
encoded++;
*(buffer + encoded) = 0x00 | ((pkmfaddress->spare & 0x1) << 3) | (pkmfaddress->addresstype & 0x1);
encoded++;
lenPtr = (buffer + encoded);
encoded++;
*(buffer + encoded) = pkmfaddress->pkmfipv4address;
encoded++;
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
}
return encoded;
}
/*
* PKMFAddress.h
*
* Created on: Jun 11, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#ifndef OPENAIR3_NAS_COMMON_IES_PKMFADDRESS_H_
#define OPENAIR3_NAS_COMMON_IES_PKMFADDRESS_H_
typedef struct pkmf_address_s {
uint8_t spare:5;
#define ADDRESS_TYPE 001
uint8_t addresstype:3;
#define PKMF_IPV4_ADDRESS
//uint32_t pkmfipv4address;
uint32_t pkmfipv4address;
}pkmf_address_t;
int encode_pkmf_address(pkmf_address_t *pkmfaddress, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_pkmf_address(pkmf_address_t *pkmfaddress, uint8_t iei, uint8_t *buffer, uint32_t len);
#endif /* OPENAIR3_NAS_COMMON_IES_PKMFADDRESS_H_ */
/*
* RemoteUEContext.c
*
* Created on: Jun 11, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "RemoteUEContext.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "nas_log.h"
//#include "RemoteUserID.h"
static int nas_decode_imsi (imsi_identity_t * imsi, uint8_t * buffer, const uint8_t ie_len);
static int nas_encode_imsi (imsi_identity_t * imsi, uint8_t * buffer);
int decode_remote_ue_context(
remote_ue_context_t *remoteuecontext,
uint8_t iei,
uint8_t *buffer,
uint32_t len)
{
int decoded = 0;
uint8_t ielen = 0;
if (iei > 0)
{
CHECK_IEI_DECODER (iei, *buffer);
decoded++;
}
DECODE_U8 (buffer + decoded, ielen, decoded);
memset (remoteuecontext, 0, sizeof (remote_ue_context_t));
//OAILOG_TRACE (LOG_NAS_EMM, "decode_remote_ue_context = %d\n", ielen);
CHECK_LENGTH_DECODER (len - decoded, ielen);
remoteuecontext->numberofuseridentity = *(buffer + decoded ) & 0x1;;
//OAILOG_TRACE (LOG_NAS_EMM, "remoteuecontext decoded number of identities\n");
if (iei > 1){
remoteuecontext->imsi_identity->num_digits = *(buffer + decoded ) & 0xf;
decoded++;
}
if (iei > 2){
decoded += nas_decode_imsi(&remoteuecontext->imsi_identity, buffer + decoded, len - decoded);
decoded++;
}
//OAILOG_TRACE (LOG_NAS_EMM, "remoteuserid decoded=%u\n", decoded);
if ((ielen + 2) != decoded) {
decoded = ielen + 1 + (iei > 0 ? 1 : 0) /* Size of header for this IE */ ;
//OAILOG_TRACE (LOG_NAS_EMM, "remoteuecontext then decoded=%u\n", decoded);
}
return decoded;
}
int encode_remote_ue_context(
remote_ue_context_t *remoteuecontext,
uint8_t iei,
uint8_t *buffer,
uint32_t len)
{
uint8_t *lenPtr;
uint32_t encoded = 0;
if (iei > 0)
{
*buffer = iei;
encoded++;
}
lenPtr = (buffer + encoded);
encoded++;
*(buffer + encoded) = remoteuecontext->numberofuseridentity;
encoded++;
*(buffer + encoded) = remoteuecontext->imsi_identity->num_digits;
encoded++;
encoded += nas_encode_imsi(&remoteuecontext->imsi_identity, buffer + encoded);
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
return encoded;
}
//-----------------------------------------------------
int nas_decode_imsi (imsi_identity_t * imsi, uint8_t * buffer, const uint8_t ie_len)
{
//OAILOG_FUNC_IN (LOG_NAS_EMM);
int decoded = 0;
imsi->typeofidentity = *(buffer + decoded) & 0x7;
// if (imsi->typeofidentity != EPS_MOBILE_IDENTITY_IMSI)
//{
//return (TLV_VALUE_DOESNT_MATCH);
//}
imsi->oddeven = (*(buffer + decoded) >> 3) & 0x1;
imsi->identity_digit1 = (*(buffer + decoded) >> 4) & 0xf;
imsi->num_digits = 1;
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit2 = *(buffer + decoded) & 0xf;
imsi->identity_digit3 = (*(buffer + decoded) >> 4) & 0xf;
decoded++;
imsi->num_digits += 2;
if (decoded < ie_len)
{
imsi->identity_digit4 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit5 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_EVEN == imsi->oddeven) && (imsi->identity_digit5 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit6 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit7 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_EVEN == imsi->oddeven) && (imsi->identity_digit7 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit8 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit9 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_EVEN == imsi->oddeven) && (imsi->identity_digit9 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit10 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit11 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_EVEN == imsi->oddeven) && (imsi->identity_digit11 != 0x0f)) {
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit12 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit13 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_EVEN == imsi->oddeven) && (imsi->identity_digit13 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit14 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit15 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_EVEN == imsi->oddeven) && (imsi->identity_digit15 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
}
}
}
}
}
}
}
return decoded;
//OAILOG_FUNC_RETURN (LOG_NAS_EMM, decoded);
}
//---------------------------------------------------------------------
int nas_encode_imsi (imsi_identity_t * imsi, uint8_t * buffer)
{
uint32_t encoded = 0;
*(buffer + encoded) = 0x00 | (imsi->identity_digit1 << 4) | (imsi->oddeven << 3) | (imsi->typeofidentity);
encoded++;
*(buffer + encoded) = 0x00 | (imsi->identity_digit3 << 4) | imsi->identity_digit2;
encoded++;
// Quick fix, should do a loop, but try without modifying struct!
if (imsi->num_digits > 3) {
if (imsi->oddeven != IMSI_EVEN) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit5 << 4) | imsi->identity_digit4;
} else {
*(buffer + encoded) = 0xf0 | imsi->identity_digit4;
}
encoded++;
if (imsi->num_digits > 5) {
if (imsi->oddeven != IMSI_EVEN) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit7 << 4) | imsi->identity_digit6;
} else {
*(buffer + encoded) = 0xf0 | imsi->identity_digit6;
}
encoded++;
if (imsi->num_digits > 7) {
if (imsi->oddeven != IMSI_EVEN) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit9 << 4) | imsi->identity_digit8;
} else {
*(buffer + encoded) = 0xf0 | imsi->identity_digit8;
}
encoded++;
if (imsi->num_digits > 9) {
if (imsi->oddeven != IMSI_EVEN) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit11 << 4) | imsi->identity_digit10;
} else {
*(buffer + encoded) = 0xf0 | imsi->identity_digit10;
}
encoded++;
if (imsi->num_digits > 11) {
if (imsi->oddeven != IMSI_EVEN) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit13 << 4) | imsi->identity_digit12;
} else {
*(buffer + encoded) = 0xf0 | imsi->identity_digit12;
}
encoded++;
if (imsi->num_digits > 13) {
if (imsi->oddeven != IMSI_EVEN) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit15 << 4) | imsi->identity_digit14;
} else {
*(buffer + encoded) = 0xf0 | imsi->identity_digit14;
}
encoded++;
}
}
}
}
}
}
return encoded;
}
/*
* RemoteUEContext.h
*
* Created on: Jun 11, 2019
* Author: nepes
*/
#ifndef OPENAIR3_NAS_COMMON_IES_REMOTEUECONTEXT_H_
#define OPENAIR3_NAS_COMMON_IES_REMOTEUECONTEXT_H_
#include "RemoteUserID.h"
#define REMOTE_UE_CONTEXT_MINIMUM_LENGTH 16
#define REMOTE_UE_CONTEXT_MAXIMUM_LENGTH 28
//typedef struct imsi_identity_s {
//uint8_t identity_digit1:4;
//#define IMSI_EVEN 0
//#define IMSI_ODD 1
//uint8_t oddeven:1;
//#define REMOTE_UE_MOBILE_IDENTITY_IMSI 010
//uint8_t typeofidentity:3;
//uint8_t identity_digit2:4;
//uint8_t identity_digit3:4;
// uint8_t identity_digit4:4;
//uint8_t identity_digit5:4;
// uint8_t identity_digit6:4;
// uint8_t identity_digit7:4;
// uint8_t identity_digit8:4;
// uint8_t identity_digit9:4;
// uint8_t identity_digit10:4;
// uint8_t identity_digit11:4;
// uint8_t identity_digit12:4;
// uint8_t identity_digit13:4;
// uint8_t identity_digit14:4;
// uint8_t identity_digit15:4;
// because of union put this extra attribute at the end
// uint8_t num_digits;
//} imsi_identity_t;
typedef struct remote_ue_context_s {
uint8_t spare:4;
//#define REMOTE_UE_MOBILE_IDENTITY_IMSI 010
//uint8_t typeofuseridentity:3;
#define NUMBER_OF_REMOTE_UE_CONTEXT_IDENTITIES 1
uint8_t numberofuseridentity:8;
#define EVEN_IDENTITY 0
#define ODD_IDENTITY 1
uint8_t oddevenindic:1;
bool flags_present;
imsi_identity_t *imsi_identity;
}remote_ue_context_t;
//typedef union remote_ue_mobile_identity_s {
//#define REMOTE_UE_MOBILE_IDENTITY_IMSI_ENCRYPTED 001
//#define REMOTE_UE_MOBILE_IDENTITY_IMSI 010
//#define REMOTE_UE_MOBILE_IDENTITY_MSISDN 011
//#define REMOTE_UE_MOBILE_IDENTITY_IMEI 100
//#define REMOTE_UE_MOBILE_IDENTITY_IMEISV 101
// imsi_e_remote_ue_mobile_identity_t imsi_encrypted;
// imsi_remote_ue_mobile_identity_t imsi;
// msisdn_remote_ue_mobile_identity_t msisdn;
// imei_remote_ue_mobile_identity_t imei;
// imeisv_remote_ue_mobile_identity_t imeisv;
//} remote_ue_mobile_identity_t;
//#define REMOTE_UE_MOBILE_IDENTITY "remote_ue_identity_type"
int encode_remote_ue_context(remote_ue_context_t *remoteuecontext, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_remote_ue_context(remote_ue_context_t *remoteuecontext, uint8_t iei, uint8_t *buffer, uint32_t len);
#endif /* OPENAIR3_NAS_COMMON_IES_REMOTEUECONTEXT_H_ */
/*
* RemoteUserID.c
*
* Created on: Jun 11, 2019
* Author: nepes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "RemoteUserID.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
//#include "RemoteUEContext.h"
//#include "3gpp_23.003.h"
#include "nas_log.h"
#include "EpsMobileIdentity.h"
static int remoteue_decode_imsi (imsi_identity_t * imsi, uint8_t * buffer, const uint8_t ie_len);
static int remoteue_encode_imsi (imsi_identity_t * imsi, uint8_t * buffer);
int decode_remote_user_id(
remote_user_id_t *remoteuserid,
uint8_t iei,
uint8_t *buffer,
uint32_t len)
{
int decoded = 0;
uint8_t ielen = 0;
if (iei > 0)
{
CHECK_IEI_DECODER (iei, *buffer);
decoded++;
}
DECODE_U8 (buffer + decoded, ielen, decoded);
memset (remoteuserid, 0, sizeof (remote_user_id_t));
//OAILOG_TRACE (LOG_NAS_EMM, "decode_remote_user_id = %d\n", ielen);
CHECK_LENGTH_DECODER (len - decoded, ielen);
remoteuserid ->spare = (*(buffer + decoded) << 4) & 0x1;
remoteuserid->instance = *(buffer + decoded) & 0x1;
decoded++;
remoteuserid->spare_instance = 1;
//OAILOG_TRACE (LOG_NAS_EMM, "remoteuserid decoded spare_instance\n");
if (iei > 1){
remoteuserid ->spare1 = (*(buffer + decoded) << 2) & 0x5f;
remoteuserid->imeif = (*(buffer + decoded) << 1) & 0x1;
remoteuserid->msisdnf = *(buffer + decoded ) & 0x1;
decoded++;
remoteuserid->flags_present = 1;
// OAILOG_TRACE (LOG_NAS_EMM, "remoteuserid decoded flags_present\n");
if (iei > 2){
remoteuserid->imsi_identity->num_digits = *(buffer + decoded ) & 0xf;
decoded++;
if (iei > 3){
decoded += remoteue_decode_imsi(&remoteuserid->imsi_identity, buffer + decoded, len-decoded);
decoded++;
}
}
}
//OAILOG_TRACE (LOG_NAS_EMM, "remoteuserid decoded=%u\n", decoded);
if ((ielen + 2) != decoded) {
decoded = ielen + 1 + (iei > 0 ? 1 : 0) /* Size of header for this IE */ ;
//OAILOG_TRACE (LOG_NAS_EMM, "remoteuserid then decoded=%u\n", decoded);
}
return decoded;
}
int encode_remote_user_id(
remote_user_id_t *remoteuserid,
uint8_t iei,
uint8_t *buffer,
uint32_t len)
{
uint8_t *lenPtr;
uint32_t encoded = 0;
if (iei > 0)
{
*buffer = iei;
encoded++;
}
lenPtr = (buffer + encoded);
encoded++;
if(remoteuserid->spare_instance){
*(buffer + encoded) = 0x00 | ((remoteuserid->spare & 0x1) << 4) | (remoteuserid->instance & 0x1);
encoded++;
}
if(remoteuserid->flags_present){
*(buffer + encoded) = ((remoteuserid->spare1 & 0x7) << 2) | // spare coded as zero
((remoteuserid->imeif & 0x1) << 1) |
(remoteuserid->msisdnf & 0x1);
encoded++;
}
lenPtr = (buffer + encoded);
encoded++;
*(buffer + encoded) = remoteuserid->imsi_identity->num_digits;
encoded++;
encoded += remoteue_encode_imsi(&remoteuserid->imsi_identity, buffer + encoded);
encoded++;
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
return encoded;
}
int remoteue_decode_imsi (imsi_identity_t * imsi, uint8_t * buffer, const uint8_t ie_len)
{
//OAILOG_FUNC_IN (LOG_NAS_EMM);
int decoded = 0;
imsi->instanceimsi = *(buffer + decoded) & 0xf;
imsi->spareimsi = (*(buffer + decoded) >> 4) & 0xf;
//imsi->typeofidentity = *(buffer + decoded) & 0x7;
// if (imsi->typeofidentity != EPS_MOBILE_IDENTITY_IMSI)
//{
//return (TLV_VALUE_DOESNT_MATCH);
//}
//imsi->oddeven = (*(buffer + decoded) >> 3) & 0x1;
//imsi->identity_digit1 = (*(buffer + decoded) >> 4) & 0xf;
imsi->num_digits = 1;
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit1 = *(buffer + decoded) & 0xf;
imsi->identity_digit2 = (*(buffer + decoded) >> 4) & 0xf;
decoded++;
imsi->num_digits += 2;
if (decoded < ie_len)
{
imsi->identity_digit3 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit4 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_ODD == imsi->oddeven) && (imsi->identity_digit5 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit5 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit6 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_ODD == imsi->oddeven) && (imsi->identity_digit7 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit7 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit8 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_ODD == imsi->oddeven) && (imsi->identity_digit9 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit9 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit10 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_ODD == imsi->oddeven) && (imsi->identity_digit11 != 0x0f)) {
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit11 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit12 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_ODD == imsi->oddeven) && (imsi->identity_digit13 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
if (decoded < ie_len)
{
imsi->identity_digit13 = *(buffer + decoded) & 0xf;
imsi->num_digits++;
imsi->identity_digit14 = (*(buffer + decoded) >> 4) & 0xf;
if ((IMSI_ODD == imsi->oddeven) && (imsi->identity_digit15 != 0x0f))
{
return (TLV_DECODE_VALUE_DOESNT_MATCH);
}
else
{
imsi->num_digits++;
}
decoded++;
}
}
}
}
}
}
}
return decoded;
//OAILOG_FUNC_RETURN (LOG_NAS_EMM, decoded);
}
//---------------------------------------------------------------------
int remoteue_encode_imsi (imsi_identity_t * imsi, uint8_t * buffer)
{
uint32_t encoded = 0;
*(buffer + encoded) = 0x00 | (imsi->spareimsi << 4) | (imsi->instanceimsi);
encoded++;
*(buffer + encoded) = 0x00 | (imsi->identity_digit2 << 4) | imsi->identity_digit1;
encoded++;
// Quick fix, should do a loop, but try without modifying struct!
if (imsi->num_digits > 2) {
//if (imsi->oddeven != IMSI_ODD) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit4 << 4) | imsi->identity_digit3;
// } else {
// *(buffer + encoded) = 0xf0 | imsi->identity_digit3;
encoded++;
if (imsi->num_digits > 4) {
//if (imsi->oddeven != IMSI_ODD) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit6 << 4) | imsi->identity_digit5;
// } else {
// *(buffer + encoded) = 0xf0 | imsi->identity_digit5;
//}
encoded++;
if (imsi->num_digits > 6) {
//if (imsi->oddeven != IMSI_ODD) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit8 << 4) | imsi->identity_digit7;
// } else {
// *(buffer + encoded) = 0xf0 | imsi->identity_digit7;
//}
encoded++;
if (imsi->num_digits > 8) {
// if (imsi->oddeven != IMSI_ODD) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit10 << 4) | imsi->identity_digit9;
// } else {
//*(buffer + encoded) = 0xf0 << 4 | imsi->identity_digit9;
//}
encoded++;
if (imsi->num_digits > 10) {
//if (imsi->oddeven != IMSI_ODD) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit12 << 4) | imsi->identity_digit11;
//} else {
//*(buffer + encoded) = 0xf0 | imsi->identity_digit11;
//}
encoded++;
if (imsi->num_digits > 12) {
//if (imsi->oddeven != IMSI_ODD) {
*(buffer + encoded) = 0x00 | (imsi->identity_digit14 << 4) | imsi->identity_digit13;
//} else {
//*(buffer + encoded) = 0xf0 | imsi->identity_digit13;
//}
encoded++;
if (imsi->num_digits > 14) {
*(buffer + encoded) = (0xf0 << 4) | imsi->identity_digit15;
}
encoded++;
}
}
}
}
}
}
if (imsi->oddeven == IMSI_ODD) {
*(buffer + encoded - 1) = 0xf0 | *(buffer + encoded - 1);
}
return encoded;
}
/*
* RemoteUserID.h
*
* Created on: Jun 11, 2019
* Author: nepes
*/
#include "EpsMobileIdentity.h"
//#include "RemoteUEContext.h"
#ifndef OPENAIR3_NAS_COMMON_IES_REMOTEUSERID_H_
#define OPENAIR3_NAS_COMMON_IES_REMOTEUSERID_H_
//#include "3gpp_23.003.h"
#include "EpsMobileIdentity.h"
#define REMOTE_USER_ID_MINIMUM_LENGTH 10
//#define REMOTE_USER_ID_MAXIMUM_LENGTH 1
typedef struct imsi_identity_s {
uint8_t spareimsi:4;
#define IMSI_INSTANCE 0
uint8_t instanceimsi:4;
uint8_t identity_digit1:4;
#define IMSI_EVEN 0
#define IMSI_ODD 1
uint8_t oddeven:1;
#define REMOTE_UE_MOBILE_IDENTITY_IMSI 010
uint8_t typeofidentity:3;
uint8_t identity_digit2:4;
uint8_t identity_digit3:4;
uint8_t identity_digit4:4;
uint8_t identity_digit5:4;
uint8_t identity_digit6:4;
uint8_t identity_digit7:4;
uint8_t identity_digit8:4;
uint8_t identity_digit9:4;
uint8_t identity_digit10:4;
uint8_t identity_digit11:4;
uint8_t identity_digit12:4;
uint8_t identity_digit13:4;
uint8_t identity_digit14:4;
uint8_t identity_digit15:4;
// because of union put this extra attribute at the end
uint8_t num_digits;
} imsi_identity_t;
typedef imsi_identity_t;
typedef struct remote_user_id_s {
uint8_t spare:4;
#define REMOTE_USER_ID_INSTANCE 0
uint8_t instance:4;
uint8_t spare1:6;
#define REMOTE_USER_ID_IMEIF 0
uint8_t imeif:1;
#define REMOTE_USER_ID_MSISDN 0
uint8_t msisdnf:1;
bool flags_present;
bool spare_instance;
imsi_identity_t *imsi_identity;
}remote_user_id_t;
//typedef union remoteuser_mobile_identity_s {
//imsi_identity_t imsi;
//} remoteuser_mobile_identity_t;
int encode_remote_user_id(remote_user_id_t *remoteuserid, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_remote_user_id(remote_user_id_t *remoteuserid, uint8_t iei, uint8_t *buffer, uint32_t len);
#endif /* OPENAIR3_NAS_COMMON_IES_REMOTEUSERID_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*****************************************************************************
Source RemoteUereport.c
Version
Date 2019/06/08
Product NAS stack
Subsystem EPS Session Management
Author
Description
*****************************************************************************/
#include <stdlib.h> // malloc, free
#include <string.h> // memset, memcpy, memcmp
#include <ctype.h> // isprint
#include "esm_proc.h"
#include "commonDef.h"
#include "nas_log.h"
#include "PdnConnectivity.c"
#include "esmData.h"
#include "esm_cause.h"
#include "esm_pt.h"
#include "emm_sap.h"
#if defined(ENABLE_ITTI)
# include "assertions.h"
#endif
/****************************************************************************/
/**************** E X T E R N 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 *******************/
/****************************************************************************/
/*
* --------------------------------------------------------------------------
* Internal data handled by the PDN connectivity procedure in the UE
* --------------------------------------------------------------------------
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
int esm_proc_remote_ue_report(nas_user_t *user,int cid, unsigned int *pti)
{
LOG_FUNC_IN;
int rc = RETURNerror;
int pid = cid - 1;
if (pti != NULL) {
esm_data_t *esm_data = user-> esm_data;
esm_pt_data_t *esm_pt_data = user-> esm_pt_data;
LOG_TRACE(INFO, "ESM-PROC - Assign new procedure transaction identity ");
/* Assign new procedure transaction identity */
*pti = esm_pt_assign(esm_pt_data);
if (*pti == ESM_PT_UNASSIGNED) {
LOG_TRACE(WARNING, "ESM-PROC - Failed to assign new procedure transaction identity");
LOG_FUNC_RETURN (RETURNerror);
}
//static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti);
/* Update the PDN connection data */
rc = _pdn_connectivity_set_pti(esm_data, pid, *pti);
if (rc != RETURNok) {
LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection");
}
}
LOG_FUNC_RETURN(rc);
}
...@@ -158,6 +158,20 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) ...@@ -158,6 +158,20 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg)
esm_sap_primitive2str(primitive - ESM_START - 1), primitive); esm_sap_primitive2str(primitive - ESM_START - 1), primitive);
switch (primitive) { switch (primitive) {
case ESM_REMOTE_UE_REPORT_REQ:
{
esm_remote_ue_report_t *remote_ue_report = &msg->data.remote_ue_report;
unsigned int pti = 0;
int cid;
/* Assign new procedure transaction identity */
rc = esm_proc_remote_ue_report(user, cid, &pti);
rc = _esm_sap_send(user, REMOTE_UE_REPORT,
msg->is_standalone,
pti, EPS_BEARER_IDENTITY_UNASSIGNED,
&msg->data, &msg->send);
}
break;
case ESM_PDN_CONNECTIVITY_REQ: case ESM_PDN_CONNECTIVITY_REQ:
{ {
esm_pdn_connectivity_t *pdn_connect = &msg->data.pdn_connect; esm_pdn_connectivity_t *pdn_connect = &msg->data.pdn_connect;
...@@ -757,6 +771,11 @@ static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, ...@@ -757,6 +771,11 @@ static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone,
case BEARER_RESOURCE_MODIFICATION_REQUEST: case BEARER_RESOURCE_MODIFICATION_REQUEST:
break; break;
case REMOTE_UE_REPORT:
rc = esm_proc_remote_ue_report(user, pti, &esm_msg.remote_ue_report);
//#error "TODO"//
break;
default: default:
LOG_TRACE(WARNING, "ESM-SAP - Send unexpected ESM message 0x%x", LOG_TRACE(WARNING, "ESM-SAP - Send unexpected ESM message 0x%x",
msg_type); msg_type);
......
...@@ -77,6 +77,7 @@ typedef enum esm_primitive_s { ...@@ -77,6 +77,7 @@ typedef enum esm_primitive_s {
ESM_BEARER_RESOURCE_MODIFY_REJ, ESM_BEARER_RESOURCE_MODIFY_REJ,
/* ESM data indication ("raw" ESM message) */ /* ESM data indication ("raw" ESM message) */
ESM_UNITDATA_IND, ESM_UNITDATA_IND,
ESM_REMOTE_UE_REPORT_REQ,
ESM_END ESM_END
} esm_primitive_t; } esm_primitive_t;
...@@ -136,6 +137,14 @@ typedef struct esm_eps_bearer_context_deactivate_s { ...@@ -136,6 +137,14 @@ typedef struct esm_eps_bearer_context_deactivate_s {
* to be deactivated */ * to be deactivated */
} esm_eps_bearer_context_deactivate_t; } esm_eps_bearer_context_deactivate_t;
/*
* ESM primitive for triggering a remote ue report procedure from ESM
* ---------------------------------------------------------
*/
typedef struct esm_remote_ue_report_s {
unsigned int dummy;
} esm_remote_ue_report_t;
/* /*
* ------------------------------ * ------------------------------
* Structure of ESM-SAP primitive * Structure of ESM-SAP primitive
...@@ -145,6 +154,7 @@ typedef union { ...@@ -145,6 +154,7 @@ typedef union {
esm_pdn_connectivity_t pdn_connect; esm_pdn_connectivity_t pdn_connect;
esm_pdn_disconnect_t pdn_disconnect; esm_pdn_disconnect_t pdn_disconnect;
esm_eps_bearer_context_deactivate_t eps_bearer_context_deactivate; esm_eps_bearer_context_deactivate_t eps_bearer_context_deactivate;
esm_remote_ue_report_t remote_ue_report;
} esm_sap_data_t; } esm_sap_data_t;
typedef struct esm_sap_s { typedef struct esm_sap_s {
......
...@@ -117,6 +117,12 @@ int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *m ...@@ -117,6 +117,12 @@ int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *m
int sent_by_ue); int sent_by_ue);
/*
* --------------------------------------------------------------------------
* REMOTE UE REPORT procedure
* --------------------------------------------------------------------------
*/
int esm_proc_remote_ue_report(nas_user_t *user,int cid, unsigned int *pti);
/* /*
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* PDN connectivity procedure * PDN connectivity procedure
......
...@@ -985,7 +985,51 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid) ...@@ -985,7 +985,51 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid)
LOG_FUNC_RETURN (rc); LOG_FUNC_RETURN (rc);
} }
/* /****************************************************************************
** **
** Name: nas_proc_remote_ue_report() **
** **
** Description: Ask the NAS to send a REMOTE UE REPORT **
** **
** Inputs: cid: Identifier of the PDN context **
** Others: None **
** **
** Outputs: None **
** Return: RETURNok, RETURNerror **
** Others: None **
** **
***************************************************************************/
int nas_proc_remote_ue_report(nas_user_t *user, int cid)
{
LOG_FUNC_IN;
int rc = RETURNok;
if ( !emm_main_is_attached(user->emm_data) ) {
/*
* If the UE is not attached to the network, perform EPS attach
* procedure prior to attempt to request any PDN connectivity
*/
LOG_TRACE(WARNING, "NAS-PROC - UE is not attached to the network");
rc = nas_proc_attach(user);
} else if (emm_main_is_emergency(user->emm_data)) {
/* The UE is attached for emergency bearer services; It shall not
* request a PDN connection to any other PDN */
LOG_TRACE(WARNING,"NAS-PROC - Attached for emergency bearer services");
rc = RETURNerror;
}
if (rc != RETURNerror) {
if (cid > 0) {
/* Activate only the specified PDN context */
rc = _nas_proc_activate(user, cid, TRUE);
} else {
/// log?
}
}
LOG_FUNC_RETURN (rc);
}/*
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* NAS procedures triggered by the network * NAS procedures triggered by the network
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
...@@ -1341,6 +1385,40 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) ...@@ -1341,6 +1385,40 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all)
LOG_FUNC_RETURN (rc); LOG_FUNC_RETURN (rc);
} }
/****************************************************************************
** **
** Name: _nas_proc_remote_ue_report() **
** **
** Description: Initiates a PDN connectivity procedure **
** **
** Inputs: cid: Identifier of the PDN context used to es- **
** tablished connectivity to specified PDN **
** Others: None **
** **
** Outputs: None **
** Return: RETURNok, RETURNerror **
** Others: None **
** **
***************************************************************************/
static int _nas_proc_remote_ue_report(nas_user_t *user, int cid)
{
LOG_FUNC_IN;
int rc = RETURNok;
esm_sap_t esm_sap = {};
/*
* Notify ESM that a default EPS bearer has to be established
* for the specified PDN
*/
esm_sap.primitive = ESM_REMOTE_UE_REPORT_REQ;
esm_sap.is_standalone = TRUE;
esm_sap.data.remote_ue_report.dummy = 0;
rc = esm_sap_send(user, &esm_sap);
LOG_FUNC_RETURN (rc);
}
/**************************************************************************** /****************************************************************************
** ** ** **
** Name: _nas_proc_deactivate() ** ** Name: _nas_proc_deactivate() **
......
...@@ -105,6 +105,7 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add ...@@ -105,6 +105,7 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add
const char **addr2, int n_addr_max); const char **addr2, int n_addr_max);
int nas_proc_deactivate_pdn(nas_user_t *user, int cid); int nas_proc_deactivate_pdn(nas_user_t *user, int cid);
int nas_proc_activate_pdn(nas_user_t *user, int cid); int nas_proc_activate_pdn(nas_user_t *user, int cid);
int nas_proc_remote_ue_report(nas_user_t *user, int cid);
/* /*
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
......
...@@ -203,6 +203,16 @@ void *nas_ue_task(void *args_p) ...@@ -203,6 +203,16 @@ void *nas_ue_task(void *args_p)
/* TODO not processed by NAS currently */ /* TODO not processed by NAS currently */
break; break;
//for Remote UE Report
case NAS_REMOTE_UE_REPORT:
LOG_I(NAS, "[UE %d] Received %s: \n", Mod_id, ITTI_MSG_NAME (msg_p));
// To send remote ue report to be sent by RRC UE to CN
int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id);
/* TODO not processed by NAS currently */
break;
case NAS_CONN_ESTABLI_CNF: case NAS_CONN_ESTABLI_CNF:
LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME (msg_p), LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
......
...@@ -172,7 +172,7 @@ int s1ap_eNB_handle_nas_first_req( ...@@ -172,7 +172,7 @@ int s1ap_eNB_handle_nas_first_req(
do { do {
struct s1ap_eNB_ue_context_s *collision_p; struct s1ap_eNB_ue_context_s *collision_p;
/* Peek a random value for the eNB_ue_s1ap_id */ /* Pick a random value for the eNB_ue_s1ap_id */
ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff; ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff;
if ((collision_p = RB_INSERT(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_desc_p)) if ((collision_p = RB_INSERT(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_desc_p))
...@@ -321,7 +321,7 @@ int s1ap_eNB_handle_nas_first_req( ...@@ -321,7 +321,7 @@ int s1ap_eNB_handle_nas_first_req(
ie->id = S1AP_ProtocolIE_ID_id_RelayNode_Indicator; ie->id = S1AP_ProtocolIE_ID_id_RelayNode_Indicator;
ie->criticality = S1AP_Criticality_ignore; ie->criticality = S1AP_Criticality_ignore;
ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_RelayNode_Indicator; ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_RelayNode_Indicator;
// ie->value.choice.RelayNode_Indicator =; //ie->value.choice.RelayNode_Indicator = S1AP_RelayNode_Indicator_t;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
} }
......
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