diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 345ed424ea..9546a2b2bb 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1166,10 +1166,10 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_c } } } - if (sdap_config) { - // nr_reconfigure_sdap_entity - AssertFatal(false, "Function to reconfigure SDAP entity not implemented yet\n"); - } + /* SDAP entity reconfiguration */ + if (sdap_config) + nr_reconfigure_sdap_entity(sdap_config, ue_id, sdap_config->pdu_Session, drb_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index cb4406ecd1..c19fd4e00e 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1237,8 +1237,6 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, /* PDCP and SDAP reconfiguration */ if (drb->pdcp_Config || sdap_Config) nr_pdcp_reconfigure_drb(ue_rrc->ue_id, DRB_id, drb->pdcp_Config, sdap_Config); - if (drb->cnAssociation) - AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n"); } else { ue_rrc->status_DRBs[DRB_id] = RB_ESTABLISHED; add_drb(false, diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 5508c5294a..1a1d28782f 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -641,3 +641,43 @@ bool nr_sdap_delete_ue_entities(ue_id_t ue_id) } return ret; } + +/** + * @brief SDAP Entity reconfiguration at UE according to TS 37.324 + * and triggered by RRC reconfiguration events according to clause 5.3.5.6.5 of TS 38.331. + * This function performs: + * - QoS flow to DRB mapping according to clause 5.3.1 of TS 37.324 + */ +void nr_reconfigure_sdap_entity(NR_SDAP_Config_t *sdap_config, ue_id_t ue_id, int pdusession_id, int drb_id) +{ + bool is_gnb = false; + /* fetch SDAP entity */ + nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, pdusession_id); + AssertError(sdap_entity != NULL, + return, + "Could not find SDAP Entity for RNTI/UE ID: %lu and PDU SESSION ID: %d\n", + ue_id, + pdusession_id); + /* QFI to DRB mapping */ + NR_QFI_t *mappedQFIs2Add = (NR_QFI_t *)sdap_config->mappedQoS_FlowsToAdd->list.array[0]; + uint8_t mappedQFIs2AddCount = sdap_config->mappedQoS_FlowsToAdd->list.count; + bool has_sdap_rx = is_sdap_rx(is_gnb, sdap_config); + bool has_sdap_tx = is_sdap_tx(is_gnb, sdap_config); + nr_sdap_ue_qfi2drb_config(sdap_entity, + sdap_entity->default_drb, + ue_id, + mappedQFIs2Add, + mappedQFIs2AddCount, + drb_id, + has_sdap_rx, + has_sdap_tx); + /* handle QFIs to DRB mapping rule to release */ + if (sdap_config->mappedQoS_FlowsToRelease) { + NR_QFI_t *mappedQFIs2release = (NR_QFI_t *)sdap_config->mappedQoS_FlowsToRelease->list.array[0]; + uint8_t mappedQFIs2RemoveCount = sdap_config->mappedQoS_FlowsToRelease->list.count; + for(int i = 0; i < mappedQFIs2RemoveCount; i++){ + uint8_t qfi = mappedQFIs2release[i]; + sdap_entity->qfi2drb_map_delete(sdap_entity, qfi); + } + } +} diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index 2e6056748e..3768d60f6a 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -205,4 +205,10 @@ bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config); */ bool is_sdap_tx(bool is_gnb, NR_SDAP_Config_t *sdap_config); +/** + * @brief Run the SDAP reconfiguration for the DRB + * @param[in] ue_id Unique identifier for the User Equipment. ID Range [0, 65536]. + */ +void nr_reconfigure_sdap_entity(NR_SDAP_Config_t *sdap_config, ue_id_t ue_id, int pdusession_id, int drb_id); + #endif