From 0de51bcd93cf18bea2da83cea3a65c78d4de4333 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 16 Mar 2023 18:03:09 +0100 Subject: [PATCH 01/36] scheduling aperiodic SRS at UE --- .../nfapi/public_inc/fapi_nr_ue_interface.h | 4 - openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 197 ++++++++++++------ 4 files changed, 145 insertions(+), 68 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 94bf1b02dc..d4fc713c19 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -423,9 +423,6 @@ typedef struct { typedef struct { fapi_nr_dl_config_dci_dl_pdu_rel15_t dci_config_rel15; } fapi_nr_dl_config_dci_pdu; -typedef struct{ - uint8_t aperiodicSRS_ResourceTrigger; -} fapi_nr_dl_srs_config_t; typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t; @@ -462,7 +459,6 @@ typedef struct { uint16_t dmrs_ports; uint8_t n_front_load_symb; uint8_t tci_state; - fapi_nr_dl_srs_config_t srs_config; uint8_t cbgti; uint8_t codeBlockGroupFlushIndicator; // to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index eb773672d4..a402498eb0 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -189,6 +189,8 @@ int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, in uint32_t get_ssb_frame(uint32_t test); +void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger, int frame, int slot); + bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f9bc506102..3ffba2081d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -536,6 +536,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr // - SECOND_DAI // - SRS_RESOURCE_IND + /* SRS_REQUEST */ + AssertFatal(dci->srs_request.nbits == 2, "If SUL is supported in the cell, there is an additional bit in SRS request field\n"); + if(dci->srs_request.val > 0) + nr_ue_aperiodic_srs_scheduling(mac, dci->srs_request.val, frame, slot); + // Schedule PUSCH tda_info = get_ul_tda_info(current_UL_BWP, coreset_type, dci_ind->ss_type, get_rnti_type(mac, rnti), dci->time_domain_assignment.val); if (tda_info.nrOfSymbols == 0) @@ -1072,8 +1077,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_1->tci_state = dci->transmission_configuration_indication.val; } /* SRS_REQUEST */ - // if SUL is supported in the cell, there is an additional bit in this field and the value of this bit represents table 7.1.1.1-1 TS 38.212 FIXME!!! - dlsch_config_pdu_1_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request.val & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212 + AssertFatal(dci->srs_request.nbits == 2, "If SUL is supported in the cell, there is an additional bit in SRS request field\n"); + if(dci->srs_request.val > 0 ) + nr_ue_aperiodic_srs_scheduling(mac, dci->srs_request.val, frame, slot); /* CBGTI */ dlsch_config_pdu_1_1->cbgti = dci->cbgti.val; /* CBGFI */ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 5c68295739..3360cf5a34 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -789,6 +789,140 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, NR_tda_info_t *tda_info, nfapi_nr } +void configure_srs_pdu(NR_UE_MAC_INST_t *mac, + NR_SRS_Resource_t *srs_resource, + fapi_nr_ul_config_srs_pdu *srs_config_pdu, + int period, int offset) +{ + NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + + srs_config_pdu->rnti = mac->crnti; + srs_config_pdu->handle = 0; + srs_config_pdu->bwp_size = current_UL_BWP->BWPSize; + srs_config_pdu->bwp_start = current_UL_BWP->BWPStart; + srs_config_pdu->subcarrier_spacing = current_UL_BWP->scs; + srs_config_pdu->cyclic_prefix = 0; + srs_config_pdu->num_ant_ports = srs_resource->nrofSRS_Ports; + srs_config_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols; + srs_config_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor; + srs_config_pdu->time_start_position = srs_resource->resourceMapping.startPosition; + srs_config_pdu->config_index = srs_resource->freqHopping.c_SRS; + srs_config_pdu->sequence_id = srs_resource->sequenceId; + srs_config_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS; + srs_config_pdu->comb_size = srs_resource->transmissionComb.present - 1; + + switch(srs_resource->transmissionComb.present) { + case NR_SRS_Resource__transmissionComb_PR_n2: + srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n2->combOffset_n2; + srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n2->cyclicShift_n2; + break; + case NR_SRS_Resource__transmissionComb_PR_n4: + srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n4->combOffset_n4; + srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n4->cyclicShift_n4; + break; + default: + LOG_W(NR_MAC, "Invalid or not implemented comb_size!\n"); + } + + srs_config_pdu->frequency_position = srs_resource->freqDomainPosition; + srs_config_pdu->frequency_shift = srs_resource->freqDomainShift; + srs_config_pdu->frequency_hopping = srs_resource->freqHopping.b_hop; + srs_config_pdu->group_or_sequence_hopping = srs_resource->groupOrSequenceHopping; + srs_config_pdu->resource_type = srs_resource->resourceType.present - 1; + if(srs_config_pdu->resource_type > 0) { // not aperiodic + srs_config_pdu->t_srs = period; + srs_config_pdu->t_offset = offset; + } + +#ifdef SRS_DEBUG + LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot); + LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti); + LOG_I(NR_MAC,"srs_config_pdu->handle = %u\n", srs_config_pdu->handle); + LOG_I(NR_MAC,"srs_config_pdu->bwp_size = %u\n", srs_config_pdu->bwp_size); + LOG_I(NR_MAC,"srs_config_pdu->bwp_start = %u\n", srs_config_pdu->bwp_start); + LOG_I(NR_MAC,"srs_config_pdu->subcarrier_spacing = %u\n", srs_config_pdu->subcarrier_spacing); + LOG_I(NR_MAC,"srs_config_pdu->cyclic_prefix = %u (0: Normal; 1: Extended)\n", srs_config_pdu->cyclic_prefix); + LOG_I(NR_MAC,"srs_config_pdu->num_ant_ports = %u (0 = 1 port, 1 = 2 ports, 2 = 4 ports)\n", srs_config_pdu->num_ant_ports); + LOG_I(NR_MAC,"srs_config_pdu->num_symbols = %u (0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols)\n", srs_config_pdu->num_symbols); + LOG_I(NR_MAC,"srs_config_pdu->num_repetitions = %u (0 = 1, 1 = 2, 2 = 4)\n", srs_config_pdu->num_repetitions); + LOG_I(NR_MAC,"srs_config_pdu->time_start_position = %u\n", srs_config_pdu->time_start_position); + LOG_I(NR_MAC,"srs_config_pdu->config_index = %u\n", srs_config_pdu->config_index); + LOG_I(NR_MAC,"srs_config_pdu->sequence_id = %u\n", srs_config_pdu->sequence_id); + LOG_I(NR_MAC,"srs_config_pdu->bandwidth_index = %u\n", srs_config_pdu->bandwidth_index); + LOG_I(NR_MAC,"srs_config_pdu->comb_size = %u (0 = comb size 2, 1 = comb size 4, 2 = comb size 8)\n", srs_config_pdu->comb_size); + LOG_I(NR_MAC,"srs_config_pdu->comb_offset = %u\n", srs_config_pdu->comb_offset); + LOG_I(NR_MAC,"srs_config_pdu->cyclic_shift = %u\n", srs_config_pdu->cyclic_shift); + LOG_I(NR_MAC,"srs_config_pdu->frequency_position = %u\n", srs_config_pdu->frequency_position); + LOG_I(NR_MAC,"srs_config_pdu->frequency_shift = %u\n", srs_config_pdu->frequency_shift); + LOG_I(NR_MAC,"srs_config_pdu->frequency_hopping = %u\n", srs_config_pdu->frequency_hopping); + LOG_I(NR_MAC,"srs_config_pdu->group_or_sequence_hopping = %u (0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping)\n", srs_config_pdu->group_or_sequence_hopping); + LOG_I(NR_MAC,"srs_config_pdu->resource_type = %u (0: aperiodic, 1: semi-persistent, 2: periodic)\n", srs_config_pdu->resource_type); + LOG_I(NR_MAC,"srs_config_pdu->t_srs = %u\n", srs_config_pdu->t_srs); + LOG_I(NR_MAC,"srs_config_pdu->t_offset = %u\n", srs_config_pdu->t_offset); +#endif +} + +// Aperiodic SRS scheduling +void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger, int frame, int slot) +{ + NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; + + if (!srs_config) { + LOG_E(NR_MAC, "DCI is triggering aperiodic SRS but there is no SRS configuration\n"); + return; + } + + int slot_offset = 0; + NR_SRS_Resource_t *srs_resource = NULL; + for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { + + // Find aperiodic resource set + NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; + if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_aperiodic) + continue; + // the resource trigger need to match the DCI one + if(srs_resource_set->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger != resource_trigger) + continue; + // if slotOffset is null -> offset = 0 + if(srs_resource_set->resourceType.choice.aperiodic->slotOffset) + slot_offset = *srs_resource_set->resourceType.choice.aperiodic->slotOffset; + + // Find the corresponding srs resource + for(int r1 = 0; r1 < srs_resource_set->srs_ResourceIdList->list.count; r1++) { + for (int r2 = 0; r2 < srs_config->srs_ResourceToAddModList->list.count; r2++) { + if ((*srs_resource_set->srs_ResourceIdList->list.array[r1] == srs_config->srs_ResourceToAddModList->list.array[r2]->srs_ResourceId) && + (srs_config->srs_ResourceToAddModList->list.array[r2]->resourceType.present == NR_SRS_Resource__resourceType_PR_aperiodic)) { + srs_resource = srs_config->srs_ResourceToAddModList->list.array[r2]; + break; + } + } + } + } + + if(srs_resource == NULL) { + LOG_E(NR_MAC, "Couldn't find SRS aperiodic resource with trigger %ld\n", resource_trigger); + return; + } + + AssertFatal(slot_offset >= DURATION_RX_TO_TX,"Slot offset between DCI and aperiodic SRS (%d) cannot be less than DURATION_RX_TO_TX (%d)\n", + slot_offset, DURATION_RX_TO_TX); + int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; + int sched_slot = (slot + slot_offset) % n_slots_frame; + NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon; + if (!is_nr_UL_slot(tdd_config, sched_slot, mac->frame_type)) { + LOG_E(NR_MAC, "Slot for scheduling aperiodic SRS %d is not an UL slot\n", sched_slot); + return; + } + int sched_frame = frame + (slot + slot_offset >= n_slots_frame) % 1024; + + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot); + fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu; + configure_srs_pdu(mac, srs_resource, srs_config_pdu, 0, 0); + fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS); +} + + // Periodic SRS scheduling bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slot) { @@ -838,68 +972,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot); fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu; - srs_config_pdu->rnti = mac->crnti; - srs_config_pdu->handle = 0; - srs_config_pdu->bwp_size = current_UL_BWP->BWPSize; - srs_config_pdu->bwp_start = current_UL_BWP->BWPStart; - srs_config_pdu->subcarrier_spacing = current_UL_BWP->scs; - srs_config_pdu->cyclic_prefix = 0; - srs_config_pdu->num_ant_ports = srs_resource->nrofSRS_Ports; - srs_config_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols; - srs_config_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor; - srs_config_pdu->time_start_position = srs_resource->resourceMapping.startPosition; - srs_config_pdu->config_index = srs_resource->freqHopping.c_SRS; - srs_config_pdu->sequence_id = srs_resource->sequenceId; - srs_config_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS; - srs_config_pdu->comb_size = srs_resource->transmissionComb.present - 1; - - switch(srs_resource->transmissionComb.present) { - case NR_SRS_Resource__transmissionComb_PR_n2: - srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n2->combOffset_n2; - srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n2->cyclicShift_n2; - break; - case NR_SRS_Resource__transmissionComb_PR_n4: - srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n4->combOffset_n4; - srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n4->cyclicShift_n4; - break; - default: - LOG_W(NR_MAC, "Invalid or not implemented comb_size!\n"); - } - - srs_config_pdu->frequency_position = srs_resource->freqDomainPosition; - srs_config_pdu->frequency_shift = srs_resource->freqDomainShift; - srs_config_pdu->frequency_hopping = srs_resource->freqHopping.b_hop; - srs_config_pdu->group_or_sequence_hopping = srs_resource->groupOrSequenceHopping; - srs_config_pdu->resource_type = srs_resource->resourceType.present - 1; - srs_config_pdu->t_srs = period; - srs_config_pdu->t_offset = offset; - -#ifdef SRS_DEBUG - LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot); - LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti); - LOG_I(NR_MAC,"srs_config_pdu->handle = %u\n", srs_config_pdu->handle); - LOG_I(NR_MAC,"srs_config_pdu->bwp_size = %u\n", srs_config_pdu->bwp_size); - LOG_I(NR_MAC,"srs_config_pdu->bwp_start = %u\n", srs_config_pdu->bwp_start); - LOG_I(NR_MAC,"srs_config_pdu->subcarrier_spacing = %u\n", srs_config_pdu->subcarrier_spacing); - LOG_I(NR_MAC,"srs_config_pdu->cyclic_prefix = %u (0: Normal; 1: Extended)\n", srs_config_pdu->cyclic_prefix); - LOG_I(NR_MAC,"srs_config_pdu->num_ant_ports = %u (0 = 1 port, 1 = 2 ports, 2 = 4 ports)\n", srs_config_pdu->num_ant_ports); - LOG_I(NR_MAC,"srs_config_pdu->num_symbols = %u (0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols)\n", srs_config_pdu->num_symbols); - LOG_I(NR_MAC,"srs_config_pdu->num_repetitions = %u (0 = 1, 1 = 2, 2 = 4)\n", srs_config_pdu->num_repetitions); - LOG_I(NR_MAC,"srs_config_pdu->time_start_position = %u\n", srs_config_pdu->time_start_position); - LOG_I(NR_MAC,"srs_config_pdu->config_index = %u\n", srs_config_pdu->config_index); - LOG_I(NR_MAC,"srs_config_pdu->sequence_id = %u\n", srs_config_pdu->sequence_id); - LOG_I(NR_MAC,"srs_config_pdu->bandwidth_index = %u\n", srs_config_pdu->bandwidth_index); - LOG_I(NR_MAC,"srs_config_pdu->comb_size = %u (0 = comb size 2, 1 = comb size 4, 2 = comb size 8)\n", srs_config_pdu->comb_size); - LOG_I(NR_MAC,"srs_config_pdu->comb_offset = %u\n", srs_config_pdu->comb_offset); - LOG_I(NR_MAC,"srs_config_pdu->cyclic_shift = %u\n", srs_config_pdu->cyclic_shift); - LOG_I(NR_MAC,"srs_config_pdu->frequency_position = %u\n", srs_config_pdu->frequency_position); - LOG_I(NR_MAC,"srs_config_pdu->frequency_shift = %u\n", srs_config_pdu->frequency_shift); - LOG_I(NR_MAC,"srs_config_pdu->frequency_hopping = %u\n", srs_config_pdu->frequency_hopping); - LOG_I(NR_MAC,"srs_config_pdu->group_or_sequence_hopping = %u (0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping)\n", srs_config_pdu->group_or_sequence_hopping); - LOG_I(NR_MAC,"srs_config_pdu->resource_type = %u (0: aperiodic, 1: semi-persistent, 2: periodic)\n", srs_config_pdu->resource_type); - LOG_I(NR_MAC,"srs_config_pdu->t_srs = %u\n", srs_config_pdu->t_srs); - LOG_I(NR_MAC,"srs_config_pdu->t_offset = %u\n", srs_config_pdu->t_offset); -#endif + configure_srs_pdu(mac, srs_resource, srs_config_pdu, period, offset); fill_ul_config(ul_config, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS); srs_scheduled = true; From 50bf5713476bb3f3b776389da2f3b1cbf8c6d3f0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 30 Mar 2023 12:57:10 +0200 Subject: [PATCH 02/36] hack: see "Bye." message when quitting gnb running with aw2s For some (unclear) reason, nr-softmodem with aw2s device does not print "Bye." when stopping it with control+c, which is problematic in the CI. This little hack solves the problem. (Maybe not the right solution, to be changed if needed.) --- executables/nr-ru.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 6c527defca..6a2b6e7e9f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -328,7 +328,9 @@ void fh_if5_south_in(RU_t *ru, if (proc->first_rx == 0) { if (proc->tti_rx != *tti) { LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*tti); - exit_fun("Exiting"); + if (!oai_exit) + exit_fun("Exiting"); + return; } if (proc->frame_rx != *frame) { From 5c333cca65bc7c19302aa4d5bc59b36081cbec76 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 23 Mar 2023 17:46:50 +0100 Subject: [PATCH 03/36] move radio link failure detection on pbch at MAC --- executables/nr-ue.c | 5 - .../nfapi/public_inc/fapi_nr_ue_interface.h | 3 +- openair1/PHY/INIT/nr_init_ue.c | 3 - .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 14 +-- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 57 +++++----- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 1 - openair1/PHY/defs_nr_UE.h | 14 --- openair1/SCHED_NR_UE/defs.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 61 ++++------- openair1/SIMULATION/NR_PHY/pbchsim.c | 5 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 5 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 + openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 6 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 103 ++++++++++-------- 15 files changed, 124 insertions(+), 160 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 10509a2870..1dab8c8078 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -755,7 +755,6 @@ void *UE_thread(void *arg) { fapi_nr_config_request_t *cfg = &UE->nrUE_config; AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); UE->rfdevice.host_type = RAU_HOST; - UE->lost_sync = 0; UE->is_synchronized = 0; AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); @@ -776,10 +775,6 @@ void *UE_thread(void *arg) { int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0; while (!oai_exit) { - if (UE->lost_sync) { - UE->is_synchronized = 0; - UE->lost_sync = 0; - } if (syncRunning) { notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool)); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index d429bf43ba..544b175b7c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -116,7 +116,8 @@ typedef struct { } fapi_nr_pdsch_pdu_t; typedef struct { - uint8_t* pdu; // 3bytes + bool decoded_pdu; + uint8_t pdu[3]; uint8_t additional_bits; uint8_t ssb_index; uint8_t ssb_length; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 32e5647b69..55e1bca868 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -202,7 +202,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // create shortcuts NR_DL_FRAME_PARMS *const fp = &ue->frame_parms; NR_UE_COMMON *const common_vars = &ue->common_vars; - NR_UE_PBCH **const pbch_vars = ue->pbch_vars; NR_UE_PRACH **const prach_vars = ue->prach_vars; NR_UE_CSI_IM **const csiim_vars = ue->csiim_vars; NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars; @@ -357,7 +356,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // DLSCH for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH)); - pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH)); csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM)); csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS)); srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS)); @@ -476,7 +474,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->csirs_vars[gNB_id]); free_and_zero(ue->srs_vars[gNB_id]); - free_and_zero(ue->pbch_vars[gNB_id]); free_and_zero(ue->prach_vars[gNB_id]); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 061eede6dd..da99ba7405 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -155,12 +155,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF); stop_meas(&ue->dlsch_channel_estimation_stats); - fapiPbch_t result; + fapiPbch_t result = {0}; ret = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, - ue->pbch_vars[0], frame_parms, temp_ptr->i_ssb, SISO, @@ -188,11 +187,6 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini // openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1; - // flip byte endian on 24-bits for MIB - // dummy = ue->pbch_vars[0]->decoded_output[0]; - // ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2]; - // ue->pbch_vars[0]->decoded_output[2] = dummy; - #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id); #endif @@ -447,8 +441,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, // send sync status to higher layers later when timing offset converge to target timing - ue->pbch_vars[0]->pdu_errors_conseq=0; - } @@ -466,10 +458,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, frame_parms->Nid_cell,frame_parms->frame_type); #endif - ue->pbch_vars[0]->pdu_errors_last=ue->pbch_vars[0]->pdu_errors; - ue->pbch_vars[0]->pdu_errors++; - ue->pbch_vars[0]->pdu_errors_conseq++; - } // gain control diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 0c2149e997..3d6abc661e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -302,8 +302,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, #endif } -static void nr_pbch_unscrambling(NR_UE_PBCH *pbch, - int16_t *demod_pbch_e, +static void nr_pbch_unscrambling(int16_t *demod_pbch_e, uint16_t Nid, uint8_t nushift, uint16_t M, @@ -311,7 +310,8 @@ static void nr_pbch_unscrambling(NR_UE_PBCH *pbch, uint8_t bitwise, uint32_t unscrambling_mask, uint32_t pbch_a_prime, - uint32_t *pbch_a_interleaved) { + uint32_t *pbch_a_interleaved) +{ uint8_t reset, offset; uint32_t x1 = 0, x2 = 0, s = 0; uint8_t k=0; @@ -384,17 +384,17 @@ unsigned char sign(int8_t x) { uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23}; -int nr_rx_pbch( PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - int estimateSz, struct complex16 dl_ch_estimates [][estimateSz], - NR_UE_PBCH *nr_ue_pbch_vars, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t i_ssb, - MIMO_mode_t mimo_mode, - nr_phy_data_t *phy_data, - fapiPbch_t *result, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - +int nr_rx_pbch(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + int estimateSz, + struct complex16 dl_ch_estimates [][estimateSz], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t i_ssb, + MIMO_mode_t mimo_mode, + nr_phy_data_t *phy_data, + fapiPbch_t *result, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +{ int max_h=0; int symbol; //uint8_t pbch_a[64]; @@ -456,7 +456,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, } #ifdef DEBUG_PBCH - LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h); + LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n", log2_maxh, max_h); #endif __attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; nr_pbch_channel_compensation(rxdataF_ext, @@ -464,7 +464,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, nb_re, rxdataF_comp, frame_parms, - log2_maxh); // log2_maxh+I0_shift + log2_maxh); // log2_maxh+I0_shift /*if (frame_parms->nb_antennas_rx > 1) pbch_detection_mrc(frame_parms, @@ -504,16 +504,27 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041; uint32_t pbch_a_interleaved=0; uint32_t pbch_a_prime=0; - nr_pbch_unscrambling(nr_ue_pbch_vars, pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_E, + nr_pbch_unscrambling(pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_E, 0, 0, pbch_a_prime, &pbch_a_interleaved); //polar decoding de-rate matching uint64_t tmp=0; decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&tmp,0, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL); - pbch_a_prime=tmp; - if(decoderState) - return(decoderState); + pbch_a_prime = tmp; + nr_downlink_indication_t dl_indication; + fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind), 1); + uint16_t number_pdus = 1; + + if(decoderState) { + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, phy_data); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL); + if (ue->if_inst && ue->if_inst->dl_indication) + ue->if_inst->dl_indication(&dl_indication, NULL); + else + free(rx_ind); // dl_indication would free(), so free() here if not called + return(decoderState); + } // printf("polar decoder output 0x%08x\n",pbch_a_prime); // Decoder reversal uint32_t a_reversed=0; @@ -526,7 +537,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); nushift = ((pbch_a_prime>>24)&1) ^ (((pbch_a_prime>>6)&1)<<1); pbch_a_interleaved=0; - nr_pbch_unscrambling(nr_ue_pbch_vars, pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, + nr_pbch_unscrambling(pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 1, unscrambling_mask, pbch_a_prime, &pbch_a_interleaved); //printf("nushift %d sfn 3rd %d 2nd %d", nushift,((pbch_a_prime>>6)&1), ((pbch_a_prime>>24)&1) ); //payload deinterleaving @@ -577,10 +588,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, } #endif - nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1); - uint16_t number_pdus = 1; - nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, phy_data); nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc,(void *)result); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 0d6c334c45..b90ba5d20e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -285,7 +285,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, const int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], - NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, uint8_t i_ssb, MIMO_mode_t mimo_mode, diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 9ba7233770..47fe45a1f9 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -316,17 +316,6 @@ typedef struct { #define PBCH_A 24 -typedef struct { - /// \brief Total number of PDU errors. - uint32_t pdu_errors; - /// \brief Total number of PDU errors 128 frames ago. - uint32_t pdu_errors_last; - /// \brief Total number of consecutive PDU errors. - uint32_t pdu_errors_conseq; - /// \brief FER (in percent) . - //uint32_t pdu_fer; -} NR_UE_PBCH; - typedef struct { int16_t amp; bool active; @@ -402,8 +391,6 @@ typedef struct { int is_synchronized; /// \brief Target gNB Nid_cell when UE is resynchronizing int target_Nid_cell; - /// \brief Indicator that UE lost frame synchronization - int lost_sync; /// Data structure for UE process scheduling UE_nr_proc_t proc; /// Flag to indicate the UE shouldn't do timing correction at all @@ -444,7 +431,6 @@ typedef struct { fapi_nr_config_request_t nrUE_config; nr_synch_request_t synch_request; - NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_CSI_IM *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_CSI_RS *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX]; diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 1439c9fd01..628c8f4959 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -83,7 +83,7 @@ typedef struct { - uint8_t decoded_output[64]; + uint8_t decoded_output[3]; // PBCH paylod not larger than 3B uint8_t xtra_byte; } fapiPbch_t; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f88b81ad52..6fa14c3cd0 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -118,10 +118,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void *typeSpecific){ - - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - + void *typeSpecific) +{ if (n_pdus > 1){ LOG_E(PHY, "In %s: multiple number of DL PDUs not supported yet...\n", __FUNCTION__); } @@ -154,17 +152,23 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, AssertFatal(1==0,"Second codeword currently not supported\n"); } break; - case FAPI_NR_RX_PDU_TYPE_SSB: - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.pdu=malloc(sizeof(((fapiPbch_t*)typeSpecific)->decoded_output)); - memcpy(rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.pdu, - ((fapiPbch_t*)typeSpecific)->decoded_output, - sizeof(((fapiPbch_t*)typeSpecific)->decoded_output)); - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.additional_bits = ((fapiPbch_t*)typeSpecific)->xtra_byte; - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_index = (frame_parms->ssb_index)&0x7; - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_length = frame_parms->Lmax; - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.cell_id = frame_parms->Nid_cell; - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; - rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.ssb_rsrp_dBm[frame_parms->ssb_index]; + case FAPI_NR_RX_PDU_TYPE_SSB: { + fapi_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu; + if(typeSpecific) { + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + fapiPbch_t *pbch = (fapiPbch_t *)typeSpecific; + memcpy(ssb_pdu->pdu, pbch->decoded_output, sizeof(pbch->decoded_output)); + ssb_pdu->additional_bits = pbch->xtra_byte; + ssb_pdu->ssb_index = (frame_parms->ssb_index)&0x7; + ssb_pdu->ssb_length = frame_parms->Lmax; + ssb_pdu->cell_id = frame_parms->Nid_cell; + ssb_pdu->ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; + ssb_pdu->rsrp_dBm = ue->measurements.ssb_rsrp_dBm[frame_parms->ssb_index]; + ssb_pdu->decoded_pdu = true; + } + else + ssb_pdu->decoded_pdu = false; + } break; case FAPI_NR_CSIRS_IND: memcpy(&rx_ind->rx_indication_body[n_pdus - 1].csirs_measurements, @@ -382,7 +386,6 @@ static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, proc, estimateSz, dl_ch_estimates, - ue->pbch_vars[gNB_id], &ue->frame_parms, (ue->frame_parms.ssb_index)&7, SISO, @@ -392,8 +395,6 @@ static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, if (ret==0) { - ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0; - #ifdef DEBUG_PHY_PROC uint16_t frame_tx; LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", @@ -426,36 +427,12 @@ static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1); - write_output("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1); - write_output("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1); - write_output("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4); exit(-1); */ - ue->pbch_vars[gNB_id]->pdu_errors_conseq++; - ue->pbch_vars[gNB_id]->pdu_errors++; - - if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) { - if (get_softmodem_params()->non_stop) { - LOG_E(PHY,"More that 100 consecutive PBCH errors! Going back to Sync mode!\n"); - ue->lost_sync = 1; - } else { - LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n"); - exit_fun("More that 100 consecutive PBCH errors! Exiting!\n"); - } - } } - if (frame_rx % 100 == 0) { - ue->pbch_vars[gNB_id]->pdu_errors_last = ue->pbch_vars[gNB_id]->pdu_errors; - } -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", - ue->Mod_id,frame_rx, nr_slot_rx, - ue->pbch_vars[gNB_id]->pdu_errors, - ue->pbch_vars[gNB_id]->pdu_errors_conseq); -#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ee67e8d52e..cdaf9ce214 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -793,8 +793,8 @@ int main(int argc, char **argv) fapiPbch_t result; ret = nr_rx_pbch(UE, &proc, - estimateSz, dl_ch_estimates, - UE->pbch_vars[0], + estimateSz, + dl_ch_estimates, frame_parms, ssb_index%8, SISO, @@ -813,7 +813,6 @@ int main(int argc, char **argv) for (i=0;i<3;i++){ payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); } - //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte); //printf("ret %d\n", payload_ret); if (payload_ret!=4) n_errors_payload++; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b1af5393a1..6e5a9ddc0c 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -376,8 +376,9 @@ typedef struct { uint32_t ssb_index; /// SSB RSRP in dBm short ssb_rsrp_dBm; + int consecutive_bch_failures; -} NR_PHY_meas_t; +} NR_SSB_meas_t; /*!\brief Top level UE MAC structure */ typedef struct { @@ -465,7 +466,7 @@ typedef struct { uint16_t nr_band; uint8_t ssb_subcarrier_offset; - NR_PHY_meas_t phy_measurements; + NR_SSB_meas_t ssb_measurements; dci_pdu_rel15_t def_dci_pdu_rel15[8]; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 2babe56ec8..31c665524e 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -55,6 +55,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { nr_ue_mac_inst->sib1_decoded = false; nr_ue_mac_inst->phy_config_request_sent = false; nr_ue_mac_inst->state = UE_NOT_SYNC; + memset(&nr_ue_mac_inst->ssb_measurements, 0, sizeof(nr_ue_mac_inst->ssb_measurements)); for (int j=0;jra; - int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm); + int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); @@ -674,7 +674,7 @@ void nr_get_prach_resources(module_id_t mod_id, } else { /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */ - int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0; + int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm) : 0; ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon); ra_preambles_config(prach_resources, mac, dl_pathloss); LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 3978d52711..d5fc404a6e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -238,6 +238,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id, AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); + mac->ssb_measurements.consecutive_bch_failures = 0; // resetting decoding failures + uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused); uint16_t frame_number_4lsb = 0; @@ -1564,7 +1566,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, return (PUCCH_POWER_DEFAULT); } - int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm); + int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs))); int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c; @@ -2179,7 +2181,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, } } AssertFatal(*SSB_resource.list.array[ssb_rsrp[0][0]] == mac->mib_ssb, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n"); - ssb_rsrp[1][0] = mac->phy_measurements.ssb_rsrp_dBm; + ssb_rsrp[1][0] = mac->ssb_measurements.ssb_rsrp_dBm; uint8_t ssbi; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 5ddd59fcc1..0506b40368 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -304,25 +304,24 @@ static void fill_dl_info_with_pdcch(fapi_nr_dci_indication_t *dci, nfapi_nr_dl_d static void fill_mib_in_rx_ind(nfapi_nr_dl_tti_request_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_ind, int pdu_idx, int pdu_type) { - AssertFatal(pdu_idx < sizeof(rx_ind->rx_indication_body) / sizeof(rx_ind->rx_indication_body[0]), - "pdu_index (%d) is greater than rx_indication_body size!\n", pdu_idx); - AssertFatal(pdu_idx == rx_ind->number_pdus, "Invalid pdu_idx %d!\n", pdu_idx); + AssertFatal(pdu_idx < sizeof(rx_ind->rx_indication_body) / sizeof(rx_ind->rx_indication_body[0]), + "pdu_index (%d) is greater than rx_indication_body size!\n", pdu_idx); + AssertFatal(pdu_idx == rx_ind->number_pdus, "Invalid pdu_idx %d!\n", pdu_idx); - LOG_T(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n"); - - nfapi_nr_dl_tti_ssb_pdu_rel15_t *ssb_pdu = &pdu_list->ssb_pdu.ssb_pdu_rel15; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.cell_id = ssb_pdu->PhysCellId; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu = MALLOC(3 * sizeof(*rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu)); - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[0] = (ssb_pdu->bchPayload) & 0xff; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[1] = (ssb_pdu->bchPayload >> 8) & 0xff; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[2] = (ssb_pdu->bchPayload >> 16) & 0xff; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.rsrp_dBm = ssb_pdu->ssbRsrp; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_index = ssb_pdu->SsbBlockIndex; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_length = pdu_list->PDUSize; - rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_start_subcarrier = ssb_pdu->SsbSubcarrierOffset; - rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type; - rx_ind->number_pdus = pdu_idx + 1; + LOG_T(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n"); + nfapi_nr_dl_tti_ssb_pdu_rel15_t *ssb_pdu = &pdu_list->ssb_pdu.ssb_pdu_rel15; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.cell_id = ssb_pdu->PhysCellId; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[0] = (ssb_pdu->bchPayload) & 0xff; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[1] = (ssb_pdu->bchPayload >> 8) & 0xff; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[2] = (ssb_pdu->bchPayload >> 16) & 0xff; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.rsrp_dBm = ssb_pdu->ssbRsrp; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_index = ssb_pdu->SsbBlockIndex; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_length = pdu_list->PDUSize; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_start_subcarrier = ssb_pdu->SsbSubcarrierOffset; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.decoded_pdu = true; + rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type; + rx_ind->number_pdus = pdu_idx + 1; } static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu) @@ -1045,18 +1044,26 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, uint16_t ssb_start_subcarrier, uint16_t cell_id){ return nr_ue_decode_mib(module_id, - cc_id, - gNB_index, - phy_data, - additional_bits, - ssb_length, // Lssb = 64 is not support - ssb_index, - pduP, - ssb_start_subcarrier, - cell_id); + cc_id, + gNB_index, + phy_data, + additional_bits, + ssb_length, // Lssb = 64 is not support + ssb_index, + pduP, + ssb_start_subcarrier, + cell_id); } +void handle_bch_failure(NR_UE_MAC_INST_t *mac) +{ + mac->ssb_measurements.consecutive_bch_failures++; + //TODO handle this properly by scheduling re-synchronization + AssertFatal(mac->ssb_measurements.consecutive_bch_failures < 100, + "Radio link failure caused by 100 consecutive PBCH detection failures.\n"); +} + // L2 Abstraction Layer int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len){ return nr_ue_decode_BCCH_DL_SCH(module_id, cc_id, gNB_index, ack_nack, pduP, pdu_len); @@ -1069,10 +1076,10 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t } -void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm) +void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm) { - mac->phy_measurements.ssb_index = ssb_index; - mac->phy_measurements.ssb_rsrp_dBm = rsrp_dbm; + mac->ssb_measurements.ssb_index = ssb_index; + mac->ssb_measurements.ssb_rsrp_dBm = rsrp_dbm; } // L2 Abstraction Layer @@ -1180,31 +1187,35 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ for (int i=0; irx_ind->number_pdus; ++i) { + fapi_nr_rx_indication_body_t rx_indication_body = dl_info->rx_ind->rx_indication_body[i]; LOG_D(NR_MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n", __FUNCTION__, - dl_info->rx_ind->rx_indication_body[i].pdu_type, + rx_indication_body.pdu_type, dl_info->rx_ind->number_pdus); - switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){ + switch(rx_indication_body.pdu_type){ case FAPI_NR_RX_PDU_TYPE_SSB: - handle_ssb_meas(mac, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm); - ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier, - (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB; - free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu); + if(rx_indication_body.ssb_pdu.decoded_pdu) { + handle_ssb_meas(mac, + rx_indication_body.ssb_pdu.ssb_index, + rx_indication_body.ssb_pdu.rsrp_dBm); + ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data, + rx_indication_body.ssb_pdu.pdu, + rx_indication_body.ssb_pdu.additional_bits, + rx_indication_body.ssb_pdu.ssb_index, + rx_indication_body.ssb_pdu.ssb_length, + rx_indication_body.ssb_pdu.ssb_start_subcarrier, + rx_indication_body.ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB; + } + else + handle_bch_failure(mac); break; case FAPI_NR_RX_PDU_TYPE_SIB: ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, - (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.ack_nack, - (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu, - (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB; + rx_indication_body.pdsch_pdu.ack_nack, + rx_indication_body.pdsch_pdu.pdu, + rx_indication_body.pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB; break; case FAPI_NR_RX_PDU_TYPE_DLSCH: ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH; @@ -1216,7 +1227,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ ret_mask |= (handle_csirs_measurements(dl_info->module_id, dl_info->frame, dl_info->slot, - &(dl_info->rx_ind->rx_indication_body+i)->csirs_measurements)) << FAPI_NR_CSIRS_IND; + &rx_indication_body.csirs_measurements)) << FAPI_NR_CSIRS_IND; break; default: break; From 15c12caa376311d8c1a6fcf3249f03749c342e94 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 22 Nov 2022 10:23:22 -0500 Subject: [PATCH 04/36] Contains MAC changes to run || DLSCH DL config as array in MAC Run RX slot processing in Tpool thread Fixed race in phy config Changed mac_IF_mutex Proc Tx: Lets wait for Proc Rx to get ACK/NACK -(only on slots that carry ACK/NACK) Fix problem with rfsim Separated PDCCH and PDSCH decoding functions. Run PDCCH decoding in main UE_thread. Fixed race in MAC dci config struct needed for parallel processing of slots Moved DLSCH transport block buffer to stack rx_ind as static allocation L2sim: Fixed calling of MAC sched in wrong slot Fix DCI extract bug for RA procedure --- executables/nr-ue.c | 78 ++++++++---- .../nfapi/public_inc/fapi_nr_ue_interface.h | 4 +- openair1/PHY/INIT/nr_init_ue.c | 9 -- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 8 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 10 +- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 8 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 +- .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 2 - openair1/PHY/defs_nr_UE.h | 5 + openair1/SCHED_NR_UE/defs.h | 18 +-- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 4 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 113 ++++++++++++------ openair1/SIMULATION/NR_PHY/dlschsim.c | 12 +- openair1/SIMULATION/NR_PHY/dlsim.c | 19 ++- openair1/SIMULATION/NR_PHY/pbchsim.c | 3 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 17 ++- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 4 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 +- .../NR_MAC_UE/nr_ue_dci_configuration.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 56 +++++---- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 95 ++++++++++----- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 27 +++-- 22 files changed, 333 insertions(+), 169 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 10509a2870..3d468ad64b 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -203,6 +203,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) nfapi_nr_ul_tti_request_t *ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot); if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0) { check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc); + free_and_zero(ul_tti_request_crc); } } @@ -232,6 +233,8 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) if (get_softmodem_params()->nsa) save_nr_measurement_info(dl_tti_request); check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL); + free_and_zero(dl_tti_request); + free_and_zero(tx_data_request); } else { AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n", @@ -240,6 +243,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) } if (ul_dci_request && ul_dci_request->numPdus > 0) { check_and_process_dci(NULL, NULL, ul_dci_request, NULL); + free_and_zero(ul_dci_request); } } @@ -324,14 +328,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) if (pthread_mutex_lock(&mac->mutex_dl_info)) abort(); - memset(&mac->dl_info, 0, sizeof(mac->dl_info)); - mac->dl_info.cc_id = CC_id; - mac->dl_info.gNB_index = gNB_id; - mac->dl_info.module_id = mod_id; - mac->dl_info.frame = frame; - mac->dl_info.slot = slot; - mac->dl_info.dci_ind = NULL; - mac->dl_info.rx_ind = NULL; if (ch_info) { mac->nr_ue_emul_l1.pmi = ch_info->csi[0].pmi; mac->nr_ue_emul_l1.ri = ch_info->csi[0].ri; @@ -343,6 +339,14 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, ul_info.slot_rx)) { + memset(&mac->dl_info, 0, sizeof(mac->dl_info)); + mac->dl_info.cc_id = CC_id; + mac->dl_info.gNB_index = gNB_id; + mac->dl_info.module_id = mod_id; + mac->dl_info.frame = frame; + mac->dl_info.slot = slot; + mac->dl_info.dci_ind = NULL; + mac->dl_info.rx_ind = NULL; nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); } @@ -563,6 +567,13 @@ void processSlotTX(void *arg) { LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type); if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){ + // wait for rx slots to send indication + for(int i=0; i < UE->tx_wait_for_dlsch[proc->nr_slot_tx]; i++) { + notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo[proc->nr_slot_tx]); + delNotifiedFIFO_elt(res); + } + UE->tx_wait_for_dlsch[proc->nr_slot_tx] = 0; + // trigger L2 to run ue_scheduler thru IF module // [TODO] mapping right after NR initial sync if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) { @@ -589,10 +600,8 @@ void processSlotTX(void *arg) { RU_write(rxtxD); } -void UE_processing(nr_rxtx_thread_data_t *rxtxD) { +nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { - UE_nr_rxtx_proc_t *proc = &rxtxD->proc; - PHY_VARS_NR_UE *UE = rxtxD->UE; nr_phy_data_t phy_data = {0}; if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) { @@ -624,17 +633,28 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) { UE->if_inst->dl_indication(&dl_indication, NULL); } - // Process Rx data for one sub-frame -#ifdef UE_SLOT_PARALLELISATION - phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL ); -#else uint64_t a=rdtsc_oai(); - phy_procedures_nrUE_RX(UE, proc, &phy_data); + pbch_pdcch_processing(UE, proc, &phy_data); + if (phy_data.dlsch[0].active) { + // indicate to tx thread to wait for DLSCH decoding + const int ack_nack_slot = (proc->nr_slot_rx + phy_data.dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame; + UE->tx_wait_for_dlsch[ack_nack_slot]++; + } + LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500); -#endif } ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx); + return phy_data; +} + +void UE_dl_processing(void *arg) { + nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg; + UE_nr_rxtx_proc_t *proc = &rxtxD->proc; + PHY_VARS_NR_UE *UE = rxtxD->UE; + nr_phy_data_t *phy_data = &rxtxD->phy_data; + + pdsch_processing(UE, proc, phy_data); } void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) { @@ -774,6 +794,13 @@ void *UE_thread(void *arg) { bool syncRunning=false; const int nb_slot_frame = UE->frame_parms.slots_per_frame; int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0; + initNotifiedFIFO(&UE->phy_config_ind); + + int num_ind_fifo = nb_slot_frame; + for(int i=0; i < num_ind_fifo; i++) { + UE->tx_resume_ind_fifo[i] = malloc(sizeof(*UE->tx_resume_ind_fifo[i])); + initNotifiedFIFO(UE->tx_resume_ind_fifo[i]); + } while (!oai_exit) { if (UE->lost_sync) { @@ -796,6 +823,11 @@ void *UE_thread(void *arg) { decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); // shift the frame index with all the frames we trashed meanwhile we perform the synch search decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER; + // wait for RRC to configure PHY parameters from SIB + if (get_softmodem_params()->sa) { + notifiedFIFO_elt_t *phy_config_res = pullNotifiedFIFO(&UE->phy_config_ind); + delNotifiedFIFO_elt(phy_config_res); + } } delNotifiedFIFO_elt(res); start_rx_stream=0; @@ -935,13 +967,19 @@ void *UE_thread(void *arg) { curMsgTx->UE = UE; pushTpool(&(get_nrUE_params()->Tpool), newElt); - // RX slot processing - UE_processing(&curMsg); + // RX slot processing. We launch and forget. + nr_phy_data_t phy_data = UE_dl_preprocessing(UE, &curMsg.proc); + newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing); + nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt); + curMsgRx->proc = curMsg.proc; + curMsgRx->UE = UE; + curMsgRx->phy_data = phy_data; + pushTpool(&(get_nrUE_params()->Tpool), newElt); if (curMsg.proc.decoded_frame_rx != -1) decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | curMsg.proc.decoded_frame_rx); else - decoded_frame_rx=-1; + decoded_frame_rx=-1; if (decoded_frame_rx>0 && decoded_frame_rx != curMsg.proc.frame_rx) LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n", diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index d429bf43ba..e227bc5fa2 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -21,6 +21,7 @@ #include "stddef.h" #include "platform_types.h" #include "fapi_nr_ue_constants.h" +#include "PHY/impl_defs_top.h" #include "PHY/impl_defs_nr.h" #include "common/utils/nr/nr_common.h" @@ -390,8 +391,6 @@ typedef struct { } fapi_nr_ul_config_request_pdu_t; typedef struct { - //uint16_t sfn; - //uint16_t slot; uint16_t sfn; uint16_t slot; uint8_t number_pdus; @@ -483,6 +482,7 @@ typedef struct { uint8_t nscid; uint16_t dlDmrsScramblingId; uint16_t pduBitmap; + uint32_t k1_feedback; } fapi_nr_dl_config_dlsch_pdu_rel15_t; typedef struct { diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 32e5647b69..72c0fbe070 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -523,7 +523,6 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES for (int j=0; j < 2; j++) { for (int i=0; iif_inst && ue->if_inst->dl_indication) { ue->if_inst->dl_indication(&dl_indication, NULL); - } else { - free(rx_ind); } return 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index db6a15213c..bf18d79189 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -77,7 +77,7 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid, nr_codeword_unscrambling(llr, size, q, Nid, n_RNTI); } -bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p) { +bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p, int b_size, uint8_t b[b_size]) { ldpcDecode_ue_t *rdata = (ldpcDecode_ue_t*) NotifiedFifoData(req); NR_DL_UE_HARQ_t *harq_process = rdata->harq_process; NR_UE_DLSCH_t *dlsch = (NR_UE_DLSCH_t *) rdata->dlsch; @@ -90,7 +90,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool bool decodeSuccess = (rdata->decodeIterations < (1+dlsch->max_ldpc_iterations)); if (decodeSuccess) { - memcpy(harq_process->b+rdata->offset, + memcpy(b+rdata->offset, harq_process->c[r], rdata->Kr_bytes - (harq_process->F>>3) -((harq_process->C>1)?3:0)); @@ -311,7 +311,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint32_t frame, uint16_t nb_symb_sch, uint8_t nr_slot_rx, - uint8_t harq_pid) { + uint8_t harq_pid, + int b_size, + uint8_t b[b_size]) { uint32_t A,E; uint32_t G; uint32_t ret,offset; @@ -493,7 +495,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, bool last = false; if (r == nbDecode - 1) last = true; - bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf); + bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf, b_size, b); delNotifiedFIFO_elt(req); if (stop) break; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 0c2149e997..d8c1010536 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -578,16 +578,14 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #endif nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1); + fapi_nr_rx_indication_t rx_ind = {0}; uint16_t number_pdus = 1; - nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, phy_data); - nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc,(void *)result); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, phy_data); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc,(void *)result, NULL); if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication, NULL); - else - free(rx_ind); // dl_indication would free(), so free() here if not called return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 0d6c334c45..42951d687e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -205,7 +205,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint32_t frame, uint16_t nb_symb_sch, uint8_t nr_slot_rx, - uint8_t harq_pid); + uint8_t harq_pid, + int b_size, + uint8_t b[b_size]); int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, NR_UE_ULSCH_t *ulsch, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index dc09714da9..811fa7711b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -119,8 +119,6 @@ typedef struct { uint32_t TBS; /// The payload + CRC size in bits uint32_t B; - /// Pointer to the payload - uint8_t *b; /// Pointers to transport block segments uint8_t **c; /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 9ba7233770..e5bc7bfbce 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -664,6 +664,10 @@ typedef struct { void *phy_sim_pdsch_rxdataF_comp; void *phy_sim_pdsch_dl_ch_estimates; void *phy_sim_pdsch_dl_ch_estimates_ext; + uint8_t *phy_sim_dlsch_b; + notifiedFIFO_t phy_config_ind; + notifiedFIFO_t *tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; + int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME]; } PHY_VARS_NR_UE; typedef struct nr_phy_data_tx_s { @@ -682,6 +686,7 @@ typedef struct nr_rxtx_thread_data_s { UE_nr_rxtx_proc_t proc; PHY_VARS_NR_UE *UE; int writeBlockSize; + nr_phy_data_t phy_data; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 1439c9fd01..f7128fd85a 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -98,17 +98,16 @@ typedef struct { */ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); -/*! \brief Scheduling for UE RX procedures in normal subframes. - @param ue Pointer to UE variables on which to act - @param proc Pointer to proc information - @param dlsch_parallel use multithreaded dlsch processing - @param phy_pdcch_config PDCCH Config for this slot - @param txFifo Result fifo if PDSCH is run in parallel -*/ -int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, +void send_slot_ind(notifiedFIFO_t *nf, int slot); + +void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); +void pdsch_processing(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_phy_data_t *phy_data); + int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type); void processSlotTX(void *arg); @@ -166,7 +165,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void *typeSpecific); + void *typeSpecific, + uint8_t *b); bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 255ecf17ca..64ec900b2a 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -544,8 +544,10 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config) { fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; - if(phy_config != NULL) + if(phy_config != NULL) { memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t)); + pushNotifiedFIFO(&PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->phy_config_ind, newNotifiedFIFO_elt(1,0,NULL,NULL)); + } return 0; } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f88b81ad52..9af0c591c1 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -118,7 +118,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void *typeSpecific){ + void *typeSpecific, + uint8_t *b){ NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; @@ -131,7 +132,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, if ((pdu_type != FAPI_NR_RX_PDU_TYPE_SSB) && dlsch0) { dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr]; trace_NRpdu(DIRECTION_DOWNLINK, - dl_harq0->b, + b, dlsch0->dlsch_config.TBS / 8, WS_C_RNTI, dlsch0->rnti, @@ -147,7 +148,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr]; rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->dlsch_config.harq_process_nbr; rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dl_harq0->ack; - rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dl_harq0->b; + rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = b; rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->dlsch_config.TBS / 8; } if(dlsch1) { @@ -696,6 +697,15 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, return 0; } +void send_slot_ind(notifiedFIFO_t *nf, int slot) { + if (nf) { + notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL); + int *msgData = (int *) NotifiedFifoData(newElt); + *msgData = slot; + pushNotifiedFIFO(nf, newElt); + } +} + bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], @@ -716,7 +726,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[1][harq_pid]; uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind)); + fapi_nr_rx_indication_t rx_ind = {0}; uint16_t number_pdus = 1; // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; @@ -739,8 +749,12 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active); // exit dlsch procedures as there are no active dlsch - if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE) + if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE) { + // don't wait anymore + const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame; + send_slot_ind(ue->tx_resume_ind_fifo[ack_nack_slot], proc->nr_slot_rx); return false; + } // start ldpc decode for CW 0 dl_harq0->G = nr_get_G(dlsch[0].dlsch_config.number_rbs, @@ -762,6 +776,16 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, start_meas(&ue->dlsch_decoding_stats); + // create memory to store decoder output + int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated + int num_rb = dlsch[0].dlsch_config.number_rbs; + if (num_rb != 273) { + a_segments = a_segments*num_rb; + a_segments = (a_segments/273)+1; + } + uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + __attribute__ ((aligned(32))) uint8_t p_b[dlsch_bytes]; + ret = nr_dlsch_decoding(ue, proc, gNB_id, @@ -772,7 +796,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, frame_rx, nb_symb_sch, nr_slot_rx, - harq_pid); + harq_pid, + dlsch_bytes, + p_b); LOG_T(PHY,"dlsch decoding, ret = %d\n", ret); @@ -799,8 +825,8 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, break; } - nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, NULL); - nr_fill_rx_indication(rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL); + nr_fill_rx_indication(&rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL, p_b); LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8); @@ -840,7 +866,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, frame_rx, nb_symb_sch, nr_slot_rx, - harq_pid); + harq_pid, + dlsch_bytes, + p_b); LOG_T(PHY,"CW dlsch decoding, ret1 = %d\n", ret1); stop_meas(&ue->dlsch_decoding_stats); @@ -857,6 +885,13 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ue->if_inst->dl_indication(&dl_indication, ul_time_alignment); } + // DLSCH decoding finished! don't wait anymore + const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame; + send_slot_ind(ue->tx_resume_ind_fifo[ack_nack_slot], proc->nr_slot_rx); + + if (ue->phy_sim_dlsch_b) + memcpy(ue->phy_sim_dlsch_b, p_b, dlsch_bytes); + if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer! /* Time Alignment procedure @@ -989,8 +1024,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, return dec; } - -int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, +void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) { @@ -1169,41 +1203,44 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF); } + LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); phy_pdcch_config->nb_search_space = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); +} + +void pdsch_processing(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_phy_data_t *phy_data) { + + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; + int gNB_id = proc->gNB_id; NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[0]; - if (dci_cnt > 0) { - - LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); - - if (dlsch->active) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN); - uint16_t nb_symb_sch = dlsch[0].dlsch_config.number_symbols; - uint16_t start_symb_sch = dlsch[0].dlsch_config.start_symbol; - - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - //to update from pdsch config - - for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ - nr_slot_fep(ue, - proc, - m, //to be updated from higher layer - rxdataF); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); - } - } else { - LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx); - } - #endif //NR_PDCCH_SCHED - start_meas(&ue->generic_stat); // do procedures for C-RNTI int ret_pdsch = 0; + + const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; + __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; if (dlsch[0].active) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN); + uint16_t nb_symb_sch = dlsch[0].dlsch_config.number_symbols; + uint16_t start_symb_sch = dlsch[0].dlsch_config.start_symbol; + + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); + //to update from pdsch config + + for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ + nr_slot_fep(ue, + proc, + m, //to be updated from higher layer + rxdataF); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); + uint8_t nb_re_dmrs; if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; @@ -1243,6 +1280,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if (ret_pdsch >= 0) nr_ue_dlsch_procedures(ue, proc, dlsch, llr); + else + // don't wait anymore + send_slot_ind(ue->tx_resume_ind_fifo[(proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame], proc->nr_slot_rx); stop_meas(&ue->dlsch_procedures_stat); if (cpumeas(CPUMEAS_GETSTATE)) { @@ -1333,7 +1373,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_slot_rx); UEscopeCopy(ue, commonRxdataF, rxdataF, sizeof(int32_t), ue->frame_parms.nb_antennas_rx, rxdataF_sz); - return (0); } diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index cdbe21465f..8b56ed0f4e 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -542,9 +542,17 @@ int main(int argc, char **argv) vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN); + int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated + int num_rb = dlsch0_ue->dlsch_config.number_rbs; + if (num_rb != 273) { + a_segments = a_segments*num_rb; + a_segments = (a_segments/273)+1; + } + uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + __attribute__ ((aligned(32))) uint8_t b[dlsch_bytes]; ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms, dlsch0_ue, harq_process, frame, nb_symb_sch, - slot,harq_pid); + slot,harq_pid,dlsch_bytes,b); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT); @@ -555,7 +563,7 @@ int main(int argc, char **argv) errors_bit = 0; for (i = 0; i < TBS; i++) { - estimated_output_bit[i] = (harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7); + estimated_output_bit[i] = (b[i / 8] & (1 << (i & 7))) >> (i & 7); test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments if (estimated_output_bit[i] != test_input_bit[i]) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index b2c9ac5a33..dce9817557 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -940,6 +940,13 @@ int main(int argc, char **argv) UE->phy_sim_pdsch_rxdataF_comp = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); UE->phy_sim_pdsch_dl_ch_estimates = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); + int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated + if (g_rbSize != 273) { + a_segments = a_segments*g_rbSize; + a_segments = (a_segments/273)+1; + } + uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + UE->phy_sim_dlsch_b = calloc(1, dlsch_bytes); for (SNR = snr0; SNR < snr1; SNR += .2) { @@ -1153,9 +1160,12 @@ int main(int argc, char **argv) nr_ue_dcireq(&dcireq); //to be replaced with function pointer later nr_ue_scheduled_response(&scheduled_response); - phy_procedures_nrUE_RX(UE, - &UE_proc, - &phy_data); + pbch_pdcch_processing(UE, + &UE_proc, + &phy_data); + pdsch_processing(UE, + &UE_proc, + &phy_data); //---------------------------------------------------------- //---------------------- count errors ---------------------- @@ -1198,7 +1208,7 @@ int main(int argc, char **argv) for (i = 0; i < TBS; i++) { - estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7); + estimated_output_bit[i] = (UE->phy_sim_dlsch_b[i/8] & (1 << (i & 7))) >> (i & 7); test_input_bit[i] = (gNB_dlsch->harq_process.b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments if (estimated_output_bit[i] != test_input_bit[i]) { @@ -1347,6 +1357,7 @@ int main(int argc, char **argv) free(UE->phy_sim_pdsch_rxdataF_comp); free(UE->phy_sim_pdsch_dl_ch_estimates); free(UE->phy_sim_pdsch_dl_ch_estimates_ext); + free(UE->phy_sim_dlsch_b); if (output_fd) fclose(output_fd); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ee67e8d52e..f1bcf65cc5 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -96,7 +96,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void *typeSpecific ) {} + void *typeSpecific, + uint8_t *b) {} int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index bd08153aff..8dfc05952d 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -701,6 +701,9 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, RA_config_t *ra = &mac->ra; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + if (mac->dl_config_request == NULL) // for SIB1 reception + mac->dl_config_request = calloc(NR_MAX_SLOTS_PER_FRAME, sizeof(*mac->dl_config_request)); + // TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc. if(mibP != NULL){ @@ -726,9 +729,21 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, } } LOG_I(NR_MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); - mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); + mac->ul_config_request = calloc(num_slots_ul, sizeof(*mac->ul_config_request)); for (int i=0; iul_config_request[i].mutex_ul_config), NULL); + + int num_slots_dl = nr_slots_per_frame[mac->mib->subCarrierSpacingCommon]; + if (cfg->cell_config.frame_duplex_type == TDD) { + num_slots_dl = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; + if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) { + num_slots_dl++; + } + } + LOG_I(NR_MAC, "Initializing dl_config_request. num_slots_dl = %d\n", num_slots_dl); + mac->dl_config_request = realloc(mac->dl_config_request, num_slots_dl*sizeof(*mac->dl_config_request)); + memset(mac->dl_config_request, 0, num_slots_dl*sizeof(fapi_nr_dl_config_request_t)); + // Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); if (!get_softmodem_params()->emulate_l1) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b1af5393a1..c91521a807 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -441,7 +441,7 @@ typedef struct { int first_ul_tx[NR_MAX_HARQ_PROCESSES]; //// FAPI-like interface message fapi_nr_ul_config_request_t *ul_config_request; - fapi_nr_dl_config_request_t dl_config_request; + fapi_nr_dl_config_request_t *dl_config_request; /// Interface module instances nr_ue_if_module_t *if_module; @@ -467,7 +467,7 @@ typedef struct { NR_PHY_meas_t phy_measurements; - dci_pdu_rel15_t def_dci_pdu_rel15[8]; + dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8]; // Defined for abstracted mode nr_downlink_indication_t dl_info; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9776003e3f..9a7f6084e0 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -441,9 +441,11 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, uint16_t rnti, int ss_type, uint64_t *dci_pdu, - dci_pdu_rel15_t *dci_pdu_rel15); + dci_pdu_rel15_t *dci_pdu_rel15, + int slot); fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot); +fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot); void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 45b6a56978..5aa4438af0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -172,7 +172,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP, current_UL_BWP, mac->cg, - &mac->def_dci_pdu_rel15[dci_format], + &mac->def_dci_pdu_rel15[dl_config->slot][dci_format], dci_format, NR_RNTI_TC, coreset, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 3978d52711..0ea9dc0f9d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -316,9 +316,6 @@ int8_t nr_ue_decode_mib(module_id_t module_id, mac->first_sync_frame = frame; } - mac->dl_config_request.sfn = frame; - mac->dl_config_request.slot = ssb_start_symbol/14; - if(get_softmodem_params()->phy_test) mac->state = UE_CONNECTED; else if(mac->state == UE_NOT_SYNC) @@ -419,15 +416,15 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format]; + dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][dci->dci_format]; LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); - int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15); + int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15, slot); if ((ret&1) == 1) return -1; else if (ret == 2) { dci->dci_format = NR_UL_DCI_FORMAT_0_0; - def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format]; + def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][dci->dci_format]; } int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); return ret_proc; @@ -445,7 +442,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr bool valid_ptrs_setup = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); RA_config_t *ra = &mac->ra; - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); uint8_t is_Msg3 = 0; NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; @@ -809,6 +806,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_0->accumulated_delta_PUCCH, dci->pucch_resource_indicator, 1+dci->pdsch_to_harq_feedback_timing_indicator.val); + + dlsch_config_pdu_1_0->k1_feedback = 1+dci->pdsch_to_harq_feedback_timing_indicator.val; LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); @@ -1071,7 +1070,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_1->n_front_load_symb); /* TCI */ - if (mac->dl_config_request.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1){ + if (dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1){ // 0 bit if higher layer parameter tci-PresentInDCI is not enabled // otherwise 3 bits as defined in Subclause 5.1.5 of [6, TS38.214] dlsch_config_pdu_1_1->tci_state = dci->transmission_configuration_indication.val; @@ -1106,6 +1105,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); dl_config->number_pdus = dl_config->number_pdus + 1; + + // send the ack/nack slot number to phy to indicate tx thread to wait for DLSCH decoding + dlsch_config_pdu_1_1->k1_feedback = feedback_ti; + /* TODO same calculation for MCS table as done in UL */ dlsch_config_pdu_1_1->mcs_table = (pdsch_Config->mcs_Table) ? (*pdsch_Config->mcs_Table + 1) : 0; dlsch_config_pdu_1_1->qamModOrder = nr_get_Qm_dl(dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table); @@ -1208,14 +1211,12 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, // FIXME k0 != 0 currently not taken into consideration current_harq->dl_frame = frame; current_harq->dl_slot = slot; - if (get_softmodem_params()->emulate_l1) { - int scs = get_softmodem_params()->numerology; - int slots_per_frame = nr_slots_per_frame[scs]; - slot += data_toul_fb; - if (slot >= slots_per_frame) { - frame = (frame + 1) % 1024; - slot %= slots_per_frame; - } + int scs = get_softmodem_params()->numerology; + int slots_per_frame = nr_slots_per_frame[scs]; + slot += data_toul_fb; + if (slot >= slots_per_frame) { + frame = (frame + 1) % 1024; + slot %= slots_per_frame; } LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n", @@ -1820,10 +1821,14 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, } number_harq_feedback++; - if (current_harq->ack_received) + if (current_harq->ack_received) { ack_data[code_word][dai_current - 1] = current_harq->ack; - else + current_harq->active = false; + current_harq->ack_received = false; + } else { + LOG_W(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); ack_data[code_word][dai_current - 1] = 0; + } dai[code_word][dai_current - 1] = dai_current; pucch->resource_indicator = current_harq->pucch_resource_indicator; @@ -1831,9 +1836,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, pucch->N_CCE = current_harq->N_CCE; pucch->delta_pucch = current_harq->delta_pucch; pucch->is_common = current_harq->is_common; - current_harq->active = false; - current_harq->ack_received = false; - LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid); + LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid); } } } @@ -2398,7 +2401,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, uint16_t rnti, int ss_type, uint64_t *dci_pdu, - dci_pdu_rel15_t *dci_pdu_rel15) + dci_pdu_rel15_t *dci_pdu_rel15, + int slot) { int pos = 0; @@ -2466,8 +2470,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, //switch to DCI_0_0 if (dci_pdu_rel15->format_indicator == 0) { - dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; - return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15); + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_UL_DCI_FORMAT_0_0]; + return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); } #ifdef DEBUG_EXTRACT_DCI LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); @@ -2657,8 +2661,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, //switch to DCI_0_0 if (dci_pdu_rel15->format_indicator == 0) { - dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; - return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15); + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_UL_DCI_FORMAT_0_0]; + return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); } if (dci_pdu_rel15->format_indicator == 0) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index b0d181f3da..5a0a8eb303 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -112,11 +112,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon; - //Check if request to access ul_config is for a UL slot - if (is_nr_UL_slot(tdd_config, slot, mac->frame_type) == 0) { - LOG_W(NR_MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__); - return NULL; - } + //Check if requested on the right slot + AssertFatal(is_nr_UL_slot(tdd_config, slot, mac->frame_type) != 0, "%s called at wrong slot %d\n", __func__, slot); // Calculate the index of the UL slot in mac->ul_config_request list. This is // based on the TDD pattern (slot configuration period) and number of UL+mixed @@ -127,16 +124,57 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl const int num_slots_ul = tdd_config ? (tdd_config->pattern1.nrofUplinkSlots + (tdd_config->pattern1.nrofUplinkSymbols != 0)) : n; int index = slot % num_slots_ul; - LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots_ul %d, index %d\n", + LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots %d, index %d\n", __FUNCTION__, tdd_config ? "TDD" : "FDD", num_slots_per_tdd, num_slots_ul, index); - if(!mac->ul_config_request) + if (mac->ul_config_request) return &mac->ul_config_request[index]; + else { + LOG_E(NR_MAC, "mac->ul_config_request not set\n"); return NULL; - return &mac->ul_config_request[index]; + } +} + +/* + * This function returns the DL config corresponding to a given DL slot + * from MAC instance . + */ +fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot) +{ + int index; + if (!mac->scc && !mac->scc_SIB) + index = 0; + else { + NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon; + + //Check if requested on the right slot + AssertFatal(is_nr_DL_slot(tdd_config, slot) != 0, "%s called at wrong slot %d\n", __func__, slot); + + // Calculate the index of the DL slot in mac->ul_config_request list. This is + // based on the TDD pattern (slot configuration period) and number of DL+mixed + // slots in the period. TS 38.213 Sec 11.1 + int mu = mac->current_UL_BWP.scs; + const int n = nr_slots_per_frame[mu]; + const int num_slots_per_tdd = tdd_config ? (n >> (7 - tdd_config->pattern1.dl_UL_TransmissionPeriodicity)) : n; + const int num_slots_dl = tdd_config ? (tdd_config->pattern1.nrofDownlinkSlots + (tdd_config->pattern1.nrofDownlinkSymbols != 0)) : n; + + index = slot % num_slots_dl; + LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots %d, index %d\n", + __FUNCTION__, + tdd_config ? "TDD" : "FDD", + num_slots_per_tdd, + num_slots_dl, + index); + } + + if (mac->dl_config_request) return &mac->dl_config_request[index]; + else { + LOG_E(NR_MAC, "mac->dl_config_request not set\n"); + return NULL; + } } void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format) @@ -895,7 +933,9 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) slot_t rx_slot = dl_info->slot; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, rx_slot); + dl_config->sfn = rx_frame; + dl_config->slot = rx_slot; nr_scheduled_response_t scheduled_response; nr_dcireq_t dcireq; @@ -909,11 +949,11 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) dcireq.slot = rx_slot; dcireq.dl_config_req.number_pdus = 0; nr_ue_dcireq(&dcireq); //to be replaced with function pointer later - mac->dl_config_request = dcireq.dl_config_req; + *dl_config = dcireq.dl_config_req; nr_schedule_csirs_reception(mac, rx_frame, rx_slot); nr_schedule_csi_for_im(mac, rx_frame, rx_slot); - dcireq.dl_config_req = mac->dl_config_request; + dcireq.dl_config_req = *dl_config; fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->phy_data); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { @@ -2177,7 +2217,7 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) { if (csi_measconfig->csi_IM_ResourceToAddModList == NULL) return; - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); NR_CSI_IM_Resource_t *imcsi; int period, offset; @@ -2231,7 +2271,7 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) { if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList == NULL) return; - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); NR_NZP_CSI_RS_Resource_t *nzpcsi; int period, offset; NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; @@ -2553,9 +2593,6 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); nr_scheduled_response_t scheduled_response; - int frame_s,slot_s; - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; uint8_t scs_ssb = get_softmodem_params()->numerology; uint16_t ssb_offset_point_a = (ssb_start_subcarrier - ssb_subcarrier_offset)/12; @@ -2573,17 +2610,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame ssb_offset_point_a); - if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); - if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); - - fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); - fill_searchSpaceZero(mac->search_space_zero, &mac->type0_PDCCH_CSS_config); - rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; - rel15->num_dci_options = 1; - rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; - config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1); - fill_dci_search_candidates(mac->search_space_zero, rel15, -1, -1); - + int frame_s,slot_s; if(mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern == 1){ // same frame as ssb if ((mac->type0_PDCCH_CSS_config.frame & 0x1) == mac->type0_PDCCH_CSS_config.sfn_c) @@ -2596,6 +2623,20 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, frame_s = 0; // same frame as ssb slot_s = mac->type0_PDCCH_CSS_config.n_c; } + fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request[0]; // Take the first dl_config_request for SIB1 + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + + if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); + if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); + + fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); + fill_searchSpaceZero(mac->search_space_zero, &mac->type0_PDCCH_CSS_config); + rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + rel15->num_dci_options = 1; + rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1); + fill_dci_search_candidates(mac->search_space_zero, rel15, -1, -1); + LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus); fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, phy_data); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 5ddd59fcc1..a950d746db 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -66,6 +66,7 @@ queue_t nr_dl_tti_req_queue; queue_t nr_tx_req_queue; queue_t nr_ul_dci_req_queue; queue_t nr_ul_tti_req_queue; +pthread_mutex_t mac_IF_mutex; void nrue_init_standalone_socket(int tx_port, int rx_port) { @@ -692,7 +693,6 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, slot = dl_tti_request->Slot; LOG_D(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot); copy_dl_tti_req_to_dl_info(&mac->dl_info, dl_tti_request); - free_and_zero(dl_tti_request); } /* This checks if the previously recevied DCI matches our current RNTI value. The assumption is that if the DCI matches our RNTI, then the @@ -711,14 +711,12 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, else { LOG_D(NR_MAC, "Unexpected tx_data_req\n"); } - free_and_zero(tx_data_request); } else if (ul_dci_request) { frame = ul_dci_request->SFN; slot = ul_dci_request->Slot; LOG_D(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot); copy_ul_dci_data_req_to_dl_info(&mac->dl_info, ul_dci_request); - free_and_zero(ul_dci_request); } else if (ul_tti_request) { frame = ul_tti_request->SFN; @@ -735,7 +733,10 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, NR_UL_TIME_ALIGNMENT_t ul_time_alignment; memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); - fill_dci_from_dl_config(&mac->dl_info, &mac->dl_config_request); + if (dl_tti_request || tx_data_request || ul_dci_request) { + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); + fill_dci_from_dl_config(&mac->dl_info, dl_config); + } nr_ue_dl_scheduler(&mac->dl_info); nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); @@ -1116,6 +1117,9 @@ void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nac int nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { + + pthread_mutex_lock(&mac_IF_mutex); + module_id_t module_id = ul_info->module_id; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -1125,15 +1129,19 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info) NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon; if (mac->phy_config_request_sent && is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type)) nr_ue_ul_scheduler(ul_info); + + pthread_mutex_unlock(&mac_IF_mutex); + return 0; } int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ + pthread_mutex_lock(&mac_IF_mutex); uint32_t ret_mask = 0x0; module_id_t module_id = dl_info->module_id; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, dl_info->slot); if ((!dl_info->dci_ind && !dl_info->rx_ind)) { // UL indication to schedule DCI reception @@ -1160,7 +1168,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n"); continue; } - dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format]; + dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dl_info->slot][dci_index->dci_format]; g_harq_pid = def_dci_pdu_rel15->harq_pid; LOG_T(NR_MAC, "Setting harq_pid = %d and dci_index = %d (based on format)\n", g_harq_pid, dci_index->dci_format); @@ -1222,10 +1230,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ break; } } - free(dl_info->rx_ind); dl_info->rx_ind = NULL; } } + pthread_mutex_unlock(&mac_IF_mutex); return 0; } @@ -1247,6 +1255,7 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id){ nr_ue_if_module_inst[module_id]->dl_indication = nr_ue_dl_indication; nr_ue_if_module_inst[module_id]->ul_indication = nr_ue_ul_indication; } + pthread_mutex_init(&mac_IF_mutex, NULL); return nr_ue_if_module_inst[module_id]; } @@ -1263,8 +1272,8 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) { fapi_nr_dl_config_request_t *dl_config = &dcireq->dl_config_req; NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0); - dl_config->sfn = UE_mac->dl_config_request.sfn; - dl_config->slot = UE_mac->dl_config_request.slot; + dl_config->sfn = dcireq->frame; + dl_config->slot = dcireq->slot; LOG_T(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot); From 1d9a4a42e7a58d6a75fd12f4900cf2f66568b20a Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 22 Nov 2022 10:42:28 -0500 Subject: [PATCH 05/36] Corrected thread pool help message --- executables/softmodem-common.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index d9aedd768c..cf6ef56ea4 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -38,11 +38,12 @@ extern "C" #endif /* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" -#define CONFIG_HLP_SPLIT73 "Split 7.3 (below rate matching) option: ::" +#define CONFIG_HLP_SPLIT73 "Split 7.3 (below rate matching) option: ::\n" #define CONFIG_HLP_TPOOL "Thread pool configuration: \n\ - default no pool (runs in calling thread),\n\ list of cores, comma separated (negative value is no core affinity)\n\ - example: -1,3 launches two working threads one floating, the second set on core 3" + example: -1,3 launches two working threads one floating, the second set on core 3\n\ + default 8 floating threads\n\ + use N for no pool (runs in calling thread) recommended with rfsim.\n" #define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" #define CONFIG_HLP_CALUER "set UE RX calibration\n" #define CONFIG_HLP_CALUERM "" From f3be849904df24f0644cb8ce7fc3d8d72169c7ed Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 28 Nov 2022 16:51:07 -0500 Subject: [PATCH 06/36] Delete job data when no response FIFO --- common/utils/threadPool/thread-pool.c | 2 ++ common/utils/threadPool/thread-pool.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index b351a667b5..f0f4769faf 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -98,6 +98,8 @@ void *one_thread(void *arg) { myThread->runningOnKey=-1; mutexunlock(tp->incomingFifo.lockF); } + else + delNotifiedFIFO_elt(elt); } while (!myThread->terminate); return NULL; } diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 0c544e5b0f..b06671c728 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -279,6 +279,8 @@ static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { if (msg->reponseFifo) pushNotifiedFIFO(msg->reponseFifo, msg); + else + delNotifiedFIFO_elt(msg); } } From a03864ee8c0a58a518ad527a6a37ba63b27989d0 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 30 Nov 2022 12:47:24 -0500 Subject: [PATCH 07/36] Fix printing help message --- executables/nr-ue.c | 4 +-- executables/nr-uesoftmodem.c | 57 +++++++++++---------------------- executables/nr-uesoftmodem.h | 61 +++++++++++++++++------------------- openair1/PHY/defs_nr_UE.h | 3 -- 4 files changed, 50 insertions(+), 75 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 3d468ad64b..c0021ee337 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -450,7 +450,7 @@ static void UE_synch(void *arg) { break; */ case pbch: - LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + LOG_I(PHY, "[UE thread Synch] Running Initial Synch \n"); uint64_t dl_carrier, ul_carrier; nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier); @@ -708,7 +708,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { - LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { // Resynchonize by slot (will work with numerology 1 only) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 3c884ea390..8bf0f6efec 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -264,7 +264,6 @@ static void get_options(void) { paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ; int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); config_get(cmdline_params,numparams,NULL); - config_process_cmdline( cmdline_params,numparams,NULL); if (vcdflag > 0) ouput_vcd = 1; @@ -272,38 +271,7 @@ static void get_options(void) { // set PHY vars from command line void set_options(int CC_id, PHY_VARS_NR_UE *UE){ - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; - paramdef_t cmdline_params[] = CMDLINE_NRUE_PHYPARAMS_DESC ; - int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); - - UE->mode = normal_txrx; - - config_get(cmdline_params,numparams,NULL); - - int pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRX_OPT); - if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue; - - pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXMED_OPT); - if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_med; - - pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXBYP_OPT); - if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_byp; - - pindex = config_paramidx_fromname(cmdline_params,numparams, DBGPRACH_OPT); - if (cmdline_params[pindex].uptr) - if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = debug_prach; - - pindex = config_paramidx_fromname(cmdline_params,numparams,NOL2CONNECT_OPT ); - if (cmdline_params[pindex].uptr) - if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = no_L2_connect; - - pindex = config_paramidx_fromname(cmdline_params,numparams,CALIBPRACH_OPT ); - if (cmdline_params[pindex].uptr) - if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = calib_prach_tx; - - pindex = config_paramidx_fromname(cmdline_params,numparams,DUMPFRAME_OPT ); - if ((cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) - UE->mode = rx_dump_frame; + NR_DL_FRAME_PARMS *fp = &UE->frame_parms; // Init power variables tx_max_power[CC_id] = tx_max_power[0]; @@ -316,9 +284,18 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ UE->tx_power_max_dBm = tx_max_power[CC_id]; UE->rf_map.card = card_offset; UE->rf_map.chain = CC_id + chain_offset; + UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations; + UE->UE_scan_carrier = nrUE_params.UE_scan_carrier; + UE->UE_fo_compensation = nrUE_params.UE_fo_compensation; + UE->if_freq = nrUE_params.if_freq; + UE->if_freq_off = nrUE_params.if_freq_off; + UE->chest_freq = nrUE_params.chest_freq; + UE->chest_time = nrUE_params.chest_time; + UE->no_timing_correction = nrUE_params.no_timing_correction; + UE->timing_advance = nrUE_params.timing_advance; - LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d\n", - UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq); + LOG_I(PHY,"Set UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d, chest-time %d\n", + UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time); // Set FP variables @@ -327,10 +304,14 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type); } - LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier); + fp->nb_antennas_rx = nrUE_params.nb_antennas_rx; + fp->nb_antennas_tx = nrUE_params.nb_antennas_tx; + fp->threequarter_fs = nrUE_params.threequarter_fs; + fp->N_RB_DL = nrUE_params.N_RB_DL; + fp->ssb_start_subcarrier = nrUE_params.ssb_start_subcarrier; + fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor; - fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor; - UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations; + LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier); } diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 60b9d91f72..99c97eae28 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -36,54 +36,51 @@ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \ - {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .u8ptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \ + {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \ {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \ - {"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0} \ -} -// clang-format on - -/*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters defining UE running mode */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*------------------------------------------------------------------------------------------------------------------------------------------*/ -// clang-format off -#define CMDLINE_NRUE_PHYPARAMS_DESC { \ - { CALIBRX_OPT, CONFIG_HLP_CALUER, 0, .iptr=&rx_input_level_dBm, .defintval=0, TYPE_INT, 0}, \ - { CALIBRXMED_OPT, CONFIG_HLP_CALUERM, 0, .iptr=&rx_input_level_dBm, .defintval=0, TYPE_INT, 0}, \ - { CALIBRXBYP_OPT, CONFIG_HLP_CALUERB, 0, .iptr=&rx_input_level_dBm, .defintval=0, TYPE_INT, 0}, \ - { DBGPRACH_OPT, CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=1, TYPE_INT, 0}, \ - { NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=1, TYPE_INT, 0}, \ - { CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=1, TYPE_INT, 0}, \ - { DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, .iptr=&dumpframe, .defintval=0, TYPE_INT, 0}, \ + {"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \ {"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \ {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \ {"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&(tx_gain[0][0]), .defdblval=0, TYPE_DOUBLE, 0}, \ - {"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, .u8ptr=&(fp->nb_antennas_rx), .defuintval=1, TYPE_UINT8, 0}, \ - {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, .u8ptr=&(fp->nb_antennas_tx), .defuintval=1, TYPE_UINT8, 0}, \ - {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, .iptr=&(UE->UE_scan_carrier), .defintval=0, TYPE_INT, 0}, \ - {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, .iptr=&(UE->UE_fo_compensation), .defintval=0, TYPE_INT, 0}, \ + {"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, .iptr=&(nrUE_params.nb_antennas_rx), .defuintval=1, TYPE_UINT8, 0}, \ + {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, .iptr=&(nrUE_params.nb_antennas_tx), .defuintval=1, TYPE_UINT8, 0}, \ + {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_scan_carrier), .defintval=0, TYPE_INT, 0}, \ + {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_fo_compensation), .defintval=0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, .iptr=&(tx_max_power[0]), .defintval=90, TYPE_INT, 0}, \ - {"A" , CONFIG_HLP_TADV, 0, .iptr=&(UE->timing_advance), .defintval=0, TYPE_INT, 0}, \ - {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .u8ptr=&(fp->threequarter_fs), .defintval=0, TYPE_UINT8, 0}, \ - {"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(fp->N_RB_DL), .defintval=106, TYPE_UINT, 0}, \ - {"ssb", CONFIG_HLP_SSC, 0, .u16ptr=&(fp->ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \ + {"A" , CONFIG_HLP_TADV, 0, .iptr=&(nrUE_params.timing_advance), .defintval=0, TYPE_INT, 0}, \ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&(nrUE_params.threequarter_fs), .defintval=0, TYPE_UINT8, 0}, \ + {"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(nrUE_params.N_RB_DL), .defintval=106, TYPE_UINT, 0}, \ + {"ssb", CONFIG_HLP_SSC, 0, .iptr=&(nrUE_params.ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, .iptr=&tddflag, .defintval=0, TYPE_INT, 0}, \ - {"if_freq" , CONFIG_HLP_IF_FREQ, 0, .u64ptr=&(UE->if_freq), .defuintval=0, TYPE_UINT64, 0}, \ - {"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, .iptr=&(UE->if_freq_off), .defuintval=0, TYPE_INT, 0}, \ - {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&(UE->chest_freq), .defintval=0, TYPE_INT, 0}, \ - {"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(UE->chest_time), .defintval=0, TYPE_INT, 0}, \ - {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(UE->no_timing_correction), .defintval=0, TYPE_INT, 0}, \ + {"if_freq" , CONFIG_HLP_IF_FREQ, 0, .u64ptr=&(nrUE_params.if_freq), .defuintval=0, TYPE_UINT64, 0}, \ + {"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, .iptr=&(nrUE_params.if_freq_off), .defuintval=0, TYPE_INT, 0}, \ + {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&(nrUE_params.chest_freq), .defintval=0, TYPE_INT, 0}, \ + {"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(nrUE_params.chest_time), .defintval=0, TYPE_INT, 0}, \ + {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \ } // clang-format on typedef struct { uint64_t optmask; //mask to store boolean config options uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol - uint8_t max_ldpc_iterations; // number of maximum LDPC iterations + int max_ldpc_iterations; // number of maximum LDPC iterations tpool_t Tpool; // thread pool + int UE_scan_carrier; + int UE_fo_compensation; + int timing_advance; + uint64_t if_freq; + int if_freq_off; + int chest_freq; + int chest_time; + int no_timing_correction; + int nb_antennas_rx; + int nb_antennas_tx; + int threequarter_fs; + int N_RB_DL; + int ssb_start_subcarrier; } nrUE_params_t; extern uint64_t get_nrUE_optmask(void); extern uint64_t set_nrUE_optmask(uint64_t bitmask); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index e5bc7bfbce..15ae6a466a 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -385,9 +385,6 @@ typedef struct { uint8_t CC_id; /// \brief Mapping of CC_id antennas to cards openair0_rf_map rf_map; - //uint8_t local_flag; - /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) - runmode_t mode; /// \brief Indicator that UE should perform band scanning int UE_scan; /// \brief Indicator that UE should perform coarse scanning around carrier From f1841639f577ebef2497c5fa650a1e943c632605 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Sun, 22 Jan 2023 21:51:52 +0530 Subject: [PATCH 08/36] Updated documentation --- doc/nr-ue-design.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nr-ue-design.md b/doc/nr-ue-design.md index 32abe6bd80..6b8bd89bf1 100644 --- a/doc/nr-ue-design.md +++ b/doc/nr-ue-design.md @@ -27,8 +27,8 @@ graph TD graph TD E[syncInFrame
--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"] F --> |Tpool thread| G["processSlotTX (slot n+4)
--PUSCH encode
--PUCCH encode
--trx_write_func"] - F --> |UE_thread| H["UE_processing (slot n)
--PDCCH decode
--PDSCH decode"] - G --> |Tpool thread| I(Merge) - H --> |UE_thread| I(Merge) + F --> |Tpool thread| J["UE_processing (slot n)
--PDCCH decode
--PDSCH decode"] + F --> |UE_thread| I(Merge) + G --> |Tpool thread| I I --> |Go to next slot
UE_thread| F ``` From 7d23ec27b5b2ca2ef31d13b38a01111979380985 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 3 Feb 2023 09:33:39 -0500 Subject: [PATCH 09/36] Changed NR_UE_CAPABILITY_SLOT_RX_TO_TX to 3 Tested with X300 and there was no real-time problems. Could get the same throughput as when NR_UE_CAPABILITY_SLOT_RX_TO_TX is 4. --- openair1/PHY/impl_defs_top.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 6afbd1bf2b..679fd34a49 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -270,7 +270,7 @@ /* FFS_NR_TODO it defines ue capability which is the number of slots */ /* - between reception of pdsch and tarnsmission of its acknowlegment */ /* - between reception of un uplink grant and its related transmission */ -#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (4) +#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3) #ifndef NO_RAT_NR #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */ From 5c6778be0c54b4f09add1800fbbd3194856b97ca Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 7 Feb 2023 10:49:39 -0500 Subject: [PATCH 10/36] Fixed Harq stats print --- openair1/PHY/defs_nr_UE.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 15ae6a466a..9301f3fb9d 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -652,7 +652,7 @@ typedef struct { SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; #endif int dl_errors; - int dl_stats[8]; + _Atomic(int) dl_stats[16]; void* scopeData; // Pointers to hold PDSCH data only for phy simulators void *phy_sim_rxdataF; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 9af0c591c1..0a9a996017 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1158,7 +1158,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, p += snprintf(p, end - p, "Harq round stats for Downlink: %d", ue->dl_stats[0]); for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round) p += snprintf(p, end - p,"/%d", ue->dl_stats[round]); - LOG_I(NR_PHY,"%s/0\n", output); + LOG_I(NR_PHY,"%s\n", output); LOG_I(NR_PHY,"============================================\n"); } From e45a051c80d76eeec721ac007bc67a21a2f0b479 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Feb 2023 10:17:59 -0500 Subject: [PATCH 11/36] Perform CRC check for whole TB --- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 37 ++++++++++--------- openair1/PHY/defs_nr_UE.h | 1 + 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index bf18d79189..470164817b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -51,15 +51,8 @@ #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 //#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX -static uint64_t nb_total_decod =0; -static uint64_t nb_error_decod =0; - static extended_kpi_ue kpiStructure = {0}; -notifiedFIFO_t freeBlocks_dl; -notifiedFIFO_elt_t *msgToPush_dl; -int nbDlProcessing =0; - extended_kpi_ue* getKPIUE(void) { return &kpiStructure; } @@ -77,7 +70,7 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid, nr_codeword_unscrambling(llr, size, q, Nid, n_RNTI); } -bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p, int b_size, uint8_t b[b_size]) { +bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p, int b_size, uint8_t b[b_size], int *num_seg_ok, UE_nr_rxtx_proc_t *proc) { ldpcDecode_ue_t *rdata = (ldpcDecode_ue_t*) NotifiedFifoData(req); NR_DL_UE_HARQ_t *harq_process = rdata->harq_process; NR_UE_DLSCH_t *dlsch = (NR_UE_DLSCH_t *) rdata->dlsch; @@ -94,6 +87,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool harq_process->c[r], rdata->Kr_bytes - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + (*num_seg_ok)++; } else { if ( !last ) { int nb=abortTpoolJob(&get_nrUE_params()->Tpool, req->key); @@ -111,7 +105,20 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool kpiStructure.dl_mcs = dlsch->dlsch_config.mcs; kpiStructure.nofRBs = dlsch->dlsch_config.number_rbs; - if (decodeSuccess) { + if (*num_seg_ok == harq_process->C) { + if (harq_process->C > 1) { + /* check global CRC */ + int A = dlsch->dlsch_config.TBS; + int crc_length = A > 3824 ? 3 : 2; + int crc_type = A > 3824 ? CRC24_A : CRC16; + if (!check_crc(b, A + crc_length*8, 0 /* F - unused */, crc_type)) { + harq_process->ack = 0; + dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1; + LOG_E(PHY, " Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n", proc->frame_rx, proc->nr_slot_rx, harq_process->C); + LOG_D(PHY, "DLSCH received nok \n"); + return true; //stop + } + } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", // phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); harq_process->status = SCH_IDLE; @@ -277,7 +284,7 @@ void nr_processDLSegment(void* arg) { if (no_iteration_ldpc > dlsch->max_ldpc_iterations) no_iteration_ldpc = dlsch->max_ldpc_iterations; } else { - LOG_D(PHY,"CRC NOT OK\n"); + LOG_I(PHY,"%d.%d CRC NOT OK\n",rdata->proc->frame_rx,rdata->proc->nr_slot_rx); no_iteration_ldpc = dlsch->max_ldpc_iterations + 1; } @@ -287,12 +294,6 @@ void nr_processDLSegment(void* arg) { rdata->decodeIterations = no_iteration_ldpc; - nb_total_decod++; - - if (no_iteration_ldpc > dlsch->max_ldpc_iterations) { - nb_error_decod++; - } - for (int m=0; m < Kr>>3; m ++) { harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; } @@ -478,6 +479,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, rdata->offset = offset; rdata->dlsch = dlsch; rdata->dlsch_id = 0; + rdata->proc = proc; reset_meas(&rdata->ts_deinterleave); reset_meas(&rdata->ts_rate_unmatch); reset_meas(&rdata->ts_ldpc_decode); @@ -488,6 +490,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); ////////////////////////////////////////////////////////////////////////////////////////// } + int num_seg_ok = 0; for (r=0; rTpool); if (req == NULL) @@ -495,7 +498,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, bool last = false; if (r == nbDecode - 1) last = true; - bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf, b_size, b); + bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf, b_size, b, &num_seg_ok, proc); delNotifiedFIFO_elt(req); if (stop) break; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 9301f3fb9d..2276def8cd 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -709,6 +709,7 @@ typedef struct LDPCDecode_ue_s { time_stats_t ts_deinterleave; time_stats_t ts_rate_unmatch; time_stats_t ts_ldpc_decode; + UE_nr_rxtx_proc_t *proc; } ldpcDecode_ue_t; #include "SIMULATION/ETH_TRANSPORT/defs.h" From 9e4d52293771f2b10c5f7c48c8eb2d0c7fc31c33 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Mar 2023 15:31:58 -0500 Subject: [PATCH 12/36] Make kpi variables atomic Mutex for phy scope: Repeating this change again. My earlier change in commit 06ef311975d was erased by someone during merge of QT scope. --- CMakeLists.txt | 4 +++- openair1/PHY/TOOLS/nr_phy_qt_scope.cpp | 1 + openair1/PHY/TOOLS/nr_phy_scope.c | 4 +--- openair1/PHY/TOOLS/phy_scope_interface.c | 18 ++++++++++++++---- openair1/PHY/TOOLS/phy_scope_interface.h | 17 ++++++++++++----- openair1/PHY/defs_nr_UE.h | 4 ++++ 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 691cb4aaa8..113197f673 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2016,7 +2016,9 @@ add_boolean_option(ENABLE_NRQTSCOPE OFF "Build the Qt-Scope" OFF) if (ENABLE_NRQTSCOPE) find_package(Qt5 REQUIRED COMPONENTS Widgets Charts) message ("Qt5 Widgets and Charts found for nrqtscope") - set(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.cpp) + set(QTSCOPE_SOURCE_NR + ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.cpp + ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c) # Creates rules for calling the Meta-Object Compiler (moc) on the given source files qt5_wrap_cpp(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.h) add_library(nrqtscope MODULE ${QTSCOPE_SOURCE_NR}) diff --git a/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp b/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp index fecfefd131..f1da2dce36 100644 --- a/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp +++ b/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp @@ -1147,6 +1147,7 @@ void nrUEinitQtScope(PHY_VARS_NR_UE *ue) scope->liveData = calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems); scope->copyData = UEcopyData; + UEcopyDataMutexInit(); ue->scopeData = scope; diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 206ed490e5..17141c7158 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -1137,8 +1137,6 @@ static void *nrUEscopeThread(void *arg) { } #endif -pthread_mutex_t UEcopyDataMutex; - STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue) { AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),""); @@ -1148,8 +1146,8 @@ STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue) #ifndef WEBSRVSCOPE pthread_t forms_thread; threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW); + UEcopyDataMutexInit(); #endif - pthread_mutex_init(&UEcopyDataMutex, NULL); } void nrscope_autoinit(void *dataptr) { diff --git a/openair1/PHY/TOOLS/phy_scope_interface.c b/openair1/PHY/TOOLS/phy_scope_interface.c index b567e96b03..6dfcc36c75 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.c +++ b/openair1/PHY/TOOLS/phy_scope_interface.c @@ -35,9 +35,16 @@ #include "phy_scope_interface.h" #define SOFTSCOPE_ENDFUNC_IDX 0 +#define THREAD_MEM 4 static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}}; +pthread_mutex_t UEcopyDataMutex; + +int UEcopyDataMutexInit(void) { + return pthread_mutex_init(&UEcopyDataMutex, NULL); +} + int load_softscope(char *exectype, void *initarg) { char libname[64]; sprintf(libname,"%.10sscope",exectype); @@ -56,16 +63,19 @@ int end_forms(void) { void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) { // Local static copy of the scope data bufs // The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input) - // Index of "2" could be set to the number of Rx threads + 1 - static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0}; + // Index of THREAD_MEM could be set to the number of Rx threads + 1. Rx slots could run asynchronous to each other. + // THREAD_MEM = 4 slot process running in parallel is an assumption. THREAD_MEM can be increased if scope appears inconsistent. + static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][THREAD_MEM] = {0}; static int copyDataBufsIdx[UEdataTypeNumberOfItems] = {0}; scopeData_t *tmp = (scopeData_t *)ue->scopeData; if (tmp) { - // Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex - int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0; + // Begin of critical zone between UE Rx threads that might copy new data at the same time: + pthread_mutex_lock(&UEcopyDataMutex); + int newCopyDataIdx = (copyDataBufsIdx[type]<(THREAD_MEM-1))?copyDataBufsIdx[type]+1:0; copyDataBufsIdx[type] = newCopyDataIdx; + pthread_mutex_unlock(&UEcopyDataMutex); // End of critical zone between UE Rx threads // New data will be copied in a different buffer than the live one diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h index b6d4480762..19395891ad 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.h +++ b/openair1/PHY/TOOLS/phy_scope_interface.h @@ -31,15 +31,21 @@ */ #ifndef __PHY_SCOPE_INTERFACE_H__ #define __PHY_SCOPE_INTERFACE_H__ + +#ifdef __cplusplus +#include +#define _Atomic(X) std::atomic< X > +#endif + #include #include typedef struct { - uint32_t nb_total; - uint32_t nb_nack; - uint32_t blockSize; // block size, to be used for throughput calculation - uint16_t nofRBs; - uint8_t dl_mcs; + _Atomic(uint32_t) nb_total; + _Atomic(uint32_t) nb_nack; + _Atomic(uint32_t) blockSize; // block size, to be used for throughput calculation + _Atomic(uint16_t) nofRBs; + _Atomic(uint8_t ) dl_mcs; } extended_kpi_ue; typedef struct { @@ -80,6 +86,7 @@ typedef struct { int load_softscope(char *exectype, void *initarg); int end_forms(void) ; +int UEcopyDataMutexInit(void); void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz); #define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 2276def8cd..ac5379fe42 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -32,6 +32,10 @@ #ifndef __PHY_DEFS_NR_UE__H__ #define __PHY_DEFS_NR_UE__H__ +#ifdef __cplusplus +#include +#define _Atomic(X) std::atomic< X > +#endif #include "defs_nr_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" From 0004626ac7ff46b68664b8e243948ce93273c767 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Mar 2023 19:24:57 -0500 Subject: [PATCH 13/36] Fix bug in QT scope The UE copies scope data not in a single buffer to avoid overwiring in case of multiple slots processing in parallel. But the scope upates data from single buffer thats assigned during selection. A getPlotValue() method is created to update the data pointer on every timerEvent. --- openair1/PHY/TOOLS/nr_phy_qt_scope.cpp | 119 +++++++++++++++++++++++-- openair1/PHY/TOOLS/nr_phy_qt_scope.h | 61 ++++++++++++- 2 files changed, 170 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp b/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp index f1da2dce36..5aecc3906b 100644 --- a/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp +++ b/openair1/PHY/TOOLS/nr_phy_qt_scope.cpp @@ -317,6 +317,34 @@ void CIRPlot::timerEvent(QTimerEvent *event) this->series->replace(points); } +void CIRPlotUE::timerEvent(QTimerEvent *event) +{ + if (!this->isVisible()) + return; + + scopeGraphData_t *data = this->valueProvider->getPlotValue(); + if (data) { + this->data = (complex16 *)(data + 1); + this->len = data->lineSz; + QVector points(this->len); + float maxY = this->axisY->max(); + + for (int i = 0; i < this->len / 2; i++) { + float value = SquaredNorm(this->data[i + this->len / 2]); + points[i] = QPointF(i - this->len / 2, value); + maxY = std::max(maxY, value); + } + for (int i = 0; i < this->len / 2; i++) { + float value = SquaredNorm(this->data[i]); + points[i + this->len / 2] = QPointF(i, value); + maxY = std::max(maxY, value); + } + + this->axisY->setMax(maxY); + this->series->replace(points); + } +} + LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len) { this->legend()->hide(); @@ -361,6 +389,28 @@ void LLRPlot::timerEvent(QTimerEvent *event) this->series->replace(points); } +void LLRPlotUE::timerEvent(QTimerEvent *event) +{ + if (!this->isVisible()) + return; + + scopeGraphData_t *data = this->valueProvider->getPlotValue(); + if (data) { + this->data = (int16_t *)(data + 1); + this->len = data->lineSz; + QVector points(this->len); + int maxY = this->axisY->max(); + + for (int i = 0; i < this->len; i++) { + points[i] = QPointF(i, this->data[i]); + maxY = std::max(maxY, abs(this->data[i])); + } + + this->axisY->setRange(-maxY, maxY); + this->series->replace(points); + } +} + IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len) { this->legend()->hide(); @@ -407,6 +457,32 @@ void IQPlot::timerEvent(QTimerEvent *event) this->series->replace(points); } +void IQPlotUE::timerEvent(QTimerEvent *event) +{ + if (!this->isVisible()) + return; + + scopeGraphData_t *data = this->valueProvider->getPlotValue(); + if (data) { + this->data = (complex16 *)(data + 1); + this->len = data->lineSz; + QVector points(this->len); + int maxX = this->axisX->max(); + int maxY = this->axisY->max(); + + for (int i = 0; i < this->len; i++) { + points[i] = QPointF(this->data[i].r, this->data[i].i); + + maxX = std::max(maxX, abs(this->data[i].r)); + maxY = std::max(maxY, abs(this->data[i].i)); + } + + this->axisX->setRange(-maxX, maxX); + this->axisY->setRange(-maxY, maxY); + this->series->replace(points); + } +} + KPIPlot::KPIPlot(ValueProvider *valueProvider, float *limits) : valueProvider(valueProvider), limits(limits) { this->series = new QLineSeries(); @@ -815,11 +891,42 @@ float PainterWidgetUE::getValue() case PlotTypeUE::timingAdvance: return (float)this->ue->timing_advance; + default: return 0; } } +scopeGraphData_t *PainterWidgetUE::getPlotValue() +{ + scopeData_t *scope = (scopeData_t *)this->ue->scopeData; + scopeGraphData_t **data = (scopeGraphData_t **)scope->liveData; + switch (this->plotType) { + case PlotTypeUE::CIR: + return data[pbchDlChEstimateTime]; + + case PlotTypeUE::pbchLLR: + return data[pbchLlr]; + case PlotTypeUE::pbchIQ: + return data[pbchRxdataF_comp]; + + case PlotTypeUE::pdcchLLR: + return data[pdcchLlr]; + + case PlotTypeUE::pdcchIQ: + return data[pdcchRxdataF_comp]; + + case PlotTypeUE::pdschLLR: + return data[pdschLlr]; + + case PlotTypeUE::pdschIQ: + return data[pdschRxdataF_comp]; + + default: + return nullptr; + } +} + /* @UE Class: this function is called when a resize event is detected, then the widget will be adjusted accordignly. */ void PainterWidgetUE::resizeEvent(QResizeEvent *event) { @@ -890,7 +997,7 @@ void PainterWidgetUE::makeConnections(int type) this->comboBox->setCurrentIndex(static_cast(PlotTypeUE::empty)); break; } - newChart = new LLRPlot((int16_t *)(data[pbchLlr] + 1), data[pbchLlr]->lineSz); + newChart = new LLRPlotUE((int16_t *)(data[pbchLlr] + 1), data[pbchLlr]->lineSz, this); break; } case PlotTypeUE::pbchIQ: { @@ -900,7 +1007,7 @@ void PainterWidgetUE::makeConnections(int type) this->comboBox->setCurrentIndex(static_cast(PlotTypeUE::empty)); break; } - newChart = new IQPlot((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz); + newChart = new IQPlotUE((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz, this); break; } case PlotTypeUE::pdcchLLR: { @@ -910,7 +1017,7 @@ void PainterWidgetUE::makeConnections(int type) this->comboBox->setCurrentIndex(static_cast(PlotTypeUE::empty)); break; } - newChart = new LLRPlot((int16_t *)(data[pdcchLlr] + 1), data[pdcchLlr]->lineSz); + newChart = new LLRPlotUE((int16_t *)(data[pdcchLlr] + 1), data[pdcchLlr]->lineSz, this); break; } case PlotTypeUE::pdcchIQ: { @@ -920,7 +1027,7 @@ void PainterWidgetUE::makeConnections(int type) this->comboBox->setCurrentIndex(static_cast(PlotTypeUE::empty)); break; } - newChart = new IQPlot((complex16 *)(data[pdcchRxdataF_comp] + 1), data[pdcchRxdataF_comp]->lineSz); + newChart = new IQPlotUE((complex16 *)(data[pdcchRxdataF_comp] + 1), data[pdcchRxdataF_comp]->lineSz, this); break; } case PlotTypeUE::pdschLLR: { @@ -930,7 +1037,7 @@ void PainterWidgetUE::makeConnections(int type) this->comboBox->setCurrentIndex(static_cast(PlotTypeUE::empty)); break; } - newChart = new LLRPlot((int16_t *)(data[pdschLlr] + 1), data[pdschLlr]->lineSz); + newChart = new LLRPlotUE((int16_t *)(data[pdschLlr] + 1), data[pdschLlr]->lineSz, this); break; } case PlotTypeUE::pdschIQ: { @@ -940,7 +1047,7 @@ void PainterWidgetUE::makeConnections(int type) this->comboBox->setCurrentIndex(static_cast(PlotTypeUE::empty)); break; } - newChart = new IQPlot((complex16 *)(data[pdschRxdataF_comp] + 1), data[pdschRxdataF_comp]->lineSz); + newChart = new IQPlotUE((complex16 *)(data[pdschRxdataF_comp] + 1), data[pdschRxdataF_comp]->lineSz, this); break; } diff --git a/openair1/PHY/TOOLS/nr_phy_qt_scope.h b/openair1/PHY/TOOLS/nr_phy_qt_scope.h index f10fef9d61..8a00d5fa96 100644 --- a/openair1/PHY/TOOLS/nr_phy_qt_scope.h +++ b/openair1/PHY/TOOLS/nr_phy_qt_scope.h @@ -91,6 +91,14 @@ class ValueProvider { virtual float getValue() = 0; }; +class ValueProviderUE : public ValueProvider { + public: + /// This pure virtual function is meant to provide the graph values to be plotted + virtual scopeGraphData_t *getPlotValue() { + return nullptr; + } +}; + /// An editable GUI field for a dialog box to set certain KPI configurations class ConfigBoxFloat : public QLineEdit { Q_OBJECT @@ -206,7 +214,6 @@ class CIRPlot : public QChart { /// \param event Pointer to the timer event virtual void timerEvent(QTimerEvent *event) override; - private: /// Pointer to the CIR data complex16 *data; @@ -223,6 +230,21 @@ class CIRPlot : public QChart { QValueAxis *axisY; }; +class CIRPlotUE : public CIRPlot { + Q_OBJECT + + public: + CIRPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : CIRPlot(data, len), valueProvider(valueProvider) {} + + protected: + /// This function is triggered when the own timer expires. It updates the plotted CIR + /// \param event Pointer to the timer event + virtual void timerEvent(QTimerEvent *event) override; + + private: + ValueProviderUE *valueProvider; +}; + /// Chart class for plotting LLRs class LLRPlot : public QChart { Q_OBJECT @@ -238,7 +260,6 @@ class LLRPlot : public QChart { /// \param event Pointer to the timer event virtual void timerEvent(QTimerEvent *event) override; - private: /// Pointer to the LLR data int16_t *data; @@ -255,6 +276,21 @@ class LLRPlot : public QChart { QValueAxis *axisY; }; +class LLRPlotUE : public LLRPlot { + Q_OBJECT + + public: + LLRPlotUE(int16_t *data, int len, ValueProviderUE *valueProvider) : LLRPlot(data, len), valueProvider(valueProvider) {} + + protected: + /// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram + /// \param event Pointer to the timer event + virtual void timerEvent(QTimerEvent *event) override; + + private: + ValueProviderUE *valueProvider; +}; + /// Chart class for plotting the I/Q constellation diagram class IQPlot : public QChart { Q_OBJECT @@ -270,7 +306,6 @@ class IQPlot : public QChart { /// \param event Pointer to the timer event virtual void timerEvent(QTimerEvent *event) override; - private: /// Pointer to the I/Q data complex16 *data; @@ -287,6 +322,22 @@ class IQPlot : public QChart { QValueAxis *axisY; }; +class IQPlotUE : public IQPlot { + Q_OBJECT + + public: + IQPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : IQPlot(data, len), valueProvider(valueProvider) {} + + protected: + /// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram + /// \param event Pointer to the timer event + virtual void timerEvent(QTimerEvent *event) override; + + private: + /// Pointer to an instance of a class that implements the ValueProvider interface + ValueProviderUE *valueProvider; +}; + /// Generic class for plotting KPI values with min., max. and average bars class KPIPlot : public QChart { Q_OBJECT @@ -422,7 +473,7 @@ class PainterWidgetGnb : public QWidget, public ValueProvider { }; /// Widget showing one selectable UE KPI -class PainterWidgetUE : public QWidget, public ValueProvider { +class PainterWidgetUE : public QWidget, public ValueProviderUE { Q_OBJECT public: @@ -435,6 +486,8 @@ class PainterWidgetUE : public QWidget, public ValueProvider { /// This function provides the current KPI value to be plotted virtual float getValue() override; + virtual scopeGraphData_t *getPlotValue() override; + protected: /// This function is called to change the widget size /// \param event Pointer to the resize event From c8a61331ea60e72d2b7f888274a7af13d450d0f8 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 9 Mar 2023 14:25:37 -0500 Subject: [PATCH 14/36] Update UE design doc --- doc/nr-ue-design.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/doc/nr-ue-design.md b/doc/nr-ue-design.md index 6b8bd89bf1..7ee42335d6 100644 --- a/doc/nr-ue-design.md +++ b/doc/nr-ue-design.md @@ -16,19 +16,20 @@ The UE exits when at any point in operation it gets out of synchronization. When ## Initial Synchronization Block ```mermaid graph TD - A(Start) -->|UE_thread| B["readFrame
--Reads samples worth 2 frames"] - B --> |Tpool thread| C["UE_synch
--PSS & SSS detection
--PBCH decode"] - B --> |UE_thread| D["readFrame
--trash samples to unblock radio"] - C --> |Tpool thread| E[syncInFrame
--shift first sample to start of frame] - D --> |UE_thread| E + start(Start) -->|UE_thread| rxRu["RU read
(Reads two frames)"] + rxRu --> |Tpool thread| sync["SSB detection
(PSS & SSS detection
PBCH decoding
SIB decoding)"] + rxRu --> |UE_thread| rxRuDummy["RU read
(Dummy read till sync detection to avoid buffer overflow at radio)"] + sync --> |Tpool thread| frameSync["Frame synchronization
(Shift received samples to align with frame)"] + rxRuDummy --> |UE_thread| frameSync ``` ## Regular Slot Processing ```mermaid graph TD - E[syncInFrame
--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"] - F --> |Tpool thread| G["processSlotTX (slot n+4)
--PUSCH encode
--PUCCH encode
--trx_write_func"] - F --> |Tpool thread| J["UE_processing (slot n)
--PDCCH decode
--PDSCH decode"] - F --> |UE_thread| I(Merge) - G --> |Tpool thread| I - I --> |Go to next slot
UE_thread| F + sync["Frame synchronization
(Shift received samples to align with frame)"] -->|UE_thread| hw_read["RU read (slot n)"] + hw_read --> |UE_thread| rxPreProc["PBCH & PDCCH decoding (slot n)"] + hw_read --> |Tpool thread| txProc["Tx processing (slot n+3)
PUSCH encode
PUCCH encode (wait for DLSCH in slot n+3-k1 to finish)
RU write"] + rxPreProc --> |Tpool thread| rxProc["PDSCH decoding (slot n)"] + rxPreProc --> |UE_thread| join(Merge) + txProc --> |Tpool thread| join + join --> |Go to next slot
UE_thread| hw_read ``` From 2bfe9ba2298ab4f1691a7f96bedf7d65dc68404f Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 14 Mar 2023 18:52:13 -0400 Subject: [PATCH 15/36] Remove dead code --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0ea9dc0f9d..377a7e2f08 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2665,9 +2665,6 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); } - if (dci_pdu_rel15->format_indicator == 0) - return 1; // discard dci, format indicator not corresponding to dci_format - // Freq domain assignment 0-16 bit fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1)); pos+=fsize; From 1f6d111f6a179dc3777e689ca24b1150e8d3263f Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 20 Mar 2023 13:48:07 -0400 Subject: [PATCH 16/36] Num wait idication as Tpool message field --- executables/nr-ue.c | 11 ++++++----- openair1/PHY/defs_nr_UE.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index c0021ee337..c0eb210420 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -567,12 +567,11 @@ void processSlotTX(void *arg) { LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type); if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){ - // wait for rx slots to send indication - for(int i=0; i < UE->tx_wait_for_dlsch[proc->nr_slot_tx]; i++) { + // wait for rx slots to send indication (if any) that DLSCH decoding is finished + for(int i=0; i < rxtxD->tx_wait_for_dlsch; i++) { notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo[proc->nr_slot_tx]); delNotifiedFIFO_elt(res); } - UE->tx_wait_for_dlsch[proc->nr_slot_tx] = 0; // trigger L2 to run ue_scheduler thru IF module // [TODO] mapping right after NR initial sync @@ -798,6 +797,7 @@ void *UE_thread(void *arg) { int num_ind_fifo = nb_slot_frame; for(int i=0; i < num_ind_fifo; i++) { + UE->tx_wait_for_dlsch[num_ind_fifo] = 0; UE->tx_resume_ind_fifo[i] = malloc(sizeof(*UE->tx_resume_ind_fifo[i])); initNotifiedFIFO(UE->tx_resume_ind_fifo[i]); } @@ -965,15 +965,16 @@ void *UE_thread(void *arg) { curMsgTx->writeBlockSize = writeBlockSize; curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->UE = UE; + curMsgTx->tx_wait_for_dlsch = UE->tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx]; + UE->tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0; pushTpool(&(get_nrUE_params()->Tpool), newElt); // RX slot processing. We launch and forget. - nr_phy_data_t phy_data = UE_dl_preprocessing(UE, &curMsg.proc); newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing); nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt); curMsgRx->proc = curMsg.proc; curMsgRx->UE = UE; - curMsgRx->phy_data = phy_data; + curMsgRx->phy_data = UE_dl_preprocessing(UE, &curMsg.proc); pushTpool(&(get_nrUE_params()->Tpool), newElt); if (curMsg.proc.decoded_frame_rx != -1) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index ac5379fe42..fabe35ef8d 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -688,6 +688,7 @@ typedef struct nr_rxtx_thread_data_s { PHY_VARS_NR_UE *UE; int writeBlockSize; nr_phy_data_t phy_data; + int tx_wait_for_dlsch; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { From 540319899694f44a407f03d15da00d3c755da2c7 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 00:16:15 +0200 Subject: [PATCH 17/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Added struct member to gNB_RRC_UE_t to store the established DRBs for a UE, this can be used to generate ASN1 structs, during RRCReconfiguration --- openair2/RRC/NR/nr_rrc_defs.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index e53ad60685..fd19220188 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -271,6 +271,40 @@ typedef struct pdu_session_param_s { uint8_t cause_value; } rrc_pdu_session_param_t; +typedef struct drb_s { + int status; + int defaultDRBid; + int drb_id; + int reestablishPDCP; + int recoverPDCP; + int daps_Config_r16; + struct cnAssociation_s { + int present; + int eps_BearerIdentity; + struct sdap_config_s { + bool defaultDRB; + int pdusession_id; + int sdap_HeaderDL; + int sdap_HeaderUL; + int mappedQoS_FlowsToAdd[QOSFLOW_MAX_VALUE]; + } sdap_config; + } cnAssociation; + struct pdcp_config_s { + int discardTimer; + int pdcp_SN_SizeUL; + int pdcp_SN_SizeDL; + int t_Reordering; + int integrityProtection; + struct headerCompression_s{ + int NotUsed; + int present; + } headerCompression; + struct ext1_s { + int cipheringDisabled; + } ext1; + } pdcp_config; +} drb_t; + typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; NR_SRB_ToAddModList_t *SRB_configList; @@ -278,6 +312,7 @@ typedef struct gNB_RRC_UE_s { 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]; NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity From af8b3b048601e4dbdc8823c442503088060e006f Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 00:28:50 +0200 Subject: [PATCH 18/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Added function to create ASN1 DRB-ToAddMod structs from, gNB_RRC_UE_t established_drbs --- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 47 +++++++++++++++++++++++++ openair2/RRC/NR/rrc_gNB_radio_bearers.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 1848601de8..acbcd2c9ab 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -98,6 +98,53 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session return DRB_config; } +NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) +{ + NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config)); + NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); + + asn1cCalloc(DRB_config->cnAssociation, association); + asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows); + asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig); + asn1cCalloc(pdcpConfig->drb, drb); + + DRB_config->drb_Identity = drb_asn1.drb_id; + association->present = drb_asn1.cnAssociation.present; + + /* SDAP Configuration */ + SDAP_config->pdu_Session = drb_asn1.cnAssociation.sdap_config.pdusession_id; + SDAP_config->sdap_HeaderDL = drb_asn1.cnAssociation.sdap_config.sdap_HeaderDL; + SDAP_config->sdap_HeaderUL = drb_asn1.cnAssociation.sdap_config.sdap_HeaderUL; + SDAP_config->defaultDRB = drb_asn1.cnAssociation.sdap_config.defaultDRB; + + for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) + { + if(drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) { + asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi); + *qfi = drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index]; + } + } + + association->choice.sdap_Config = SDAP_config; + + /* PDCP Configuration */ + asn1cCallocOne(drb->discardTimer, drb_asn1.pdcp_config.discardTimer); + asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1.pdcp_config.pdcp_SN_SizeUL); + asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1.pdcp_config.pdcp_SN_SizeDL); + asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1.pdcp_config.t_Reordering); + asn1cCallocOne(drb->integrityProtection, drb_asn1.pdcp_config.integrityProtection); + + drb->headerCompression.present = drb_asn1.pdcp_config.headerCompression.present; + drb->headerCompression.choice.notUsed = drb_asn1.pdcp_config.headerCompression.NotUsed; + + if (!drb_asn1.pdcp_config.ext1.cipheringDisabled) { + asn1cCalloc(pdcpConfig->ext1, ext1); + asn1cCallocOne(ext1->cipheringDisabled, drb_asn1.pdcp_config.ext1.cipheringDisabled); + } + + return DRB_config; +} + uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr) { uint8_t drb_id; diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 62065c1d87..f8049b9abb 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -35,6 +35,10 @@ #define GBR_FLOW (1) #define NONGBR_FLOW (0) +/// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t. +/// @param drb_t drb_asn1 +/// @return Returns the ASN1 DRB-ToAddMod structs. +NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1); NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_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); bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id); From 33c09b777623da2e4632fe4adb5630beab637fcc Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 00:44:22 +0200 Subject: [PATCH 19/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression The generateDRB function now creates a DRB and puts it in the struct member of gNB_RRC_UE_t, from this struct we can generate ASN1 messages by calling the generateDRB_ASN1 --- openair2/RRC/NR/rrc_gNB.c | 3 +- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 107 +++++++++++------------- openair2/RRC/NR/rrc_gNB_radio_bearers.h | 10 ++- 3 files changed, 61 insertions(+), 59 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 8bdc83d58a..0f07f310e4 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -643,7 +643,8 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, 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 { - NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering); + 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); diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index acbcd2c9ab..af953fc36d 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -36,66 +36,59 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create) return ue->pduSession + j; } -NR_DRB_ToAddMod_t *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) +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) { - NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config)); - DRB_config->drb_Identity = drb_id; - asn1cCalloc(DRB_config->cnAssociation, association); - association->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + int i; + int qos_flow_index; + if (ue->established_drbs[drb_id - 1].status == DRB_INACTIVE) { + /* DRB Management */ + ue->established_drbs[drb_id - 1].drb_id = drb_id; + ue->established_drbs[drb_id - 1].reestablishPDCP = -1; + ue->established_drbs[drb_id - 1].recoverPDCP = -1; + for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { + if ((ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == 0 || + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id) && + ue->established_drbs[drb_id - 1].defaultDRBid == 0) { + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.defaultDRB = true; + ue->established_drbs[drb_id - 1].defaultDRBid = drb_id; + } + } + /* SDAP Configuration */ + ue->established_drbs[drb_id - 1].cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id; + if (enable_sdap) { + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; + } else { + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; + ue->established_drbs[drb_id - 1].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++) + { + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi; + if(pduSession->param.qos[qos_flow_index].fiveQI > 5) + ue->established_drbs[drb_id - 1].status = DRB_ACTIVE_NONGBR; + else + ue->established_drbs[drb_id - 1].status = DRB_ACTIVE; + } + /* PDCP Configuration */ + ue->established_drbs[drb_id - 1].pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; + ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; + ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; + ue->established_drbs[drb_id - 1].pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100; + ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.NotUsed = 0; + if (do_drb_integrity) + ue->established_drbs[drb_id - 1].pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled; + if (!do_drb_ciphering) + ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; - /* SDAP Configuration */ - NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); - asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows); - - SDAP_config->pdu_Session = pduSession->param.pdusession_id; - - if (enable_sdap) { - SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; - SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; - } else { - SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; - SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; } - - SDAP_config->defaultDRB = true; - - for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) - { - asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi); - *qfi = pduSession->param.qos[qos_flow_index].qfi; - if(pduSession->param.qos[qos_flow_index].fiveQI > 5) - pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR; - else - pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE; - } - - association->choice.sdap_Config = SDAP_config; - - /* PDCP Configuration */ - asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig); - asn1cCalloc(pdcpConfig->drb, drb); - - asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity); - - asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits); - asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits); - - drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - drb->headerCompression.choice.notUsed = 0; - - asn1cCallocOne(pdcpConfig->t_Reordering, NR_PDCP_Config__t_Reordering_ms100); - - if (do_drb_integrity) { - asn1cCallocOne(drb->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled); - } - if (!do_drb_ciphering) { - asn1cCalloc(pdcpConfig->ext1, ext1); - asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true); - } - - ue->DRB_active[drb_id-1] = DRB_ACTIVE; - - return DRB_config; } NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index f8049b9abb..10f1ff8c05 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -39,7 +39,15 @@ /// @param drb_t drb_asn1 /// @return Returns the ASN1 DRB-ToAddMod structs. NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1); -NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering); +/// @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. +/// @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); bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id); From 22db2d613f965e8b2063fae6bca14b828bfe58d1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Apr 2023 08:40:48 +0200 Subject: [PATCH 20/36] Correctly allocate GUTI in NAS UE structures --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e411c53994..e20a0fc99e 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -622,7 +622,7 @@ static void decodeRegistrationAccept(uint8_t *buf, int len, nr_ue_nas_t *nas) AssertFatal(reg_acc.guti->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI, "registration accept 5GS Mobile Identity is not GUTI, but %d\n", reg_acc.guti->guti.typeofidentity); - nas->guti = malloc(sizeof(nas->guti)); + nas->guti = malloc(sizeof(*nas->guti)); AssertFatal(nas->guti, "out of memory\n"); *nas->guti = reg_acc.guti->guti; free(reg_acc.guti); /* no proper memory management for NAS decoded messages */ From 0a4e28688bfb5e13051e5d92fae322db1be4539c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Apr 2023 09:39:28 +0200 Subject: [PATCH 21/36] Update phytest-timing test timing thresholds --- ci-scripts/datalog_rt_stats.1x1.60.yaml | 4 ++-- ci-scripts/datalog_rt_stats.60.2x2.yaml | 6 +++--- ci-scripts/datalog_rt_stats.default.yaml | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ci-scripts/datalog_rt_stats.1x1.60.yaml b/ci-scripts/datalog_rt_stats.1x1.60.yaml index bf22c6f432..c65c4614d2 100644 --- a/ci-scripts/datalog_rt_stats.1x1.60.yaml +++ b/ci-scripts/datalog_rt_stats.1x1.60.yaml @@ -14,8 +14,8 @@ Ref : L1 Tx processing : 210.0 DLSCH encoding : 137.0 L1 Rx processing : 345.0 - PUSCH inner-receiver : 184.0 - PUSCH decoding : 276.0 + PUSCH inner-receiver : 210.0 + PUSCH decoding : 210.0 Schedule Response : 48.0 DL & UL scheduling timing : 13.0 UL Indication : 60.0 diff --git a/ci-scripts/datalog_rt_stats.60.2x2.yaml b/ci-scripts/datalog_rt_stats.60.2x2.yaml index b0d861d758..50444cc6b0 100644 --- a/ci-scripts/datalog_rt_stats.60.2x2.yaml +++ b/ci-scripts/datalog_rt_stats.60.2x2.yaml @@ -14,10 +14,10 @@ Ref : L1 Tx processing : 400.0 DLSCH encoding : 177.0 L1 Rx processing : 345.0 - PUSCH inner-receiver : 184.0 - PUSCH decoding : 276.0 + PUSCH inner-receiver : 210.0 + PUSCH decoding : 210.0 Schedule Response : 111.0 - DL & UL scheduling timing : 37.0 + DL & UL scheduling timing : 20.0 UL Indication : 127.0 Threshold : feprx : 1.25 diff --git a/ci-scripts/datalog_rt_stats.default.yaml b/ci-scripts/datalog_rt_stats.default.yaml index 971e72944a..8f7f0f015c 100644 --- a/ci-scripts/datalog_rt_stats.default.yaml +++ b/ci-scripts/datalog_rt_stats.default.yaml @@ -14,11 +14,11 @@ Ref : L1 Tx processing : 170.0 DLSCH encoding : 118.0 L1 Rx processing : 305.0 - PUSCH inner-receiver : 117.0 - PUSCH decoding : 303.0 - Schedule Response : 25.0 + PUSCH inner-receiver : 150.0 + PUSCH decoding : 210.0 + Schedule Response : 20.0 DL & UL scheduling timing : 10.0 - UL Indication : 34.0 + UL Indication : 30.0 Threshold : feprx : 1.25 feptx_prec : 1.25 From 26909e7c3249cf237533308da49c78066c1c9ff2 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 11:28:56 +0200 Subject: [PATCH 22/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Cosmetic changes, added doxygen configuration, and changed the rrc_gNB_process_RRCReestablishmentComplete function arguments' alignment, so in the future if an argument is removed or added to be better visible in the commits --- openair2/RRC/NR/rrc_gNB.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 0f07f310e4..df7d70a099 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1280,9 +1280,19 @@ 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); } -//----------------------------------------------------------------------------- -void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, const rnti_t reestablish_rnti, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t xid) -//----------------------------------------------------------------------------- +/* + * Handle RRC Reestablishment Complete Functions + */ + +/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. +/// @param ctxt_pP Protocol context containing information regarding the UE and gNB +/// @param reestablish_rnti is the old C-RNTI +/// @param ue_context_pP UE context container information regarding the UE +/// @param xid Transaction Identifier used in RRC messages +void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + const rnti_t reestablish_rnti, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t xid) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", ue_p->rnti); From 7eb2e99dcd9560dba7e98def97b45f034d37ad0b Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 11:37:36 +0200 Subject: [PATCH 23/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Simplify RRCReestablishmentComplete procedure with respective function, removed the block that frees all the NAS PDUs and created a function for this. --- openair2/RRC/NR/rrc_gNB.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index df7d70a099..f008a1d060 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1284,6 +1284,20 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, * Handle RRC Reestablishment Complete Functions */ +/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. +void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP) +{ + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + /* 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; + } + } +} + /// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. /// @param ctxt_pP Protocol context containing information regarding the UE and gNB /// @param reestablish_rnti is the old C-RNTI @@ -1475,14 +1489,7 @@ cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGr LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); - /* Free all NAS PDUs */ - for (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; - } - } + RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); if (size < 0) { LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n"); From bf844247bf990aa7a3884f681101bff5cd4a74cc Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 11:46:54 +0200 Subject: [PATCH 24/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Simplify RRCReestablishmentComplete procedure with respective function, removed the block that updates NAS PDUSession and created a function, with doxygen --- openair2/RRC/NR/rrc_gNB.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f008a1d060..3338cfbad0 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1284,6 +1284,22 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, * Handle RRC Reestablishment Complete Functions */ +/// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid. +/// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid. +/// @todo parameters yet to process inside the for loop. +/// @todo should test if pdu session are Ok before! inside the for loop. +void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t old_xid) +{ + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + /* Add all NAS PDUs to the list */ + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_p->pduSession[i].xid = old_xid; + LOG_D(NR_RRC, "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + } +} + /// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP) { @@ -1425,6 +1441,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx return; } } + RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); /* Update RNTI in ue_context */ LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); @@ -1444,15 +1461,6 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx /* TODO: hardcoded to 13 for the time being, to be changed? */ long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13}; - /* Add all NAS PDUs to the list */ - for (i = 0; i < ue_p->nb_of_pdusessions; i++) { - /* TODO parameters yet to process ... */ - /* TODO should test if pdu session are Ok before! */ - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->pduSession[i].xid = xid; - 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"); - } - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); From a3c13fdc7183bd8bffa238083c704d7ecd93d9b6 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 11:55:10 +0200 Subject: [PATCH 25/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Simplify RRCReestablishmentComplete procedure with respective function, removed the block that updates NGU Tunnels and created a function, with doxygen --- openair2/RRC/NR/rrc_gNB.c | 85 ++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3338cfbad0..97aea26bcf 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1284,6 +1284,54 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, * Handle RRC Reestablishment Complete Functions */ +/// @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, + rrc_gNB_ue_context_t *ue_context_pP, + const rnti_t reestablish_rnti) +{ + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + int i = 0; + int j = 0; + int ret = 0; + + if (get_softmodem_params()->sa) { + LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n"); + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; + /* Save e RAB information for later */ + + for (j = 0, i = 0; i < NB_RB_MAX; i++) { + if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { + create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; + create_tunnel_req.incoming_rb_id[j] = i+1; + create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; + // to be developped, use the first QFI only + create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; + memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); + create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length; + j++; + } + } + + create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above + create_tunnel_req.num_tunnels = j; + ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, + &create_tunnel_req, + reestablish_rnti); + + if ( ret != 0 ) { + LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); + ue_p->ue_release_timer_s1 = 1; + ue_p->ue_release_timer_thres_s1 = 100; + ue_p->ue_release_timer = 0; + ue_p->ue_reestablishment_timer = 0; + ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + ue_p->ul_failure_timer = 0; + return; + } + } +} + /// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid. /// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid. /// @todo parameters yet to process inside the for loop. @@ -1405,42 +1453,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx ue_p->Srb[1].Active = 1; - if (get_softmodem_params()->sa) { - LOG_W(NR_RRC, "Rework identity mapping need to be done properly!\n"); - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; - /* Save e RAB information for later */ - int j; - for (j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; - create_tunnel_req.incoming_rb_id[j] = i+1; - create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; - // to be developped, use the first QFI only - create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); - create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length; - j++; - } - } - - create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above - create_tunnel_req.num_tunnels = j; - ret = gtpv1u_update_ngu_tunnel( - ctxt_pP->instance, - &create_tunnel_req, - reestablish_rnti); - - if ( ret != 0 ) { - LOG_E(NR_RRC, "gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - ue_p->ue_release_timer_s1 = 1; - ue_p->ue_release_timer_thres_s1 = 100; - ue_p->ue_release_timer = 0; - ue_p->ue_reestablishment_timer = 0; - ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - ue_p->ul_failure_timer = 0; - return; - } - } + RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); /* Update RNTI in ue_context */ From 914235706987d68924434ea8945eb83bb46ef58b Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 13:07:17 +0200 Subject: [PATCH 26/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Simplify RRCReestablishmentComplete procedure with respective function, removed the block that creates the ASN1 DRBs and created a function, with doxygen --- openair2/RRC/NR/rrc_gNB.c | 47 +++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 97aea26bcf..c9d57cc3fb 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1284,6 +1284,35 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, * Handle RRC Reestablishment Complete Functions */ +/// @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, @@ -1433,23 +1462,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n"); } - if (*DRB_configList2) { - free(*DRB_configList2); - LOG_D(NR_RRC, "free(ue_p->DRB_configList2[%d])\n", new_xid); - } - - *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); - - if (DRB_configList != NULL) { - LOG_D(NR_RRC, "get DRB_config from (ue_p->DRB_configList)\n"); - - for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) { - DRB_config = DRB_configList->list.array[i]; - asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); - // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete - asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config); - } - } + RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); ue_p->Srb[1].Active = 1; From 1923bed4a32b1bcce278f421c4c6da70be520cb2 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 13:19:51 +0200 Subject: [PATCH 27/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Simplify RRCReestablishmentComplete procedure with respective function, removed the block that creates the SRB2 and created a function, with doxygen --- openair2/RRC/NR/rrc_gNB.c | 118 ++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index c9d57cc3fb..b508495ba0 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1284,6 +1284,68 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, * Handle RRC Reestablishment Complete Functions */ +/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the SRB2. +/// @param old_xid The old RRC transaction id. +/// @param new_xid The new RRC transaction id. +void RRCReestablishmentComplete_fill_SRB2_configList(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t old_xid, + const uint8_t new_xid) +{ + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + NR_SRB_ToAddMod_t *SRB2_config = NULL; + NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList; + NR_SRB_ToAddModList_t **SRB_configList2 = NULL; + + SRB_configList2 = &ue_p->SRB_configList2[old_xid]; + + // get old configuration of SRB2 + if (*SRB_configList2 != NULL) { + if((*SRB_configList2)->list.count!=0) { + LOG_D(NR_RRC, "RRC Reestablishment - SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p\n", + SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); + } + + for (int i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { + if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { + LOG_D(NR_RRC, "RRC Reestablishment - get SRB2_config from (ue_p->SRB_configList2[%d])\n", old_xid); + SRB2_config = (*SRB_configList2)->list.array[i]; + SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP)); + *SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true; + break; + } + } + } + + SRB_configList2 = &(ue_p->SRB_configList2[new_xid]); + + if (*SRB_configList2) { + free(*SRB_configList2); + LOG_D(NR_RRC, "RRC Reestablishment - free(ue_p->SRB_configList2[%d])\n", new_xid); + } + + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + + if (SRB2_config != NULL) { + // Add SRB2 to SRB configuration list + asn1cSeqAdd(&SRB_configList->list, SRB2_config); + asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); + LOG_D(NR_RRC, "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity); + LOG_D(NR_RRC, "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid); + } else { + // SRB configuration list only contains SRB1. + LOG_W(NR_RRC,"RRC Reestablishment - SRB2 configuration does not exist in SRB configuration list\n"); + } + + ue_p->Srb[1].Active = 1; + + if (get_softmodem_params()->sa) { + uint8_t send_security_mode_command = false; + nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command); + LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n"); + } +} + /// @brief Function used in RRCReestablishmentComplete procedure to reestablish the DRBs /// that the UE previously had, it gets the information from the established_drbs /// struct. @@ -1418,54 +1480,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx ue_p->StatusRrc = NR_RRC_CONNECTED; ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED ue_p->reestablishment_xid = new_xid; - SRB_configList2 = &ue_p->SRB_configList2[xid]; - - // get old configuration of SRB2 - if (*SRB_configList2 != NULL) { - if((*SRB_configList2)->list.count!=0) { - LOG_D(NR_RRC, "SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p", - SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); - } - - for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { - if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { - LOG_D(NR_RRC, "get SRB2_config from (ue_p->SRB_configList2[%d])\n", xid); - SRB2_config = (*SRB_configList2)->list.array[i]; - SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP)); - *SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true; - break; - } - } - } - - // SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - // SRB2_config->srb_Identity = 2; - - SRB_configList2 = &(ue_p->SRB_configList2[new_xid]); - DRB_configList2 = &(ue_p->DRB_configList2[new_xid]); - - if (*SRB_configList2) { - free(*SRB_configList2); - LOG_D(NR_RRC, "free(ue_p->SRB_configList2[%d])\n", new_xid); - } - - *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); - - if (SRB2_config != NULL) { - // Add SRB2 to SRB configuration list - asn1cSeqAdd(&SRB_configList->list, SRB2_config); - asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); - LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity); - LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid); - } else { - // SRB configuration list only contains SRB1. - LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n"); - } + RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); - - ue_p->Srb[1].Active = 1; - RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); @@ -1473,15 +1490,6 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id); - if (get_softmodem_params()->sa) { - uint8_t send_security_mode_command = false; - nr_rrc_pdcp_config_security( - ctxt_pP, - ue_context_pP, - send_security_mode_command ? 0 : 1); - LOG_D(NR_RRC, "set security successfully \n"); - } - uint8_t drb_id_to_setup_start = DRB_configList ? DRB_configList->list.array[0]->drb_Identity : 1; uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_p->nb_of_pdusessions; /* TODO: hardcoded to 13 for the time being, to be changed? */ From ca010654bffbb5af5c523affcd110ce75e410806 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 13:22:51 +0200 Subject: [PATCH 28/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Changed the SRB2 and DRB at the do_RRCReconfiguration arguments, to pass the correct structures that are generated --- openair2/RRC/NR/rrc_gNB.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b508495ba0..d324adb035 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1516,8 +1516,8 @@ cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGr buffer, RRC_BUF_SIZE, new_xid, - *SRB_configList2, - DRB_configList, + *ue_p->SRB_configList2, + *ue_p->DRB_configList2, NULL, NULL, NULL, From ad598a2d5da76f50580a42f83fc32ef55d08eb94 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 13:29:08 +0200 Subject: [PATCH 29/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Removed the unused variables, and changed the tenary operator conditions of drb_id_to_setup_start & nb_drb_to_setup, to the correct ones --- openair2/RRC/NR/rrc_gNB.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d324adb035..6fc7b57c2f 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1466,17 +1466,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", ue_p->rnti); - NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList; - NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList; - NR_SRB_ToAddModList_t **SRB_configList2 = NULL; - NR_DRB_ToAddModList_t **DRB_configList2 = NULL; - NR_SRB_ToAddMod_t *SRB2_config = NULL; - NR_DRB_ToAddMod_t *DRB_config = NULL; - //NR_SDAP_Config_t *sdap_config = NULL; int i = 0; uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - int ret = 0; ue_p->StatusRrc = NR_RRC_CONNECTED; ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED ue_p->reestablishment_xid = new_xid; @@ -1490,8 +1482,8 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id); - uint8_t drb_id_to_setup_start = DRB_configList ? DRB_configList->list.array[0]->drb_Identity : 1; - uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_p->nb_of_pdusessions; + uint8_t drb_id_to_setup_start = ue_p->DRB_configList ? ue_p->DRB_configList->list.array[0]->drb_Identity : 1; + uint8_t nb_drb_to_setup = ue_p->DRB_configList ? ue_p->DRB_configList->list.count : ue_p->nb_of_pdusessions; /* TODO: hardcoded to 13 for the time being, to be changed? */ long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13}; From 778c88d8a9ba8bfab6db118a2af62bd9a5582d68 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 13:34:31 +0200 Subject: [PATCH 30/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Cosmetic changes, also changed the LOG message for updating the UEid, and moved the drb_id_to_setup_start and nb_drb_to_setup right before the function that they are used --- openair2/RRC/NR/rrc_gNB.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 6fc7b57c2f..5bf4843180 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1469,9 +1469,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx int i = 0; uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - ue_p->StatusRrc = NR_RRC_CONNECTED; + ue_p->StatusRrc = NR_RRC_CONNECTED; ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_p->reestablishment_xid = new_xid; + ue_p->reestablishment_xid = new_xid; RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); @@ -1479,22 +1479,22 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); /* Update RNTI in ue_context */ - LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); + LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id); - uint8_t drb_id_to_setup_start = ue_p->DRB_configList ? ue_p->DRB_configList->list.array[0]->drb_Identity : 1; - uint8_t nb_drb_to_setup = ue_p->DRB_configList ? ue_p->DRB_configList->list.count : ue_p->nb_of_pdusessions; - /* TODO: hardcoded to 13 for the time being, to be changed? */ - long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13}; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment - ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; - ue_p->spCellConfigReestablishment = NULL; - cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; -cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; + ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; + ue_p->spCellConfigReestablishment = NULL; + cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; + cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; + + uint8_t drb_id_to_setup_start = ue_p->DRB_configList ? ue_p->DRB_configList->list.array[0]->drb_Identity : 1; + uint8_t nb_drb_to_setup = ue_p->DRB_configList ? ue_p->DRB_configList->list.count : ue_p->nb_of_pdusessions; + /* TODO: hardcoded to 13 for the time being, to be changed? */ + long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13}; fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); @@ -1505,21 +1505,21 @@ cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGr uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_RRCReconfiguration(ctxt_pP, - buffer, - RRC_BUF_SIZE, - new_xid, - *ue_p->SRB_configList2, - *ue_p->DRB_configList2, - NULL, - NULL, - NULL, - NULL, // MeasObj_list, - NULL, - ue_context_pP, - &rrc->carrier, - NULL, - NULL, - cellGroupConfig); + buffer, + RRC_BUF_SIZE, + new_xid, + *ue_p->SRB_configList2, + *ue_p->DRB_configList2, + NULL, + NULL, + NULL, + NULL, // MeasObj_list, + NULL, + ue_context_pP, + &rrc->carrier, + NULL, + NULL, + cellGroupConfig); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); From f4dc36224755633d86a0473aaa0387233bec4ebd Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Tue, 4 Apr 2023 13:59:14 +0200 Subject: [PATCH 31/36] NR RRC - RRCReestablishment - Fix MultiplePDU Regression Fixed a bug where the integrity protection was included in the ASN1 and caused significant throughput bottleneck. --- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index af953fc36d..68bf78482a 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -125,11 +125,13 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1.pdcp_config.pdcp_SN_SizeUL); asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1.pdcp_config.pdcp_SN_SizeDL); asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1.pdcp_config.t_Reordering); - asn1cCallocOne(drb->integrityProtection, drb_asn1.pdcp_config.integrityProtection); drb->headerCompression.present = drb_asn1.pdcp_config.headerCompression.present; drb->headerCompression.choice.notUsed = drb_asn1.pdcp_config.headerCompression.NotUsed; + if (!drb_asn1.pdcp_config.integrityProtection) { + asn1cCallocOne(drb->integrityProtection, drb_asn1.pdcp_config.integrityProtection); + } if (!drb_asn1.pdcp_config.ext1.cipheringDisabled) { asn1cCalloc(pdcpConfig->ext1, ext1); asn1cCallocOne(ext1->cipheringDisabled, drb_asn1.pdcp_config.ext1.cipheringDisabled); From 6fb10cd5fa39308870922c8ab3204e4fd8ad8f89 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Tue, 4 Apr 2023 18:13:11 +0100 Subject: [PATCH 32/36] Fix SRB_configList2 and DRB_configList2 array position (new_xid) while creating RRCReconfiguration message after RRCReestablishmentComplete --- openair2/RRC/NR/rrc_gNB.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5bf4843180..301e069adb 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1508,8 +1508,8 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx buffer, RRC_BUF_SIZE, new_xid, - *ue_p->SRB_configList2, - *ue_p->DRB_configList2, + ue_p->SRB_configList2[new_xid], + ue_p->DRB_configList2[new_xid], NULL, NULL, NULL, From 3cf3a42b44fcb4d547b05f868ebc20035f24c02b Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Tue, 4 Apr 2023 18:20:58 +0100 Subject: [PATCH 33/36] Flag integrityProtection work in inverse logic state, '0' means enabled which is the default the value, we need to set it to '1' to disable it --- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 68bf78482a..d969ebccf6 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -84,8 +84,12 @@ void generateDRB(gNB_RRC_UE_t *ue, ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.NotUsed = 0; if (do_drb_integrity) - ue->established_drbs[drb_id - 1].pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled; - if (!do_drb_ciphering) + ue->established_drbs[drb_id - 1].pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled; + else + ue->established_drbs[drb_id - 1].pdcp_config.integrityProtection = 1; + if (do_drb_ciphering) + ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = 1; + else ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; } From 5b35523c2cc4a2786c3c873e15af2e89e024dac9 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Wed, 5 Apr 2023 11:22:59 +0200 Subject: [PATCH 34/36] NR RRC - RRCReestablishment - Apply clang format --- openair2/RRC/NR/nr_rrc_defs.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 130 ++++++++++++++---------- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 44 ++++---- openair2/RRC/NR/rrc_gNB_radio_bearers.h | 17 ++-- 4 files changed, 111 insertions(+), 82 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index fd19220188..f8d69e942a 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -295,7 +295,7 @@ typedef struct drb_s { int pdcp_SN_SizeDL; int t_Reordering; int integrityProtection; - struct headerCompression_s{ + struct headerCompression_s { int NotUsed; int present; } headerCompression; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 301e069adb..ec5ded4989 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1281,7 +1281,7 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, } /* - * Handle RRC Reestablishment Complete Functions + * Handle RRC Reestablishment Complete Functions */ /// @brief Function used in RRCReestablishmentComplete procedure to reestablish the SRB2. @@ -1292,25 +1292,28 @@ void RRCReestablishmentComplete_fill_SRB2_configList(const protocol_ctxt_t *cons const uint8_t old_xid, const uint8_t new_xid) { - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_SRB_ToAddMod_t *SRB2_config = NULL; - NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + NR_SRB_ToAddMod_t *SRB2_config = NULL; + NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList; NR_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_p->SRB_configList2[old_xid]; // get old configuration of SRB2 if (*SRB_configList2 != NULL) { - if((*SRB_configList2)->list.count!=0) { - LOG_D(NR_RRC, "RRC Reestablishment - SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p\n", - SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); + if ((*SRB_configList2)->list.count != 0) { + LOG_D(NR_RRC, + "RRC Reestablishment - SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p\n", + SRB_configList2, + (*SRB_configList2)->list.count, + (*SRB_configList2)->list.array[0]); } for (int i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { - if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { + if ((*SRB_configList2)->list.array[i]->srb_Identity == 2) { LOG_D(NR_RRC, "RRC Reestablishment - get SRB2_config from (ue_p->SRB_configList2[%d])\n", old_xid); SRB2_config = (*SRB_configList2)->list.array[i]; - SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP)); + SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP)); *SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true; break; } @@ -1331,10 +1334,13 @@ void RRCReestablishmentComplete_fill_SRB2_configList(const protocol_ctxt_t *cons asn1cSeqAdd(&SRB_configList->list, SRB2_config); asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); LOG_D(NR_RRC, "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity); - LOG_D(NR_RRC, "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid); + LOG_D(NR_RRC, + "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", + SRB2_config->srb_Identity, + new_xid); } else { // SRB configuration list only contains SRB1. - LOG_W(NR_RRC,"RRC Reestablishment - SRB2 configuration does not exist in SRB configuration list\n"); + LOG_W(NR_RRC, "RRC Reestablishment - SRB2 configuration does not exist in SRB configuration list\n"); } ue_p->Srb[1].Active = 1; @@ -1346,16 +1352,16 @@ void RRCReestablishmentComplete_fill_SRB2_configList(const protocol_ctxt_t *cons } } -/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the DRBs -/// that the UE previously had, it gets the information from the established_drbs +/// @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. +/// @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; + 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) { @@ -1376,26 +1382,26 @@ void RRCReestablishmentComplete_fill_DRB_configList(const protocol_ctxt_t *const } /// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels. -/// @param reestablish_rnti is the old C-RNTI +/// @param reestablish_rnti is the old C-RNTI void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, const rnti_t reestablish_rnti) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - int i = 0; - int j = 0; + int i = 0; + int j = 0; int ret = 0; if (get_softmodem_params()->sa) { LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n"); - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; /* Save e RAB information for later */ - + for (j = 0, i = 0; i < NB_RB_MAX; i++) { if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; - create_tunnel_req.incoming_rb_id[j] = i+1; - create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; + create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; + create_tunnel_req.incoming_rb_id[j] = i + 1; + create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; // to be developped, use the first QFI only create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); @@ -1404,20 +1410,18 @@ void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const c } } - create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above + create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above create_tunnel_req.num_tunnels = j; - ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, - &create_tunnel_req, - reestablish_rnti); + ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, &create_tunnel_req, reestablish_rnti); - if ( ret != 0 ) { + if (ret != 0) { LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - ue_p->ue_release_timer_s1 = 1; + ue_p->ue_release_timer_s1 = 1; ue_p->ue_release_timer_thres_s1 = 100; - ue_p->ue_release_timer = 0; - ue_p->ue_reestablishment_timer = 0; - ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - ue_p->ul_failure_timer = 0; + ue_p->ue_release_timer = 0; + ue_p->ue_reestablishment_timer = 0; + ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + ue_p->ul_failure_timer = 0; return; } } @@ -1427,19 +1431,22 @@ void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const c /// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid. /// @todo parameters yet to process inside the for loop. /// @todo should test if pdu session are Ok before! inside the for loop. -void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t old_xid) +void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; /* Add all NAS PDUs to the list */ for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; ue_p->pduSession[i].xid = old_xid; - LOG_D(NR_RRC, "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + LOG_D(NR_RRC, + "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n", + i, + ue_p->pduSession[i].status, + "PDU_SESSION_STATUS_DONE"); } } -/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. +/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -1464,14 +1471,16 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx const uint8_t xid) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", ue_p->rnti); + LOG_I(NR_RRC, + "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", + ue_p->rnti); int i = 0; uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - ue_p->StatusRrc = NR_RRC_CONNECTED; + ue_p->StatusRrc = NR_RRC_CONNECTED; ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_p->reestablishment_xid = new_xid; + ue_p->reestablishment_xid = new_xid; RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); @@ -1486,9 +1495,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment - ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; - ue_p->spCellConfigReestablishment = NULL; - cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; + ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; + ue_p->spCellConfigReestablishment = NULL; + cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; uint8_t drb_id_to_setup_start = ue_p->DRB_configList ? ue_p->DRB_configList->list.array[0]->drb_Identity : 1; @@ -1496,10 +1505,17 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx /* TODO: hardcoded to 13 for the time being, to be changed? */ long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13}; - fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + fill_mastercellGroupConfig(cellGroupConfig, + ue_p->masterCellGroup, + rrc->um_on_default_drb, + (drb_id_to_setup_start < 2) ? 1 : 0, + drb_id_to_setup_start, + nb_drb_to_setup, + drb_priority); - 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)); + 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; } @@ -1521,7 +1537,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx NULL, cellGroupConfig); - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); @@ -1529,9 +1545,15 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n"); return; } else { - LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); + LOG_I(NR_RRC, + "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\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 %04x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD " + "%u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, @@ -1545,12 +1567,16 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx } if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, + ue_p->rnti, + *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, + delay_ms); } } //----------------------------------------------------------------------------- diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index d969ebccf6..e9fa7922fb 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -47,19 +47,19 @@ void generateDRB(gNB_RRC_UE_t *ue, int qos_flow_index; if (ue->established_drbs[drb_id - 1].status == DRB_INACTIVE) { /* DRB Management */ - ue->established_drbs[drb_id - 1].drb_id = drb_id; + ue->established_drbs[drb_id - 1].drb_id = drb_id; ue->established_drbs[drb_id - 1].reestablishPDCP = -1; - ue->established_drbs[drb_id - 1].recoverPDCP = -1; + ue->established_drbs[drb_id - 1].recoverPDCP = -1; for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { - if ((ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == 0 || - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id) && - ue->established_drbs[drb_id - 1].defaultDRBid == 0) { + if ((ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == 0 + || ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id) + && ue->established_drbs[drb_id - 1].defaultDRBid == 0) { ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.defaultDRB = true; ue->established_drbs[drb_id - 1].defaultDRBid = drb_id; } } /* SDAP Configuration */ - ue->established_drbs[drb_id - 1].cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + ue->established_drbs[drb_id - 1].cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id; if (enable_sdap) { ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; @@ -68,19 +68,19 @@ void generateDRB(gNB_RRC_UE_t *ue, ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; ue->established_drbs[drb_id - 1].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++) - { - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi; - if(pduSession->param.qos[qos_flow_index].fiveQI > 5) + for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) { + ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = + pduSession->param.qos[qos_flow_index].qfi; + if (pduSession->param.qos[qos_flow_index].fiveQI > 5) ue->established_drbs[drb_id - 1].status = DRB_ACTIVE_NONGBR; else ue->established_drbs[drb_id - 1].status = DRB_ACTIVE; } /* PDCP Configuration */ - ue->established_drbs[drb_id - 1].pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; - ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - ue->established_drbs[drb_id - 1].pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100; + ue->established_drbs[drb_id - 1].pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; + ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; + ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; + ue->established_drbs[drb_id - 1].pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100; ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.NotUsed = 0; if (do_drb_integrity) @@ -91,7 +91,6 @@ void generateDRB(gNB_RRC_UE_t *ue, ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = 1; else ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; - } } @@ -106,17 +105,16 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) asn1cCalloc(pdcpConfig->drb, drb); DRB_config->drb_Identity = drb_asn1.drb_id; - association->present = drb_asn1.cnAssociation.present; + association->present = drb_asn1.cnAssociation.present; /* SDAP Configuration */ - SDAP_config->pdu_Session = drb_asn1.cnAssociation.sdap_config.pdusession_id; + SDAP_config->pdu_Session = drb_asn1.cnAssociation.sdap_config.pdusession_id; SDAP_config->sdap_HeaderDL = drb_asn1.cnAssociation.sdap_config.sdap_HeaderDL; SDAP_config->sdap_HeaderUL = drb_asn1.cnAssociation.sdap_config.sdap_HeaderUL; - SDAP_config->defaultDRB = drb_asn1.cnAssociation.sdap_config.defaultDRB; - - for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) - { - if(drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) { + SDAP_config->defaultDRB = drb_asn1.cnAssociation.sdap_config.defaultDRB; + + for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) { + if (drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) { asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi); *qfi = drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index]; } @@ -130,7 +128,7 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1.pdcp_config.pdcp_SN_SizeDL); asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1.pdcp_config.t_Reordering); - drb->headerCompression.present = drb_asn1.pdcp_config.headerCompression.present; + drb->headerCompression.present = drb_asn1.pdcp_config.headerCompression.present; drb->headerCompression.choice.notUsed = drb_asn1.pdcp_config.headerCompression.NotUsed; if (!drb_asn1.pdcp_config.integrityProtection) { diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 10f1ff8c05..732394ef82 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -35,19 +35,24 @@ #define GBR_FLOW (1) #define NONGBR_FLOW (0) -/// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t. -/// @param drb_t drb_asn1 +/// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t. +/// @param drb_t drb_asn1 /// @return Returns the ASN1 DRB-ToAddMod structs. NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1); -/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity, +/// @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. /// @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); +/// @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); bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id); From 733c7e5e8949c33b174bdf7ce98ec5ca8594faa1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 19 Feb 2023 17:42:52 +0100 Subject: [PATCH 35/36] bugfix: change memory management of interface between PHY and MAC scheduler This commit fixes a bug caused by global variables in the gNB_MAC_INST structure used to transfer MAC scheduler's results to the PHY layer. When using several threads in the PHY layer, it may happen that the MAC scheduler is called a second time by the second PHY thread for the next slot before the content of the global variables in the gNB_MAC_INST structure used to store the result of the MAC scheduler for the current slot have been consumed by the first thread, leading to unpredictable results (all of them certainly wrong). The solution is to introduce a small memory management module for the interface between the PHY threads and the MAC scheduler. The MAC scheduler now fills the data structures passed to it, and not a global variable anymore. The PHY layer manages the structures and ensures that no data is overwritten before being fully consumed by the various threads of the PHY layer. Some care has to be taken because several PHY threads will access the same structures at the same time for a given slot (in read mode, so it's okay). A mechanism of reference counting has thus been introduced. Only one CC is supported. This restriction should not be too hard to remove if/when needed. (The code before this commit does not seem to work for more than one CC anyway.) --- CMakeLists.txt | 1 + executables/nr-gnb.c | 3 + openair1/PHY/defs_gNB.h | 2 + openair1/SCHED_NR/fapi_nr_l1.c | 20 ++- openair1/SIMULATION/NR_PHY/dlschsim.c | 11 ++ openair1/SIMULATION/NR_PHY/dlsim.c | 33 ++-- openair1/SIMULATION/NR_PHY/pbchsim.c | 11 ++ openair1/SIMULATION/NR_PHY/prachsim.c | 11 ++ openair1/SIMULATION/NR_PHY/pucchsim.c | 11 ++ openair1/SIMULATION/NR_PHY/ulschsim.c | 11 ++ openair1/SIMULATION/NR_PHY/ulsim.c | 4 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 81 +++++++--- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 85 ++++++---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 28 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 18 ++- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 9 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 4 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 69 +++++--- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 9 -- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 30 ++-- openair2/NR_PHY_INTERFACE/NR_IF_Module.h | 10 +- openair2/NR_PHY_INTERFACE/nr_sched_response.c | 153 ++++++++++++++++++ openair2/NR_PHY_INTERFACE/nr_sched_response.h | 32 ++++ 23 files changed, 497 insertions(+), 149 deletions(-) create mode 100644 openair2/NR_PHY_INTERFACE/nr_sched_response.c create mode 100644 openair2/NR_PHY_INTERFACE/nr_sched_response.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 691cb4aaa8..04f87ad8ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1474,6 +1474,7 @@ set (MAC_SRC set (MAC_NR_SRC ${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c + ${NR_PHY_INTERFACE_DIR}/nr_sched_response.c ${NR_GNB_MAC_DIR}/main.c ${NR_GNB_MAC_DIR}/config.c ${NR_GNB_MAC_DIR}/gNB_scheduler.c diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 05516e01b4..773f89416c 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -51,6 +51,7 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/MODULATION/nr_modulation.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -126,6 +127,8 @@ void tx_func(void *param) { 1); clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]); + /* this thread is done with the sched_info, decrease the reference counter */ + deref_sched_response(info->sched_response_id); } void rx_func(void *param) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 1c248bc4a9..71853765af 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -823,6 +823,8 @@ typedef struct processingData_L1tx { uint16_t num_pdsch_slot; int num_dl_pdcch; int num_ul_pdcch; + /* a reference to the sched_response, to release it when not needed anymore */ + int sched_response_id; } processingData_L1tx_t; #endif diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 43223906d5..6f644c4ba5 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -35,6 +35,7 @@ #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); @@ -131,10 +132,10 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) { // copy data from L2 interface into L1 structures module_id_t Mod_id = Sched_INFO->module_id; - nfapi_nr_dl_tti_request_t *DL_req = Sched_INFO->DL_req; - nfapi_nr_tx_data_request_t *TX_req = Sched_INFO->TX_req; - nfapi_nr_ul_tti_request_t *UL_tti_req = Sched_INFO->UL_tti_req; - nfapi_nr_ul_dci_request_t *UL_dci_req = Sched_INFO->UL_dci_req; + nfapi_nr_dl_tti_request_t *DL_req = &Sched_INFO->DL_req; + nfapi_nr_tx_data_request_t *TX_req = &Sched_INFO->TX_req; + nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req; + nfapi_nr_ul_dci_request_t *UL_dci_req = &Sched_INFO->UL_dci_req; frame_t frame = Sched_INFO->frame; sub_frame_t slot = Sched_INFO->slot; @@ -169,6 +170,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) msgTx->num_ul_pdcch = number_ul_dci_pdu; msgTx->slot = slot; msgTx->frame = frame; + /* store the sched_response_id for the TX thread to release it when done */ + msgTx->sched_response_id = Sched_INFO->sched_response_id; for (int i=0;idl_tti_request_body.dl_tti_pdu_list[i]; @@ -208,6 +211,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) for (int i=0; iul_pdcch_pdu[i] = UL_dci_req->ul_dci_pdu_list[i]; + /* Both the current thread and the TX thread will access the sched_info + * at the same time, so increase its reference counter, so that it is + * released only when both threads are done with it. + */ + inc_ref_sched_response(Sched_INFO->sched_response_id); pushNotifiedFIFO(&gNB->L1_tx_filled,res); } @@ -250,5 +258,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) if (number_dl_pdu>0) oai_nfapi_dl_tti_req(DL_req); } + + /* this thread is done with the sched_info, decrease the reference counter */ + deref_sched_response(Sched_INFO->sched_response_id); + stop_meas(&gNB->schedule_response_stats); } diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index cdbe21465f..317159f6bd 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -81,6 +81,17 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); } nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; } +void inc_ref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} +void deref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} + nrUE_params_t nrUE_params={0}; nrUE_params_t *get_nrUE_params(void) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index b2c9ac5a33..ce3c564773 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -328,7 +328,7 @@ int main(int argc, char **argv) //int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; UE_nr_rxtx_proc_t UE_proc; - NR_Sched_Rsp_t Sched_INFO; + NR_Sched_Rsp_t *Sched_INFO; gNB_MAC_INST *gNB_mac; NR_UE_MAC_INST_t *UE_mac; int cyclic_prefix_type = NFAPI_CP_NORMAL; @@ -994,28 +994,33 @@ int main(int argc, char **argv) round = 0; UE_harq_process->DLround = round; UE_harq_process->first_rx = 1; - + + Sched_INFO = malloc(sizeof(*Sched_INFO)); + if (Sched_INFO == NULL) { + LOG_E(PHY, "out of memory\n"); + exit(1); + } + memset(Sched_INFO, 0, sizeof(*Sched_INFO)); + Sched_INFO->sched_response_id = -1; + while ((roundack==0)) { round_trials[round]++; - clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); + clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req); UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1); UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round; - nr_schedule_ue_spec(0, frame, slot); - Sched_INFO.module_id = 0; - Sched_INFO.CC_id = 0; - Sched_INFO.frame = frame; - Sched_INFO.slot = slot; - Sched_INFO.DL_req = &gNB_mac->DL_req[0]; - Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[0]; - Sched_INFO.UL_dci_req = NULL; - Sched_INFO.TX_req = &gNB_mac->TX_req[0]; + nr_schedule_ue_spec(0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req); + Sched_INFO->module_id = 0; + Sched_INFO->CC_id = 0; + Sched_INFO->frame = frame; + Sched_INFO->slot = slot; + Sched_INFO->UL_dci_req.numPdus = 0; pushNotifiedFIFO(&gNB->L1_tx_free,msgL1Tx); - nr_schedule_response(&Sched_INFO); + nr_schedule_response(Sched_INFO); /* PTRS values for DLSIM calculations */ - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[Sched_INFO.CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; pdu_bit_map = pdsch_pdu_rel15->pduBitmap; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ee67e8d52e..5f254bc1cd 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -67,6 +67,17 @@ openair0_config_t openair0_cfg[MAX_CARDS]; uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; +void inc_ref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} +void deref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} + uint64_t get_softmodem_optmask(void) {return 0;} static softmodem_params_t softmodem_params; softmodem_params_t *get_softmodem_params(void) { diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 629b7316b0..aa441e4c61 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -86,6 +86,17 @@ softmodem_params_t *get_softmodem_params(void) {return 0;} instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; +void inc_ref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} +void deref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} + int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { return 0; diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 01eec03c4d..a0631767ba 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -73,6 +73,17 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); } nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; } +void inc_ref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} +void deref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} + nrUE_params_t nrUE_params={0}; nrUE_params_t *get_nrUE_params(void) { diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 344f3f3310..69b12e78ee 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -80,6 +80,17 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } }; uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; +void inc_ref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} +void deref_sched_response(int _) +{ + LOG_E(PHY, "fatal\n"); + exit(1); +} + int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req); NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 109b4faf20..d8ffdcc55e 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -759,10 +759,10 @@ int main(int argc, char **argv) NR_gNB_ULSCH_t *ulsch_gNB = &gNB->ulsch[UE_id]; // nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_process->ulsch_pdu; - nfapi_nr_ul_tti_request_t *UL_tti_req = malloc(sizeof(*UL_tti_req)); NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO)); memset((void*)Sched_INFO,0,sizeof(*Sched_INFO)); - Sched_INFO->UL_tti_req=UL_tti_req; + nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req; + Sched_INFO->sched_response_id = -1; nr_phy_data_tx_t phy_data = {0}; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 41a2153cf8..c4ed4e2d2a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -56,10 +56,13 @@ const uint8_t nr_rv_round_map[4] = { 0, 2, 3, 1 }; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; -void clear_nr_nfapi_information(gNB_MAC_INST * gNB, +void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, frame_t frameP, - sub_frame_t slotP) + sub_frame_t slotP, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req, + nfapi_nr_ul_dci_request_t *UL_dci_req) { NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; @@ -67,10 +70,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP, frameP, slotP, *scc->ssbSubcarrierSpacing); - nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP]; - nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0]; - nfapi_nr_tx_data_request_t *TX_req = &gNB->TX_req[0]; gNB->pdu_index[CC_idP] = 0; @@ -96,23 +96,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, future_ul_tti_req->n_ulcch = 0; future_ul_tti_req->n_group = 0; - /* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e., - * it walks over UL_tti_req_ahead in a circular fashion */ - const int current_index = ul_buffer_index(frameP, slotP, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size); - gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][current_index]; TX_req[CC_idP].Number_of_PDUs = 0; - } bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { return (bitmap >> (slot % 64)) & 0x01; } -void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, - frame_t frame, - sub_frame_t slot) +/* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */ +static void copy_ul_tti_req(nfapi_nr_ul_tti_request_t *to, nfapi_nr_ul_tti_request_t *from) { + int i; + to->header = from->header; + to->SFN = from->SFN; + to->Slot = from->Slot; + to->n_pdus = from->n_pdus; + to->rach_present = from->rach_present; + to->n_ulsch = from->n_ulsch; + to->n_ulcch = from->n_ulcch; + to->n_group = from->n_group; + + for (i = 0; i < from->n_pdus; i++) { + to->pdus_list[i].pdu_type = from->pdus_list[i].pdu_type; + to->pdus_list[i].pdu_size = from->pdus_list[i].pdu_size; + + switch (from->pdus_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + to->pdus_list[i].prach_pdu = from->pdus_list[i].prach_pdu; + break; + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + to->pdus_list[i].pusch_pdu = from->pdus_list[i].pusch_pdu; + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + to->pdus_list[i].pucch_pdu = from->pdus_list[i].pucch_pdu; + break; + case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: + to->pdus_list[i].srs_pdu = from->pdus_list[i].srs_pdu; + break; + } + } + + for (i = 0; i < from->n_group; i++) + to->groups_list[i] = from->groups_list[i]; +} + +void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t *sched_info) +{ protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); @@ -157,8 +187,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL; memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE); - clear_nr_nfapi_information(gNB, CC_id, frame, slot); - + clear_nr_nfapi_information(gNB, CC_id, frame, slot, &sched_info->DL_req, &sched_info->TX_req, &sched_info->UL_dci_req); } if ((slot == 0) && (frame & 127) == 0) { @@ -172,12 +201,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, schedule_nr_bwp_switch(module_idP, frame, slot); // This schedules MIB - schedule_nr_mib(module_idP, frame, slot); + schedule_nr_mib(module_idP, frame, slot, &sched_info->DL_req); // This schedules SIB1 if (get_softmodem_params()->sa == 1) - schedule_nr_sib1(module_idP, frame, slot); - + schedule_nr_sib1(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req); // This schedule PRACH if we are not in phy_test mode if (get_softmodem_params()->phy_test == 0) { @@ -194,7 +222,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } // Schedule CSI-RS transmission - nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]); + nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing], &sched_info->DL_req); // Schedule CSI measurement reporting nr_csi_meas_reporting(module_idP, frame, slot); @@ -204,22 +232,29 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // This schedule RA procedure if not in phy_test mode // Otherwise consider 5G already connected if (get_softmodem_params()->phy_test == 0) { - nr_schedule_RA(module_idP, frame, slot); + nr_schedule_RA(module_idP, frame, slot, &sched_info->UL_dci_req, &sched_info->DL_req, &sched_info->TX_req); } // This schedules the DCI for Uplink and subsequently PUSCH - nr_schedule_ulsch(module_idP, frame, slot); + nr_schedule_ulsch(module_idP, frame, slot, &sched_info->UL_dci_req); // This schedules the DCI for Downlink and PDSCH start_meas(&gNB->schedule_dlsch); - nr_schedule_ue_spec(module_idP, frame, slot); + nr_schedule_ue_spec(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req); stop_meas(&gNB->schedule_dlsch); nr_sr_reporting(gNB, frame, slot); nr_schedule_pucch(gNB, frame, slot); + /* TODO: we copy from gNB->UL_tti_req_ahead[0][current_index], ie. CC_id == 0, + * is more than 1 CC supported? + */ + AssertFatal(MAX_NUM_CCs == 1, "only 1 CC supported\n"); + const int current_index = ul_buffer_index(frame, slot, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size); + copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]); + stop_meas(&gNB->eNB_scheduler); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 587575241f..d08d2fefb3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -662,8 +662,13 @@ void nr_initiate_ra_proc(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { - +void nr_schedule_RA(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + nfapi_nr_ul_dci_request_t *ul_dci_req, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; start_meas(&mac->schedule_ra); @@ -674,15 +679,15 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); switch (ra->state) { case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); break; case Msg3_retransmission: - nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra); + nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req); break; case Msg3_dcch_dtch: - nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra); + nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); case Msg4: - nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra); + nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); break; case WAIT_Msg4_ACK: nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); @@ -695,9 +700,13 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { stop_meas(&mac->schedule_ra); } - -void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) { - +void nr_generate_Msg3_retransmission(module_id_t module_idP, + int CC_id, + frame_t frame, + sub_frame_t slot, + NR_RA_t *ra, + nfapi_nr_ul_dci_request_t *ul_dci_req) +{ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -784,8 +793,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t NR_ControlResourceSet_t *coreset = ra->coreset; AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n"); - nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id]; - const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; if (!pdcch_pdu_rel15) { @@ -1148,8 +1155,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); } -void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { - +void nr_generate_Msg2(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) +{ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; @@ -1198,7 +1211,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } // Checking if the DCI allocation is feasible in current subframe - nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); return; @@ -1369,7 +1382,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra nr_mac->cset0_bwp_size); // DL TX request - nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; // Program UL processing for Msg3 nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); @@ -1395,9 +1408,9 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; tx_req->TLVs[0].length = tx_req->PDU_length + 2; - nr_mac->TX_req[CC_id].SFN = frameP; - nr_mac->TX_req[CC_id].Number_of_PDUs++; - nr_mac->TX_req[CC_id].Slot = slotP; + TX_req->SFN = frameP; + TX_req->Number_of_PDUs++; + TX_req->Slot = slotP; // Mark the corresponding symbols RBs as used fill_pdcch_vrb_map(nr_mac, @@ -1600,7 +1613,13 @@ void prepare_dl_pdus(gNB_MAC_INST *nr_mac, LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); } -void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) +void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; @@ -1654,7 +1673,7 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram } // Checking if the DCI allocation is feasible in current subframe - nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti); return; @@ -1734,15 +1753,15 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram 0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize); // DL TX request - nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size); tx_req->PDU_length = tb_size; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; tx_req->TLVs[0].length = tb_size + 2; - nr_mac->TX_req[CC_id].SFN = frameP; - nr_mac->TX_req[CC_id].Number_of_PDUs++; - nr_mac->TX_req[CC_id].Slot = slotP; + TX_req->SFN = frameP; + TX_req->Number_of_PDUs++; + TX_req->Slot = slotP; // Mark the corresponding symbols and RBs as used fill_pdcch_vrb_map(nr_mac, @@ -1780,7 +1799,13 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram sched_ctrl->ul_failure = 0; } -void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) +void nr_generate_Msg4(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; @@ -1854,7 +1879,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } // Checking if the DCI allocation is feasible in current subframe - nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti); return; @@ -2006,15 +2031,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size)); // DL TX request - nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size); tx_req->PDU_length = harq->tb_size; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; tx_req->TLVs[0].length = harq->tb_size + 2; - nr_mac->TX_req[CC_id].SFN = frameP; - nr_mac->TX_req[CC_id].Number_of_PDUs++; - nr_mac->TX_req[CC_id].Slot = slotP; + TX_req->SFN = frameP; + TX_req->Number_of_PDUs++; + TX_req->Slot = slotP; // Mark the corresponding symbols and RBs as used fill_pdcch_vrb_map(nr_mac, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 121ad179cc..37ceeddbee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -89,10 +89,10 @@ void schedule_ssb(frame_t frame, sub_frame_t slot, } -void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req) +{ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc; - nfapi_nr_dl_tti_request_t *dl_tti_request; nfapi_nr_dl_tti_request_body_t *dl_req; NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib; uint8_t num_tdd_period,num_ssb; @@ -103,8 +103,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) cc = &gNB->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - dl_tti_request = &gNB->DL_req[CC_id]; - dl_req = &dl_tti_request->dl_tti_request_body; + dl_req = &DL_req->dl_tti_request_body; // get MIB every 8 frames if(((slotP == 0) && (frameP & 7) == 0) || @@ -255,7 +254,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) } } - void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { //---------------------------------------- } @@ -520,8 +518,12 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, } -void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { - +void schedule_nr_sib1(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) +{ // TODO: Get these values from RRC const int CC_id = 0; uint8_t candidate_idx = 0; @@ -586,12 +588,12 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) candidate_idx, sib1_sdu_length); - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, tda_info.startSymbolIndex, tda_info.nrOfSymbols); - const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; - nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; + const int ntx_req = TX_req->Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; // Data to be transmitted memcpy(tx_req->TLVs[0].value.direct, sib1_payload, TBS); @@ -600,9 +602,9 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) tx_req->PDU_index = pdu_index; tx_req->num_TLV = 1; tx_req->TLVs[0].length = TBS + 2; - gNB_mac->TX_req[CC_id].Number_of_PDUs++; - gNB_mac->TX_req[CC_id].SFN = frameP; - gNB_mac->TX_req[CC_id].Slot = slotP; + TX_req->Number_of_PDUs++; + TX_req->SFN = frameP; + TX_req->Slot = slotP; type0_PDCCH_CSS_config->active = false; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7d3cd511e9..e6f32b1405 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -873,8 +873,10 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, - sub_frame_t slot) { - + sub_frame_t slot, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) +{ gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot)) @@ -885,7 +887,7 @@ void nr_schedule_ue_spec(module_id_t module_id, const int CC_id = 0; NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; NR_UEs_t *UE_info = &gNB_mac->UE_info; - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -1326,16 +1328,16 @@ void nr_schedule_ue_spec(module_id_t module_id, T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS)); } - const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; - nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; + const int ntx_req = TX_req->Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; tx_req->PDU_length = TBS; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; tx_req->TLVs[0].length = TBS + 2; memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS); - gNB_mac->TX_req[CC_id].Number_of_PDUs++; - gNB_mac->TX_req[CC_id].SFN = frame; - gNB_mac->TX_req[CC_id].Slot = slot; + TX_req->Number_of_PDUs++; + TX_req->SFN = frame; + TX_req->Slot = slot; /* mark UE as scheduled */ sched_pdsch->rbSize = 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 09d4d95458..99ce0ab235 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2538,11 +2538,8 @@ int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, } } -void nr_csirs_scheduling(int Mod_idP, - frame_t frame, - sub_frame_t slot, - int n_slots_frame){ - +void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req) +{ int CC_id = 0; NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; @@ -2581,7 +2578,7 @@ void nr_csirs_scheduling(int Mod_idP, NR_NZP_CSI_RS_Resource_t *nzpcsi; int period, offset; - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){ nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 09aad3d9cb..3c314c6c86 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1997,7 +1997,7 @@ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id) return nr_fr1_ulsch_preprocessor; } -void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) +void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; /* Uplink data ONLY can be scheduled when the current slot is downlink slot, @@ -2010,8 +2010,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) if (!do_sched) return; - const int CC_id = 0; - nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id]; ul_dci_req->SFN = frame; ul_dci_req->Slot = slot; /* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index b62984943c..a700c5c652 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -60,17 +60,19 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); -void clear_nr_nfapi_information(gNB_MAC_INST * gNB, +void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, - frame_t frameP, - sub_frame_t subframeP); + frame_t frameP, + sub_frame_t slotP, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req, + nfapi_nr_ul_dci_request_t *UL_dci_req); void nr_mac_update_timers(module_id_t module_id, frame_t frame, sub_frame_t slot); -void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, - frame_t frame_rxP, sub_frame_t slot_rxP); +void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP, NR_Sched_Rsp_t *sched_info); void schedule_nr_bwp_switch(module_id_t module_id, frame_t frame, @@ -81,7 +83,9 @@ void schedule_nr_bwp_switch(module_id_t module_id, * messages, statistics, HARQ handling, CEs, ... */ void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, - sub_frame_t slot); + sub_frame_t slot, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req); uint32_t schedule_control_sib1(module_id_t module_id, int CC_id, @@ -95,21 +99,30 @@ uint32_t schedule_control_sib1(module_id_t module_id, /* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id); -void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +void schedule_nr_sib1(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req); -void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req); /* \brief main UL scheduler function. Calls a preprocessor to decide on * resource allocation, then "post-processes" resource allocation (nFAPI * messages, statistics, HARQ handling, ... */ -void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot); +void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req); /* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id); /////// Random Access MAC-PHY interface functions and primitives /////// -void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); +void nr_schedule_RA(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + nfapi_nr_ul_dci_request_t *ul_dci_req, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req); /* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure. @param module_idP Instance ID of gNB @@ -134,7 +147,12 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_RA_t *ra, int16_t *tdd_beam_association); -void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); +void nr_generate_Msg3_retransmission(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_ul_dci_request_t *ul_dci_req); /* \brief Function in gNB to fill RAR pdu when requested by PHY. @param ra Instance of RA resources of gNB @@ -201,10 +219,7 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr void nr_schedule_srs(int module_id, frame_t frame, int slot); -void nr_csirs_scheduling(int Mod_idP, - frame_t frame, - sub_frame_t slot, - int n_slots_frame); +void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req); void nr_csi_meas_reporting(int Mod_idP, frame_t frameP, @@ -365,13 +380,31 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, unsigned char drx_cmd, unsigned char *ue_cont_res_id); -void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); +void nr_generate_Msg2(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *dl_req, + nfapi_nr_tx_data_request_t *TX_req); -void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); +void nr_generate_Msg4(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req); void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra); -void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); +void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req); int binomial(int n, int k); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 96734aa8b1..1cd0f89736 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -719,24 +719,15 @@ typedef struct gNB_MAC_INST_s { uint16_t ulprbbl[MAX_BWP_SIZE]; /// NFAPI Config Request Structure nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX]; - /// NFAPI DL Config Request Structure - nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX]; /// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure /// keeps pointers to PDCCH PDUs within DL_req so that we can easily track /// PDCCH PDUs per CC/BWP/CORESET nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_CORESET]; - /// NFAPI UL TTI Request Structure, simple pointer into structure - /// UL_tti_req_ahead for current frame/slot - nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX]; /// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated /// because length depends on number of slots nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX]; int UL_tti_req_ahead_size; int vrb_map_UL_size; - /// NFAPI HI/DCI0 Config Request Structure - nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX]; - /// NFAPI DL PDU structure - nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX]; NR_UEs_t UE_info; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 60db353949..117b028c9a 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -39,12 +39,12 @@ #include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/gnb_ind_vars.h" #include "openair2/PHY_INTERFACE/queue_t.h" +#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" #define MAX_IF_MODULES 100 //#define UL_HARQ_PRINT static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES]; -static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); @@ -389,7 +389,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { AssertFatal(UL_info!=NULL,"UL_info is null\n"); module_id_t module_id = UL_info->module_id; int CC_id = UL_info->CC_id; - NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id]; + NR_Sched_Rsp_t *sched_info; NR_IF_Module_t *ifi = nr_if_inst[module_id]; LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n", @@ -451,8 +451,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { } if (NFAPI_MODE != NFAPI_MODE_PNF) { gNB_MAC_INST *mac = RC.nrmac[module_id]; - // clear UL DCI prior to handling ULSCH - mac->UL_dci_req[CC_id].numPdus = 0; if (ifi->CC_mask==0) { ifi->current_frame = UL_info->frame; ifi->current_slot = UL_info->slot; @@ -471,21 +469,20 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { */ nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id]; int spf = get_spf(cfg); + sched_info = allocate_sched_response(); + // clear UL DCI prior to handling ULSCH + sched_info->UL_dci_req.numPdus = 0; gNB_dlsch_ulsch_scheduler(module_id, - (UL_info->frame+((UL_info->slot>(spf-1-ifi->sl_ahead))?1:0)) % 1024, - (UL_info->slot+ifi->sl_ahead)%spf); + (UL_info->frame + ((UL_info->slot > (spf - 1 - ifi->sl_ahead)) ? 1 : 0)) % 1024, + (UL_info->slot + ifi->sl_ahead) % spf, + sched_info); ifi->CC_mask = 0; sched_info->module_id = module_id; sched_info->CC_id = CC_id; sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-ifi->sl_ahead)) ? 1 : 0)) % 1024; sched_info->slot = (UL_info->slot+ifi->sl_ahead)%spf; - sched_info->DL_req = &mac->DL_req[CC_id]; - sched_info->UL_dci_req = &mac->UL_dci_req[CC_id]; - sched_info->UL_tti_req = mac->UL_tti_req[CC_id]; - - sched_info->TX_req = &mac->TX_req[CC_id]; #ifdef DUMP_FAPI dump_dl(sched_info); #endif @@ -496,10 +493,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { CC_id); ifi->NR_Schedule_response(sched_info); - LOG_D(NR_PHY,"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n", - sched_info->frame, - sched_info->slot, - sched_info->DL_req->dl_tti_request_body.nPDUs); + LOG_D(NR_PHY, + "NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n", + sched_info->frame, + sched_info->slot, + sched_info->DL_req.dl_tti_request_body.nPDUs); } } } @@ -520,5 +518,7 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id); } + init_sched_response(); + return nr_if_inst[Mod_id]; } diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 47e961da2b..f85d44398f 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -83,6 +83,8 @@ typedef struct { typedef struct { + /// the ID of this sched_response - used by sched_reponse memory management + int sched_response_id; /// Module ID module_id_t module_id; /// CC ID @@ -92,13 +94,13 @@ typedef struct { /// slot slot_t slot; /// nFAPI DL Config Request - nfapi_nr_dl_tti_request_t *DL_req; + nfapi_nr_dl_tti_request_t DL_req; /// nFAPI UL Config Request - nfapi_nr_ul_tti_request_t *UL_tti_req; + nfapi_nr_ul_tti_request_t UL_tti_req; /// nFAPI UL_DCI Request - nfapi_nr_ul_dci_request_t *UL_dci_req; + nfapi_nr_ul_dci_request_t UL_dci_req; /// Pointers to DL SDUs - nfapi_nr_tx_data_request_t *TX_req; + nfapi_nr_tx_data_request_t TX_req; } NR_Sched_Rsp_t; typedef struct { diff --git a/openair2/NR_PHY_INTERFACE/nr_sched_response.c b/openair2/NR_PHY_INTERFACE/nr_sched_response.c new file mode 100644 index 0000000000..f0aa25781c --- /dev/null +++ b/openair2/NR_PHY_INTERFACE/nr_sched_response.c @@ -0,0 +1,153 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* sched response memory management */ + +/* A system with reference counting is implemented. + * It is needed because several threads will access the structure, + * which has to be released only when all the threads are done with it. + * So the main thread allocates a sched_response with allocate_sched_response() + * which allocates a sched_response with a reference counter == 1 + * and then for each other thread that will access sched_response, a + * call to inc_ref_sched_response() is done. When a thread has finished + * using the sched_response, it calls deref_sched_response() which will + * in turn call release_sched_response() when the reference counter becomes 0. + * + * The several threads in question are accessing the _same_ sched_response, + * it has not to be confused with the various TX processes that may run in + * parallel and which are accessing _different_ sched_response (the maximum + * number of parallel processes is N_RESP). + */ + +#include "nr_sched_response.h" + +#include +#include + +#include "common/utils/LOG/log.h" +#include "common/utils/assertions.h" + +#define N_RESP 3 +static NR_Sched_Rsp_t resp[N_RESP]; +static int resp_refcount[N_RESP]; +static int resp_freelist_next[N_RESP]; +static int resp_freelist_head; +static pthread_mutex_t resp_mutex = PTHREAD_MUTEX_INITIALIZER; +static bool resp_freelist_inited = false; + +void init_sched_response(void) +{ + /* init only once */ + if (pthread_mutex_lock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_lock failed\n"); + if (resp_freelist_inited) { + if (pthread_mutex_unlock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_unlock failed\n"); + return; + } + resp_freelist_inited = true; + if (pthread_mutex_unlock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_unlock failed\n"); + + int i; + for (i = 0; i < N_RESP - 1; i++) + resp_freelist_next[i] = i + 1; + resp_freelist_next[N_RESP - 1] = -1; + resp_freelist_head = 0; +} + +NR_Sched_Rsp_t *allocate_sched_response(void) +{ + NR_Sched_Rsp_t *ret; + int new_head; + + if (pthread_mutex_lock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_lock failed\n"); + + AssertFatal(resp_freelist_inited, "sched_response used before init\n"); + + if (resp_freelist_head == -1) { + LOG_E(PHY, "fatal: sched_response cannot be allocated, increase N_RESP\n"); + exit(1); + } + + ret = &resp[resp_freelist_head]; + ret->sched_response_id = resp_freelist_head; + resp_refcount[resp_freelist_head] = 1; + + new_head = resp_freelist_next[resp_freelist_head]; + resp_freelist_next[resp_freelist_head] = -1; + resp_freelist_head = new_head; + + if (pthread_mutex_unlock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_unlock failed\n"); + + return ret; +} + +static void release_sched_response(int sched_response_id) +{ + resp_freelist_next[sched_response_id] = resp_freelist_head; + resp_freelist_head = sched_response_id; +} + +void deref_sched_response(int sched_response_id) +{ + /* simulators (ulsim/dlsim) deal with their own sched_response but call + * functions that call this one, let's handle this case with a special + * value -1 where we do nothing (yes it's a hack) + */ + if (sched_response_id == -1) + return; + + if (pthread_mutex_lock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_lock failed\n"); + + AssertFatal(resp_freelist_inited, "sched_response used before init\n"); + AssertFatal(resp_refcount[sched_response_id] > 0, "sched_reponse decreased too much\n"); + + resp_refcount[sched_response_id]--; + if (resp_refcount[sched_response_id] == 0) + release_sched_response(sched_response_id); + + if (pthread_mutex_unlock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_unlock failed\n"); +} + +void inc_ref_sched_response(int sched_response_id) +{ + /* simulators (ulsim/dlsim) deal with their own sched_response but call + * functions that call this one, let's handle this case with a special + * value -1 where we do nothing (yes it's a hack) + */ + if (sched_response_id == -1) + return; + + if (pthread_mutex_lock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_lock failed\n"); + + AssertFatal(resp_freelist_inited, "sched_response used before init\n"); + + resp_refcount[sched_response_id]++; + + if (pthread_mutex_unlock(&resp_mutex)) + AssertFatal(0, "pthread_mutex_unlock failed\n"); +} diff --git a/openair2/NR_PHY_INTERFACE/nr_sched_response.h b/openair2/NR_PHY_INTERFACE/nr_sched_response.h new file mode 100644 index 0000000000..33a0af93d0 --- /dev/null +++ b/openair2/NR_PHY_INTERFACE/nr_sched_response.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H +#define OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H + +#include "NR_IF_Module.h" + +void init_sched_response(void); +NR_Sched_Rsp_t *allocate_sched_response(void); +void deref_sched_response(int sched_response_id); +void inc_ref_sched_response(int sched_response_id); + +#endif /* OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H */ From 1679cf38ba30794248b648f7657940a674cdfac6 Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Wed, 5 Apr 2023 22:26:08 +0200 Subject: [PATCH 36/36] NR RRC - RRCReestablishment - Reviewer comments Changes 1. Passing function argument by reference. 2. Use a pointer for ue->established_drbs[drb_id - 1] in generateDRB. --- openair2/RRC/NR/rrc_gNB.c | 4 +- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 96 ++++++++++++------------- openair2/RRC/NR/rrc_gNB_radio_bearers.h | 2 +- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ec5ded4989..f9447fc57a 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -644,7 +644,7 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, 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]); + 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); @@ -1374,7 +1374,7 @@ void RRCReestablishmentComplete_fill_DRB_configList(const protocol_ctxt_t *const 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]); + DRB_config = generateDRB_ASN1(&ue_p->established_drbs[i]); asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config); } diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index e9fa7922fb..b4d6c55762 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -45,56 +45,56 @@ void generateDRB(gNB_RRC_UE_t *ue, { int i; int qos_flow_index; - if (ue->established_drbs[drb_id - 1].status == DRB_INACTIVE) { + drb_t *est_drb = &ue->established_drbs[drb_id - 1]; + if (est_drb->status == DRB_INACTIVE) { /* DRB Management */ - ue->established_drbs[drb_id - 1].drb_id = drb_id; - ue->established_drbs[drb_id - 1].reestablishPDCP = -1; - ue->established_drbs[drb_id - 1].recoverPDCP = -1; + est_drb->drb_id = drb_id; + est_drb->reestablishPDCP = -1; + est_drb->recoverPDCP = -1; for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { - if ((ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == 0 - || ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id) - && ue->established_drbs[drb_id - 1].defaultDRBid == 0) { - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.defaultDRB = true; - ue->established_drbs[drb_id - 1].defaultDRBid = drb_id; + 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 */ - ue->established_drbs[drb_id - 1].cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id; + 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) { - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; + 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 { - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; + 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++) { - ue->established_drbs[drb_id - 1].cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = - pduSession->param.qos[qos_flow_index].qfi; + 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) - ue->established_drbs[drb_id - 1].status = DRB_ACTIVE_NONGBR; + est_drb->status = DRB_ACTIVE_NONGBR; else - ue->established_drbs[drb_id - 1].status = DRB_ACTIVE; + est_drb->status = DRB_ACTIVE; } /* PDCP Configuration */ - ue->established_drbs[drb_id - 1].pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; - ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - ue->established_drbs[drb_id - 1].pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - ue->established_drbs[drb_id - 1].pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100; - ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - ue->established_drbs[drb_id - 1].pdcp_config.headerCompression.NotUsed = 0; + 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) - ue->established_drbs[drb_id - 1].pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled; + est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled; else - ue->established_drbs[drb_id - 1].pdcp_config.integrityProtection = 1; + est_drb->pdcp_config.integrityProtection = 1; if (do_drb_ciphering) - ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = 1; + est_drb->pdcp_config.ext1.cipheringDisabled = 1; else - ue->established_drbs[drb_id - 1].pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; + est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; } } -NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) +NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1) { NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config)); NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); @@ -104,39 +104,39 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1) asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig); asn1cCalloc(pdcpConfig->drb, drb); - DRB_config->drb_Identity = drb_asn1.drb_id; - association->present = drb_asn1.cnAssociation.present; + DRB_config->drb_Identity = drb_asn1->drb_id; + association->present = drb_asn1->cnAssociation.present; /* SDAP Configuration */ - SDAP_config->pdu_Session = drb_asn1.cnAssociation.sdap_config.pdusession_id; - SDAP_config->sdap_HeaderDL = drb_asn1.cnAssociation.sdap_config.sdap_HeaderDL; - SDAP_config->sdap_HeaderUL = drb_asn1.cnAssociation.sdap_config.sdap_HeaderUL; - SDAP_config->defaultDRB = drb_asn1.cnAssociation.sdap_config.defaultDRB; + SDAP_config->pdu_Session = drb_asn1->cnAssociation.sdap_config.pdusession_id; + SDAP_config->sdap_HeaderDL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderDL; + SDAP_config->sdap_HeaderUL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderUL; + SDAP_config->defaultDRB = drb_asn1->cnAssociation.sdap_config.defaultDRB; for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) { - if (drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) { + if (drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) { asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi); - *qfi = drb_asn1.cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index]; + *qfi = drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index]; } } association->choice.sdap_Config = SDAP_config; /* PDCP Configuration */ - asn1cCallocOne(drb->discardTimer, drb_asn1.pdcp_config.discardTimer); - asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1.pdcp_config.pdcp_SN_SizeUL); - asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1.pdcp_config.pdcp_SN_SizeDL); - asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1.pdcp_config.t_Reordering); + asn1cCallocOne(drb->discardTimer, drb_asn1->pdcp_config.discardTimer); + asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1->pdcp_config.pdcp_SN_SizeUL); + asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1->pdcp_config.pdcp_SN_SizeDL); + asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1->pdcp_config.t_Reordering); - drb->headerCompression.present = drb_asn1.pdcp_config.headerCompression.present; - drb->headerCompression.choice.notUsed = drb_asn1.pdcp_config.headerCompression.NotUsed; + drb->headerCompression.present = drb_asn1->pdcp_config.headerCompression.present; + drb->headerCompression.choice.notUsed = drb_asn1->pdcp_config.headerCompression.NotUsed; - if (!drb_asn1.pdcp_config.integrityProtection) { - asn1cCallocOne(drb->integrityProtection, drb_asn1.pdcp_config.integrityProtection); + if (!drb_asn1->pdcp_config.integrityProtection) { + asn1cCallocOne(drb->integrityProtection, drb_asn1->pdcp_config.integrityProtection); } - if (!drb_asn1.pdcp_config.ext1.cipheringDisabled) { + if (!drb_asn1->pdcp_config.ext1.cipheringDisabled) { asn1cCalloc(pdcpConfig->ext1, ext1); - asn1cCallocOne(ext1->cipheringDisabled, drb_asn1.pdcp_config.ext1.cipheringDisabled); + asn1cCallocOne(ext1->cipheringDisabled, drb_asn1->pdcp_config.ext1.cipheringDisabled); } return DRB_config; diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 732394ef82..219bc21948 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -38,7 +38,7 @@ /// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t. /// @param drb_t drb_asn1 /// @return Returns the ASN1 DRB-ToAddMod structs. -NR_DRB_ToAddMod_t *generateDRB_ASN1(drb_t drb_asn1); +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. /// @param ue The gNB_RRC_UE_t struct that holds information for the UEs