Merge remote-tracking branch 'origin/e1ap-lib-improvements' into integration_2025_w06 (!3219)
E1AP enc/dec lib improvements This MR is including some fixes and improvements for the E1AP library, focusing mostly on Bearer Context Management: - struct reorganization: split setup and modification request messages into distinct structures, ensuring compliance with 3GPP TS 38.463 specifications - add encoding/decoding sub-functions for different IEs - improvements to Bearer Context Management: Implemented various improvements to the E1 Bearer Context Setup Response and Request, including the adoption of encoding/decoding sub-functions for different IEs - use lib functions whenever need (e.g. cp_bearer_context_setup_request in cucp_cuup_e1ap.c) - handle optional struct members as pointers - updated copy/equality check utility functions EDIT: The MR is also including the changes from !3222 (closed): > While testing E1 with security enabled for DRBs, it was found that > data traffic was not functional. > > The problem was that security settings were modified in the PDCP > reestablishment happening when receiving Bearer Context Modification > Request. > > So some restructuring was done. > > The actual fix is in 18176297, the others are for support. Basically > we introduce a boolean to check if the security settings are present in > Bearer Context Modification Request and we change PDCP security settings > only if they are. > > (Note that in OAI CU security settings are not sent in Bearer Context > Modification Request, so we could also remove all this, but we need to > be compatible with other cu-up and/or cu-cp.)
This commit is contained in:
@@ -9,6 +9,7 @@ services:
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --telnetsrv --telnetsrv.listenport 9090 --telnetsrv.shrmod ci
|
||||
--log_config.global_log_options level,nocolor,time,line_num,function
|
||||
--security.drb_integrity yes
|
||||
volumes:
|
||||
- ../../conf_files/gnb-cucp.sa.f1.quectel.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
# for performance reasons, we use host mode: in bridge mode, we have
|
||||
|
||||
@@ -125,7 +125,7 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t
|
||||
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
|
||||
|
||||
void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); }
|
||||
void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); }
|
||||
void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) { abort(); }
|
||||
void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); }
|
||||
|
||||
int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) {
|
||||
|
||||
@@ -51,7 +51,7 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req)
|
||||
void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t
|
||||
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
|
||||
void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); }
|
||||
void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); }
|
||||
void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) { abort(); }
|
||||
void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); }
|
||||
|
||||
int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) {
|
||||
|
||||
@@ -138,12 +138,6 @@ typedef enum BEARER_CONTEXT_STATUS_e {
|
||||
BEARER_RESUME,
|
||||
} BEARER_CONTEXT_STATUS_t;
|
||||
|
||||
typedef enum activity_notification_level_e {
|
||||
ANL_DRB = 0,
|
||||
ANL_PDU_SESSION,
|
||||
ANL_UE,
|
||||
} activity_notification_level_t;
|
||||
|
||||
typedef enum cell_group_id_e {
|
||||
MCG = 0,
|
||||
SCG,
|
||||
@@ -258,10 +252,16 @@ typedef struct e1ap_setup_fail_s {
|
||||
criticality_diagnostics_t *crit_diag;
|
||||
} e1ap_setup_fail_t;
|
||||
|
||||
typedef struct up_params_s {
|
||||
typedef struct UP_TL_information_s {
|
||||
in_addr_t tlAddress;
|
||||
long teId;
|
||||
int cell_group_id;
|
||||
int32_t teId;
|
||||
} UP_TL_information_t;
|
||||
|
||||
typedef struct up_params_s {
|
||||
// Transport layer info
|
||||
UP_TL_information_t tl_info;
|
||||
// Cell Group ID (M)
|
||||
cell_group_id_t cell_group_id;
|
||||
} up_params_t;
|
||||
|
||||
/* IE SDAP Configuration (clause 9.3.1.39 of 3GPP TS 38.463) */
|
||||
@@ -331,38 +331,63 @@ typedef struct qos_flow_level_qos_parameters_s {
|
||||
ngran_allocation_retention_priority_t alloc_reten_priority; // additional members should be added!!
|
||||
} qos_flow_level_qos_parameters_t;
|
||||
|
||||
// QoS Flow QoS Parameters List 9.3.1.25
|
||||
typedef struct qos_flow_setup_e {
|
||||
long qfi; // qos flow identifier
|
||||
qos_flow_level_qos_parameters_t qos_params;
|
||||
} qos_flow_to_setup_t;
|
||||
|
||||
/* DRB To Setup List according to 3GPP TS 38.463 */
|
||||
// 9.3.1.60 QoS Flow Mapping Indication
|
||||
typedef enum qos_flow_mapping_indication_e {
|
||||
QF_UL = 0,
|
||||
QF_DL,
|
||||
QF_BOTH
|
||||
} qos_flow_mapping_indication_t;
|
||||
|
||||
typedef struct qos_flow_list_s {
|
||||
long qfi; // qos flow identifier
|
||||
qos_flow_mapping_indication_t *indication;
|
||||
} qos_flow_list_t;
|
||||
|
||||
/**
|
||||
* DRB To Setup List according to 3GPP TS 38.463
|
||||
*/
|
||||
typedef struct DRB_nGRAN_to_setup_s {
|
||||
/* DRB ID (clause 9.3.1.16) */
|
||||
// DRB ID (M) (clause 9.3.1.16)
|
||||
long id;
|
||||
|
||||
/* SDAP Configuration (clause 9.3.1.39) */
|
||||
// SDAP Configuration (M) (clause 9.3.1.39)
|
||||
bearer_context_sdap_config_t sdap_config;
|
||||
/* PDCP Configuration (clause 9.3.1.38) */
|
||||
// PDCP Configuration (M) (clause 9.3.1.38)
|
||||
bearer_context_pdcp_config_t pdcp_config;
|
||||
|
||||
/* DRB Data Forwarding Information (clause 9.3.2.6) */
|
||||
/* Transport Layer Address (clause 9.3.2.4) */
|
||||
in_addr_t tlAddress;
|
||||
/* GTP-TEID (clause 9.3.2.3) */
|
||||
int teId;
|
||||
/* DL UP Transport Layer Information (clause 9.3.2.1) */
|
||||
int numDlUpParam;
|
||||
up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM];
|
||||
|
||||
/* Cell Group Information (clause 9.3.1.11) */
|
||||
// DRB Inactivity Timer (O)
|
||||
int *drb_inactivity_timer;
|
||||
// Cell Group Information (M) (clause 9.3.1.11)
|
||||
int numCellGroups;
|
||||
cell_group_id_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
|
||||
|
||||
/* DRB QoS Flows Parameters (clause 9.3.1.26) */
|
||||
// QoS Flows Information To Be Setup (M) (clause 9.3.1.25, 9.3.1.26)
|
||||
int numQosFlow2Setup;
|
||||
qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
} DRB_nGRAN_to_setup_t, DRB_nGRAN_to_mod_t;
|
||||
} DRB_nGRAN_to_setup_t;
|
||||
|
||||
/**
|
||||
* DRB To Modify List according to 3GPP TS 38.463
|
||||
*/
|
||||
typedef struct DRB_nGRAN_to_modify_s {
|
||||
// DRB ID (M) (clause 9.3.1.16)
|
||||
long id;
|
||||
// SDAP Configuration (O) (clause 9.3.1.39)
|
||||
bearer_context_sdap_config_t *sdap_config;
|
||||
// PDCP Configuration (O) (clause 9.3.1.38)
|
||||
bearer_context_pdcp_config_t *pdcp_config;
|
||||
// PDCP SN Status Request (O)
|
||||
bool pdcp_sn_status_requested;
|
||||
// DL UP Transport Layer Information (O) (clause 9.3.1.13, 9.3.2.1)
|
||||
int numDlUpParam;
|
||||
up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM];
|
||||
// QoS Flows Information To Modify (O) (clause 9.3.1.25, 9.3.1.26)
|
||||
int numQosFlow2Setup;
|
||||
qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
} DRB_nGRAN_to_mod_t;
|
||||
|
||||
typedef enum e1ap_indication_e {
|
||||
SECURITY_REQUIRED = 0,
|
||||
@@ -377,48 +402,108 @@ typedef struct security_indication_s {
|
||||
long maxIPrate;
|
||||
} security_indication_t;
|
||||
|
||||
typedef struct UP_TL_information_s {
|
||||
in_addr_t tlAddress;
|
||||
int32_t teId;
|
||||
} UP_TL_information_t;
|
||||
|
||||
/**
|
||||
* PDU Session Resource To Setup List (clause 9.3.3.10)
|
||||
* PDU Session Resource To Modify List (clause 9.3.3.11)
|
||||
*/
|
||||
typedef struct pdu_session_to_setup_s {
|
||||
long sessionId;
|
||||
long sessionType;
|
||||
e1ap_nssai_t nssai;
|
||||
security_indication_t securityIndication;
|
||||
UP_TL_information_t UP_TL_information;
|
||||
long numDRB2Setup;
|
||||
DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_DRBS];
|
||||
long numDRB2Modify;
|
||||
DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
|
||||
} pdu_session_to_setup_t, pdu_session_to_mod_t;
|
||||
|
||||
/**
|
||||
* Bearer Context Setup Request message, clause 9.2.2.1 of 3GPP TS 38.463
|
||||
* out of simplicity, this same struct is used for clause 9.2.2.4
|
||||
* i.e. Bearer Context Modification Request message
|
||||
*/
|
||||
typedef struct e1ap_bearer_setup_req_s {
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
uint32_t gNB_cu_up_ue_id; // Bearer Context Modification Request only
|
||||
// Security Information (9.3.1.10)
|
||||
typedef struct security_information_s {
|
||||
uint64_t cipheringAlgorithm;
|
||||
uint64_t integrityProtectionAlgorithm;
|
||||
char encryptionKey[E1AP_SECURITY_KEY_SIZE];
|
||||
char integrityProtectionKey[E1AP_SECURITY_KEY_SIZE];
|
||||
long ueDlAggMaxBitRate;
|
||||
} security_information_t;
|
||||
|
||||
/**
|
||||
* PDU Session Resource To Setup List (clause 9.3.3.10)
|
||||
*/
|
||||
typedef struct pdu_session_to_setup_s {
|
||||
// PDU Session ID (M)
|
||||
long sessionId;
|
||||
// PDU Session Type (M)
|
||||
long sessionType;
|
||||
// S-NSSAI (M)
|
||||
e1ap_nssai_t nssai;
|
||||
// Security Indication (M)
|
||||
security_indication_t securityIndication;
|
||||
// PDU Session Resource DL Aggregate Maximum Bit Rate (O)
|
||||
long *dlAggregateMaxBitRate;
|
||||
// NG UL UP Transport Layer Information (M)
|
||||
UP_TL_information_t UP_TL_information;
|
||||
// PDU Session Inactivity Timer (O)
|
||||
int *inactivityTimer;
|
||||
// DRB To Setup List (M)
|
||||
int numDRB2Setup;
|
||||
// DRB To Setup Item (1..<E1AP_MAX_NUM_DRBS>)
|
||||
DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_DRBS];
|
||||
} pdu_session_to_setup_t;
|
||||
|
||||
/**
|
||||
* PDU Session Resource To Modify List (clause 9.3.3.11)
|
||||
*/
|
||||
typedef struct pdu_session_to_mod_s {
|
||||
// PDU Session ID (M)
|
||||
long sessionId;
|
||||
// Security Indication (O)
|
||||
security_indication_t *securityIndication;
|
||||
// NG UL UP Transport Layer Information (O)
|
||||
UP_TL_information_t *UP_TL_information;
|
||||
// DRB To Setup List (0..1)
|
||||
int numDRB2Setup;
|
||||
// DRB To Setup Item (1..<E1AP_MAX_NUM_DRBS>)
|
||||
DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_DRBS];
|
||||
// DRB To Modify List (0..1)
|
||||
long numDRB2Modify;
|
||||
// DRB To Modify Item (1..<E1AP_MAX_NUM_DRBS>)
|
||||
DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
|
||||
} pdu_session_to_mod_t;
|
||||
|
||||
/**
|
||||
* Bearer Context Setup Request message, clause 9.2.2.1 of 3GPP TS 38.463
|
||||
*/
|
||||
typedef struct e1ap_bearer_setup_req_s {
|
||||
// gNB-CU-CP UE E1AP ID (M)
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
// Security Information (M)
|
||||
security_information_t secInfo;
|
||||
// UE DL Aggregate Maximum Bit Rate (M)
|
||||
long ueDlAggMaxBitRate;
|
||||
// UE DL Maximum Integrity Protected Data Rate (O)
|
||||
long *ueDlMaxIPBitRate;
|
||||
// Serving PLMN (M)
|
||||
PLMN_ID_t servingPLMNid;
|
||||
// Bearer Context Status Change (O)
|
||||
BEARER_CONTEXT_STATUS_t bearerContextStatus;
|
||||
activity_notification_level_t activityNotificationLevel;
|
||||
// UE Inactivity Timer (O)
|
||||
int *inactivityTimerUE;
|
||||
// NG-RAN PDU Session Resource To Setup List (M)
|
||||
int numPDUSessions;
|
||||
pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
} e1ap_bearer_setup_req_t;
|
||||
|
||||
/**
|
||||
* Bearer Context Modification Request, clause 9.2.2.4 of 3GPP TS 38.463
|
||||
*/
|
||||
typedef struct e1ap_bearer_mod_req_s {
|
||||
// gNB-CU-CP UE E1AP ID (M)
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
// gNB-CU-UP UE E1AP ID (M)
|
||||
uint32_t gNB_cu_up_ue_id;
|
||||
// Security Information (O)
|
||||
security_information_t *secInfo;
|
||||
// UE DL Aggregate Maximum Bit Rate (O)
|
||||
uint32_t *ueDlAggMaxBitRate;
|
||||
// UE DL Maximum Integrity Protected Data Rate (O)
|
||||
uint32_t *ueDlMaxIPBitRate;
|
||||
// Bearer Context Status Change (O)
|
||||
BEARER_CONTEXT_STATUS_t *bearerContextStatus;
|
||||
// UE Inactivity Timer (O)
|
||||
int *inactivityTimer;
|
||||
// Data Discard Required (O)
|
||||
bool dataDiscardRequired;
|
||||
// NG-RAN PDU Session Resource To Setup List (O)
|
||||
int numPDUSessions;
|
||||
pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
// NG-RAN PDU Session Resource To Modify List (O)
|
||||
int numPDUSessionsMod;
|
||||
pdu_session_to_mod_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
} e1ap_bearer_setup_req_t, e1ap_bearer_mod_req_t;
|
||||
} e1ap_bearer_mod_req_t;
|
||||
|
||||
typedef struct e1ap_bearer_release_cmd_s {
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
@@ -432,43 +517,61 @@ typedef struct e1ap_bearer_release_cplt_s {
|
||||
uint32_t gNB_cu_up_ue_id;
|
||||
} e1ap_bearer_release_cplt_t;
|
||||
|
||||
typedef struct qos_flow_setup_s {
|
||||
long qfi;
|
||||
} qos_flow_setup_t;
|
||||
|
||||
typedef struct DRB_nGRAN_setup_s {
|
||||
// DRB ID (M)
|
||||
long id;
|
||||
int numUpParam;
|
||||
up_params_t UpParamList[E1AP_MAX_NUM_UP_PARAM];
|
||||
// Flow Setup List (M)
|
||||
int numQosFlowSetup;
|
||||
qos_flow_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
qos_flow_list_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
} DRB_nGRAN_setup_t;
|
||||
|
||||
/* DRB Modified Item */
|
||||
typedef struct DRB_nGRAN_modified_s {
|
||||
// DRB ID (M)
|
||||
long id;
|
||||
// UL UP Parameters (O)
|
||||
int numUpParam;
|
||||
up_params_t ul_UP_Params[E1AP_MAX_NUM_UP_PARAM];
|
||||
// Flow Setup List (O)
|
||||
int numQosFlowSetup;
|
||||
qos_flow_list_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
// Old QoS Flow List (O)
|
||||
int numOldQosFlow;
|
||||
qos_flow_list_t oldQosFlows[E1AP_MAX_NUM_QOS_FLOWS];
|
||||
} DRB_nGRAN_modified_t;
|
||||
|
||||
typedef struct DRB_nGRAN_failed_s {
|
||||
long id;
|
||||
long cause_type;
|
||||
long cause;
|
||||
e1ap_cause_t cause;
|
||||
} DRB_nGRAN_failed_t;
|
||||
|
||||
typedef struct pdu_session_setup_s {
|
||||
long id;
|
||||
in_addr_t tlAddress;
|
||||
long teId;
|
||||
// Transport layer info
|
||||
UP_TL_information_t tl_info;
|
||||
int numDRBSetup;
|
||||
DRB_nGRAN_setup_t DRBnGRanList[E1AP_MAX_NUM_DRBS];
|
||||
int numDRBFailed;
|
||||
DRB_nGRAN_failed_t DRBnGRanFailedList[E1AP_MAX_NUM_DRBS];
|
||||
} pdu_session_setup_t;
|
||||
|
||||
/* PDU Session Resource Modified List (9.3.3.17) */
|
||||
typedef struct pdu_session_modif_s {
|
||||
// PDU Session ID (M)
|
||||
long id;
|
||||
// setup as part of PDU session modification not supported yet
|
||||
// Security Result (O)
|
||||
e1ap_indication_t *integrityProtectionIndication;
|
||||
e1ap_indication_t *confidentialityProtectionIndication;
|
||||
// NG DL UP Transport Layer Information (O)
|
||||
UP_TL_information_t *ng_DL_UP_TL_info;
|
||||
// DRB Modified List (O)
|
||||
int numDRBModified;
|
||||
DRB_nGRAN_modified_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
|
||||
// DRB Setup List (O)
|
||||
int numDRBSetup;
|
||||
DRB_nGRAN_setup_t DRBnGRanSetupList[E1AP_MAX_NUM_DRBS];
|
||||
} pdu_session_modif_t;
|
||||
|
||||
typedef struct e1ap_bearer_setup_resp_s {
|
||||
@@ -479,8 +582,11 @@ typedef struct e1ap_bearer_setup_resp_s {
|
||||
} e1ap_bearer_setup_resp_t;
|
||||
|
||||
typedef struct e1ap_bearer_modif_resp_s {
|
||||
// gNB-CU-CP UE E1AP ID (M)
|
||||
uint32_t gNB_cu_cp_ue_id;
|
||||
// gNB-CU-UP UE E1AP ID (M)
|
||||
uint32_t gNB_cu_up_ue_id;
|
||||
// NG-RAN PDU Session Resource Modified List (O)
|
||||
int numPDUSessionsMod;
|
||||
pdu_session_modif_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
} e1ap_bearer_modif_resp_t;
|
||||
|
||||
@@ -10,3 +10,7 @@ target_include_directories(e1ap PUBLIC ${CMAKE_CURRENT_DIR})
|
||||
if(ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
target_compile_definitions(e1ap PRIVATE E1AP_LOG_ERRORS)
|
||||
endif()
|
||||
|
||||
+48
-11
@@ -431,7 +431,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upc
|
||||
BEARER CONTEXT MODIFICATION REQUEST
|
||||
*/
|
||||
|
||||
static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu)
|
||||
static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_mod_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu)
|
||||
{
|
||||
pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu->choice.initiatingMessage, msg);
|
||||
@@ -453,6 +453,21 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
|
||||
ieC2->criticality = E1AP_Criticality_reject;
|
||||
ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
|
||||
ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id;
|
||||
/* optional */
|
||||
/* Security Information */
|
||||
if (bearerCxt->secInfo) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ie);
|
||||
ie->id = E1AP_ProtocolIE_ID_id_SecurityInformation;
|
||||
ie->criticality = E1AP_Criticality_reject;
|
||||
ie->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_SecurityInformation;
|
||||
E1AP_SecurityAlgorithm_t *securityAlgorithm = &ie->value.choice.SecurityInformation.securityAlgorithm;
|
||||
E1AP_UPSecuritykey_t *uPSecuritykey = &ie->value.choice.SecurityInformation.uPSecuritykey;
|
||||
securityAlgorithm->cipheringAlgorithm = bearerCxt->secInfo->cipheringAlgorithm;
|
||||
OCTET_STRING_fromBuf(&uPSecuritykey->encryptionKey, bearerCxt->secInfo->encryptionKey, E1AP_SECURITY_KEY_SIZE);
|
||||
asn1cCallocOne(securityAlgorithm->integrityProtectionAlgorithm, bearerCxt->secInfo->integrityProtectionAlgorithm);
|
||||
asn1cCalloc(uPSecuritykey->integrityProtectionKey, protKey);
|
||||
OCTET_STRING_fromBuf(protKey, bearerCxt->secInfo->integrityProtectionKey, E1AP_SECURITY_KEY_SIZE);
|
||||
}
|
||||
/* optional */
|
||||
/* c3. E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3);
|
||||
@@ -475,7 +490,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
|
||||
asn1cSequenceAdd(drb2Mod_List->list, E1AP_DRB_To_Modify_Item_NG_RAN_t, drb2Mod);
|
||||
drb2Mod->dRB_ID = j->id;
|
||||
asn1cCalloc(drb2Mod->pDCP_Configuration, pDCP_Configuration);
|
||||
if (j->pdcp_config.pDCP_Reestablishment) {
|
||||
if (j->pdcp_config && j->pdcp_config->pDCP_Reestablishment) {
|
||||
asn1cCallocOne(pDCP_Configuration->pDCP_Reestablishment, E1AP_PDCP_Reestablishment_true);
|
||||
}
|
||||
if (j->numDlUpParam > 0) {
|
||||
@@ -484,8 +499,8 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
|
||||
asn1cSequenceAdd(DL_UP_Param_List->list, E1AP_UP_Parameters_Item_t, DL_UP_Param);
|
||||
DL_UP_Param->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
|
||||
asn1cCalloc(DL_UP_Param->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress);
|
||||
INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tl_info.tlAddress, &gTPTunnel->transportLayerAddress);
|
||||
INT32_TO_OCTET_STRING(k->tl_info.teId, &gTPTunnel->gTP_TEID);
|
||||
|
||||
DL_UP_Param->cell_Group_ID = k->cell_group_id;
|
||||
}
|
||||
@@ -493,7 +508,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
|
||||
}
|
||||
}
|
||||
/* c4. E1AP_ProtocolIE_ID_id_BearerContextStatusChange */
|
||||
if (bearerCxt->bearerContextStatus == BEARER_SUSPEND) {
|
||||
if (bearerCxt->bearerContextStatus && *bearerCxt->bearerContextStatus == BEARER_SUSPEND) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC4);
|
||||
ieC4->id = E1AP_ProtocolIE_ID_id_BearerContextStatusChange;
|
||||
ieC4->criticality = E1AP_Criticality_reject;
|
||||
@@ -608,6 +623,26 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
|
||||
bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
|
||||
break;
|
||||
|
||||
case E1AP_ProtocolIE_ID_id_SecurityInformation: {
|
||||
DevAssert(ie->criticality == E1AP_Criticality_reject);
|
||||
DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_SecurityInformation);
|
||||
E1AP_SecurityInformation_t *sec = &ie->value.choice.SecurityInformation;
|
||||
DevAssert(sec->uPSecuritykey.encryptionKey.size == E1AP_SECURITY_KEY_SIZE);
|
||||
DevAssert(sec->uPSecuritykey.integrityProtectionKey == NULL
|
||||
|| sec->uPSecuritykey.integrityProtectionKey->size == E1AP_SECURITY_KEY_SIZE);
|
||||
bearerCxt->secInfo = malloc_or_fail(sizeof(*bearerCxt->secInfo));
|
||||
bearerCxt->secInfo->cipheringAlgorithm = sec->securityAlgorithm.cipheringAlgorithm;
|
||||
bearerCxt->secInfo->integrityProtectionAlgorithm = sec->securityAlgorithm.integrityProtectionAlgorithm == NULL
|
||||
? 0
|
||||
: *sec->securityAlgorithm.integrityProtectionAlgorithm;
|
||||
memcpy(bearerCxt->secInfo->encryptionKey, sec->uPSecuritykey.encryptionKey.buf, E1AP_SECURITY_KEY_SIZE);
|
||||
if (sec->securityAlgorithm.integrityProtectionAlgorithm == NULL)
|
||||
memset(bearerCxt->secInfo->integrityProtectionKey, 0, E1AP_SECURITY_KEY_SIZE);
|
||||
else
|
||||
memcpy(bearerCxt->secInfo->integrityProtectionKey, sec->uPSecuritykey.integrityProtectionKey->buf, E1AP_SECURITY_KEY_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
case E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest:
|
||||
DevAssert(ie->criticality == E1AP_Criticality_reject);
|
||||
DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest);
|
||||
@@ -637,7 +672,8 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
|
||||
if (drb2Mod->pDCP_Configuration != NULL
|
||||
&& drb2Mod->pDCP_Configuration->pDCP_Reestablishment != NULL
|
||||
&& *drb2Mod->pDCP_Configuration->pDCP_Reestablishment == E1AP_PDCP_Reestablishment_true) {
|
||||
drb->pdcp_config.pDCP_Reestablishment = true;
|
||||
drb->pdcp_config = malloc_or_fail(sizeof(*drb->pdcp_config));
|
||||
drb->pdcp_config->pDCP_Reestablishment = true;
|
||||
}
|
||||
if (drb2Mod->dL_UP_Parameters) { /* Optional IE in the DRB To Modify Item */
|
||||
E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters;
|
||||
@@ -649,8 +685,8 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
|
||||
DevAssert(dl_up_param_in->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel);
|
||||
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(
|
||||
&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
|
||||
dl_up_param->tlAddress);
|
||||
OCTET_STRING_TO_INT32(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->gTP_TEID, dl_up_param->teId);
|
||||
dl_up_param->tl_info.tlAddress);
|
||||
OCTET_STRING_TO_INT32(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->gTP_TEID, dl_up_param->tl_info.teId);
|
||||
} else {
|
||||
AssertFatal(false, "gTPTunnel IE is missing. It is mandatory at this point\n");
|
||||
}
|
||||
@@ -665,7 +701,8 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
|
||||
/* Bearer Context Status Change */
|
||||
DevAssert(ie->criticality == E1AP_Criticality_reject);
|
||||
DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange);
|
||||
bearerCxt->bearerContextStatus = (ie->value.choice.BearerContextStatusChange == E1AP_BearerContextStatusChange_suspend) ? BEARER_SUSPEND : BEARER_ACTIVE;
|
||||
bearerCxt->bearerContextStatus = malloc_or_fail(*bearerCxt->bearerContextStatus);
|
||||
*bearerCxt->bearerContextStatus = (ie->value.choice.BearerContextStatusChange == E1AP_BearerContextStatusChange_suspend) ? BEARER_SUSPEND : BEARER_ACTIVE;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1131,7 +1168,7 @@ static void e1_task_handle_sctp_association_resp(E1_t type,
|
||||
if (getCxtE1(instance)->gtpInstF1U < 0)
|
||||
getCxtE1(instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr);
|
||||
if (getCxtE1(instance)->gtpInstF1U < 0)
|
||||
LOG_E(E1AP, "Failed to create CUUP F1-U UDP listener");
|
||||
LOG_E(E1AP, "Failed to create CUUP F1-U UDP listener\n");
|
||||
extern instance_t CUuniqInstance;
|
||||
CUuniqInstance = getCxtE1(instance)->gtpInstF1U;
|
||||
cuup_init_n3(instance);
|
||||
@@ -1154,7 +1191,7 @@ void cuup_init_n3(instance_t instance)
|
||||
legacyInstanceMapping = getCxtE1(instance)->gtpInstN3 = gtpv1Init(tmp);
|
||||
}
|
||||
if (getCxtE1(instance)->gtpInstN3 < 0)
|
||||
LOG_E(E1AP, "Failed to create CUUP N3 UDP listener");
|
||||
LOG_E(E1AP, "Failed to create CUUP N3 UDP listener\n");
|
||||
extern instance_t *N3GTPUInst;
|
||||
N3GTPUInst = &getCxtE1(instance)->gtpInstN3;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
add_library(e1ap_lib OBJECT
|
||||
e1ap_bearer_context_management.c
|
||||
e1ap_interface_management.c
|
||||
e1ap_lib_common.c
|
||||
)
|
||||
|
||||
target_link_libraries(e1ap_lib PRIVATE asn1_e1ap)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,4 +40,10 @@ void free_e1ap_context_setup_response(const e1ap_bearer_setup_resp_t *msg);
|
||||
e1ap_bearer_setup_resp_t cp_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *msg);
|
||||
bool eq_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *a, const e1ap_bearer_setup_resp_t *b);
|
||||
|
||||
struct E1AP_E1AP_PDU *encode_E1_bearer_context_mod_request(const e1ap_bearer_mod_req_t *msg);
|
||||
bool decode_E1_bearer_context_mod_request(const struct E1AP_E1AP_PDU *pdu, e1ap_bearer_mod_req_t *out);
|
||||
void free_e1ap_context_mod_request(const e1ap_bearer_mod_req_t *msg);
|
||||
e1ap_bearer_mod_req_t cp_bearer_context_mod_request(const e1ap_bearer_mod_req_t *msg);
|
||||
bool eq_bearer_context_mod_request(const e1ap_bearer_mod_req_t *a, const e1ap_bearer_mod_req_t *b);
|
||||
|
||||
#endif /* E1AP_BEARER_CONTEXT_MANAGEMENT_H_ */
|
||||
|
||||
@@ -508,61 +508,6 @@ bool eq_e1ap_cuup_setup_response(const e1ap_setup_resp_t *a, const e1ap_setup_re
|
||||
* GNB-CU-UP E1 SETUP FAILURE
|
||||
* ==================================== */
|
||||
|
||||
static E1AP_Cause_t encode_e1ap_cause_ie(const e1ap_cause_t *cause)
|
||||
{
|
||||
E1AP_Cause_t ie;
|
||||
switch (cause->type) {
|
||||
case E1AP_CAUSE_RADIO_NETWORK:
|
||||
ie.present = E1AP_Cause_PR_radioNetwork;
|
||||
ie.choice.radioNetwork = cause->value;
|
||||
break;
|
||||
case E1AP_CAUSE_TRANSPORT:
|
||||
ie.present = E1AP_Cause_PR_transport;
|
||||
ie.choice.transport = cause->value;
|
||||
break;
|
||||
case E1AP_CAUSE_PROTOCOL:
|
||||
ie.present = E1AP_Cause_PR_protocol;
|
||||
ie.choice.protocol = cause->value;
|
||||
break;
|
||||
case E1AP_CAUSE_MISC:
|
||||
ie.present = E1AP_Cause_PR_misc;
|
||||
ie.choice.misc = cause->value;
|
||||
break;
|
||||
default:
|
||||
ie.present = E1AP_Cause_PR_NOTHING;
|
||||
break;
|
||||
}
|
||||
return ie;
|
||||
}
|
||||
|
||||
static e1ap_cause_t decode_e1ap_cause_ie(const E1AP_Cause_t *ie)
|
||||
{
|
||||
e1ap_cause_t cause;
|
||||
// Decode the 'choice' field based on the 'present' value
|
||||
switch (ie->present) {
|
||||
case E1AP_Cause_PR_radioNetwork:
|
||||
cause.value = ie->choice.radioNetwork;
|
||||
cause.type = E1AP_CAUSE_RADIO_NETWORK;
|
||||
break;
|
||||
case E1AP_Cause_PR_transport:
|
||||
cause.value = ie->choice.transport;
|
||||
cause.type = E1AP_CAUSE_TRANSPORT;
|
||||
break;
|
||||
case E1AP_Cause_PR_protocol:
|
||||
cause.value = ie->choice.protocol;
|
||||
cause.type = E1AP_CAUSE_PROTOCOL;
|
||||
break;
|
||||
case E1AP_Cause_PR_misc:
|
||||
cause.value = ie->choice.misc;
|
||||
cause.type = E1AP_CAUSE_MISC;
|
||||
break;
|
||||
default:
|
||||
cause.type = E1AP_CAUSE_NOTHING;
|
||||
break;
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encoder for GNB-CU-UP E1 Setup Failure
|
||||
* @ref 9.2.1.6 GNB-CU-UP E1 SETUP FAILURE of 3GPP TS 38.463
|
||||
@@ -588,7 +533,7 @@ E1AP_E1AP_PDU_t *encode_e1ap_cuup_setup_failure(const e1ap_setup_fail_t *msg)
|
||||
ie2->id = E1AP_ProtocolIE_ID_id_Cause;
|
||||
ie2->criticality = E1AP_Criticality_ignore;
|
||||
ie2->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_Cause;
|
||||
ie2->value.choice.Cause = encode_e1ap_cause_ie(&msg->cause);
|
||||
ie2->value.choice.Cause = e1_encode_cause_ie(&msg->cause);
|
||||
// Time To Wait (O)
|
||||
if (msg->time_to_wait) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie3);
|
||||
@@ -630,7 +575,7 @@ bool decode_e1ap_cuup_setup_failure(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_fail_
|
||||
case E1AP_ProtocolIE_ID_id_Cause:
|
||||
// Cause
|
||||
E1AP_LIB_FIND_IE(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, E1AP_ProtocolIE_ID_id_Cause, true);
|
||||
out->cause = decode_e1ap_cause_ie(&ie->value.choice.Cause);
|
||||
out->cause = e1_decode_cause_ie(&ie->value.choice.Cause);
|
||||
break;
|
||||
case E1AP_ProtocolIE_ID_id_Transport_Layer_Address_Info:
|
||||
// Time To Wait (O)
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "e1ap_lib_common.h"
|
||||
#include "e1ap_lib_includes.h"
|
||||
#include "e1ap_messages_types.h"
|
||||
|
||||
E1AP_Cause_t e1_encode_cause_ie(const e1ap_cause_t *cause)
|
||||
{
|
||||
E1AP_Cause_t ie;
|
||||
switch (cause->type) {
|
||||
case E1AP_CAUSE_RADIO_NETWORK:
|
||||
ie.present = E1AP_Cause_PR_radioNetwork;
|
||||
ie.choice.radioNetwork = cause->value;
|
||||
break;
|
||||
case E1AP_CAUSE_TRANSPORT:
|
||||
ie.present = E1AP_Cause_PR_transport;
|
||||
ie.choice.transport = cause->value;
|
||||
break;
|
||||
case E1AP_CAUSE_PROTOCOL:
|
||||
ie.present = E1AP_Cause_PR_protocol;
|
||||
ie.choice.protocol = cause->value;
|
||||
break;
|
||||
case E1AP_CAUSE_MISC:
|
||||
ie.present = E1AP_Cause_PR_misc;
|
||||
ie.choice.misc = cause->value;
|
||||
break;
|
||||
default:
|
||||
ie.present = E1AP_Cause_PR_NOTHING;
|
||||
PRINT_ERROR("encode_e1ap_cause_ie: no cause value provided\n");
|
||||
break;
|
||||
}
|
||||
return ie;
|
||||
}
|
||||
|
||||
e1ap_cause_t e1_decode_cause_ie(const E1AP_Cause_t *ie)
|
||||
{
|
||||
e1ap_cause_t cause;
|
||||
// Decode the 'choice' field based on the 'present' value
|
||||
switch (ie->present) {
|
||||
case E1AP_Cause_PR_radioNetwork:
|
||||
cause.value = ie->choice.radioNetwork;
|
||||
cause.type = E1AP_CAUSE_RADIO_NETWORK;
|
||||
break;
|
||||
case E1AP_Cause_PR_transport:
|
||||
cause.value = ie->choice.transport;
|
||||
cause.type = E1AP_CAUSE_TRANSPORT;
|
||||
break;
|
||||
case E1AP_Cause_PR_protocol:
|
||||
cause.value = ie->choice.protocol;
|
||||
cause.type = E1AP_CAUSE_PROTOCOL;
|
||||
break;
|
||||
case E1AP_Cause_PR_misc:
|
||||
cause.value = ie->choice.misc;
|
||||
cause.type = E1AP_CAUSE_MISC;
|
||||
break;
|
||||
default:
|
||||
cause.type = E1AP_CAUSE_NOTHING;
|
||||
PRINT_ERROR("decode_e1ap_cause_ie: no cause value provided\n");
|
||||
break;
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
@@ -26,13 +26,22 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
#include "e1ap_messages_types.h"
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
#ifdef E1AP_LOG_ERRORS
|
||||
#define PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__);
|
||||
#else
|
||||
#define PRINT_ERROR(...) // Do nothing
|
||||
#endif
|
||||
|
||||
#define CHECK_E1AP_DEC(exp) \
|
||||
do { \
|
||||
if (!(exp)) { \
|
||||
PRINT_ERROR("Failed executing " #exp " in %s() line %d\n", __func__, __LINE__); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _E1_EQ_CHECK_GENERIC(condition, fmt, ...) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
@@ -66,4 +75,40 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* deep copy of optional E1AP IE */
|
||||
#define _E1_CP_OPTIONAL_IE(dest, src, field) \
|
||||
do { \
|
||||
if ((src)->field) { \
|
||||
(dest)->field = malloc_or_fail(sizeof(*(dest)->field)); \
|
||||
*(dest)->field = *(src)->field; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _E1_EQ_CHECK_OPTIONAL_IE(a, b, field, EQ_MACRO) \
|
||||
do { \
|
||||
if (((a)->field && !(b)->field) || (!(a)->field && (b)->field)) { \
|
||||
return false; /* One of the two is not allocated */ \
|
||||
} \
|
||||
if ((a)->field && (b)->field) { \
|
||||
EQ_MACRO(*(a)->field, *(b)->field) \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _E1_EQ_CHECK_OPTIONAL_PTR(a, b, field) \
|
||||
do { \
|
||||
if (((a)->field && !(b)->field) || (!(a)->field && (b)->field)) { \
|
||||
PRINT_ERROR("%s:%d: optional IE '%s' not allocated: %p, %p\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#field, \
|
||||
(void *)(a)->field, \
|
||||
(void *)(b)->field); \
|
||||
return false; /* One of the two is not allocated */ \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct E1AP_Cause;
|
||||
struct E1AP_Cause e1_encode_cause_ie(const e1ap_cause_t *cause);
|
||||
e1ap_cause_t e1_decode_cause_ie(const struct E1AP_Cause *ie);
|
||||
|
||||
#endif /* E1AP_LIB_COMMON_H_ */
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "E1AP_System-BearerContextSetupRequest.h"
|
||||
#include "E1AP_MaximumIPdatarate.h"
|
||||
#include "E1AP_PDU-Session-Type.h"
|
||||
#include "E1AP_Data-Forwarding-Information.h"
|
||||
// E1 Bearer Context Setup Response
|
||||
#include "E1AP_PDU-Session-Resource-Setup-Item.h"
|
||||
#include "E1AP_DRB-Setup-Item-NG-RAN.h"
|
||||
@@ -66,5 +67,11 @@
|
||||
#include "E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-Item.h"
|
||||
#include "E1AP_GTPTLAs.h"
|
||||
#include "E1AP_GTPTLA-Item.h"
|
||||
// E1 Bearer Context Modification Request
|
||||
#include "E1AP_PDU-Session-Resource-To-Modify-Item.h"
|
||||
#include "E1AP_DRB-To-Modify-List-NG-RAN.h"
|
||||
#include "E1AP_DRB-To-Modify-Item-NG-RAN.h"
|
||||
#include "E1AP_PDU-Session-Resource-To-Setup-Mod-Item.h"
|
||||
#include "E1AP_DRB-To-Setup-Mod-Item-NG-RAN.h"
|
||||
|
||||
#endif /* E1AP_LIB_INCLUDES_H_ */
|
||||
|
||||
@@ -70,6 +70,14 @@ static void e1ap_msg_free(E1AP_E1AP_PDU_t *pdu)
|
||||
ASN_STRUCT_FREE(asn_DEF_E1AP_E1AP_PDU, pdu);
|
||||
}
|
||||
|
||||
static UP_TL_information_t create_up_tl_info(void)
|
||||
{
|
||||
UP_TL_information_t tl_info;
|
||||
tl_info.tlAddress = htonl(0xC0A90001); // 192.169.0.1
|
||||
tl_info.teId = 0x2345;
|
||||
return tl_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test E1AP Bearer Context Setup Request encoding/decoding
|
||||
*/
|
||||
@@ -77,7 +85,7 @@ static void test_bearer_context_setup_request(void)
|
||||
{
|
||||
bearer_context_pdcp_config_t pdcp = {
|
||||
.discardTimer = E1AP_DiscardTimer_ms10,
|
||||
.pDCP_Reestablishment = E1AP_PDCP_Reestablishment_true,
|
||||
.pDCP_Reestablishment = true,
|
||||
.pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_12,
|
||||
.pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_12,
|
||||
.reorderingTimer = 10,
|
||||
@@ -107,14 +115,13 @@ static void test_bearer_context_setup_request(void)
|
||||
// Step 1: Initialize the E1AP Bearer Context Setup Request
|
||||
e1ap_bearer_setup_req_t orig = {
|
||||
.gNB_cu_cp_ue_id = 1234,
|
||||
.cipheringAlgorithm = 0x01,
|
||||
.integrityProtectionAlgorithm = 0x01,
|
||||
.secInfo.cipheringAlgorithm = 0x01,
|
||||
.secInfo.integrityProtectionAlgorithm = 0x01,
|
||||
.ueDlAggMaxBitRate = 1000000000,
|
||||
.bearerContextStatus = 0,
|
||||
.servingPLMNid.mcc = 001,
|
||||
.servingPLMNid.mnc = 01,
|
||||
.servingPLMNid.mnc_digit_length = 0x02,
|
||||
.activityNotificationLevel = ANL_PDU_SESSION,
|
||||
.numPDUSessions = 1,
|
||||
.pduSession[0].sessionId = 1,
|
||||
.pduSession[0].sessionType = E1AP_PDU_Session_Type_ipv4,
|
||||
@@ -122,8 +129,7 @@ static void test_bearer_context_setup_request(void)
|
||||
.pduSession[0].nssai.sst = 0x01,
|
||||
.pduSession[0].securityIndication = security,
|
||||
.pduSession[0].numDRB2Setup = 1,
|
||||
.pduSession[0].UP_TL_information.tlAddress = 167772161,
|
||||
.pduSession[0].UP_TL_information.teId = 0x12345,
|
||||
.pduSession[0].UP_TL_information = create_up_tl_info(),
|
||||
.pduSession[0].DRBnGRanList[0].id = 1,
|
||||
.pduSession[0].DRBnGRanList[0].sdap_config = sdap,
|
||||
.pduSession[0].DRBnGRanList[0].pdcp_config = pdcp,
|
||||
@@ -133,8 +139,8 @@ static void test_bearer_context_setup_request(void)
|
||||
.pduSession[0].DRBnGRanList[0].numQosFlow2Setup = 1,
|
||||
.pduSession[0].DRBnGRanList[0].qosFlows[0] = qos,
|
||||
};
|
||||
memset(orig.encryptionKey, 0xAB, sizeof(orig.encryptionKey));
|
||||
memset(orig.integrityProtectionKey, 0xCD, sizeof(orig.integrityProtectionKey));
|
||||
memset(orig.secInfo.encryptionKey, 0xAB, sizeof(orig.secInfo.encryptionKey));
|
||||
memset(orig.secInfo.integrityProtectionKey, 0xCD, sizeof(orig.secInfo.integrityProtectionKey));
|
||||
// E1AP encode the original message
|
||||
E1AP_E1AP_PDU_t *enc = encode_E1_bearer_context_setup_request(&orig);
|
||||
// E1AP decode the encoded message
|
||||
@@ -172,8 +178,7 @@ static void test_bearer_context_setup_response(void)
|
||||
.gNB_cu_up_ue_id = 5678,
|
||||
.numPDUSessions = 1,
|
||||
.pduSession[0].id = 1,
|
||||
.pduSession[0].tlAddress = 167772161,
|
||||
.pduSession[0].teId = 0x12345,
|
||||
.pduSession[0].tl_info = create_up_tl_info(),
|
||||
.pduSession[0].numDRBSetup = 1,
|
||||
.pduSession[0].numDRBFailed = 0,
|
||||
.pduSession[0].DRBnGRanList[0].id = 1,
|
||||
@@ -181,8 +186,7 @@ static void test_bearer_context_setup_response(void)
|
||||
.pduSession[0].DRBnGRanList[0].numQosFlowSetup = 1,
|
||||
.pduSession[0].DRBnGRanList[0].qosFlows[0].qfi = 1,
|
||||
.pduSession[0].DRBnGRanList[0].UpParamList[0].cell_group_id = MCG,
|
||||
.pduSession[0].DRBnGRanList[0].UpParamList[0].teId = 0x34345,
|
||||
.pduSession[0].DRBnGRanList[0].UpParamList[0].tlAddress = 167772161,
|
||||
.pduSession[0].DRBnGRanList[0].UpParamList[0].tl_info = create_up_tl_info(),
|
||||
};
|
||||
// E1AP encode the original message
|
||||
E1AP_E1AP_PDU_t *enc = encode_E1_bearer_context_setup_response(&orig);
|
||||
@@ -335,6 +339,120 @@ static void test_e1_cuup_setup_failure(void)
|
||||
free_e1ap_cuup_setup_failure(&orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test E1AP Bearer Context Modification Request encoding/decoding
|
||||
*/
|
||||
static void test_bearer_context_modification_request(void)
|
||||
{
|
||||
const bearer_context_sdap_config_t dummy_sdap_config = {
|
||||
.defaultDRB = 0,
|
||||
.sDAP_Header_DL = false,
|
||||
.sDAP_Header_UL = false,
|
||||
};
|
||||
|
||||
const bearer_context_pdcp_config_t dummy_pdcp_config = {
|
||||
.discardTimer = E1AP_DiscardTimer_ms100,
|
||||
.pDCP_Reestablishment = true,
|
||||
.pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_12,
|
||||
.pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_12,
|
||||
.reorderingTimer = 5,
|
||||
.rLC_Mode = E1AP_RLC_Mode_rlc_um_bidirectional,
|
||||
};
|
||||
|
||||
const qos_flow_to_setup_t dummy_qos_flows = {
|
||||
.qfi = 9,
|
||||
.qos_params.alloc_reten_priority.preemption_capability = E1AP_Pre_emptionCapability_may_trigger_pre_emption,
|
||||
.qos_params.alloc_reten_priority.preemption_vulnerability = E1AP_Pre_emptionVulnerability_pre_emptable,
|
||||
.qos_params.alloc_reten_priority.priority_level = E1AP_PriorityLevel_no_priority,
|
||||
.qos_params.qos_characteristics.non_dynamic.fiveqi = 9,
|
||||
};
|
||||
|
||||
DRB_nGRAN_to_mod_t drb_to_mod = {
|
||||
.numDlUpParam = 1,
|
||||
.DlUpParamList[0].cell_group_id = MCG,
|
||||
.DlUpParamList[0].tl_info = create_up_tl_info(),
|
||||
.id = 1,
|
||||
.pdcp_config = malloc_or_fail(sizeof(*drb_to_mod.pdcp_config)),
|
||||
.pdcp_sn_status_requested = true,
|
||||
.numQosFlow2Setup = 1,
|
||||
.qosFlows[0] = dummy_qos_flows,
|
||||
};
|
||||
*drb_to_mod.pdcp_config = dummy_pdcp_config;
|
||||
|
||||
pdu_session_to_mod_t pdusession_mod_item = {
|
||||
.sessionId = 1,
|
||||
.numDRB2Modify = 1,
|
||||
.DRBnGRanModList[0] = drb_to_mod,
|
||||
};
|
||||
|
||||
DRB_nGRAN_to_setup_t drb_to_setup = {
|
||||
.id = 1,
|
||||
.cellGroupList[0] = MCG,
|
||||
.numCellGroups = 1,
|
||||
.pdcp_config = dummy_pdcp_config,
|
||||
.sdap_config = dummy_sdap_config,
|
||||
.numQosFlow2Setup = 1,
|
||||
.qosFlows[0] = dummy_qos_flows,
|
||||
.drb_inactivity_timer = malloc_or_fail(sizeof(*drb_to_setup.drb_inactivity_timer)),
|
||||
};
|
||||
*drb_to_setup.drb_inactivity_timer = 500;
|
||||
|
||||
pdu_session_to_setup_t pdusession_setup_item = {
|
||||
.numDRB2Setup = 1,
|
||||
.nssai.sd = 0x01,
|
||||
.nssai.sst = 0x01,
|
||||
.UP_TL_information.teId = 0x12345,
|
||||
.UP_TL_information.tlAddress = 167772161,
|
||||
.DRBnGRanList[0] = drb_to_setup,
|
||||
};
|
||||
|
||||
// Initialize the Bearer Context Modification Request
|
||||
e1ap_bearer_mod_req_t orig = {
|
||||
.gNB_cu_cp_ue_id = 0x1234,
|
||||
.gNB_cu_up_ue_id = 0x5678,
|
||||
.bearerContextStatus = malloc_or_fail(sizeof(*orig.bearerContextStatus)),
|
||||
.inactivityTimer = malloc_or_fail(sizeof(*orig.inactivityTimer)),
|
||||
.numPDUSessions = 1,
|
||||
.pduSession[0] = pdusession_setup_item,
|
||||
.numPDUSessionsMod = 1,
|
||||
.pduSessionMod[0] = pdusession_mod_item,
|
||||
};
|
||||
*orig.bearerContextStatus = BEARER_SUSPEND;
|
||||
*orig.inactivityTimer = 1000;
|
||||
|
||||
// Encode the original message
|
||||
E1AP_E1AP_PDU_t *enc = encode_E1_bearer_context_mod_request(&orig);
|
||||
|
||||
// Decode the encoded message
|
||||
E1AP_E1AP_PDU_t *dec = e1ap_encode_decode(enc);
|
||||
|
||||
// Free the encoded message
|
||||
e1ap_msg_free(enc);
|
||||
|
||||
// Decode the message into a new struct
|
||||
e1ap_bearer_mod_req_t decoded = {0};
|
||||
AssertFatal(decode_E1_bearer_context_mod_request(dec, &decoded), "decode_E1_bearer_context_mod_request(): could not decode message\n");
|
||||
|
||||
// Free the decoded E1AP message
|
||||
e1ap_msg_free(dec);
|
||||
|
||||
// Compare the original and decoded structs
|
||||
AssertFatal(eq_bearer_context_mod_request(&orig, &decoded), "eq_bearer_context_mod_request(): decoded message doesn't match\n");
|
||||
|
||||
// Free the memory for the decoded message
|
||||
free_e1ap_context_mod_request(&decoded);
|
||||
|
||||
// Deep copy the original message
|
||||
e1ap_bearer_mod_req_t cp = cp_bearer_context_mod_request(&orig);
|
||||
|
||||
// Verify the deep copy matches the original
|
||||
AssertFatal(eq_bearer_context_mod_request(&orig, &cp), "eq_bearer_context_mod_request(): copied message doesn't match\n");
|
||||
|
||||
// Free the copied and original message
|
||||
free_e1ap_context_mod_request(&cp);
|
||||
free_e1ap_context_mod_request(&orig);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// E1 Bearer Context Setup
|
||||
@@ -344,5 +462,7 @@ int main()
|
||||
test_e1_cuup_setup_request();
|
||||
test_e1_cuup_setup_response();
|
||||
test_e1_cuup_setup_failure();
|
||||
// E1 Bearer Context Modification Request
|
||||
test_bearer_context_modification_request();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,6 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
const pdu_session_to_setup_t *req_pdu = req->pduSession + i;
|
||||
resp_pdu->id = req_pdu->sessionId;
|
||||
|
||||
AssertFatal(req_pdu->numDRB2Modify == 0, "DRB modification not implemented\n");
|
||||
AssertFatal(req_pdu->numDRB2Setup == 1, "can only handle one DRB per PDU session\n");
|
||||
resp_pdu->numDRBSetup = req_pdu->numDRB2Setup;
|
||||
const DRB_nGRAN_to_setup_t *req_drb = &req_pdu->DRBnGRanList[0];
|
||||
@@ -178,7 +177,7 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup;
|
||||
for (int k = 0; k < resp_drb->numQosFlowSetup; k++) {
|
||||
const qos_flow_to_setup_t *qosflow2Setup = &req_drb->qosFlows[k];
|
||||
qos_flow_setup_t *qosflowSetup = &resp_drb->qosFlows[k];
|
||||
qos_flow_list_t *qosflowSetup = &resp_drb->qosFlows[k];
|
||||
qosflowSetup->qfi = qosflow2Setup->qfi;
|
||||
}
|
||||
|
||||
@@ -197,17 +196,17 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
&resp_n3);
|
||||
AssertFatal(ret >= 0, "Unable to create GTP Tunnel for NG-U\n");
|
||||
AssertFatal(resp_n3.num_tunnels == req_pdu->numDRB2Setup, "could not create all tunnels\n");
|
||||
resp_pdu->teId = resp_n3.gnb_NGu_teid[0];
|
||||
memcpy(&resp_pdu->tlAddress, &resp_n3.gnb_addr.buffer, 4);
|
||||
resp_pdu->tl_info.teId = resp_n3.gnb_NGu_teid[0];
|
||||
memcpy(&resp_pdu->tl_info.tlAddress, &resp_n3.gnb_addr.buffer, 4);
|
||||
|
||||
// create PDCP bearers. This will also create SDAP bearers
|
||||
NR_DRB_ToAddModList_t DRB_configList = {0};
|
||||
fill_DRB_configList_e1(&DRB_configList, req_pdu);
|
||||
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
|
||||
security_parameters.ciphering_algorithm = req->cipheringAlgorithm;
|
||||
security_parameters.integrity_algorithm = req->integrityProtectionAlgorithm;
|
||||
memcpy(security_parameters.ciphering_key, req->encryptionKey, NR_K_KEY_SIZE);
|
||||
memcpy(security_parameters.integrity_key, req->integrityProtectionKey, NR_K_KEY_SIZE);
|
||||
security_parameters.ciphering_algorithm = req->secInfo.cipheringAlgorithm;
|
||||
security_parameters.integrity_algorithm = req->secInfo.integrityProtectionAlgorithm;
|
||||
memcpy(security_parameters.ciphering_key, req->secInfo.encryptionKey, NR_K_KEY_SIZE);
|
||||
memcpy(security_parameters.integrity_key, req->secInfo.integrityProtectionKey, NR_K_KEY_SIZE);
|
||||
nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE
|
||||
cu_up_ue_id,
|
||||
&DRB_configList,
|
||||
@@ -230,8 +229,8 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
&resp_f1);
|
||||
resp_drb->numUpParam = 1;
|
||||
AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n");
|
||||
memcpy(&resp_drb->UpParamList[0].tlAddress, &resp_f1.gnb_addr.buffer, 4);
|
||||
resp_drb->UpParamList[0].teId = resp_f1.gnb_NGu_teid[0];
|
||||
memcpy(&resp_drb->UpParamList[0].tl_info.tlAddress, &resp_f1.gnb_addr.buffer, 4);
|
||||
resp_drb->UpParamList[0].tl_info.teId = resp_f1.gnb_NGu_teid[0];
|
||||
}
|
||||
|
||||
// We assume all DRBs to setup have been setup successfully, so we always
|
||||
@@ -273,12 +272,18 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
|
||||
DRB_nGRAN_modified_t *modified = &modif.pduSessionMod[i].DRBnGRanModList[j];
|
||||
modified->id = to_modif->id;
|
||||
|
||||
if (to_modif->pdcp_config.pDCP_Reestablishment) {
|
||||
if (to_modif->pdcp_config && to_modif->pdcp_config->pDCP_Reestablishment) {
|
||||
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
|
||||
security_parameters.ciphering_algorithm = req->cipheringAlgorithm;
|
||||
security_parameters.integrity_algorithm = req->integrityProtectionAlgorithm;
|
||||
memcpy(security_parameters.ciphering_key, req->encryptionKey, NR_K_KEY_SIZE);
|
||||
memcpy(security_parameters.integrity_key, req->integrityProtectionKey, NR_K_KEY_SIZE);
|
||||
if (req->secInfo) {
|
||||
security_parameters.ciphering_algorithm = req->secInfo->cipheringAlgorithm;
|
||||
security_parameters.integrity_algorithm = req->secInfo->integrityProtectionAlgorithm;
|
||||
memcpy(security_parameters.ciphering_key, req->secInfo->encryptionKey, NR_K_KEY_SIZE);
|
||||
memcpy(security_parameters.integrity_key, req->secInfo->integrityProtectionKey, NR_K_KEY_SIZE);
|
||||
} else {
|
||||
/* don't change security settings if not present in the Bearer Context Modification Request */
|
||||
security_parameters.ciphering_algorithm = -1;
|
||||
security_parameters.integrity_algorithm = -1;
|
||||
}
|
||||
nr_pdcp_reestablishment(req->gNB_cu_up_ue_id,
|
||||
to_modif->id,
|
||||
false,
|
||||
@@ -291,8 +296,8 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
|
||||
/* Loop through DL UP Transport Layer params list
|
||||
* and update GTP tunnel outgoing addr and TEID */
|
||||
for (int k = 0; k < to_modif->numDlUpParam; k++) {
|
||||
in_addr_t addr = to_modif->DlUpParamList[k].tlAddress;
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[k].teId);
|
||||
in_addr_t addr = to_modif->DlUpParamList[k].tl_info.tlAddress;
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[k].tl_info.teId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
void nr_pdcp_e1_if_init(bool uses_e1);
|
||||
|
||||
struct e1ap_bearer_setup_req_s;
|
||||
struct e1ap_bearer_mod_req_s;
|
||||
struct e1ap_bearer_release_cmd_s;
|
||||
void e1_bearer_context_setup(const struct e1ap_bearer_setup_req_s *req);
|
||||
void e1_bearer_context_modif(const struct e1ap_bearer_setup_req_s *req);
|
||||
void e1_bearer_context_modif(const struct e1ap_bearer_mod_req_s *req);
|
||||
void e1_bearer_release_cmd(const struct e1ap_bearer_release_cmd_s *cmd);
|
||||
void e1_reset(void);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "e1ap_messages_types.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "nr_rrc_defs.h"
|
||||
#include "E1AP/lib/e1ap_bearer_context_management.h"
|
||||
|
||||
static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req)
|
||||
{
|
||||
@@ -33,8 +34,7 @@ static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, const e1a
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ);
|
||||
msg_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p);
|
||||
memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t));
|
||||
|
||||
*bearer_req = cp_bearer_context_setup_request(req);
|
||||
itti_send_msg_to_task (TASK_CUCP_E1, 0, msg_p);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,11 @@
|
||||
#include "common/platform_types.h"
|
||||
|
||||
struct e1ap_bearer_setup_req_s;
|
||||
struct e1ap_bearer_mod_req_s;
|
||||
struct e1ap_bearer_setup_resp_s;
|
||||
struct e1ap_bearer_release_cmd_s;
|
||||
typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_setup_req_s *req);
|
||||
typedef void (*cucp_cuup_bearer_context_mod_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_mod_req_s *req);
|
||||
typedef void (*cucp_cuup_bearer_context_release_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_release_cmd_s *cmd);
|
||||
|
||||
struct gNB_RRC_INST_s;
|
||||
|
||||
@@ -343,7 +343,7 @@ typedef struct nr_mac_rrc_dl_if_s {
|
||||
|
||||
typedef struct cucp_cuup_if_s {
|
||||
cucp_cuup_bearer_context_setup_func_t bearer_context_setup;
|
||||
cucp_cuup_bearer_context_setup_func_t bearer_context_mod;
|
||||
cucp_cuup_bearer_context_mod_func_t bearer_context_mod;
|
||||
cucp_cuup_bearer_context_release_func_t bearer_context_release;
|
||||
} cucp_cuup_if_t;
|
||||
|
||||
|
||||
+36
-22
@@ -736,6 +736,14 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, buffer, size);
|
||||
}
|
||||
|
||||
static void fill_security_info(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, security_information_t *secInfo)
|
||||
{
|
||||
secInfo->cipheringAlgorithm = rrc->security.do_drb_ciphering ? UE->ciphering_algorithm : 0;
|
||||
secInfo->integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? UE->integrity_algorithm : 0;
|
||||
nr_derive_key(UP_ENC_ALG, secInfo->cipheringAlgorithm, UE->kgnb, (uint8_t *)secInfo->encryptionKey);
|
||||
nr_derive_key(UP_INT_ALG, secInfo->integrityProtectionAlgorithm, UE->kgnb, (uint8_t *)secInfo->integrityProtectionKey);
|
||||
}
|
||||
|
||||
/* \brief find existing PDU session inside E1AP Bearer Modif message, or
|
||||
* point to new one.
|
||||
* \param bearer_modif E1AP Bearer Modification Message
|
||||
@@ -793,20 +801,27 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
DRB_nGRAN_to_mod_t *drb_e1 = &pdu_e1->DRBnGRanModList[pdu_e1->numDRB2Modify];
|
||||
drb_e1->id = drb_id;
|
||||
drb_e1->numDlUpParam = 1;
|
||||
memcpy(&drb_e1->DlUpParamList[0].tlAddress, &drb->du_tunnel_config.addr.buffer, sizeof(uint8_t) * 4);
|
||||
drb_e1->DlUpParamList[0].teId = drb->du_tunnel_config.teid;
|
||||
memcpy(&drb_e1->DlUpParamList[0].tl_info.tlAddress, &drb->du_tunnel_config.addr.buffer, sizeof(uint8_t) * 4);
|
||||
drb_e1->DlUpParamList[0].tl_info.teId = drb->du_tunnel_config.teid;
|
||||
/* PDCP configuration */
|
||||
bearer_context_pdcp_config_t *pdcp_config = &drb_e1->pdcp_config;
|
||||
if (!drb_e1->pdcp_config)
|
||||
drb_e1->pdcp_config = malloc_or_fail(sizeof(*drb_e1->pdcp_config));
|
||||
bearer_context_pdcp_config_t *pdcp_config = drb_e1->pdcp_config;
|
||||
set_bearer_context_pdcp_config(pdcp_config, drb, rrc->configuration.um_on_default_drb);
|
||||
pdcp_config->pDCP_Reestablishment = true;
|
||||
/* increase DRB to modify counter */
|
||||
pdu_e1->numDRB2Modify += 1;
|
||||
}
|
||||
|
||||
req.cipheringAlgorithm = rrc->security.do_drb_ciphering ? ue_p->ciphering_algorithm : 0;
|
||||
req.integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? ue_p->integrity_algorithm : 0;
|
||||
nr_derive_key(UP_ENC_ALG, req.cipheringAlgorithm, ue_p->kgnb, (uint8_t *)req.encryptionKey);
|
||||
nr_derive_key(UP_INT_ALG, req.integrityProtectionAlgorithm, ue_p->kgnb, (uint8_t *)req.integrityProtectionKey);
|
||||
#if 0
|
||||
/* According to current understanding of E1 specifications, it is not needed
|
||||
* to send security information because this does not change.
|
||||
* But let's keep the code here in case it's needed.
|
||||
*/
|
||||
// Always send security information
|
||||
req.secInfo = malloc_or_fail(sizeof(*req.secInfo));
|
||||
fill_security_info(rrc, ue_p, req.secInfo);
|
||||
#endif
|
||||
|
||||
/* Send E1 Bearer Context Modification Request (3GPP TS 38.463) */
|
||||
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, ue_p);
|
||||
@@ -1855,12 +1870,12 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
|
||||
/* \brief fill E1 bearer modification's DRB from F1 DRB
|
||||
* \param drb_e1 pointer to a DRB inside an E1 bearer modification message
|
||||
* \param drb_f1 pointer to a DRB inside an F1 UE Ctxt modification Response */
|
||||
static void fill_e1_bearer_modif(DRB_nGRAN_to_setup_t *drb_e1, const f1ap_drb_to_be_setup_t *drb_f1)
|
||||
static void fill_e1_bearer_modif(DRB_nGRAN_to_mod_t *drb_e1, const f1ap_drb_to_be_setup_t *drb_f1)
|
||||
{
|
||||
drb_e1->id = drb_f1->drb_id;
|
||||
drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length;
|
||||
drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address;
|
||||
drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid;
|
||||
drb_e1->DlUpParamList[0].tl_info.tlAddress = drb_f1->up_dl_tnl[0].tl_address;
|
||||
drb_e1->DlUpParamList[0].tl_info.teId = drb_f1->up_dl_tnl[0].teid;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1892,8 +1907,8 @@ static void store_du_f1u_tunnel(const f1ap_drb_to_be_setup_t *drbs, int n, gNB_R
|
||||
*/
|
||||
static void f1u_ul_gtp_update(f1u_tunnel_t *f1u, const up_params_t *p)
|
||||
{
|
||||
f1u->teid = p->teId;
|
||||
memcpy(&f1u->addr.buffer, &p->tlAddress, sizeof(uint8_t) * 4);
|
||||
f1u->teid = p->tl_info.teId;
|
||||
memcpy(&f1u->addr.buffer, &p->tl_info.tlAddress, sizeof(uint8_t) * 4);
|
||||
f1u->addr.length = sizeof(in_addr_t);
|
||||
}
|
||||
|
||||
@@ -1919,10 +1934,10 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f
|
||||
LOG_E(RRC, "UE %d: UE Context Modif Response: no PDU session for DRB ID %ld\n", UE->rrc_ue_id, drb_f1->drb_id);
|
||||
continue;
|
||||
}
|
||||
pdu_session_to_setup_t *pdu_e1 = find_or_next_pdu_session(&req, pdu_ue->param.pdusession_id);
|
||||
pdu_session_to_mod_t *pdu_e1 = find_or_next_pdu_session(&req, pdu_ue->param.pdusession_id);
|
||||
DevAssert(pdu_e1 != NULL);
|
||||
pdu_e1->sessionId = pdu_ue->param.pdusession_id;
|
||||
DRB_nGRAN_to_setup_t *drb_e1 = &pdu_e1->DRBnGRanModList[pdu_e1->numDRB2Modify];
|
||||
DRB_nGRAN_to_mod_t *drb_e1 = &pdu_e1->DRBnGRanModList[pdu_e1->numDRB2Modify];
|
||||
/* Fill E1 bearer context modification */
|
||||
fill_e1_bearer_modif(drb_e1, drb_f1);
|
||||
pdu_e1->numDRB2Modify += 1;
|
||||
@@ -1930,10 +1945,9 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f
|
||||
DevAssert(req.numPDUSessionsMod > 0);
|
||||
DevAssert(req.numPDUSessions == 0);
|
||||
|
||||
req.cipheringAlgorithm = rrc->security.do_drb_ciphering ? UE->ciphering_algorithm : 0;
|
||||
req.integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? UE->integrity_algorithm : 0;
|
||||
nr_derive_key(UP_ENC_ALG, req.cipheringAlgorithm, UE->kgnb, (uint8_t *)req.encryptionKey);
|
||||
nr_derive_key(UP_INT_ALG, req.integrityProtectionAlgorithm, UE->kgnb, (uint8_t *)req.integrityProtectionKey);
|
||||
// Always send security information
|
||||
req.secInfo = malloc_or_fail(sizeof(*req.secInfo));
|
||||
fill_security_info(rrc, UE, req.secInfo);
|
||||
|
||||
// send the E1 bearer modification request message to update F1-U tunnel info
|
||||
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE);
|
||||
@@ -2270,9 +2284,9 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc,
|
||||
f1ap_drb_to_be_setup_t *drb = &drbs[nb_drb];
|
||||
drb->drb_id = pduSession[p].DRBnGRanList[i].id;
|
||||
drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM;
|
||||
drb->up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tlAddress;
|
||||
drb->up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tl_info.tlAddress;
|
||||
drb->up_ul_tnl[0].port = rrc->eth_params_s.my_portd;
|
||||
drb->up_ul_tnl[0].teid = drb_config->UpParamList[0].teId;
|
||||
drb->up_ul_tnl[0].teid = drb_config->UpParamList[0].tl_info.teId;
|
||||
drb->up_ul_tnl_length = 1;
|
||||
|
||||
/* pass QoS info to MAC */
|
||||
@@ -2323,8 +2337,8 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
|
||||
LOG_W(RRC, "E1: received setup for PDU session %ld, but has not been requested\n", e1_pdu->id);
|
||||
continue;
|
||||
}
|
||||
rrc_pdu->param.gNB_teid_N3 = e1_pdu->teId;
|
||||
memcpy(&rrc_pdu->param.gNB_addr_N3.buffer, &e1_pdu->tlAddress, sizeof(uint8_t) * 4);
|
||||
rrc_pdu->param.gNB_teid_N3 = e1_pdu->tl_info.teId;
|
||||
memcpy(&rrc_pdu->param.gNB_addr_N3.buffer, &e1_pdu->tl_info.tlAddress, sizeof(uint8_t) * 4);
|
||||
rrc_pdu->param.gNB_addr_N3.length = sizeof(in_addr_t);
|
||||
|
||||
// save the tunnel address for the DRBs
|
||||
|
||||
@@ -353,10 +353,11 @@ bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
|
||||
session->nssai = sessions[i].nssai;
|
||||
decodePDUSessionResourceSetup(session);
|
||||
bearer_req.gNB_cu_cp_ue_id = UE->rrc_ue_id;
|
||||
bearer_req.cipheringAlgorithm = UE->ciphering_algorithm;
|
||||
bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm;
|
||||
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)bearer_req.encryptionKey);
|
||||
nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, (uint8_t *)bearer_req.integrityProtectionKey);
|
||||
security_information_t *secInfo = &bearer_req.secInfo;
|
||||
secInfo->cipheringAlgorithm = rrc->security.do_drb_ciphering ? UE->ciphering_algorithm : 0;
|
||||
secInfo->integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? UE->integrity_algorithm : 0;
|
||||
nr_derive_key(UP_ENC_ALG, secInfo->cipheringAlgorithm, UE->kgnb, (uint8_t *)secInfo->encryptionKey);
|
||||
nr_derive_key(UP_INT_ALG, secInfo->integrityProtectionAlgorithm, UE->kgnb, (uint8_t *)secInfo->integrityProtectionKey);
|
||||
bearer_req.ueDlAggMaxBitRate = ueAggMaxBitRateDownlink;
|
||||
pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions;
|
||||
bearer_req.numPDUSessions++;
|
||||
|
||||
Reference in New Issue
Block a user