Refactor processing of sdap_Config in add_drb (PDCP)
* use get_sdap_Config to process sdap_Config * move SDAP config logic to the scope where it is relevant * add SDAP entity direcly in RRC, not from PDCP * replaced nr_pdcp_add_drbs with single add_drb call: it was no longer efficient to keep it in the new logic. The addMod list can be looped directly in RRC. * add specific function to add bearers from addMod list in E1, NSA, and UE
This commit is contained in:
+1
-1
@@ -325,7 +325,7 @@ The PDCP implementation is secured by a general mutex, akin to the design of the
|
||||
|
||||
Initialization of the PDCP layer follows a structure similar to that of the RLC layer. The function `nr_pdcp_layer_init()` initializes PDCP, while a second initialization function, `pdcp_module_init()`, must also be invoked.
|
||||
|
||||
To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `nr_pdcp_add_drbs()` adds UE DRBs in PDCP, with `nr_pdcp_remove_UE()` handling their removal.
|
||||
To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `add_drb()` adds UE DRB in PDCP, with `nr_pdcp_remove_UE()` handling their removal.
|
||||
|
||||
## PDCP Tx flow
|
||||
|
||||
|
||||
@@ -141,6 +141,24 @@ static instance_t get_f1_gtp_instance(void)
|
||||
return inst->gtpInst;
|
||||
}
|
||||
|
||||
/** @brief Add bearer in PDCP/SDAP for 5GC association (SA) */
|
||||
static void e1_add_bearers(const int ue_id, const NR_DRB_ToAddModList_t *addMod, const nr_pdcp_entity_security_keys_and_algos_t *sp)
|
||||
{
|
||||
for (int i = 0; i < addMod->list.count; i++) {
|
||||
NR_DRB_ToAddMod_t *drb = addMod->list.array[i];
|
||||
DevAssert(drb->cnAssociation);
|
||||
DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING);
|
||||
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config);
|
||||
DevAssert(drb->cnAssociation->choice.sdap_Config);
|
||||
// get SDAP config
|
||||
sdap_config_t sdap = nr_sdap_get_config(GNB_FLAG_YES, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity);
|
||||
// add SDAP entity
|
||||
new_nr_sdap_entity(GNB_FLAG_YES, ue_id, sdap);
|
||||
// add PDCP entity
|
||||
add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
|
||||
}
|
||||
}
|
||||
|
||||
void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
{
|
||||
bool need_ue_id_mgmt = e1_used();
|
||||
@@ -208,11 +226,10 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
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,
|
||||
&security_parameters);
|
||||
|
||||
e1_add_bearers(cu_up_ue_id, &DRB_configList, &security_parameters);
|
||||
ASN_STRUCT_RESET(asn_DEF_NR_DRB_ToAddModList, &DRB_configList.list);
|
||||
|
||||
if (f1inst >= 0) { /* we have F1(-U) */
|
||||
teid_t dummy_teid = 0xffff; // we will update later with answer from DU
|
||||
in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU
|
||||
|
||||
@@ -576,74 +576,31 @@ void add_srb(int is_gnb,
|
||||
}
|
||||
|
||||
void add_drb(int is_gnb,
|
||||
ue_id_t UEid,
|
||||
struct NR_DRB_ToAddMod *s,
|
||||
const ue_id_t UEid,
|
||||
const NR_PDCP_Config_t *pdcp,
|
||||
sdap_config_t *sdap,
|
||||
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
|
||||
{
|
||||
nr_pdcp_entity_t *pdcp_drb;
|
||||
nr_pdcp_ue_t *ue;
|
||||
|
||||
int drb_id = s->drb_Identity;
|
||||
if (!s->pdcp_Config || !s->pdcp_Config->drb) {
|
||||
LOG_E(PDCP, "DRB field mandatory present at setup. DRB %d not configured.\n", drb_id);
|
||||
if (!pdcp->drb) {
|
||||
LOG_E(PDCP, "Missing PDCP config. DRB %d not configured.\n", sdap->drb_id);
|
||||
return;
|
||||
}
|
||||
|
||||
struct NR_PDCP_Config__drb *drb = s->pdcp_Config->drb;
|
||||
struct NR_PDCP_Config__drb *drb = pdcp->drb;
|
||||
int sn_size_ul = decode_sn_size_ul(*drb->pdcp_SN_SizeUL);
|
||||
int sn_size_dl = decode_sn_size_dl(*drb->pdcp_SN_SizeDL);
|
||||
int discard_timer = decode_discard_timer(*drb->discardTimer);
|
||||
|
||||
int has_integrity;
|
||||
int has_ciphering;
|
||||
|
||||
/* if pdcp_Config->t_Reordering is not present, it means infinity (-1) */
|
||||
int t_reordering = -1;
|
||||
if (s->pdcp_Config->t_Reordering != NULL) {
|
||||
t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
|
||||
if (pdcp->t_Reordering != NULL) {
|
||||
t_reordering = decode_t_reordering(*pdcp->t_Reordering);
|
||||
}
|
||||
|
||||
if (drb->integrityProtection != NULL)
|
||||
has_integrity = 1;
|
||||
else
|
||||
has_integrity = 0;
|
||||
|
||||
if (s->pdcp_Config->ext1 != NULL && s->pdcp_Config->ext1->cipheringDisabled != NULL)
|
||||
has_ciphering = 0;
|
||||
else
|
||||
has_ciphering = 1;
|
||||
|
||||
if ((!s->cnAssociation) || s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_NOTHING) {
|
||||
LOG_E(PDCP, "fatal, cnAssociation is missing or present is NR_DRB_ToAddMod__cnAssociation_PR_NOTHING\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int pdusession_id;
|
||||
bool has_sdap_rx = false;
|
||||
bool has_sdap_tx = false;
|
||||
bool is_sdap_DefaultDRB = false;
|
||||
NR_QFI_t *mappedQFIs2Add = NULL;
|
||||
uint8_t mappedQFIs2AddCount=0;
|
||||
if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity)
|
||||
pdusession_id = s->cnAssociation->choice.eps_BearerIdentity;
|
||||
else {
|
||||
if (!s->cnAssociation->choice.sdap_Config) {
|
||||
LOG_E(PDCP,"fatal, sdap_Config is null");
|
||||
exit(-1);
|
||||
}
|
||||
pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session;
|
||||
has_sdap_rx = is_sdap_rx(is_gnb, s->cnAssociation->choice.sdap_Config);
|
||||
has_sdap_tx = is_sdap_tx(is_gnb, s->cnAssociation->choice.sdap_Config);
|
||||
is_sdap_DefaultDRB = s->cnAssociation->choice.sdap_Config->defaultDRB == true ? 1 : 0;
|
||||
mappedQFIs2Add = (NR_QFI_t*)s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.array[0];
|
||||
mappedQFIs2AddCount = s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.count;
|
||||
LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd from RRC: %ld \n", *mappedQFIs2Add);
|
||||
}
|
||||
/* TODO(?): accept different UL and DL SN sizes? */
|
||||
if (sn_size_ul != sn_size_dl) {
|
||||
LOG_E(PDCP, "fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", sn_size_ul, sn_size_dl);
|
||||
exit(1);
|
||||
}
|
||||
int has_integrity = (drb->integrityProtection != NULL) ? 1 : 0;
|
||||
int has_ciphering = (pdcp->ext1 != NULL && pdcp->ext1->cipheringDisabled != NULL) ? 0 : 1;
|
||||
|
||||
/* get actual ciphering and integrity algorithm based on pdcp_Config */
|
||||
nr_pdcp_entity_security_keys_and_algos_t actual_security_parameters = *security_parameters;
|
||||
@@ -652,29 +609,33 @@ void add_drb(int is_gnb,
|
||||
|
||||
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid);
|
||||
if (nr_pdcp_get_rb(ue, drb_id, false) != NULL) {
|
||||
LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", drb_id, UEid);
|
||||
if (nr_pdcp_get_rb(ue, sdap->drb_id, false) != NULL) {
|
||||
LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", sdap->drb_id, UEid);
|
||||
} else {
|
||||
pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id,
|
||||
has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue,
|
||||
is_gnb ?
|
||||
deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
|
||||
ue,
|
||||
sn_size_dl, t_reordering, discard_timer,
|
||||
&actual_security_parameters);
|
||||
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
|
||||
// code assumption: same SN size for both DL and UL
|
||||
if (sn_size_ul != sn_size_dl) {
|
||||
LOG_E(PDCP, "fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", sn_size_ul, sn_size_dl);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid);
|
||||
/* add new SDAP entity for the PDU session the DRB belongs to */
|
||||
new_nr_sdap_entity(is_gnb,
|
||||
has_sdap_rx,
|
||||
has_sdap_tx,
|
||||
UEid,
|
||||
pdusession_id,
|
||||
is_sdap_DefaultDRB,
|
||||
drb_id,
|
||||
mappedQFIs2Add,
|
||||
mappedQFIs2AddCount);
|
||||
// add PDCP entity
|
||||
nr_pdcp_entity_t *pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM,
|
||||
is_gnb,
|
||||
sdap->drb_id,
|
||||
sdap->pdusession_id,
|
||||
sdap->sdap_rx,
|
||||
sdap->sdap_tx,
|
||||
deliver_sdu_drb,
|
||||
ue,
|
||||
is_gnb ? deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
|
||||
ue,
|
||||
sn_size_dl,
|
||||
t_reordering,
|
||||
discard_timer,
|
||||
&actual_security_parameters);
|
||||
nr_pdcp_ue_add_drb_pdcp_entity(ue, sdap->drb_id, pdcp_drb);
|
||||
|
||||
LOG_I(PDCP, "Added DRB %d to UE ID %ld\n", sdap->drb_id, UEid);
|
||||
}
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
}
|
||||
@@ -692,22 +653,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
|
||||
LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n");
|
||||
}
|
||||
|
||||
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
|
||||
ue_id_t UEid,
|
||||
NR_DRB_ToAddModList_t *const drb2add_list,
|
||||
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
|
||||
{
|
||||
if (drb2add_list != NULL) {
|
||||
for (int i = 0; i < drb2add_list->list.count; i++) {
|
||||
add_drb(enb_flag,
|
||||
UEid,
|
||||
drb2add_list->list.array[i],
|
||||
security_parameters);
|
||||
}
|
||||
} else
|
||||
LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n");
|
||||
}
|
||||
|
||||
uint64_t get_pdcp_optmask(void)
|
||||
{
|
||||
return pdcp_optmask;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "nr_pdcp_ue_manager.h"
|
||||
struct NR_DRB_ToAddMod;
|
||||
struct NR_SRB_ToAddMod;
|
||||
struct sdap_configuration_s;
|
||||
|
||||
void nr_pdcp_layer_init(void);
|
||||
|
||||
@@ -42,19 +43,15 @@ bool nr_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
uint8_t *const sdu_buffer);
|
||||
|
||||
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
|
||||
ue_id_t UEid,
|
||||
NR_DRB_ToAddModList_t *const drb2add_list,
|
||||
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
|
||||
|
||||
void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
|
||||
ue_id_t UEid,
|
||||
NR_SRB_ToAddModList_t *const srb2add_list,
|
||||
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
|
||||
|
||||
void add_drb(int is_gnb,
|
||||
ue_id_t UEid,
|
||||
struct NR_DRB_ToAddMod *s,
|
||||
const ue_id_t UEid,
|
||||
const NR_PDCP_Config_t *pdcp,
|
||||
struct sdap_configuration_s *sdap,
|
||||
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
|
||||
|
||||
void nr_pdcp_remove_UE(ue_id_t ue_id);
|
||||
|
||||
@@ -161,6 +161,28 @@ static NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id,
|
||||
return rbconfig;
|
||||
}
|
||||
|
||||
static void rrc_nsa_add_drb(const int ue_id,
|
||||
const NR_DRB_ToAddModList_t *addMod,
|
||||
const nr_pdcp_entity_security_keys_and_algos_t *sp)
|
||||
{
|
||||
for (int i = 0; i < addMod->list.count; i++) {
|
||||
NR_DRB_ToAddMod_t *drb = addMod->list.array[i];
|
||||
DevAssert(drb->cnAssociation);
|
||||
DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING);
|
||||
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity);
|
||||
// get SDAP config
|
||||
sdap_config_t sdap = {0};
|
||||
// EPC association
|
||||
sdap.pdusession_id = drb->cnAssociation->choice.eps_BearerIdentity;
|
||||
sdap.drb_id = drb->drb_Identity;
|
||||
sdap.defaultDRB = true;
|
||||
// add SDAP entity (terminated at gNB, since it's EPC)
|
||||
new_nr_sdap_entity(GNB_FLAG_YES, ue_id, sdap);
|
||||
// add PDCP entity
|
||||
add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
|
||||
}
|
||||
}
|
||||
|
||||
/* generate prototypes for the tree management functions (RB_INSERT used in rrc_add_nsa_user) */
|
||||
RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
|
||||
rrc_gNB_compare_ue_rnti_id);
|
||||
@@ -304,10 +326,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_
|
||||
}
|
||||
|
||||
DevAssert(UE->rb_config != NULL);
|
||||
nr_pdcp_add_drbs(GNB_FLAG_YES,
|
||||
UE->rrc_ue_id,
|
||||
UE->rb_config->drb_ToAddModList,
|
||||
&security_parameters);
|
||||
rrc_nsa_add_drb(UE->rrc_ue_id, UE->rb_config->drb_ToAddModList, &security_parameters);
|
||||
|
||||
/* assumption: only a single bearer, see above */
|
||||
NR_DRB_ToAddModList_t *rb_list = UE->rb_config->drb_ToAddModList;
|
||||
|
||||
@@ -599,6 +599,31 @@ static void nr_rrc_process_dedicatedNAS_MessageList(NR_UE_RRC_INST_t *rrc, NR_RR
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Add bearer in PDCP/SDAP for 5GC association (SA) */
|
||||
static void rrc_ue_add_bearer(const int ue_id, const NR_DRB_ToAddMod_t *drb, const nr_pdcp_entity_security_keys_and_algos_t *sp)
|
||||
{
|
||||
DevAssert(drb->cnAssociation);
|
||||
DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING);
|
||||
// get SDAP config
|
||||
sdap_config_t sdap = {0};
|
||||
if (drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) {
|
||||
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity);
|
||||
|
||||
// EPC association
|
||||
sdap.pdusession_id = drb->cnAssociation->choice.eps_BearerIdentity;
|
||||
sdap.drb_id = drb->drb_Identity;
|
||||
sdap.defaultDRB = true;
|
||||
} else {
|
||||
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config);
|
||||
DevAssert(drb->cnAssociation->choice.sdap_Config);
|
||||
sdap = nr_sdap_get_config(GNB_FLAG_NO, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity);
|
||||
}
|
||||
// add SDAP entity
|
||||
new_nr_sdap_entity(GNB_FLAG_NO, ue_id, sdap);
|
||||
// add PDCP entity
|
||||
add_drb(GNB_FLAG_NO, ue_id, drb->pdcp_Config, &sdap, sp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief add, modify and release SRBs and/or DRBs
|
||||
* @ref 3GPP TS 38.331
|
||||
@@ -706,10 +731,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_Rad
|
||||
nr_reconfigure_sdap_entity(sdap_Config, ue_rrc->ue_id, sdap_Config->pdu_Session, DRB_id);
|
||||
} else {
|
||||
set_DRB_status(ue_rrc ,DRB_id, RB_ESTABLISHED);
|
||||
add_drb(false,
|
||||
ue_rrc->ue_id,
|
||||
radioBearerConfig->drb_ToAddModList->list.array[cnt],
|
||||
&security_up_parameters);
|
||||
rrc_ue_add_bearer(ue_rrc->ue_id, radioBearerConfig->drb_ToAddModList->list.array[cnt], &security_up_parameters);
|
||||
}
|
||||
}
|
||||
} // drb_ToAddModList //
|
||||
|
||||
@@ -77,7 +77,7 @@ typedef struct qfi2drb_s {
|
||||
|
||||
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
|
||||
|
||||
typedef struct {
|
||||
typedef struct sdap_configuration_s {
|
||||
int pdusession_id;
|
||||
int drb_id;
|
||||
bool sdap_rx;
|
||||
|
||||
Reference in New Issue
Block a user