refactor: improve SDAP entity add/update flow management

This commit refactors the SDAP entity QoS flow to DRB mapping functionality
to improve code organization and enhance maintainability.

Key changes:
- Split nr_sdap_qfi2drb_map_update into focused functions:
  * nr_sdap_add_qos_flows_to_drb: handles QFI addition to DRB
  * nr_sdap_rm_qos_flows_from_drb: handles QFI removal from DRB
  * nr_sdap_ue_control_pdu_config: handles UE control PDU generation
- Consolidate add/modify logic into reusable nr_sdap_addmod_entity function
- Remove entity existence checking and updating from new_nr_sdap_entity:
  this function should only add SDAP entities
- Improve function separation of concerns: do SDAP entity add or update
  separately and improve modularity by splitting operations in self
  contained functions
- At SDAP creation, do only add of QFI to DRB mapping
- rename new_nr_sdap_entity to nr_sdap_add_entity for function naming consinstency
This commit is contained in:
Guido Casati
2025-10-21 18:02:41 +02:00
parent 04a1acf376
commit 27be4e26a9
5 changed files with 61 additions and 69 deletions

View File

@@ -153,7 +153,7 @@ static void e1_add_bearers(const int ue_id, const NR_DRB_ToAddModList_t *addMod,
// 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);
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
}

View File

@@ -177,7 +177,7 @@ static void rrc_nsa_add_drb(const int ue_id,
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);
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
}

View File

@@ -619,7 +619,7 @@ static void rrc_ue_add_bearer(const int ue_id, const NR_DRB_ToAddMod_t *drb, con
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);
nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_NO, ue_id, drb->pdcp_Config, &sdap, sp);
}

View File

@@ -331,27 +331,6 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
}
}
/** @brief Update QFI to DRB mapping rules
* @param qfi the QoS Flow index, used as unique index of the qfi2drb mapping table
* @param drb the DRB ID to be mapped */
static void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Add[i];
LOG_D(SDAP, "Updating QFI to DRB mapping rules: %d mapped QFIs for DRB %d\n", sdap->mappedQFIs2AddCount, sdap->drb_id);
if (qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && sdap->drb_id > 0 && sdap->drb_id <= MAX_DRBS_PER_UE) {
entity->qfi2drb_map_add(entity, qfi, sdap->drb_id, sdap->role);
} else {
LOG_E(SDAP, "Failed to update qfi2drb mapping: QFI=%d, DRB=%d\n", qfi, sdap->drb_id);
}
}
for (int i = 0; i < sdap->mappedQFIs2ReleaseCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Release[i];
LOG_D(SDAP, "Deelting QFI to DRB mapping rules: QFI=%d for DRB=%d\n", qfi, sdap->drb_id);
entity->qfi2drb_map_delete(entity, qfi);
}
}
static void nr_sdap_qfi2drb_map_add(nr_sdap_entity_t *entity,
const uint8_t qfi,
const uint8_t drb_id,
@@ -437,13 +416,12 @@ void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hd
}
/** @brief UL QoS flow to DRB mapping configuration for a SDAP entity has already been established
* according to TS 37.324, 5.3 QoS flow to DRB Mapping, 5.3.1 Configuration Procedures.
* The function handles both UL QoS Flows mapping rules to add and to remove. */
static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *entity, const ue_id_t ue_id, const sdap_config_t sdap)
* according to TS 37.324, 5.3 QoS flow to DRB Mapping, 5.3.1 Configuration Procedures. */
static void nr_sdap_ue_control_pdu_config(nr_sdap_entity_t *entity, const ue_id_t ue_id, const sdap_config_t *sdap)
{
// handle QFIs to DRB mapping rule to add
for (int i = 0; i < sdap.mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap.mappedQFIs2Add[i];
for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Add[i];
/* a default DRB exists and there is no stored QFI to DRB mapping rule for the QFI */
if (entity->default_drb && entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE) {
// construct an end-marker control PDU (6.2.3 TS 37.324)
@@ -455,7 +433,7 @@ static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *entity, const ue_id_t ue
}
/* the stored UL QFI to DRB mapping rule is different from the configured one and has UL SDAP header */
bool ul_sdap_header = (entity->qfi2drb_table[qfi].entity_role & SDAP_UL_TX) != 0;
if (entity->qfi2drb_table[qfi].drb_id != sdap.drb_id && ul_sdap_header) {
if (entity->qfi2drb_table[qfi].drb_id != sdap->drb_id && ul_sdap_header) {
// construct an end-marker control PDU (6.2.3 TS 37.324)
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(qfi);
// map the end-marker control PDU to the DRB according to the stored QoS flow to DRB mapping rule
@@ -464,15 +442,42 @@ static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *entity, const ue_id_t ue
entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
}
}
}
// handle QFIs to DRB mapping rule to release
for (int i = 0; i < sdap.mappedQFIs2ReleaseCount; i++) {
entity->qfi2drb_map_delete(entity, sdap.mappedQFIs2Release[i]);
/** @brief Add QoS flows to a DRB */
static void nr_sdap_add_qos_flows_to_drb(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Add[i];
LOG_D(SDAP, "Adding QFI to DRB mapping rules: %d mapped QFIs for DRB %d\n", sdap->mappedQFIs2AddCount, sdap->drb_id);
if (qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && sdap->drb_id > 0 && sdap->drb_id <= MAX_DRBS_PER_UE) {
entity->qfi2drb_map_add(entity, qfi, sdap->drb_id, sdap->role);
} else {
LOG_E(SDAP, "Failed to add qfi2drb mapping: QFI=%d, DRB=%d\n", qfi, sdap->drb_id);
}
}
}
// store QFI to DRB mapping rules
LOG_D(SDAP, "Storing the configured QoS flow to DRB mapping rule\n");
entity->qfi2drb_map_update(entity, &sdap);
/** @brief Remove QoS flows from a DRB */
static void nr_sdap_rm_qos_flows_from_drb(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
for (int i = 0; i < sdap->mappedQFIs2ReleaseCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Release[i];
LOG_D(SDAP, "Removing QFI from DRB mapping rules: QFI=%d for DRB=%d\n", qfi, sdap->drb_id);
entity->qfi2drb_map_delete(entity, qfi);
}
}
/** @brief Update QFI to DRB mapping rules
* @param qfi the QoS Flow index, used as unique index of the qfi2drb mapping table
* @param drb the DRB ID to be mapped */
static void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
if (!entity->is_gnb) { // UE control PDU configuration
nr_sdap_ue_control_pdu_config(entity, entity->ue_id, sdap);
}
nr_sdap_add_qos_flows_to_drb(entity, sdap);
nr_sdap_rm_qos_flows_from_drb(entity, sdap);
}
/**
@@ -480,31 +485,11 @@ static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *entity, const ue_id_t ue
* @note there is one SDAP entity per PDU session
*
* @param is_gnb, indicates whether it is for gNB or UE
* @param has_sdap_rx, indicates whether it is a receiving SDAP entity
* @param has_sdap_tx, indicates whether it is a transmitting SDAP entity
* @param ue_id, UE ID
* @param pdusession_id, PDU session ID
* @param is_defaultDRB, indicates whether the entity has a default DRB
* @param mapped_qfi_2_add, list of QoS flows to add/update
* @param mappedQFIs2AddCount, number of QoS flows to add/update
*/
nr_sdap_entity_t *new_nr_sdap_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
* @param sdap, SDAP configuration */
static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
{
/* check whether the SDAP entity already exists and
update QFI to DRB mapping rules in that case */
nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap.pdusession_id);
if (sdap_entity) {
LOG_E(SDAP, "SDAP Entity for UE already exists with RNTI/UE ID: %lu and PDU SESSION ID: %d\n", ue_id, sdap.pdusession_id);
if (!is_gnb) {
nr_sdap_ue_qfi2drb_config(sdap_entity, ue_id, sdap);
} else {
// store QFI to DRB mapping rules
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
}
return sdap_entity;
}
sdap_entity = calloc_or_fail(1, sizeof(*sdap_entity));
nr_sdap_entity_t *sdap_entity = calloc_or_fail(1, sizeof(*sdap_entity));
// SDAP entity ids
sdap_entity->ue_id = ue_id;
@@ -533,8 +518,8 @@ nr_sdap_entity_t *new_nr_sdap_entity(const int is_gnb, const ue_id_t ue_id, cons
LOG_I(SDAP, "Default DRB for the created SDAP entity: DRB %d \n", sdap_entity->default_drb);
}
// store QFI to DRB mapping rules
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
// Add QoS flows to the DRB (initial configuration)
nr_sdap_add_qos_flows_to_drb(sdap_entity, &sdap);
// update SDAP entity list pointers
sdap_entity->next_entity = sdap_info.sdap_entity_llist;
@@ -545,7 +530,17 @@ nr_sdap_entity_t *new_nr_sdap_entity(const int is_gnb, const ue_id_t ue_id, cons
// PDCP SDUs to/from the TUN interface.
start_sdap_tun_gnb_first_ue_default_pdu_session(ue_id);
}
return sdap_entity;
}
/** @brief Add or modify an SDAP entity if it already exists */
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
{
nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap.pdusession_id);
if (sdap_entity) {
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
} else {
nr_sdap_add_entity(is_gnb, ue_id, sdap);
}
}
/**
@@ -717,7 +712,7 @@ void nr_reconfigure_sdap_entity(NR_SDAP_Config_t *sdap_config, ue_id_t ue_id, in
pdusession_id);
/* QFI to DRB mapping */
sdap_config_t sdap = nr_sdap_get_config(is_gnb, sdap_config, drb_id);
nr_sdap_ue_qfi2drb_config(sdap_entity, ue_id, sdap);
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
}
void set_qfi(uint8_t qfi, uint8_t pduid, ue_id_t ue_id)

View File

@@ -164,12 +164,6 @@ int nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, int map_type, uint8_t dl_qfi)
*/
void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
/*
* TS 37.324 4.4 5.1.1 SDAP entity establishment
* Establish an SDAP entity.
*/
nr_sdap_entity_t *new_nr_sdap_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap);
/* Entity Handling Related Functions */
nr_sdap_entity_t *nr_sdap_get_entity(ue_id_t ue_id, int pdusession_id);
@@ -177,6 +171,9 @@ sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_
void nr_sdap_release_drb(ue_id_t ue_id, int drb_id, int pdusession_id);
/** @brief Add or modify an SDAP entity based on whether it already exists */
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap);
/**
* @brief Function to delete a single SDAP Entity based on the ue_id and pdusession_id.
* @note 1. SDAP entities may have the same ue_id.