Commit 2146f29c authored by Guido Casati's avatar Guido Casati

Refactor E1 Bearer Context Management structs

Bearer context setup request and modification request messages
differ in various IEs according to 9.2.2 of 3GPP TS 38.463, e.g.
the Bearer context setup request does not contain a list of
DRBs to modify and does not contain an UP TL configuration.

Thus, the goal of this commit is to split the setup request message
and the modification request into two different structs:
* adopt e1ap_bearer_mod_req_t where necessary (e.g. fill_e1_bearer_modif)

Also, reorganized existing struct members according to specs:
* remove irrelevant struct members from the setup request
* group members from the same IEs into structs
* set optional struct members IEs as pointers
* add and adopt enc/dec/cp/eq lib functions for single IEs
* add UP_TL_information_t struct with TEID and TL address info and adopt in stack
* use int instead of long for count types
* update the relevant copy/equality check utility functions

Extra:
* add a function to handle Security Information in RRC in the process
* add create_up_tl_info and adopt in unit tests
parent 4f613ab2
......@@ -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) {
......
......@@ -252,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) */
......@@ -325,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];
// 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 QoS Flows Parameters (clause 9.3.1.26) */
/**
* 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_setup_t, DRB_nGRAN_to_mod_t;
} DRB_nGRAN_to_mod_t;
typedef enum e1ap_indication_e {
SECURITY_REQUIRED = 0,
......@@ -371,47 +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;
// 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];
} security_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 {
// 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;
long numDRB2Setup;
// 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_setup_t, pdu_session_to_mod_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 {
// gNB-CU-CP UE E1AP ID (M)
uint32_t gNB_cu_cp_ue_id;
uint32_t gNB_cu_up_ue_id; // Bearer Context Modification Request only
uint64_t cipheringAlgorithm;
uint64_t integrityProtectionAlgorithm;
char encryptionKey[E1AP_SECURITY_KEY_SIZE];
char integrityProtectionKey[E1AP_SECURITY_KEY_SIZE];
long ueDlAggMaxBitRate;
// 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;
// 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;
......@@ -425,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 {
......@@ -472,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;
......
......@@ -429,7 +429,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);
......@@ -473,7 +473,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) {
......@@ -482,8 +482,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;
}
......@@ -491,7 +491,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;
......@@ -635,7 +635,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;
......@@ -647,8 +648,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");
}
......@@ -663,7 +664,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:
......
......@@ -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"
......
......@@ -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
*/
......@@ -107,8 +115,8 @@ 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,
......@@ -121,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,
......@@ -132,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
......@@ -171,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,
......@@ -180,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);
......
......@@ -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,14 @@ 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);
}
nr_pdcp_reestablishment(req->gNB_cu_up_ue_id,
to_modif->id,
false,
......@@ -291,8 +292,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);
#endif /* CUCP_CUUP_HANDLER_H */
......@@ -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;
......
......@@ -345,7 +345,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;
......
......@@ -740,6 +740,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
......@@ -797,21 +805,20 @@ 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);
// Always send security information
req.secInfo = malloc_or_fail(sizeof(*req.secInfo));
fill_security_info(rrc, ue_p, req.secInfo);
/* Send E1 Bearer Context Modification Request (3GPP TS 38.463) */
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, ue_p);
rrc->cucp_cuup.bearer_context_mod(assoc_id, &req);
......@@ -1859,12 +1866,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;
}
/**
......@@ -1896,8 +1903,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);
}
......@@ -1923,10 +1930,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;
......@@ -1934,10 +1941,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);
......@@ -2275,9 +2281,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 */
......@@ -2328,8 +2334,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
......
......@@ -355,10 +355,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 = UE->ciphering_algorithm;
secInfo->integrityProtectionAlgorithm = UE->integrity_algorithm;
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)secInfo->encryptionKey);
nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, 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++;
......
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