From ed7b675330a330e7de43eadfe4409441fb7cf9dd Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Mon, 26 Jun 2023 15:46:11 +0200 Subject: [PATCH 1/4] remove redundant copies of pdu sessions list --- executables/nr-cuup.c | 3 +- openair2/E1AP/e1ap_api.c | 3 +- openair2/RRC/NR/cucp_cuup_direct.c | 12 +- openair2/RRC/NR/cucp_cuup_e1ap.c | 9 +- openair2/RRC/NR/cucp_cuup_if.h | 2 +- openair2/RRC/NR/nr_rrc_defs.h | 3 - openair2/RRC/NR/nr_rrc_proto.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 304 ++++++++++++----------------- openair2/RRC/NR/rrc_gNB_NGAP.c | 5 +- 9 files changed, 138 insertions(+), 205 deletions(-) diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 6fcf5b7ea3..ffa50a766b 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -111,9 +111,10 @@ f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP) return NULL; } -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid) +NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) { abort(); + return NULL; } int main(int argc, char **argv) diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index 15f05fb3ed..cf167f64e8 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -114,7 +114,8 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, // Create N3 tunnel int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); if (ret != 0) { - LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE id %ld\n", + LOG_E(NR_RRC, + "drb_config_N3gtpu_create=>gtpv1u_create_ngu_tunnel failed, cannot set up GTP tunnel for data transmissions of UE %ld\n", create_tunnel_req.ue_id); return ret; } diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 347e9fbff5..49f95c82f7 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -125,7 +125,8 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, sdap_data_req); if (ret != 0) { - LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n", + LOG_E(NR_RRC, + "drb_config_gtpu_create=>gtpv1u_create_ngu_tunnel failed, cannot set up GTP tunnel for data transmissions of UE %ld\n", create_tunnel_req.ue_id); return ret; } @@ -160,14 +161,13 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, return ret; } -static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - fill_DRB_configList(&ctxt, ue_context_p, xid); e1ap_bearer_setup_resp_t resp = {0}; resp.numPDUSessions = req->numPDUSessions; for (int i = 0; i < resp.numPDUSessions; ++i) { @@ -184,7 +184,8 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; // GTP tunnel for UL - int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, rrc->e1_inst); + NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(UE); + int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, DRB_configList, rrc->e1_inst); if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); // Used to store teids: if monolithic, will simply be NULL @@ -203,7 +204,8 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } -static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) { +static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) +{ // only update GTP tunnels if it is really a CU if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) return; diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 390ab232a7..200729ec11 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -36,13 +36,8 @@ extern RAN_CONTEXT_t RC; -static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - - fill_DRB_configList(&ctxt, ue_context_p, xid); MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); @@ -50,7 +45,7 @@ static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const r itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); } -static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index ed4702b4b2..079a32e850 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -27,7 +27,7 @@ struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; -typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance, uint8_t xid); +typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 390347362d..e72624527c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -237,9 +237,6 @@ typedef enum { typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; - NR_DRB_ToAddModList_t *DRB_configList; - NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; drb_t established_drbs[NGAP_MAX_DRBS_PER_UE]; uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE]; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 504aced681..fd9f38a3fb 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -156,7 +156,7 @@ void ue_cxt_mod_send_e1ap(MessageDef *msg, void ue_cxt_mod_direct(MessageDef *msg, instance_t instance); -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid); +NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue); void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index fbaf2364c2..0113792030 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -113,7 +113,77 @@ 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[NGAP_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) +{ + return; +} static void nr_rrc_addmod_srbs(int rnti, const NR_SRB_INFO_TABLE_ENTRY *srb_list, const int nb_srb, @@ -338,7 +408,9 @@ static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const u gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; nr_rrc_mac_update_cellgroup(ue_p->rnti, cgc); nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, cgc->rlc_BearerToAddModList); - nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, ue_p->DRB_configList, cgc->rlc_BearerToAddModList); + NR_DRB_ToAddModList_t *DRBs = fill_DRB_configList(ue_p); + nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, DRBs, cgc->rlc_BearerToAddModList); + freeDRBlist(DRBs); } void apply_macrlc_config_reest(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP, ue_id_t ue_id) @@ -591,83 +663,18 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co } } -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid) -{ - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - int qos_flow_index = 0; - int i; - uint8_t drb_id_to_setup_start = 0; - uint8_t nb_drb_to_setup = rrc->configuration.drbs; - long drb_priority[NGAP_MAX_DRBS_PER_UE]; - - if (!ue_p->DRB_configList) - ue_p->DRB_configList = CALLOC(1, sizeof(*ue_p->DRB_configList)); - if (!ue_p->DRB_configList2[xid]) - ue_p->DRB_configList2[xid] = CALLOC(1, sizeof(**ue_p->DRB_configList2)); - - for (i = 0; i < ue_p->nb_of_pdusessions; i++) { - if (ue_p->pduSession[i].status >= PDU_SESSION_STATUS_DONE) { - continue; - } - LOG_I(NR_RRC, "adding rnti %x pdusession %d, nb drb %d, xid %d\n", ue_p->rnti, ue_p->pduSession[i].param.pdusession_id, nb_drb_to_setup, xid); - 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 (qos_flow_index = 0; qos_flow_index < ue_p->pduSession[i].param.nb_qos; qos_flow_index++) { - switch (ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI) { - case 1 ... 4: /* GBR */ - drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], GBR_FLOW); - break; - case 5 ... 9: /* Non-GBR */ - if(rrc->configuration.drbs > 1) /* Force the creation from gNB Conf file - Should be used only in noS1 mode and rfsim for testing purposes. */ - drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], GBR_FLOW); - else - drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], NONGBR_FLOW); - break; - - default: - LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); - ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; - continue; - } - drb_priority[drb_id - 1] = ue_p->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_p, drb_id)){ /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/ - nb_drb_to_setup--; - } else { - generateDRB(ue_p, drb_id, &ue_p->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_p->established_drbs[drb_id-1]); - if (drb_id_to_setup_start == 0) - drb_id_to_setup_start = DRB_config->drb_Identity; - asn1cSeqAdd(&ue_p->DRB_configList->list, DRB_config); - asn1cSeqAdd(&ue_p->DRB_configList2[xid]->list, DRB_config); - } - LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now - } - } - - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->pduSession[i].xid = xid; - } -} - //----------------------------------------------------------------------------- void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - int xid = -1; + uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); int drb_id_to_setup_start = 1; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList; - int nb_drb_to_setup = DRB_configList->list.count; - + NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); + int nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : 0; + 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)); @@ -681,7 +688,10 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c 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); + 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); LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[j].param.nas_pdu.length, j); @@ -690,7 +700,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c LOG_E(NR_RRC, "no NAS info (pdusession idx %d)\n", j); } - xid = ue_p->pduSession[j].xid; + ue_p->pduSession[j].xid = xid; } /* If list is empty free the list and reset the address */ @@ -701,7 +711,6 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c NR_CellGroupConfig_t *cellGroupConfig = ue_p->masterCellGroup; - AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid); uint8_t buffer[RRC_BUF_SIZE] = {0}; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); int size = do_RRCReconfiguration(ctxt_pP, @@ -730,7 +739,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c ue_p->pduSession[i].param.nas_pdu.buffer = NULL; } } - + freeDRBlist(DRB_configList); LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", @@ -763,19 +772,15 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t *DRB_configList2 = NULL; - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList - *dedicatedNAS_MessageList = NULL; + 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); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - ue_p->xids[xid] = RRC_DEDICATED_RECONF; + ue_p->xids[xid] = RRC_PDUSESSION_MODIFY; - DRB_configList2 = CALLOC(1, sizeof(NR_DRB_ToAddModList_t)); - memset(DRB_configList2, 0, sizeof(NR_DRB_ToAddModList_t)); - - 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)); + NR_DRB_ToAddMod_t *DRB_config = NULL; for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { // bypass the new and already configured pdu sessions @@ -830,7 +835,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value; continue; } - LOG_I(NR_RRC, "PDU SESSION ID %ld, DRB ID %ld (index %d), QOS flow %d, 5QI %ld \n", DRB_config->cnAssociation->choice.sdap_Config->pdu_Session, @@ -840,7 +844,7 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); } - asn1cSeqAdd(&DRB_configList2->list, DRB_config); + asn1cSeqAdd(&DRB_configList->list, DRB_config); ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; ue_p->pduSession[i].xid = xid; @@ -862,21 +866,21 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( uint8_t buffer[RRC_BUF_SIZE]; int size = do_RRCReconfiguration(ctxt_pP, - buffer, - RRC_BUF_SIZE, - xid, - NULL, - DRB_configList2, - NULL, - NULL, - NULL, - NULL, - dedicatedNAS_MessageList, - NULL, - NULL, - NULL, - NULL, - NULL); + buffer, + RRC_BUF_SIZE, + xid, + NULL, + DRB_configList, + NULL, + NULL, + NULL, + NULL, + dedicatedNAS_MessageList, + NULL, + NULL, + NULL, + NULL, + NULL); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ @@ -922,37 +926,23 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( uint8_t *nas_buffer) //----------------------------------------------------------------------------- { - int i; - NR_DRB_ToReleaseList_t **DRB_Release_configList2 = NULL; - NR_DRB_Identity_t *DRB_release; - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList - *dedicatedNAS_MessageList = NULL; - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - DRB_Release_configList2 = &ue_p->DRB_Release_configList2[xid]; - if (*DRB_Release_configList2) { - free(*DRB_Release_configList2); - } + NR_DRB_ToReleaseList_t *DRB_Release_configList2 = CALLOC(sizeof(*DRB_Release_configList2), 1); - *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2)); - for(i = 0; i < NB_RB_MAX; i++) { + for (int i = 0; i < NB_RB_MAX; i++) { if ((ue_p->pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_p->pduSession[i].xid == xid) { - DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t)); - *DRB_release = i+1; - asn1cSeqAdd(&(*DRB_Release_configList2)->list, DRB_release); + asn1cSequenceAdd(DRB_Release_configList2->list, NR_DRB_Identity_t, DRB_release); + *DRB_release = i + 1; } } /* If list is empty free the list and reset the address */ + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; if (nas_length > 0) { - dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); - dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedNAS_Message, - (char *)nas_buffer, - nas_length); - asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); + asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, dedicatedNAS_Message); + OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)nas_buffer, nas_length); LOG_I(NR_RRC,"add NAS info with size %d\n", nas_length); } else { LOG_W(NR_RRC,"dedlicated NAS list is empty\n"); @@ -965,7 +955,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( xid, NULL, NULL, - *DRB_Release_configList2, + DRB_Release_configList2, NULL, NULL, NULL, @@ -1019,10 +1009,7 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co uint8_t kUPenc[16] = {0}; uint8_t kUPint[16] = {0}; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList2[xid]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_p->DRB_Release_configList2[xid]; - NR_DRB_Identity_t *drb_id_p = NULL; - // uint8_t nr_DRB2LCHAN[8]; + NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); /* Derive the keys from kgnb */ if (DRB_configList != NULL) { @@ -1127,25 +1114,8 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co } // end if (DRB_configList->list.array[i]) } // end for (int i = 0; i < DRB_configList->list.count; i++) - free(DRB_configList); - ue_p->DRB_configList2[xid] = NULL; } // end if DRB_configList != NULL - - if(DRB_Release_configList2 != NULL) { - for (int i = 0; i < DRB_Release_configList2->list.count; i++) { - if (DRB_Release_configList2->list.array[i]) { - drb_id_p = DRB_Release_configList2->list.array[i]; - drb_id = *drb_id_p; - - if (ue_p->DRB_active[drb_id] == 1) { - ue_p->DRB_active[drb_id] = 0; - } - } - } - - free(DRB_Release_configList2); - ue_p->DRB_Release_configList2[xid] = NULL; - } + freeDRBlist(DRB_configList); } //----------------------------------------------------------------------------- @@ -1219,35 +1189,6 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); } -/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the DRBs -/// that the UE previously had, it gets the information from the established_drbs -/// struct. -/// @param new_xid The new RRC transaction id. -void RRCReestablishmentComplete_fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t new_xid) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t **DRB_configList2 = &(ue_p->DRB_configList2[new_xid]); - - if (*DRB_configList2) { - free(*DRB_configList2); - LOG_D(NR_RRC, "RRC Reestablishment - free(ue_p->DRB_configList2[%d])\n", new_xid); - } - - *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); - - for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { - if (ue_p->established_drbs[i].status != DRB_INACTIVE) { - ue_p->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true; - DRB_config = generateDRB_ASN1(&ue_p->established_drbs[i]); - asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); - asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config); - } - } -} - /// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels. /// @param reestablish_rnti is the old C-RNTI void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP, @@ -1349,7 +1290,6 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command); LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n"); } - RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); @@ -1377,11 +1317,11 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx asn1cSeqAdd(&cellGroupConfig->rlc_BearerToAddModList->list, ue_p->masterCellGroup->rlc_BearerToAddModList->list.array[i]); for (i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { - cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = - CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC)); - *cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = NR_RLC_BearerConfig__reestablishRLC_true; + asn1cCallocOne(cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC, + NR_RLC_BearerConfig__reestablishRLC_true); } + NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); uint8_t buffer[RRC_BUF_SIZE] = {0}; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); int size = do_RRCReconfiguration(ctxt_pP, @@ -1389,7 +1329,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx RRC_BUF_SIZE, new_xid, SRBs, - ue_p->DRB_configList2[new_xid], + DRB_configList, NULL, NULL, NULL, @@ -1401,7 +1341,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx NULL, cellGroupConfig); freeSRBlist(SRBs); - + freeDRBlist(DRB_configList); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); @@ -2364,7 +2304,7 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i // send the F1 response message up to update F1-U tunnel info // it seems the rrc transaction id (xid) is not needed here - rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); + rrc->cucp_cuup.bearer_context_mod(&req, instance); } if (resp->du_to_cu_rrc_information != NULL && resp->du_to_cu_rrc_information->cellGroupConfig != NULL) { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index cb763f0583..f0a7f3b90f 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -278,9 +278,6 @@ static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session) static int decodePDUSessionResourceSetup(pdusession_t *session) { NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer = NULL; - for (int i=0; ipdusessionTransfer.length; i++) - printf("%02x:",session->pdusessionTransfer.buffer[i]); - printf("\n"); asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; asn_dec_rval_t dec_rval = aper_decode(&st, &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, (void **)&pdusessionTransfer, session->pdusessionTransfer.buffer, session->pdusessionTransfer.length, 0, 0); @@ -819,7 +816,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins } int xid = rrc_gNB_get_next_transaction_identifier(instance); UE->xids[xid] = RRC_PDUSESSION_ESTABLISH; - rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance, xid); + rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance); return; } From 7e7b3c13f1ab1ae664982b6f8a16ddbe9ac5b2e3 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 6 Jul 2023 09:01:04 +0100 Subject: [PATCH 2/4] Fix multiple PDUSessions --- openair2/E1AP/e1ap.c | 9 ++- openair2/RRC/NR/rrc_gNB.c | 80 ++++++++++++++++--------- openair2/RRC/NR/rrc_gNB_NGAP.c | 8 ++- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 10 ++++ 4 files changed, 77 insertions(+), 30 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 6c33ddf973..7a1954f714 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -589,7 +589,14 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_beare for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRB2Setup; j++) { asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1); - ieC6_1_1->dRB_ID = j->id; + + ieC6_1_1->dRB_ID = ieC6_1->pDU_Session_ID; + LOG_W(E1AP, + "%s: %d Current implementation configures one DRB per PDUSession, ieC6_1->pDU_Session_ID %ld, ieC6_1_1->dRB_ID %ld\n", + __FUNCTION__, + __LINE__, + ieC6_1->pDU_Session_ID, + ieC6_1_1->dRB_ID); ieC6_1_1->sDAP_Configuration.defaultDRB = j->defaultDRB; ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sDAP_Header_UL; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 0113792030..a23c260612 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -113,6 +113,44 @@ mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// + +static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) +{ + if (!ue->Srb[1].Active) { + LOG_E(NR_RRC, "Call SRB list while SRB1 doesn't exist\n"); + return NULL; + } + NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1); + for (int i = 0; i < maxSRBs; i++) { + if (ue->Srb[i].Active) { + asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb); + srb->srb_Identity = i; + if (reestablish && i == 2) { + asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true); + } + } + } + return list; +} + +static NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish) +{ + NR_DRB_ToAddMod_t *DRB_config = NULL; + NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); + + for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { + if (ue->established_drbs[i].status != DRB_INACTIVE) { + ue->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true; + DRB_config = generateDRB_ASN1(&ue->established_drbs[i]); + if (reestablish) { + asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); + } + asn1cSeqAdd(&DRB_configList->list, DRB_config); + } + } + return DRB_configList; +} + NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -374,24 +412,6 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP) return tmp; } -static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) -{ - if (!ue->Srb[1].Active) { - LOG_E(NR_RRC, "Call SRB list while SRB1 doesn't exist\n"); - return NULL; - } - NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1); - for (int i = 0; i < maxSRBs; i++) - if (ue->Srb[i].Active) { - asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb); - srb->srb_Identity = i; - if (reestablish && i == 2) { - asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true); - } - } - return list; -} - static void freeSRBlist(NR_SRB_ToAddModList_t *l) { if (l) { @@ -702,6 +722,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c ue_p->pduSession[j].xid = xid; } + freeDRBlist(DRB_configList); /* If list is empty free the list and reset the address */ if (dedicatedNAS_MessageList->list.count == 0) { @@ -709,16 +730,27 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c dedicatedNAS_MessageList = NULL; } + /* Free all NAS PDUs */ + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { + /* Free the NAS PDU buffer and invalidate it */ + free(ue_p->pduSession[i].param.nas_pdu.buffer); + ue_p->pduSession[i].param.nas_pdu.buffer = NULL; + } + } + NR_CellGroupConfig_t *cellGroupConfig = ue_p->masterCellGroup; uint8_t buffer[RRC_BUF_SIZE] = {0}; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); + NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false); + int size = do_RRCReconfiguration(ctxt_pP, buffer, RRC_BUF_SIZE, xid, SRBs, - DRB_configList, + DRBs, NULL, NULL, NULL, @@ -731,15 +763,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c cellGroupConfig); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n"); freeSRBlist(SRBs); - /* Free all NAS PDUs */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { - /* Free the NAS PDU buffer and invalidate it */ - free(ue_p->pduSession[i].param.nas_pdu.buffer); - ue_p->pduSession[i].param.nas_pdu.buffer = NULL; - } - } - freeDRBlist(DRB_configList); + freeDRBlist(DRBs); LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index f0a7f3b90f..fd31004a17 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -778,7 +778,13 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins 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 = session->pdusession_id; + LOG_W(NR_RRC, + "%s: %d Current implementation configures one DRB per PDUSession, session->pdusession_id %d, drb->id %ld\n", + __FUNCTION__, + __LINE__, + session->pdusession_id, + drb->id); drb->defaultDRB = E1AP_DefaultDRB_true; diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 9e6e7961d6..57dcd35a9b 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -147,6 +147,16 @@ uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession { uint8_t drb_id; + drb_id = pdusession->param.pdusession_id; + LOG_W(NR_RRC, + "%s: %d Current implementation configures one DRB per PDUSession, pdusession_id %d, drb_id %d\n", + __FUNCTION__, + __LINE__, + pdusession->param.pdusession_id, + drb_id); + + return drb_id; + if(!is_gbr) { /* Find if Non-GBR DRB exists in the same PDU Session */ for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++) if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR) From 1fdf71e1db5bf12abc0bca6f380dbe468d53b60e Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 6 Jul 2023 19:45:10 +0200 Subject: [PATCH 3/4] Address review comments --- openair2/RRC/NR/cucp_cuup_direct.c | 2 ++ openair2/RRC/NR/rrc_gNB.c | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 49f95c82f7..9c4e6462a4 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -187,6 +187,8 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(UE); int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, DRB_configList, rrc->e1_inst); if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); + // the code is very badly organized, it is not possible here to call freeDRBlist() + ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList,DRB_configList ); // Used to store teids: if monolithic, will simply be NULL if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index a23c260612..05df1da23c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -133,7 +133,10 @@ static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) return list; } -static NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish) +// not clear what this function do against fill_DRB_configList() +// it sets reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true +// else it should probably be removed and merged into fill_DRB_configList +static NR_DRB_ToAddModList_t *createDRBlistReestablish(gNB_RRC_UE_t *ue) { NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); @@ -142,9 +145,6 @@ static NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish) if (ue->established_drbs[i].status != DRB_INACTIVE) { ue->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true; DRB_config = generateDRB_ASN1(&ue->established_drbs[i]); - if (reestablish) { - asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); - } asn1cSeqAdd(&DRB_configList->list, DRB_config); } } @@ -220,6 +220,7 @@ NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) static void freeDRBlist(NR_DRB_ToAddModList_t *list) { + //ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list); return; } static void nr_rrc_addmod_srbs(int rnti, @@ -743,7 +744,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c uint8_t buffer[RRC_BUF_SIZE] = {0}; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); - NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false); + NR_DRB_ToAddModList_t *DRBs = createDRBlistReestablish(ue_p); int size = do_RRCReconfiguration(ctxt_pP, buffer, From 4deb58339b20fe6393dd10900cb547506b5bbc01 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Fri, 7 Jul 2023 11:01:04 +0100 Subject: [PATCH 4/4] Fix multiple PDUSessions after review, now DRBs are configured sequentially, no matter what PDUSession id we receive --- openair2/E1AP/e1ap.c | 9 +- openair2/RRC/NR/rrc_gNB.c | 112 ++++++++++++------------ openair2/RRC/NR/rrc_gNB_NGAP.c | 8 +- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 18 +--- 4 files changed, 63 insertions(+), 84 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 7a1954f714..6c33ddf973 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -589,14 +589,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_beare for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRB2Setup; j++) { asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1); - - ieC6_1_1->dRB_ID = ieC6_1->pDU_Session_ID; - LOG_W(E1AP, - "%s: %d Current implementation configures one DRB per PDUSession, ieC6_1->pDU_Session_ID %ld, ieC6_1_1->dRB_ID %ld\n", - __FUNCTION__, - __LINE__, - ieC6_1->pDU_Session_ID, - ieC6_1_1->dRB_ID); + ieC6_1_1->dRB_ID = j->id; ieC6_1_1->sDAP_Configuration.defaultDRB = j->defaultDRB; ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sDAP_Header_UL; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 05df1da23c..776c6b9275 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -114,43 +114,6 @@ mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) -{ - if (!ue->Srb[1].Active) { - LOG_E(NR_RRC, "Call SRB list while SRB1 doesn't exist\n"); - return NULL; - } - NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1); - for (int i = 0; i < maxSRBs; i++) { - if (ue->Srb[i].Active) { - asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb); - srb->srb_Identity = i; - if (reestablish && i == 2) { - asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true); - } - } - } - return list; -} - -// not clear what this function do against fill_DRB_configList() -// it sets reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true -// else it should probably be removed and merged into fill_DRB_configList -static NR_DRB_ToAddModList_t *createDRBlistReestablish(gNB_RRC_UE_t *ue) -{ - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); - - for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { - if (ue->established_drbs[i].status != DRB_INACTIVE) { - ue->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true; - DRB_config = generateDRB_ASN1(&ue->established_drbs[i]); - asn1cSeqAdd(&DRB_configList->list, DRB_config); - } - } - return DRB_configList; -} - NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -413,6 +376,42 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP) return tmp; } +static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) +{ + if (!ue->Srb[1].Active) { + LOG_E(NR_RRC, "Call SRB list while SRB1 doesn't exist\n"); + return NULL; + } + NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1); + for (int i = 0; i < maxSRBs; i++) + if (ue->Srb[i].Active) { + asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb); + srb->srb_Identity = i; + if (reestablish && i == 2) { + asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true); + } + } + return list; +} + +static NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish) +{ + NR_DRB_ToAddMod_t *DRB_config = NULL; + NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); + + for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { + if (ue->established_drbs[i].status != DRB_INACTIVE) { + DRB_config = generateDRB_ASN1(&ue->established_drbs[i]); + if (reestablish) { + ue->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true; + asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); + } + asn1cSeqAdd(&DRB_configList->list, DRB_config); + } + } + return DRB_configList; +} + static void freeSRBlist(NR_SRB_ToAddModList_t *l) { if (l) { @@ -744,7 +743,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c uint8_t buffer[RRC_BUF_SIZE] = {0}; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); - NR_DRB_ToAddModList_t *DRBs = createDRBlistReestablish(ue_p); + NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false); int size = do_RRCReconfiguration(ctxt_pP, buffer, @@ -1034,7 +1033,7 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co uint8_t kUPenc[16] = {0}; uint8_t kUPint[16] = {0}; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); + NR_DRB_ToAddModList_t *DRB_configList = createDRBlist(ue_p, false); /* Derive the keys from kgnb */ if (DRB_configList != NULL) { @@ -1048,18 +1047,20 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co /* Refresh SRBs/DRBs */ LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); ue_id_t reestablish_ue_id = 0; - if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) { - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i]; - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; - reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti; - LOG_D(NR_RRC, "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - // clear current C-RNTI from map - nr_reestablish_rnti_map->ue_id = 0; - nr_reestablish_rnti_map->c_rnti = 0; - break; - } + for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { + nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i]; + if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { + ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; + reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti; + LOG_D(NR_RRC, + "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", + i, + nr_reestablish_rnti_map->ue_id, + nr_reestablish_rnti_map->c_rnti); + // clear current C-RNTI from map + nr_reestablish_rnti_map->ue_id = 0; + nr_reestablish_rnti_map->c_rnti = 0; + break; } } NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); @@ -1346,15 +1347,16 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx NR_RLC_BearerConfig__reestablishRLC_true); } - NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p); - uint8_t buffer[RRC_BUF_SIZE] = {0}; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); + NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true); + + uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_RRCReconfiguration(ctxt_pP, buffer, RRC_BUF_SIZE, new_xid, SRBs, - DRB_configList, + DRBs, NULL, NULL, NULL, @@ -1366,7 +1368,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx NULL, cellGroupConfig); freeSRBlist(SRBs); - freeDRBlist(DRB_configList); + freeDRBlist(DRBs); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index fd31004a17..f0a7f3b90f 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -778,13 +778,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins for (int j=0; j < pdu->numDRB2Setup; j++) { DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j; - drb->id = session->pdusession_id; - LOG_W(NR_RRC, - "%s: %d Current implementation configures one DRB per PDUSession, session->pdusession_id %d, drb->id %ld\n", - __FUNCTION__, - __LINE__, - session->pdusession_id, - drb->id); + drb->id = i + j + UE->nb_of_pdusessions; drb->defaultDRB = E1AP_DefaultDRB_true; diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 57dcd35a9b..4c5c50fb00 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -147,25 +147,15 @@ uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession { uint8_t drb_id; - drb_id = pdusession->param.pdusession_id; - LOG_W(NR_RRC, - "%s: %d Current implementation configures one DRB per PDUSession, pdusession_id %d, drb_id %d\n", - __FUNCTION__, - __LINE__, - pdusession->param.pdusession_id, - drb_id); - - return drb_id; - - if(!is_gbr) { /* Find if Non-GBR DRB exists in the same PDU Session */ + if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */ for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++) if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR) - return drb_id+1; + 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 < NGAP_MAX_DRBS_PER_UE; drb_id++) - if(ue->DRB_active[drb_id] == DRB_INACTIVE) - return drb_id+1; + if (ue->DRB_active[drb_id] == DRB_INACTIVE) + return drb_id + 1; /* From this point, we need to handle the case that all DRBs are already used by the UE. */ LOG_E(RRC, "Error - All the DRBs are used - Handle this\n"); return DRB_INACTIVE;