Merge remote-tracking branch 'origin/e1-reestablishment' into integration_2024_w09

This commit is contained in:
Robert Schmidt
2024-03-04 08:45:47 +01:00
23 changed files with 502 additions and 228 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ static void cucp_cuup_bearer_context_setup_direct(sctp_assoc_t assoc_id, const e
e1_bearer_context_setup(req);
}
static void cucp_cuup_bearer_context_modif_direct(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req)
static void cucp_cuup_bearer_context_modif_direct(sctp_assoc_t assoc_id, const e1ap_bearer_mod_req_t *req)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id);
e1_bearer_context_modif(req);
+2 -2
View File
@@ -37,12 +37,12 @@ static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, const e1a
itti_send_msg_to_task (TASK_CUCP_E1, 0, msg_p);
}
static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req)
static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_mod_req_t *req)
{
AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id);
MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_REQ);
msg->ittiMsgHeader.originInstance = assoc_id;
e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
e1ap_bearer_mod_req_t *req_msg = &E1AP_BEARER_CONTEXT_MODIFICATION_REQ(msg);
memcpy(req_msg, req, sizeof(*req));
itti_send_msg_to_task(TASK_CUCP_E1, 0, msg);
}
+2 -1
View File
@@ -28,7 +28,8 @@
#define NR_RRC_HEADER_SIZE_MAX 64
#define NR_RRC_BUFFER_SIZE_MAX 1024
#define NR_NUM_SRB 4
#define NR_NUM_SRB 4 /* Number of Signalling Radio Bearers according to clause 4.2.2 of 3GPP TS 38.331 */
#define NR_K_KEY_SIZE 16 /* K keys have 128 bits length */
typedef struct {
char Payload[NR_RRC_BUFFER_SIZE_MAX];
+13 -1
View File
@@ -189,6 +189,16 @@ typedef struct pdu_session_param_s {
uint8_t cause_value;
} rrc_pdu_session_param_t;
/**
* @brief F1-U tunnel configuration
*/
typedef struct f1u_tunnel_s {
/* Downlink F1-U Tunnel Endpoint Identifier (CU-UP/DU) */
uint32_t cuup_teid_f1u;
/* DL F1-U Transport Layer */
transport_layer_addr_t cuup_addr_f1u;
} f1u_tunnel_t;
typedef struct drb_s {
int status;
int defaultDRBid;
@@ -221,6 +231,8 @@ typedef struct drb_s {
int cipheringDisabled;
} ext1;
} pdcp_config;
// F1-U
f1u_tunnel_t f1u_tunnel_config;
} drb_t;
typedef enum {
@@ -241,7 +253,7 @@ typedef struct gNB_RRC_UE_s {
drb_t established_drbs[MAX_DRBS_PER_UE];
NR_DRB_ToReleaseList_t *DRB_ReleaseList;
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
NR_SRB_INFO_TABLE_ENTRY Srb[NR_NUM_SRB];
NR_MeasConfig_t *measConfig;
NR_HANDOVER_INFO *handover_info;
NR_MeasResults_t *measResults;
+158 -63
View File
@@ -97,6 +97,7 @@
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#include "openair2/E1AP/e1ap.h"
#include "cucp_cuup_if.h"
#include "BIT_STRING.h"
@@ -154,15 +155,24 @@ static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, in
data->rrc->mac_rrc.dl_rrc_message_transfer(data->assoc_id, data->dl_rrc);
}
void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size)
void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc,
const gNB_RRC_UE_t *ue_p,
uint8_t srb_id,
const uint8_t *buffer,
int size)
{
DevAssert(size > 0);
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data);
f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id};
deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id };
nr_pdcp_data_req_srb(ue_p->rrc_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data);
deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id};
nr_pdcp_data_req_srb(ue_p->rrc_ue_id,
srb_id,
rrc_gNB_mui++,
size,
(unsigned char *const)buffer,
rrc_deliver_dl_rrc_message,
&data);
}
static int get_dl_band(const f1ap_served_cell_info_t *cell_info)
@@ -188,9 +198,13 @@ static int get_dl_bw(const f1ap_served_cell_info_t *cell_info)
static int get_ssb_arfcn(const f1ap_served_cell_info_t *cell_info, const NR_MIB_t *mib, const NR_SIB1_t *sib1)
{
DevAssert(cell_info != NULL && sib1 != NULL && mib != NULL);
const NR_FrequencyInfoDL_SIB_t* freq_info = &sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL;
AssertFatal(freq_info->scs_SpecificCarrierList.list.count == 1, "cannot handle more than one carrier, but has %d\n", freq_info->scs_SpecificCarrierList.list.count);
AssertFatal(freq_info->scs_SpecificCarrierList.list.array[0]->offsetToCarrier == 0, "cannot handle offsetToCarrier != 0, but is %ld\n", freq_info->scs_SpecificCarrierList.list.array[0]->offsetToCarrier);
const NR_FrequencyInfoDL_SIB_t *freq_info = &sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL;
AssertFatal(freq_info->scs_SpecificCarrierList.list.count == 1,
"cannot handle more than one carrier, but has %d\n",
freq_info->scs_SpecificCarrierList.list.count);
AssertFatal(freq_info->scs_SpecificCarrierList.list.array[0]->offsetToCarrier == 0,
"cannot handle offsetToCarrier != 0, but is %ld\n",
freq_info->scs_SpecificCarrierList.list.array[0]->offsetToCarrier);
long offsetToPointA = freq_info->offsetToPointA;
long kssb = mib->ssb_SubcarrierOffset;
@@ -216,7 +230,17 @@ static int get_ssb_arfcn(const f1ap_served_cell_info_t *cell_info, const NR_MIB_
int band_size_hz = get_supported_bw_mhz(band > 256 ? FR2 : FR1, bw_index) * 1000 * 1000;
uint32_t ssb_arfcn = to_nrarfcn(band, freqssb, scs, band_size_hz);
LOG_D(RRC, "freqpointa %ld Hz/%d offsetToPointA %ld kssb %ld scs %d band %d band_size_hz %d freqssb %ld Hz/%d\n", freqpointa, dl_arfcn, offsetToPointA, kssb, scs, band, band_size_hz, freqssb, ssb_arfcn);
LOG_D(NR_RRC,
"freqpointa %ld Hz/%d offsetToPointA %ld kssb %ld scs %d band %d band_size_hz %d freqssb %ld Hz/%d\n",
freqpointa,
dl_arfcn,
offsetToPointA,
kssb,
scs,
band,
band_size_hz,
freqssb,
ssb_arfcn);
if (RC.nrmac) {
// debugging: let's test this is the correct ARFCN
@@ -227,7 +251,11 @@ static int get_ssb_arfcn(const f1ap_served_cell_info_t *cell_info, const NR_MIB_
// taken out (but the reestablishment will likely not work).
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
uint32_t scc_ssb_arfcn = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB;
AssertFatal(ssb_arfcn == scc_ssb_arfcn, "mismatch of SCC SSB ARFCN original %d vs. computed %d! Note: you can remove this Assert, the gNB might run but UE connection instable\n", scc_ssb_arfcn, ssb_arfcn);
AssertFatal(ssb_arfcn == scc_ssb_arfcn,
"mismatch of SCC SSB ARFCN original %d vs. computed %d! Note: you can remove this Assert, the gNB might run but UE "
"connection instable\n",
scc_ssb_arfcn,
ssb_arfcn);
}
return ssb_arfcn;
@@ -348,7 +376,7 @@ static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
return NULL;
}
NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1);
for (int i = 0; i < maxSRBs; i++)
for (int i = 0; i < NR_NUM_SRB; i++)
if (ue->Srb[i].Active) {
asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb);
srb->srb_Identity = i;
@@ -408,8 +436,8 @@ static void activate_srb(gNB_RRC_UE_t *UE, int srb_id)
if (srb_id == 1) {
nr_pdcp_add_srbs(true, UE->rrc_ue_id, list, 0, NULL, NULL);
} else {
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint);
@@ -883,18 +911,87 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
//-----------------------------------------------------------------------------
/* \brief find existing PDU session inside E1AP Bearer Modif message, or
* point to new one.
* \param bearer_modif E1AP Bearer Modification Message
* \param pdu_id PDU session ID
* \return pointer to existing PDU session, or to new/unused one. */
static pdu_session_to_mod_t *find_or_next_pdu_session(e1ap_bearer_mod_req_t *bearer_modif, int pdu_id)
{
for (int i = 0; i < bearer_modif->numPDUSessionsMod; ++i) {
if (bearer_modif->pduSessionMod[i].sessionId == pdu_id)
return &bearer_modif->pduSessionMod[i];
}
/* E1AP Bearer Modification has no PDU session to modify with that ID, create
* new entry */
DevAssert(bearer_modif->numPDUSessionsMod < E1AP_MAX_NUM_PDU_SESSIONS - 1);
bearer_modif->numPDUSessionsMod += 1;
return &bearer_modif->pduSessionMod[bearer_modif->numPDUSessionsMod - 1];
}
/**
* @brief Notify E1 re-establishment to CU-UP
*/
static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
{
e1ap_bearer_mod_req_t req = {
.gNB_cu_cp_ue_id = ue_p->rrc_ue_id,
.gNB_cu_up_ue_id = ue_p->rrc_ue_id,
};
if (!ue_associated_to_cuup(rrc, ue_p))
return;
/* loop through active DRBs */
for (int drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) {
if (ue_p->established_drbs[drb_id - 1].status == DRB_INACTIVE)
continue;
/* fetch an existing PDU session for this DRB */
rrc_pdu_session_param_t *pdu = find_pduSession_from_drbId(ue_p, drb_id);
if (pdu == NULL) {
LOG_E(RRC, "UE %d: E1 Bearer Context Modification: no PDU session for DRB ID %d\n", ue_p->rrc_ue_id, drb_id);
continue;
}
/* Get pointer to existing (or new one) PDU session to modify in E1 */
pdu_session_to_mod_t *pdu_e1 = find_or_next_pdu_session(&req, pdu->param.pdusession_id);
AssertError(pdu != NULL,
continue,
"UE %d: E1 Bearer Context Modification: PDU session %d to setup is null\n",
ue_p->rrc_ue_id,
pdu->param.pdusession_id);
/* Prepare PDU for E1 Bearear Context Modification Request */
pdu_e1->sessionId = pdu->param.pdusession_id;
/* Fill DRB to setup with ID, DL TL and DL TEID */
DRB_nGRAN_to_mod_t *drb_e1 = &pdu_e1->DRBnGRanModList[pdu_e1->numDRB2Modify];
drb_e1->id = drb_id;
drb_e1->numDlUpParam = 1;
drb_t *drbs = &ue_p->established_drbs[drb_id];
memcpy(&drb_e1->DlUpParamList[0].tlAddress, &drbs->f1u_tunnel_config.cuup_addr_f1u.buffer, sizeof(uint8_t) * 4);
drb_e1->DlUpParamList[0].teId = drbs->f1u_tunnel_config.cuup_teid_f1u;
/* PDCP configuration */
bearer_context_pdcp_config_t *pdcp_config = &drb_e1->pdcp_config;
drb_t *rrc_drb = get_drb(ue_p, drb_id);
set_bearer_context_pdcp_config(pdcp_config, rrc_drb, rrc->configuration.um_on_default_drb);
pdcp_config->pDCP_Reestablishment = true;
/* increase DRB to modify counter */
pdu_e1->numDRB2Modify += 1;
}
/* 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);
}
/**
* @brief RRCReestablishment message
* Direction: Network to UE
*/
static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context_pP,
const uint8_t *masterCellGroup_from_DU,
const rnti_t old_rnti,
const nr_rrc_du_container_t *du)
//-----------------------------------------------------------------------------
{
module_id_t module_id = 0;
gNB_RRC_INST *rrc = RC.nrrrc[module_id];
int enable_ciphering = 0;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
uint8_t buffer[RRC_BUF_SIZE] = {0};
uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id);
ue_p->xids[xid] = RRC_REESTABLISH;
@@ -904,34 +1001,34 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size);
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
uint8_t kUPenc[16] = {0};
/* Ciphering and Integrity according to TS 33.501 */
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
/* Derive the keys from kgnb */
if (ue_p->Srb[1].Active)
nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc);
nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint);
LOG_I(NR_RRC, "Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", ue_p->rrc_ue_id, ue_p->rnti, ue_p->ciphering_algorithm, ue_p->integrity_algorithm);
LOG_I(NR_RRC,
"Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n",
ue_p->rrc_ue_id,
ue_p->rnti,
ue_p->ciphering_algorithm,
ue_p->integrity_algorithm);
uint8_t security_mode =
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4);
for (int srb_id = 1; srb_id < maxSRBs; srb_id++) {
/* SRBs */
for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) {
if (ue_p->Srb[srb_id].Active) {
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc);
// TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true);
}
}
// TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag
for (int drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) {
if (ue_p->established_drbs[drb_id - 1].status != DRB_INACTIVE)
nr_pdcp_reestablishment(ue_p->rrc_ue_id, drb_id, false);
}
/* PDCP Reestablishment over E1 */
cuup_notify_reestablishment(rrc, ue_p);
/* F1AP DL RRC Message Transfer */
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data);
uint32_t old_gNB_DU_ue_id = old_rnti;
@@ -1017,11 +1114,11 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
}
//-----------------------------------------------------------------------------
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
protocol_ctxt_t *const ctxt_pP,
const int dl_bwp_id,
const int ul_bwp_id) {
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
protocol_ctxt_t *const ctxt_pP,
const int dl_bwp_id,
const int ul_bwp_id)
{
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
ue_p->xids[xid] = RRC_DEDICATED_RECONF;
@@ -1044,7 +1141,10 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
return 0;
}
static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id, const NR_RRCSetupRequest_IEs_t *rrcSetupRequest, const f1ap_initial_ul_rrc_message_t *msg)
static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc,
sctp_assoc_t assoc_id,
const NR_RRCSetupRequest_IEs_t *rrcSetupRequest,
const f1ap_initial_ul_rrc_message_t *msg)
{
rrc_gNB_ue_context_t *ue_context_p = NULL;
if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) {
@@ -1121,7 +1221,10 @@ static const char *get_reestab_cause(NR_ReestablishmentCause_t c)
return "UNKNOWN Failure (ASN.1 decoder error?)";
}
static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id, const NR_RRCReestablishmentRequest_IEs_t *req, const f1ap_initial_ul_rrc_message_t *msg)
static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
sctp_assoc_t assoc_id,
const NR_RRCReestablishmentRequest_IEs_t *req,
const f1ap_initial_ul_rrc_message_t *msg)
{
uint64_t random_value = 0;
const char *scause = get_reestab_cause(req->reestablishmentCause);
@@ -1167,9 +1270,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t
// 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values
if (req->ue_Identity.c_RNTI < 0x1 || req->ue_Identity.c_RNTI > 0xffef) {
/* c_RNTI range error should not happen */
LOG_E(NR_RRC,
"NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n",
req->ue_Identity.c_RNTI);
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", req->ue_Identity.c_RNTI);
goto fallback_rrc_setup;
}
@@ -1183,8 +1284,9 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t
// update with new RNTI, and update secondary UE association
UE->rnti = msg->crnti;
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
ue_data.secondary_ue = msg->gNB_DU_ue_id;
cu_remove_f1_ue_data(UE->rrc_ue_id);
f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id, .du_assoc_id = assoc_id};
cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data);
LOG_I(NR_RRC, "Accept Reestablishment Request UE physCellId %ld cause %s\n", physCellId, scause);
@@ -1231,9 +1333,7 @@ static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_p
DevAssert(reestablishment_complete->criticalExtensions.present
== NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete);
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP,
ue_context_p,
reestablishment_complete->rrc_TransactionIdentifier);
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, ue_context_p, reestablishment_complete->rrc_TransactionIdentifier);
UE->ue_reestablishment_counter++;
return 0;
@@ -1740,22 +1840,14 @@ static void fill_e1_bearer_modif(DRB_nGRAN_to_setup_t *drb_e1, const f1ap_drb_to
drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid;
}
/* \brief find existing PDU session inside E1AP Bearer Modif message, or
* point to new one.
* \param bearer_modif E1AP Bearer Modification Message
* \param pdu_id PDU session ID
* \return pointer to existing PDU session, or to new/unused one. */
static pdu_session_to_setup_t *find_or_next_pdu_session(e1ap_bearer_setup_req_t *bearer_modif, int pdu_id)
/**
* @brief Store F1-U DL TL and TEID in RRC
*/
static void f1u_gtp_update(f1u_tunnel_t *f1u, const f1ap_drb_to_be_setup_t *drb_f1)
{
for (int i = 0; i < bearer_modif->numPDUSessionsMod; ++i) {
if (bearer_modif->pduSessionMod[i].sessionId == pdu_id)
return &bearer_modif->pduSessionMod[i];
}
/* E1AP Bearer Modification has no PDU session to modify with that ID, create
* new entry */
DevAssert(bearer_modif->numPDUSessionsMod < E1AP_MAX_NUM_PDU_SESSIONS - 1);
bearer_modif->numPDUSessionsMod += 1;
return &bearer_modif->pduSessionMod[bearer_modif->numPDUSessionsMod - 1];
f1u->cuup_teid_f1u = drb_f1->up_dl_tnl[0].teid;
memcpy(&f1u->cuup_addr_f1u.buffer, &drb_f1->up_dl_tnl[0].tl_address, sizeof(uint8_t) * 4);
f1u->cuup_addr_f1u.length = sizeof(in_addr_t);
}
/* \brief use list of DRBs and send the corresponding bearer update message via
@@ -1763,7 +1855,7 @@ static pdu_session_to_setup_t *find_or_next_pdu_session(e1ap_bearer_setup_req_t
static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb_to_be_setup_t *drbs)
{
// we assume the same UE ID in CU-UP and CU-CP
e1ap_bearer_setup_req_t req = {
e1ap_bearer_mod_req_t req = {
.gNB_cu_cp_ue_id = UE->rrc_ue_id,
.gNB_cu_up_ue_id = UE->rrc_ue_id,
};
@@ -1779,6 +1871,8 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f
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];
f1u_gtp_update(&UE->established_drbs[drb_f1->drb_id].f1u_tunnel_config, drb_f1);
/* Fill E1 bearer context modification */
fill_e1_bearer_modif(drb_e1, drb_f1);
pdu_e1->numDRB2Modify += 1;
}
@@ -2006,7 +2100,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
resp->gNB_cu_up_ue_id);
// save the tunnel address for the PDU sessions
for (int i=0; i < resp->numPDUSessions; i++) {
for (int i = 0; i < resp->numPDUSessions; i++) {
pdu_session_setup_t *e1_pdu = &resp->pduSession[i];
rrc_pdu_session_param_t *rrc_pdu = find_pduSession(UE, e1_pdu->id, false);
if (rrc_pdu == NULL) {
@@ -2115,7 +2209,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
/**
* @brief E1AP Bearer Context Modification Response processing on CU-CP
*/
*/
void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp)
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
@@ -2134,7 +2228,7 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
/**
* @brief E1AP Bearer Context Release processing
*/
*/
void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cplt_t *cplt)
{
// there is not really anything to do here as of now
@@ -2301,6 +2395,7 @@ void *rrc_gnb_task(void *args_p) {
break;
/* Messages from PDCP */
/* From DU -> CU */
case F1AP_UL_RRC_MESSAGE:
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
instance,
+10 -15
View File
@@ -60,6 +60,7 @@
#include "f1ap_messages_types.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/E1AP/e1ap_asnc.h"
#include "openair2/E1AP/e1ap.h"
#include "NGAP_asn_constant.h"
#include "NGAP_PDUSessionResourceSetupRequestTransfer.h"
#include "NGAP_PDUSessionResourceModifyRequestTransfer.h"
@@ -130,9 +131,9 @@ nr_rrc_pdcp_config_security(
)
//------------------------------------------------------------------------------
{
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
uint8_t kUPenc[16] = {0};
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
//uint8_t *k_kdf = NULL;
static int print_keys= 1;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
@@ -406,19 +407,13 @@ static void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdu
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
drb->id = rrc_drb->drb_id;
/* SDAP */
struct sdap_config_s *sdap_config = &rrc_drb->cnAssociation.sdap_config;
drb->defaultDRB = sdap_config->defaultDRB;
drb->sDAP_Header_UL = sdap_config->sdap_HeaderUL;
drb->sDAP_Header_DL = sdap_config->sdap_HeaderDL;
struct pdcp_config_s *pdcp_config = &rrc_drb->pdcp_config;
drb->pDCP_SN_Size_UL = pdcp_config->pdcp_SN_SizeUL;
drb->pDCP_SN_Size_DL = pdcp_config->pdcp_SN_SizeDL;
drb->discardTimer = pdcp_config->discardTimer;
drb->reorderingTimer = pdcp_config->t_Reordering;
drb->rLC_Mode = rrc->configuration.um_on_default_drb ? E1AP_RLC_Mode_rlc_um_bidirectional : E1AP_RLC_Mode_rlc_am;
drb->sdap_config.defaultDRB = sdap_config->defaultDRB;
drb->sdap_config.sDAP_Header_UL = sdap_config->sdap_HeaderUL;
drb->sdap_config.sDAP_Header_DL = sdap_config->sdap_HeaderDL;
/* PDCP */
set_bearer_context_pdcp_config(&drb->pdcp_config, rrc_drb, rrc->configuration.um_on_default_drb);
drb->numCellGroups = 1; // assume one cell group associated with a DRB
+2 -2
View File
@@ -126,8 +126,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
protocol_ctxt_t ctxt={0};
uint8_t kUPenc[16] = {0};
uint8_t kUPint[16] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
uint8_t kUPint[NR_K_KEY_SIZE] = {0};
int i;
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
+25 -14
View File
@@ -21,6 +21,7 @@
#include "rrc_gNB_radio_bearers.h"
#include "oai_asn1.h"
#include "openair2/E1AP/e1ap.h"
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
{
@@ -56,6 +57,29 @@ drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id)
return &ue->established_drbs[drb_id - 1];
}
void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config, int do_drb_integrity, int do_drb_ciphering)
{
AssertError(pdcp_config != NULL, return, "Failed to set default PDCP configuration for DRB!\n");
pdcp_config->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
pdcp_config->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
pdcp_config->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
pdcp_config->t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
pdcp_config->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
pdcp_config->headerCompression.NotUsed = 0;
pdcp_config->integrityProtection = do_drb_integrity ? NR_PDCP_Config__drb__integrityProtection_enabled : 1;
pdcp_config->ext1.cipheringDisabled = do_drb_ciphering ? 1 : NR_PDCP_Config__ext1__cipheringDisabled_true;
}
void set_bearer_context_pdcp_config(bearer_context_pdcp_config_t *pdcp_config, drb_t *rrc_drb, bool um_on_default_drb)
{
AssertError(rrc_drb != NULL && pdcp_config != NULL, return, "Failed to set default bearer context PDCP configuration!\n");
pdcp_config->pDCP_SN_Size_UL = rrc_drb->pdcp_config.pdcp_SN_SizeUL;
pdcp_config->pDCP_SN_Size_DL = rrc_drb->pdcp_config.pdcp_SN_SizeDL;
pdcp_config->discardTimer = rrc_drb->pdcp_config.discardTimer;
pdcp_config->reorderingTimer = rrc_drb->pdcp_config.t_Reordering;
pdcp_config->rLC_Mode = um_on_default_drb ? E1AP_RLC_Mode_rlc_um_bidirectional : E1AP_RLC_Mode_rlc_am;
}
drb_t *generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
const rrc_pdu_session_param_t *pduSession,
@@ -95,20 +119,7 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue,
est_drb->status = DRB_ACTIVE;
}
/* PDCP Configuration */
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
est_drb->pdcp_config.headerCompression.NotUsed = 0;
if (do_drb_integrity)
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
else
est_drb->pdcp_config.integrityProtection = 1;
if (do_drb_ciphering)
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
else
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering);
drb_t *rrc_drb = get_drb(ue, drb_id);
DevAssert(rrc_drb == est_drb); /* to double check that we create the same which we would retrieve */
+3
View File
@@ -71,4 +71,7 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create);
/// @brief get PDU session of UE ue through the DRB drb_id
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id);
/// @brief set PDCP configuration in a bearer context management message
void set_bearer_context_pdcp_config(bearer_context_pdcp_config_t *pdcp_config, drb_t *rrc_drb, bool um_on_default_drb);
#endif
+5 -5
View File
@@ -987,9 +987,9 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete;
}
uint8_t kRRCenc[16] = {0};
uint8_t kUPenc[16] = {0};
uint8_t kRRCint[16] = {0};
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kUPenc);
nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint);
@@ -1167,8 +1167,8 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (radioBearerConfig->srb3_ToRelease)
nr_pdcp_release_srb(ue_rrc->ue_id, 3);
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
if (ue_rrc->as_security_activated) {
if (radioBearerConfig->securityConfig != NULL) {
// When the field is not included, continue to use the currently configured keyToUse