From f81ec9c2cc13cf8a8cc5a1fde99265bcad96fe7a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 Jan 2024 18:05:18 +0100 Subject: [PATCH] Simplify RRC DRB handling code Prior to this commit, the handling of DRBs is complex: first the RRC "guessed" a DRB ID when setting up DRBs via E1AP (in rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ()), and later chose one for real in fill_DRB_Configlist() (called in rrc_gNB_generate_dedicatedRRCReconfiguration()). To simplify, remove fill_DRB_Configlist(), and instead allocate the DRB using generateDRB() before sending the message via E1AP, in rrc_gNB_generate_dedicatedRRCReconfiguration(). The rest of the logic is the same. For PDU sessions, always mark PDU sessions as "done" to match pdu session state logic. --- openair2/RRC/NR/rrc_gNB.c | 125 +++++----------------- openair2/RRC/NR/rrc_gNB_NGAP.c | 33 ++++-- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 133 ++++++++++++------------ openair2/RRC/NR/rrc_gNB_radio_bearers.h | 28 +++-- 4 files changed, 136 insertions(+), 183 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index e3cd14efe8..377e15bbab 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -121,73 +121,6 @@ mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) -{ - gNB_RRC_INST *rrc = RC.nrrrc[0]; - if (ue->nb_of_pdusessions == 0) - return NULL; - int nb_drb_to_setup = rrc->configuration.drbs; - long drb_priority[MAX_DRBS_PER_UE] = {0}; - uint8_t drb_id_to_setup_start = 0; - NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); - for (int i = 0; i < ue->nb_of_pdusessions; i++) { - if (ue->pduSession[i].status >= PDU_SESSION_STATUS_DONE) { - continue; - } - LOG_I(NR_RRC, "adding rnti %x pdusession %d, nb drb %d\n", ue->rnti, ue->pduSession[i].param.pdusession_id, nb_drb_to_setup); - for (long drb_id_add = 1; drb_id_add <= nb_drb_to_setup; drb_id_add++) { - uint8_t drb_id; - // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping - for (int qos_flow_index = 0; qos_flow_index < ue->pduSession[i].param.nb_qos; qos_flow_index++) { - switch (ue->pduSession[i].param.qos[qos_flow_index].fiveQI) { - case 1 ... 4: /* GBR */ - drb_id = next_available_drb(ue, &ue->pduSession[i], GBR_FLOW); - break; - case 5 ... 9: /* Non-GBR */ - if (rrc->configuration.drbs > 1) { /* Force the creation from gNB Conf file */ - LOG_W(NR_RRC, "Adding %d DRBs, from gNB config file (not decided by 5GC\n", rrc->configuration.drbs); - drb_id = next_available_drb(ue, &ue->pduSession[i], GBR_FLOW); - } else { - drb_id = next_available_drb(ue, &ue->pduSession[i], NONGBR_FLOW); - } - break; - - default: - LOG_E(NR_RRC, "not supported 5qi %lu\n", ue->pduSession[i].param.qos[qos_flow_index].fiveQI); - ue->pduSession[i].status = PDU_SESSION_STATUS_FAILED; - continue; - } - drb_priority[drb_id - 1] = ue->pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level; - if (drb_priority[drb_id - 1] < 0 || drb_priority[drb_id - 1] > NGAP_PRIORITY_LEVEL_NO_PRIORITY) { - LOG_E(NR_RRC, "invalid allocation_retention_priority.priority_level %ld set to _NO_PRIORITY\n", drb_priority[drb_id - 1]); - drb_priority[drb_id - 1] = NGAP_PRIORITY_LEVEL_NO_PRIORITY; - } - - if (drb_is_active(ue, drb_id)) { /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/ - nb_drb_to_setup--; - } else { - generateDRB(ue, - drb_id, - &ue->pduSession[i], - rrc->configuration.enable_sdap, - rrc->security.do_drb_integrity, - rrc->security.do_drb_ciphering); - NR_DRB_ToAddMod_t *DRB_config = generateDRB_ASN1(&ue->established_drbs[drb_id - 1]); - if (drb_id_to_setup_start == 0) - drb_id_to_setup_start = DRB_config->drb_Identity; - asn1cSeqAdd(&DRB_configList->list, DRB_config); - } - LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now - } - } - } - if (DRB_configList->list.count == 0) { - free(DRB_configList); - return NULL; - } - return DRB_configList; -} - static void freeDRBlist(NR_DRB_ToAddModList_t *list) { //ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list); @@ -579,10 +512,12 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg); OCTET_STRING_fromBuf(msg, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length); - } - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; - LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + } + if (ue_p->pduSession[i].status < PDU_SESSION_STATUS_ESTABLISHED) { + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + } } if (ue_p->nas_pdu.length) { @@ -659,34 +594,29 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); ue_p->xids[xid] = RRC_PDUSESSION_ESTABLISH; - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; - dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); - int nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : 0; - for (int i=0; i < nb_drb_to_setup; i++) { - int j = ue_p->nb_of_pdusessions - 1; - AssertFatal(j >= 0, ""); - if (ue_p->pduSession[j].param.nas_pdu.buffer != NULL) { - dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedNAS_Message, - (char *)ue_p->pduSession[j].param.nas_pdu.buffer, - ue_p->pduSession[j].param.nas_pdu.length); - ue_p->pduSession[j].status = PDU_SESSION_STATUS_DONE; - asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { + asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg); + OCTET_STRING_fromBuf(msg, + (char *)ue_p->pduSession[i].param.nas_pdu.buffer, + ue_p->pduSession[i].param.nas_pdu.length); + asn1cSeqAdd(&dedicatedNAS_MessageList->list, msg); - LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[j].param.nas_pdu.length, j); - } else { - // TODO - LOG_E(NR_RRC, "no NAS info (pdusession idx %d)\n", j); + LOG_D(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[i].param.nas_pdu.length, i); + ue_p->pduSession[i].xid = xid; + } + if (ue_p->pduSession[i].status < PDU_SESSION_STATUS_ESTABLISHED) { + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; } - - ue_p->pduSession[j].xid = xid; } - freeDRBlist(DRB_configList); + + if (ue_p->nas_pdu.length) { + asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg); + OCTET_STRING_fromBuf(msg, (char *)ue_p->nas_pdu.buffer, ue_p->nas_pdu.length); + } /* If list is empty free the list and reset the address */ if (dedicatedNAS_MessageList->list.count == 0) { @@ -748,7 +678,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( //----------------------------------------------------------------------------- { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); int qos_flow_index = 0; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_p->xids[xid] = RRC_PDUSESSION_MODIFY; @@ -819,8 +748,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); } - asn1cSeqAdd(&DRB_configList->list, DRB_config); - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; ue_p->pduSession[i].xid = xid; @@ -839,19 +766,21 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( dedicatedNAS_MessageList = NULL; } + NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false); uint8_t buffer[RRC_BUF_SIZE]; int size = do_RRCReconfiguration(ue_p, buffer, RRC_BUF_SIZE, xid, NULL, - DRB_configList, + DRBs, NULL, NULL, NULL, dedicatedNAS_MessageList, NULL); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); + freeDRBlist(DRBs); /* Free all NAS PDUs */ for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { @@ -2442,7 +2371,7 @@ rrc_gNB_generate_SecurityModeCommand( NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm; size = do_NR_SecurityModeCommand(ctxt_pP, buffer, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_p->ciphering_algorithm, integrity_algorithm); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); - LOG_I(NR_RRC, "UE %04x Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rnti, size); + LOG_I(NR_RRC, "UE %u Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rrc_ue_id, size); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 8bc76c570c..bc653a805c 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -795,24 +795,35 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed; pdu->teId = session->gtp_teid; memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target + + /* we assume for the moment one DRB per PDU session. Activate the bearer, + * and configure in RRC. */ + int drb_id = get_next_available_drb_id(UE); + drb_t *rrc_drb = generateDRB(UE, + drb_id, + pduSession, + rrc->configuration.enable_sdap, + rrc->security.do_drb_integrity, + rrc->security.do_drb_ciphering); + pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding for (int j=0; j < pdu->numDRB2Setup; j++) { DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j; - drb->id = i + j + UE->nb_of_pdusessions; + drb->id = rrc_drb->drb_id; - drb->defaultDRB = true; + struct sdap_config_s *sdap_config = &rrc_drb->cnAssociation.sdap_config; + drb->defaultDRB = sdap_config->defaultDRB ? E1AP_DefaultDRB_true : E1AP_DefaultDRB_false; + drb->sDAP_Header_UL = sdap_config->sdap_HeaderUL; + drb->sDAP_Header_DL = sdap_config->sdap_HeaderDL; - drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap); - drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap); + 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->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18; - drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18; - - drb->discardTimer = E1AP_DiscardTimer_infinity; - drb->reorderingTimer = E1AP_T_Reordering_ms100; - - drb->rLC_Mode = E1AP_RLC_Mode_rlc_am; + drb->rLC_Mode = rrc->configuration.um_on_default_drb ? E1AP_RLC_Mode_rlc_um_bidirectional : E1AP_RLC_Mode_rlc_am; drb->numCellGroups = 1; // assume one cell group associated with a DRB diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index efff9f2d8a..9c8f26e3a5 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -37,62 +37,71 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create) return ue->pduSession + j; } -void generateDRB(gNB_RRC_UE_t *ue, - uint8_t drb_id, - rrc_pdu_session_param_t *pduSession, - bool enable_sdap, - int do_drb_integrity, - int do_drb_ciphering) +drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id) { - int i; - int qos_flow_index; + DevAssert(drb_id > 0 && drb_id < 32); + DevAssert(ue != NULL); + + return &ue->established_drbs[drb_id - 1]; +} + +drb_t *generateDRB(gNB_RRC_UE_t *ue, + uint8_t drb_id, + const rrc_pdu_session_param_t *pduSession, + bool enable_sdap, + int do_drb_integrity, + int do_drb_ciphering) +{ + DevAssert(ue != NULL); + + LOG_I(NR_RRC, "UE %d: configure DRB ID %d for PDU session ID %d\n", ue->rrc_ue_id, drb_id, pduSession->param.pdusession_id); + drb_t *est_drb = &ue->established_drbs[drb_id - 1]; - if (est_drb->status == DRB_INACTIVE) { - /* DRB Management */ - est_drb->drb_id = drb_id; - est_drb->reestablishPDCP = -1; - est_drb->recoverPDCP = -1; - for (i = 0; i < MAX_DRBS_PER_UE; i++) { - if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0 - || est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id) - && est_drb->defaultDRBid == 0) { - est_drb->cnAssociation.sdap_config.defaultDRB = true; - est_drb->defaultDRBid = drb_id; - } - } - /* SDAP Configuration */ - est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; - est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id; - if (enable_sdap) { - est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; - est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; - } else { - est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; - est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; - } - for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) { - est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi; - if (pduSession->param.qos[qos_flow_index].fiveQI > 5) - est_drb->status = DRB_ACTIVE_NONGBR; - else - 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; + DevAssert(est_drb->status == DRB_INACTIVE); + + est_drb->status = DRB_ACTIVE; + est_drb->drb_id = drb_id; + est_drb->reestablishPDCP = -1; + est_drb->recoverPDCP = -1; + est_drb->cnAssociation.sdap_config.defaultDRB = true; + est_drb->defaultDRBid = drb_id; + + /* SDAP Configuration */ + est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id; + if (enable_sdap) { + est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; + est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; + } else { + est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; + est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; } + for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) { + est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi; + if (pduSession->param.qos[qos_flow_index].fiveQI > 5) + est_drb->status = DRB_ACTIVE_NONGBR; + else + 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; + + 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 */ + return rrc_drb; } NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1) @@ -143,17 +152,9 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1) return DRB_config; } -uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr) +uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue) { - uint8_t drb_id; - - if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */ - for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) - if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR) - return drb_id + 1; - } - /* GBR Flow or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */ - for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) + for (uint8_t drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) if (ue->established_drbs[drb_id].status == DRB_INACTIVE) return drb_id + 1; /* From this point, we need to handle the case that all DRBs are already used by the UE. */ @@ -163,6 +164,8 @@ uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id) { - DevAssert(drb_id > 0); - return ue->established_drbs[drb_id - 1].status == DRB_ACTIVE; + drb_t *drb = get_drb(ue, drb_id); + if (drb == NULL) + return DRB_INACTIVE; + return drb->status != DRB_INACTIVE; } diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index aff6e75ea6..ff348139de 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -39,23 +39,33 @@ /// @param drb_t drb_asn1 /// @return Returns the ASN1 DRB-ToAddMod structs. NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1); -/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity, -/// to create the actual entity use the generateDRB_ASN1. + +/// @brief retrieve the data structure representing DRB with ID drb_id of UE ue +drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id); + +/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct /// @param ue The gNB_RRC_UE_t struct that holds information for the UEs /// @param drb_id The Data Radio Bearer Identity to be created for the established DRB. /// @param pduSession The PDU Session that the DRB is created for. /// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header. /// @param do_drb_integrity /// @param do_drb_ciphering -void generateDRB(gNB_RRC_UE_t *ue, - uint8_t drb_id, - rrc_pdu_session_param_t *pduSession, - bool enable_sdap, - int do_drb_integrity, - int do_drb_ciphering); -uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr); +/// @return returns a pointer to the generated DRB structure +drb_t *generateDRB(gNB_RRC_UE_t *ue, + uint8_t drb_id, + const rrc_pdu_session_param_t *pduSession, + bool enable_sdap, + int do_drb_integrity, + int do_drb_ciphering); + +/// @brief return the next available (inactive) DRB ID of UE ue +uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue); + +/// @brief check if DRB with ID drb_id of UE ue is active bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id); +/// @brief retrieve PDU session of UE ue with ID id, optionally creating it if +/// create is true rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create); #endif