diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index b1b60a9816..b9bb149310 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2750,6 +2750,14 @@ static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *)UE->CellGroup); + + /* remove the rlc_BearerToReleaseList, we don't need it anymore */ + if (UE->CellGroup->rlc_BearerToReleaseList != NULL) { + struct NR_CellGroupConfig__rlc_BearerToReleaseList *l = UE->CellGroup->rlc_BearerToReleaseList; + asn_sequence_del(&l->list, l->list.count, /* free */1); + free(UE->CellGroup->rlc_BearerToReleaseList); + UE->CellGroup->rlc_BearerToReleaseList = NULL; + } } NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 42803b0ff1..e18c9ea5b7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -138,6 +138,42 @@ static int handle_ue_context_drbs_setup(int rnti, return drbs_len; } +static int handle_ue_context_drbs_release(int rnti, + int drbs_len, + const f1ap_drb_to_be_released_t *req_drbs, + NR_CellGroupConfig_t *cellGroupConfig) +{ + DevAssert(req_drbs != NULL && cellGroupConfig != NULL); + + cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList)); + AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n"); + + /* Note: the actual GTP tunnels are already removed in the F1AP message + * decoding */ + for (int i = 0; i < drbs_len; i++) { + const f1ap_drb_to_be_released_t *drb = &req_drbs[i]; + + long lcid = drb->rb_id + 3; /* LCID is DRB + 3 */ + int idx = 0; + while (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { + const NR_RLC_BearerConfig_t *bc = cellGroupConfig->rlc_BearerToAddModList->list.array[idx]; + if (bc->logicalChannelIdentity == lcid) + break; + ++idx; + } + if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { + nr_rlc_release_entity(rnti, lcid); + asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1); + long *plcid = malloc(sizeof(*plcid)); + AssertFatal(plcid != NULL, "out of memory\n"); + *plcid = lcid; + int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToReleaseList->list, plcid); + DevAssert(ret == 0); + } + } + return drbs_len; +} + static NR_UE_NR_Capability_t *get_ue_nr_cap(int rnti, uint8_t *buf, uint32_t len) { if (buf == NULL || len == 0) @@ -311,6 +347,11 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) new_CellGroup); } + if (req->drbs_to_be_released_length > 0) { + resp.drbs_to_be_released_length = + handle_ue_context_drbs_release(req->gNB_DU_ue_id, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup); + } + if (req->rrc_container != NULL) nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); @@ -328,7 +369,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc); } - if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0 || ue_cap != NULL) { + if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0 || req->drbs_to_be_released_length > 0) { resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n"); resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024);