diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index db78c4108b..ef2da07d57 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -888,13 +888,8 @@ void add_drb(int is_gnb, exit(-1); } pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session; - if (is_gnb) { - has_sdap_rx = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present; - has_sdap_tx = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present; - } else { - has_sdap_tx = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present; - has_sdap_rx = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present; - } + 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; @@ -926,8 +921,16 @@ void add_drb(int is_gnb, nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid); - - new_nr_sdap_entity(is_gnb, has_sdap_rx, has_sdap_tx, UEid, pdusession_id, is_sdap_DefaultDRB, drb_id, mappedQFIs2Add, mappedQFIs2AddCount); + /* 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); } nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -1127,7 +1130,7 @@ void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering) nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_config, NR_SDAP_Config_t *sdap_config) +void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_config) { // The enabling/disabling of ciphering or integrity protection // can be changed only by releasing and adding the DRB @@ -1163,10 +1166,6 @@ 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"); - } nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 97a48b0e6a..be1604dabd 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -67,7 +67,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag); void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id); void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id); void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering); -void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_config, NR_SDAP_Config_t *sdap_config); +void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_config); void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id); void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 401149d8e8..e6d017b878 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -70,6 +70,7 @@ #include "SIMULATION/TOOLS/sim.h" // for taus #include "nr_nas_msg_sim.h" +#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" static NR_UE_RRC_INST_t *NR_UE_rrc_inst; /* NAS Attach request with IMSI */ @@ -1158,6 +1159,10 @@ void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measCo } } +/** + * @brief add, modify and release SRBs and/or DRBs + * @ref 3GPP TS 38.331 + */ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_RadioBearerConfig_t *const radioBearerConfig) { @@ -1216,19 +1221,26 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, } } - // Establish DRBs if present + /** + * Establish/reconfig DRBs if DRB-ToAddMod is present + * according to 3GPP TS 38.331 clause 5.3.5.6.5 DRB addition/modification + */ if (radioBearerConfig->drb_ToAddModList != NULL) { for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt]; int DRB_id = drb->drb_Identity; + /* DRB is already established and configured */ if (ue_rrc->status_DRBs[DRB_id] == RB_ESTABLISHED) { AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); + /* sdap-Config is included (SA mode) */ NR_SDAP_Config_t *sdap_Config = drb->cnAssociation ? drb->cnAssociation->choice.sdap_Config : NULL; - 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"); + /* PDCP reconfiguration */ + if (drb->pdcp_Config) + nr_pdcp_reconfigure_drb(ue_rrc->ue_id, DRB_id, drb->pdcp_Config); + /* SDAP entity reconfiguration */ + if (sdap_Config) + nr_reconfigure_sdap_entity(sdap_Config, ue_rrc->ue_id, sdap_Config->pdu_Session, DRB_id); } 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 e119b2407a..1a1d28782f 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -37,6 +37,34 @@ static nr_sdap_entity_info sdap_info; instance_t *N3GTPUInst = NULL; +/** + * @brief indicates whether it is a receiving SDAP entity + * i.e. for UE, header for DL data is present + * for gNB, header for UL data is present + */ +bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config) +{ + if (is_gnb) { + return sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present; + } else { + return sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present; + } +} + +/** + * @brief indicates whether it is a transmitting SDAP entity + * i.e. for UE, header for UL data is present + * for gNB, header for DL data is present + */ +bool is_sdap_tx(bool is_gnb, NR_SDAP_Config_t *sdap_config) +{ + if (is_gnb) { + return sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present; + } else { + return sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present; + } +} + 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) { @@ -82,7 +110,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, } uint8_t sdap_buf[SDAP_MAX_PDU]; - rb_id_t pdcp_entity = entity->qfi2drb_map(entity, qfi, rb_id); + rb_id_t pdcp_entity = entity->qfi2drb_map(entity, qfi); if(pdcp_entity){ sdap_drb_id = pdcp_entity; @@ -184,7 +212,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, int pdusession_id, ue_id_t ue_id, char *buf, - int size) { + int size) +{ /* The offset of the SDAP header, it might be 0 if has_sdap_rx is not true in the pdcp entity. */ int offset=0; @@ -310,6 +339,9 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, } } +/** + * @brief update QFI to DRB mapping rules +*/ void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx) { if(qfi < SDAP_MAX_QFI && @@ -330,7 +362,11 @@ void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi){ LOG_D(SDAP, "Deleted mapping for QFI: %u \n", qfi); } -rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t upper_layer_rb_id){ +/** + * @brief maps the QFIs to the default DRB if not mapping rule exists + * @return DRB that is mapped to the QFI, 0 if no mapping and no default DRB exists for that QFI +*/ +rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi){ rb_id_t pdcp_entity; pdcp_entity = entity->qfi2drb_table[qfi].drb_id; @@ -368,12 +404,15 @@ rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int LOG_D(SDAP, "Mapping Control PDU QFI: %u to Default DRB: %ld\n", dl_qfi, drb_of_endmarker); } if(map_type == SDAP_CTRL_PDU_MAP_RULE_DRB){ - drb_of_endmarker = entity->qfi2drb_map(entity, dl_qfi, pdcp_entity); + drb_of_endmarker = entity->qfi2drb_map(entity, dl_qfi); LOG_D(SDAP, "Mapping Control PDU QFI: %u to DRB: %ld\n", dl_qfi, drb_of_endmarker); } return drb_of_endmarker; } +/** + * @brief Submit the end-marker control PDU to PDCP according to TS 37.324, clause 5.3 + */ void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu) { if(sdap_ctrl_pdu_drb){ @@ -382,28 +421,55 @@ void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_u } } -void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, rb_id_t pdcp_entity, ue_id_t ue_id, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount, uint8_t drb_identity, bool has_sdap_rx, bool has_sdap_tx) +/** + * @brief UL QoS flow to DRB mapping configuration for an existing SDAP entity + * according to TS 37.324, 5.3 QoS flow to DRB Mapping, clause 5.3.1 Configuration Procedures + */ +static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, + rb_id_t pdcp_entity, + ue_id_t ue_id, + NR_QFI_t *mapped_qfi_2_add, + uint8_t mappedQFIs2AddCount, + uint8_t drb_identity, + bool has_sdap_rx, + bool has_sdap_tx) { LOG_D(SDAP, "RRC Configuring SDAP Entity\n"); - uint8_t qfi = 0; - for(int i = 0; i < mappedQFIs2AddCount; i++){ - qfi = mapped_qfi_2_add[i]; + uint8_t qfi = mapped_qfi_2_add[i]; + /* a default DRB exists and there is no QFI to DRB mapping rule for the QFI */ if (existing_sdap_entity->default_drb && existing_sdap_entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE) { nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi); - rb_id_t sdap_ctrl_pdu_drb = existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi); + rb_id_t sdap_ctrl_pdu_drb = + existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi); existing_sdap_entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); } + /* the stored UL QFI to DRB mapping rule is different from the configured one and has UL SDAP header*/ if (existing_sdap_entity->qfi2drb_table[qfi].drb_id != drb_identity && existing_sdap_entity->qfi2drb_table[qfi].has_sdap_tx) { nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi); - rb_id_t sdap_ctrl_pdu_drb = existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi); + rb_id_t sdap_ctrl_pdu_drb = + existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi); existing_sdap_entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); } + /* update QFI to DRB mapping rules */ LOG_D(SDAP, "Storing the configured QoS flow to DRB mapping rule\n"); existing_sdap_entity->qfi2drb_map_update(existing_sdap_entity, qfi, drb_identity, has_sdap_rx, has_sdap_tx); } } +/** + * @brief add a new SDAP entity according to 5.1.1. of 3GPP TS 37.324 + * @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(int is_gnb, bool has_sdap_rx, bool has_sdap_tx, @@ -414,12 +480,21 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount) { + /* check whether the SDAP entity already exists and + update QFI to DRB mapping rules in that case */ if (nr_sdap_get_entity(ue_id, pdusession_id)) { LOG_E(SDAP, "SDAP Entity for UE already exists with RNTI/UE ID: %lu and PDU SESSION ID: %d\n", ue_id, pdusession_id); nr_sdap_entity_t *existing_sdap_entity = nr_sdap_get_entity(ue_id, pdusession_id); rb_id_t pdcp_entity = existing_sdap_entity->default_drb; if(!is_gnb) - nr_sdap_ue_qfi2drb_config(existing_sdap_entity, pdcp_entity, ue_id, mapped_qfi_2_add, mappedQFIs2AddCount, drb_identity, has_sdap_rx, has_sdap_tx); + nr_sdap_ue_qfi2drb_config(existing_sdap_entity, + pdcp_entity, + ue_id, + mapped_qfi_2_add, + mappedQFIs2AddCount, + drb_identity, + has_sdap_rx, + has_sdap_tx); return existing_sdap_entity; } @@ -458,6 +533,11 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, return sdap_entity; } +/** + * @brief Fetches the SDAP entity for the give PDU session ID. + * @note There is one SDAP entity per PDU session. + * @return The pointer to the SDAP entity if existing, NULL otherwise + */ nr_sdap_entity_t *nr_sdap_get_entity(ue_id_t ue_id, int pdusession_id) { nr_sdap_entity_t *sdap_entity; @@ -487,8 +567,7 @@ void nr_sdap_release_drb(ue_id_t ue_id, int drb_id, int pdusession_id) } } else - LOG_E(SDAP, "Couldn't find a SDAP entity associated with PDU session ID %d\n", - pdusession_id); + LOG_E(SDAP, "Couldn't find a SDAP entity associated with PDU session ID %d\n", pdusession_id); } bool nr_sdap_delete_entity(ue_id_t ue_id, int pdusession_id) @@ -562,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 0b4ae82bcb..3768d60f6a 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -84,7 +84,7 @@ typedef struct nr_sdap_entity_s { void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx); void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi); - rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t upper_layer_rb_id); + rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi); nr_sdap_ul_hdr_t (*sdap_construct_ctrl_pdu)(uint8_t qfi); rb_id_t (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi); @@ -132,7 +132,7 @@ void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi); * If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3, map the SDAP SDU to the default DRB * else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule. */ -rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t upper_layer_rb_id); +rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi); /* * TS 37.324 5.3 QoS flow to DRB Mapping @@ -154,17 +154,19 @@ rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int */ void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); -/* - * TS 37.324 5.3 QoS flow to DRB Mapping - * 5.3.1 Configuration Procedures - */ -void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, rb_id_t pdcp_entity, ue_id_t ue_id, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount, uint8_t drb_identity, bool has_sdap_rx, bool has_sdap_tx); - /* * TS 37.324 4.4 5.1.1 SDAP entity establishment * Establish an SDAP entity. */ -nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, bool has_sdap_rx, bool has_sdap_tx, ue_id_t ue_id, int pdusession_id, bool is_defaultDRB, uint8_t default_DRB, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount); +nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, + bool has_sdap_rx, + bool has_sdap_tx, + ue_id_t ue_id, + int pdusession_id, + bool is_defaultDRB, + uint8_t default_DRB, + NR_QFI_t *mapped_qfi_2_add, + uint8_t mappedQFIs2AddCount); /* Entity Handling Related Functions */ nr_sdap_entity_t *nr_sdap_get_entity(ue_id_t ue_id, int pdusession_id); @@ -188,4 +190,25 @@ bool nr_sdap_delete_entity(ue_id_t ue_id, int pdusession_id); * @return True, it deleted at least one entity, false otherwise. */ bool nr_sdap_delete_ue_entities(ue_id_t ue_id); + +/** + * @brief indicates whether it is a receiving SDAP entity + * i.e. for UE, header for DL data is present + * for gNB, header for UL data is present + */ +bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config); + +/** + * @brief indicates whether it is a transmitting SDAP entity + * i.e. for UE, header for UL data is present + * for gNB, header for DL data is present + */ +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