From c63abcd0f279326229999d872de4fa8404e48289 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 2 Apr 2021 15:57:42 +0200 Subject: [PATCH 01/29] nsa: x2ap: hack: exit gNB if connection to eNB failed Exit gNB if connection to eNB failed - to be modified if needed. We may want to try to connect over and over again until we succeed but the modifications to the code to get this behavior are complex. Exit on error is a simple solution. --- openair2/X2AP/x2ap_eNB.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 321190015d..0474d417df 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -130,6 +130,18 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa DevAssert(x2ap_enb_data_p != NULL); dump_trees(); + /* gNB: exit if connection to eNB failed - to be modified if needed. + * We may want to try to connect over and over again until we succeed + * but the modifications to the code to get this behavior are complex. + * Exit on error is a simple solution that can be caught by a script + * for example. + */ + if (instance_p->cell_type == CELL_MACRO_GNB + && sctp_new_association_resp->sctp_state == SCTP_STATE_UNREACHABLE) { + X2AP_ERROR("association with eNB failed, is it running? If no, run it first. If yes, check IP addresses in your configuration file.\n"); + exit(1); + } + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, From 80cc9b445cf635f15df13c983ab00a63aacdb426 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 7 Apr 2021 13:30:53 +0200 Subject: [PATCH 02/29] Add script file for (re)starting gNB automatically --- ci-scripts/auto_start_gnb.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 ci-scripts/auto_start_gnb.sh diff --git a/ci-scripts/auto_start_gnb.sh b/ci-scripts/auto_start_gnb.sh new file mode 100644 index 0000000000..86ffc66d18 --- /dev/null +++ b/ci-scripts/auto_start_gnb.sh @@ -0,0 +1,7 @@ +#!/bin/bash +while true +do + echo "gNB will be started automatically..." + sleep 1 + sudo .././cmake_targets/ran_build/build/nr-softmodem -E -O ../targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +done From ff87164011db6bdee0e46389d1c9dfaa31cb1cff Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 26 Apr 2021 16:31:20 +0200 Subject: [PATCH 03/29] bugfixes in FR2 scheduling of ssbs --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 ++-- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 60fe897456..e599d23447 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -142,7 +142,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, case FAPI_NR_RX_PDU_TYPE_MIB: rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output; rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.additional_bits = ue->pbch_vars[gNB_id]->xtra_byte; - rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = frame_parms->ssb_index; + rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = (frame_parms->ssb_index)&0x7; rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_length = frame_parms->Lmax; rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.cell_id = frame_parms->Nid_cell; break; @@ -368,7 +368,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); - LOG_D(PHY,"[UE %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id); + LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id); ret = nr_rx_pbch(ue, proc, ue->pbch_vars[gNB_id], diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 91142c3728..9701d4f1da 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -253,8 +253,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) case 3: // long bitmap FR2 max 64 SSBs num_ssb = 0; - for (int i_ssb=0; i_ssb<63; i_ssb++) { - if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) { + for (int i_ssb=0; i_ssb<64; i_ssb++) { + if ((longBitmap->buf[i_ssb/8]>>(7-(i_ssb%8)))&0x01) { ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ From bd0609433834bc0f8e8ced9f11e2b62385fedc15 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 26 Apr 2021 17:56:51 +0200 Subject: [PATCH 04/29] another bug fixed --- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index ef884512fd..66c3de97ea 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -589,7 +589,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i)); } - ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb); + ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,frame_parms->ssb_index); if (frame_parms->half_frame_bit) ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot; From 84e57113c88f2bce7e010d937100738d47cfccaa Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Mar 2021 15:10:38 +0100 Subject: [PATCH 05/29] initial_csi_index depends on local_uid Nb_ue is not unique among UEs: consider 2 UEs present. The last UE has CSI idx "2". Now the first UE disconnects, and a new UE connects. It will also get CSI idx "2", and I assume this is not what we want. --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/NR/rrc_gNB_nsa.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index a26a4ac5b1..0bb46d61ca 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1287,7 +1287,7 @@ uint16_t do_RRCReconfiguration( // 1, // 1, // carrier->pdsch_AntennaPorts, - // carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]); + // carrier->initial_csi_index[ue_context_p->local_uid + 1]); /******************** Meas Config ********************/ // measConfig diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 2336c758fc..4c0c506b8d 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -152,7 +152,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; - carrier->initial_csi_index[rrc->Nb_ue] = 0; + carrier->initial_csi_index[ue_context_p->local_uid + 1] = 0; ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ fill_default_rbconfig(ue_context_p->ue_context.rb_config, @@ -245,14 +245,14 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, - carrier->initial_csi_index[rrc->Nb_ue]); + carrier->initial_csi_index[ue_context_p->local_uid + 1]); } else { fill_default_reconfig(carrier->servingcellconfigcommon, NULL, reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, - carrier->initial_csi_index[rrc->Nb_ue]); + carrier->initial_csi_index[ue_context_p->local_uid + 1]); } ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); From f39b97a9e8c8646696e169f5ea18030451264ee6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Mar 2021 15:51:17 +0100 Subject: [PATCH 06/29] Execute nr_schedule_pucch() only in UL slots --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index f477066fc6..a8a7f3ef87 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -118,8 +118,13 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = { void nr_schedule_pucch(int Mod_idP, frame_t frameP, - sub_frame_t slotP) { - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + sub_frame_t slotP) +{ + gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP]; + if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP)) + return; + + NR_UE_info_t *UE_info = &nrmac->UE_info; const NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { From c2d16eb8d5396f44a1b15a4bc501a2078bff8152 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Mar 2021 15:26:07 +0100 Subject: [PATCH 07/29] Configure secondaryCellGroup: dedicated PUCCH, CSI, Preamble - Configure PUCCH Format 0 to be in separate RBs (each UE has dedicated resources) - Configure RA preamble to be different per UE - Configure CSI offset such that no two UEs have their report in the same frame --- openair1/SIMULATION/NR_PHY/dlsim.c | 8 +------- openair1/SIMULATION/NR_PHY/ulsim.c | 8 +------- openair2/RRC/NR/MESSAGES/asn1_msg.c | 3 ++- openair2/RRC/NR/nr_rrc_proto.h | 6 ++++-- openair2/RRC/NR/rrc_gNB_nsa.c | 6 ++++-- openair2/RRC/NR/rrc_gNB_reconfig.c | 23 ++++++++++++++++------- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index f247860e00..164ca2da43 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -717,13 +717,7 @@ int main(int argc, char **argv) prepare_scd(scd); - fill_default_secondaryCellGroup(scc, - scd, - secondaryCellGroup, - 0, - 1, - n_tx, - 0); + fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0); /* RRC parameter validation for secondaryCellGroup */ fix_scd(scd); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 920994810d..0578635807 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -663,13 +663,7 @@ int main(int argc, char **argv) prepare_scd(scd); - fill_default_secondaryCellGroup(scc, - scd, - secondaryCellGroup, - 0, - 1, - n_tx, - 0); + fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0); // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 0bb46d61ca..39222f814d 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1287,7 +1287,8 @@ uint16_t do_RRCReconfiguration( // 1, // 1, // carrier->pdsch_AntennaPorts, - // carrier->initial_csi_index[ue_context_p->local_uid + 1]); + // carrier->initial_csi_index[ue_context_p->local_uid + 1], + // ue_context_pP->local_uid); /******************** Meas Config ********************/ // measConfig diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index ea7b853c03..7923cf6e05 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -85,14 +85,16 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco int scg_id, int servCellIndex, int n_physical_antenna_ports, - int initial_csi_index); + int initial_csi_index, + int uid); void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_ServingCellConfig_t *servingcellconfigdedicated, NR_RRCReconfiguration_IEs_t *reconfig, NR_CellGroupConfig_t *secondaryCellGroup, int n_physical_antenna_ports, - int initial_csi_index); + int initial_csi_index, + int uid); void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, int eps_bearer_id, int rb_id, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 4c0c506b8d..7861f2166c 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -245,14 +245,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, - carrier->initial_csi_index[ue_context_p->local_uid + 1]); + carrier->initial_csi_index[ue_context_p->local_uid + 1], + ue_context_p->local_uid); } else { fill_default_reconfig(carrier->servingcellconfigcommon, NULL, reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, - carrier->initial_csi_index[ue_context_p->local_uid + 1]); + carrier->initial_csi_index[ue_context_p->local_uid + 1], + ue_context_p->local_uid); } ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index cd5ded9714..97533bde7c 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -149,7 +149,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco int scg_id, int servCellIndex, int n_physical_antenna_ports, - int initial_csi_index) { + int initial_csi_index, + int uid) { AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n"); AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n"); @@ -251,7 +252,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco if ((bitmap>>(63-i))&0x01){ ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); ssbElem[n_ssb]->ssb = i; - ssbElem[n_ssb]->ra_PreambleIndex = 63; + ssbElem[n_ssb]->ra_PreambleIndex = 63 - (uid % 64); ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]); n_ssb++; } @@ -975,7 +976,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3)); pucchres0->pucch_ResourceId=1; - pucchres0->startingPRB=8; + pucchres0->startingPRB= (8 + uid) % curr_bwp; pucchres0->intraSlotFrequencyHopping=NULL; pucchres0->secondHopPRB=NULL; pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -986,7 +987,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); pucchres1->pucch_ResourceId=2; - pucchres1->startingPRB=8; + pucchres1->startingPRB= (8 + uid) % curr_bwp; pucchres1->intraSlotFrequencyHopping=NULL; pucchres1->secondHopPRB=NULL; pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -1177,7 +1178,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco csirep1->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; csirep1->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep1->reportConfigType.choice.periodic)); csirep1->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320; - csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 49; + csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 9 + (10 * uid) % 320; NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1)); pucchcsires1->uplinkBandwidthPartId=1; pucchcsires1->pucch_Resource=3; @@ -1241,14 +1242,22 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon NR_RRCReconfiguration_IEs_t *reconfig, NR_CellGroupConfig_t *secondaryCellGroup, int n_physical_antenna_ports, - int initial_csi_index) { + int initial_csi_index, + int uid) { AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n"); AssertFatal(reconfig!=NULL,"reconfig is null\n"); AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n"); // radioBearerConfig reconfig->radioBearerConfig=NULL; // secondaryCellGroup - fill_default_secondaryCellGroup(servingcellconfigcommon,servingcellconfigdedicated,secondaryCellGroup,1,1,n_physical_antenna_ports,initial_csi_index); + fill_default_secondaryCellGroup(servingcellconfigcommon, + servingcellconfigdedicated, + secondaryCellGroup, + 1, + 1, + n_physical_antenna_ports, + initial_csi_index, + uid); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); char scg_buffer[1024]; From b005f9594bd8e1b8e4144c0ef93281a7f36b328b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Mar 2021 15:30:39 +0100 Subject: [PATCH 08/29] Statically allocate PUCCH F0 resource index 0 for AckNack --- openair2/LAYER2/NR_MAC_gNB/config.c | 8 ---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 42 ++----------------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 4 -- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 -- 4 files changed, 4 insertions(+), 54 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 528edc64aa..98e9ce4351 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -372,14 +372,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL, "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n"); - for (int i = 0; i < MAX_NUM_BWP; ++i) { - RC.nrmac[Mod_idP]->pucch_index_used[i] = - calloc(n, sizeof(*RC.nrmac[Mod_idP]->pucch_index_used)); - AssertFatal(RC.nrmac[Mod_idP]->pucch_index_used[i], - "could not allocate memory for RC.nrmac[]->pucch_index_used[%d]\n", - i); - } - LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n"); config_common(Mod_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index a8a7f3ef87..5f918bbcd3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1109,10 +1109,7 @@ bool nr_acknack_scheduling(int mod_id, * * we do not multiplex with CSI, which is always in pucch_sched[2] * * SR uses format 0 and is allocated in the first UL (mixed) slot (and not * later) - * * that the PUCCH resource set 0 (for up to 2 bits) points to the first N - * PUCCH resources, where N is the number of resources in the PUCCH - * resource set. This is used in pucch_index_used, which counts the used - * resources by index, and not by their ID! */ + * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */ NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; AssertFatal(pucch->csi_bits == 0, @@ -1198,12 +1195,6 @@ bool nr_acknack_scheduling(int mod_id, /* we need to find a new PUCCH occasion */ - NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - DevAssert(pucch_Config->resourceToAddModList->list.count > 0); - DevAssert(pucch_Config->resourceSetToAddModList->list.count > 0); - const int n_res = pucch_Config->resourceSetToAddModList->list.array[0]->resourceList.list.count; - int *pucch_index_used = RC.nrmac[mod_id]->pucch_index_used[sched_ctrl->active_ubwp->bwp_Id]; - /* if time information is outdated (e.g., last PUCCH occasion in last frame), * set to first possible UL occasion in this frame. Note that if such UE is * scheduled a lot and used all AckNacks, pucch->frame might have been @@ -1217,22 +1208,6 @@ bool nr_acknack_scheduling(int mod_id, pucch->ul_slot = first_ul_slot_tdd; } - // increase to first slot in which PUCCH resources are available - while (pucch_index_used[pucch->ul_slot] >= n_res) { - pucch->ul_slot++; - /* if there is no free resource anymore, abort search */ - if ((pucch->frame == frame - && pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots) - || (pucch->frame == frame + 1)) { - LOG_E(MAC, - "%4d.%2d no free PUCCH resources anymore while searching for UE %d\n", - frame, - slot, - UE_id); - return false; - } - } - // advance ul_slot if it is not reachable by UE pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]); @@ -1279,22 +1254,13 @@ bool nr_acknack_scheduling(int mod_id, pucch->timing_indicator = i; // index in the list of timing indicators pucch->dai_c++; - const int pucch_res = pucch_index_used[pucch->ul_slot]; - pucch->resource_indicator = pucch_res; - pucch_index_used[pucch->ul_slot] += 1; - AssertFatal(pucch_index_used[pucch->ul_slot] <= n_res, - "UE %d in %4d.%2d: pucch_index_used is %d (%d available)\n", - UE_id, - pucch->frame, - pucch->ul_slot, - pucch_index_used[pucch->ul_slot], - n_res); + pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources /* verify that at that slot and symbol, resources are free. We only do this * for initialCyclicShift 0 (we assume it always has that one), so other * initialCyclicShifts can overlap with ICS 0!*/ - const NR_PUCCH_Resource_t *resource = - pucch_Config->resourceToAddModList->list.array[pucch_res]; + const NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; + const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator]; DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); if (resource->format.choice.format0->initialCyclicShift == 0) { uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE]; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index c8ea892ca5..50437db3cf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -705,10 +705,6 @@ typedef struct gNB_MAC_INST_s { int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE]; /// list of allocated beams per period int16_t *tdd_beam_association; - /// PUCCH: keep track of the resources has already been used by saving the - /// highest index not yet been used in a given slot. Dynamically allocated - /// so we can have it for every slot as a function of the numerology - int *pucch_index_used[MAX_NUM_BWP]; /// bitmap of DLSCH slots, can hold up to 160 slots uint64_t dlsch_slot_bitmap[3]; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index e42d19167d..a789f0c34e 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -105,10 +105,6 @@ void handle_nr_uci(NR_UL_IND_t *UL_info) } UL_info->uci_ind.num_ucis = 0; - - // mark corresponding PUCCH resources as free - // NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs - RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0; } From 4f4e25852fc896480f22ab57e1e7f1a1c57f72b8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Mar 2021 16:14:35 +0100 Subject: [PATCH 09/29] Reduce sched_pucch array length, we only need two entries --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 8 ++++---- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 8 +++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 5f918bbcd3..318003ea0a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -509,11 +509,11 @@ void nr_csi_meas_reporting(int Mod_idP, // find free PUCCH that is in order with possibly existing PUCCH // schedulings (other CSI, SR) - NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[2]; + NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[1]; AssertFatal(curr_pucch->csi_bits == 0 && !curr_pucch->sr_flag && curr_pucch->dai_c == 0, - "PUCCH not free at index 2 for UE %04x\n", + "PUCCH not free at index 1 for UE %04x\n", UE_info->rnti[UE_id]); curr_pucch->frame = frame; curr_pucch->ul_slot = sched_slot; @@ -1132,7 +1132,7 @@ bool nr_acknack_scheduling(int mod_id, pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; pucch->ul_slot = (s + 1) % n_slots_frame; // we assume that only two indices over the array sched_pucch exist - const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2]; + const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; // skip the CSI PUCCH if it is present and if in the next frame/slot if (csi_pucch->csi_bits > 0 && csi_pucch->frame == pucch->frame @@ -1212,7 +1212,7 @@ bool nr_acknack_scheduling(int mod_id, pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]); // is there already CSI in this slot? - const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2]; + const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; // skip the CSI PUCCH if it is present and if in the next frame/slot if (csi_pucch->csi_bits > 0 && csi_pucch->frame == pucch->frame diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 50437db3cf..fa6d978517 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -522,11 +522,9 @@ typedef struct { int cce_index; uint8_t aggregation_level; - /// PUCCH scheduling information. Array of three, we assume for the moment: - /// HARQ in the first field, SR in second, CSI in third (as fixed by RRC - /// conf., i.e. if actually present). The order is important for - /// nr_acknack_scheduling()! - NR_sched_pucch_t sched_pucch[3]; + /// PUCCH scheduling information. Array of two: HARQ+SR in the first field, + /// CSI in second. This order is important for nr_acknack_scheduling()! + NR_sched_pucch_t sched_pucch[2]; /// PUSCH semi-static configuration: is not cleared across TTIs NR_pusch_semi_static_t pusch_semi_static; From f73e8e045996f450d78dad3ff2dbcc96f2c917cd Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 24 Mar 2021 17:21:54 +0100 Subject: [PATCH 10/29] Bugfixes in nr_acknack_scheduling() 1: there can be 2bits AckNack + SR in PUCCH F0 2: when allocating csi_pucch, zero out struct 3: Make unfree resources a warning 4: When asserting, explain the issue --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 318003ea0a..95dfbfc3bf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1117,12 +1117,8 @@ bool nr_acknack_scheduling(int mod_id, __func__, pucch->csi_bits); - const int max_acknacks = 2; - AssertFatal(pucch->dai_c + pucch->sr_flag <= max_acknacks, - "illegal number of bits in PUCCH of UE %d\n", - UE_id); /* if the currently allocated PUCCH of this UE is full, allocate it */ - if (pucch->sr_flag + pucch->dai_c == max_acknacks) { + if (pucch->dai_c == 2) { /* advance the UL slot information in PUCCH by one so we won't schedule in * the same slot again */ const int f = pucch->frame; @@ -1132,7 +1128,7 @@ bool nr_acknack_scheduling(int mod_id, pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; pucch->ul_slot = (s + 1) % n_slots_frame; // we assume that only two indices over the array sched_pucch exist - const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; + NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; // skip the CSI PUCCH if it is present and if in the next frame/slot if (csi_pucch->csi_bits > 0 && csi_pucch->frame == pucch->frame @@ -1144,6 +1140,7 @@ bool nr_acknack_scheduling(int mod_id, pucch->ul_slot, UE_id); nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); + memset(csi_pucch, 0, sizeof(*csi_pucch)); pucch->frame = s >= n_slots_frame - 2 ? (f + 1) % 1024 : f; pucch->ul_slot = (s + 2) % n_slots_frame; } @@ -1162,9 +1159,8 @@ bool nr_acknack_scheduling(int mod_id, uint8_t pdsch_to_harq_feedback[8]; get_pdsch_to_harq_feedback(mod_id, UE_id, ss_type, pdsch_to_harq_feedback); - /* there is a scheduled SR or HARQ. Check whether we can use it for this - * ACKNACK */ - if (pucch->sr_flag + pucch->dai_c > 0) { + /* there is a HARQ. Check whether we can use it for this ACKNACK */ + if (pucch->dai_c > 0) { /* this UE already has a PUCCH occasion */ DevAssert(pucch->frame == frame); @@ -1200,7 +1196,9 @@ bool nr_acknack_scheduling(int mod_id, * scheduled a lot and used all AckNacks, pucch->frame might have been * wrapped around to next frame */ if (frame != pucch->frame || pucch->ul_slot < first_ul_slot_tdd) { - DevAssert(pucch->sr_flag + pucch->dai_c == 0); + AssertFatal(pucch->sr_flag + pucch->dai_c == 0, + "expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n", + UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot); AssertFatal(frame + 1 != pucch->frame, "frame wrap around not handled in %s() yet\n", __func__); @@ -1212,7 +1210,7 @@ bool nr_acknack_scheduling(int mod_id, pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]); // is there already CSI in this slot? - const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; + NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; // skip the CSI PUCCH if it is present and if in the next frame/slot if (csi_pucch->csi_bits > 0 && csi_pucch->frame == pucch->frame @@ -1224,6 +1222,7 @@ bool nr_acknack_scheduling(int mod_id, pucch->ul_slot, UE_id); nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); + memset(csi_pucch, 0, sizeof(*csi_pucch)); /* advance the UL slot information in PUCCH by one so we won't schedule in * the same slot again */ const int f = pucch->frame; @@ -1265,9 +1264,8 @@ bool nr_acknack_scheduling(int mod_id, if (resource->format.choice.format0->initialCyclicShift == 0) { uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE]; const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex; - AssertFatal((vrb_map_UL[resource->startingPRB] & symb) == 0, - "symbol %x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d\n", - symb, resource->startingPRB, pucch->ul_slot); + if ((vrb_map_UL[resource->startingPRB] & symb) != 0) + LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot); vrb_map_UL[resource->startingPRB] |= symb; } return true; From 51e844e19fffc2fe6358e81e74b3c189fc629d51 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 Mar 2021 16:00:40 +0100 Subject: [PATCH 11/29] Bugfix ul preproc: check correct slot for UL --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index a2e066d8c5..bc1b6737f3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1106,7 +1106,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu); const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; - if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[slot / 64], sched_slot)) + if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) return false; sched_ctrl->sched_pusch.slot = sched_slot; From 50ac9ef2522583ac0763ad78b8ca63d44f2bfd79 Mon Sep 17 00:00:00 2001 From: imad Date: Sat, 19 Dec 2020 13:33:48 +0100 Subject: [PATCH 12/29] Add schedulingRequestConfig --- openair2/RRC/NR/rrc_gNB_reconfig.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 97533bde7c..dddf87a8c9 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -185,7 +185,17 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig); secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig)); secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL; - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL; + + secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig)); + secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); + NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf)); + SchedulingRequestConf->schedulingRequestId = 0; //Could be changed + SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer)); + *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16; //NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms32 + SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32; + ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf); + secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL; + secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config)); secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160; From 27bfe23c9babc1bfd3e2bf86aa94777ced60755d Mon Sep 17 00:00:00 2001 From: imad Date: Sat, 19 Dec 2020 13:36:52 +0100 Subject: [PATCH 13/29] Add schedulingRequestResourceConfig --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 3 ++- openair2/RRC/NR/rrc_gNB_reconfig.c | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 88333272cb..66553e813b 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -73,7 +73,8 @@ void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChann mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup)); *mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1; - mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL; + mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID)); + *mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0; mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false; mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false; mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL; diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index dddf87a8c9..7888cb5940 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -191,7 +191,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf)); SchedulingRequestConf->schedulingRequestId = 0; //Could be changed SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer)); - *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16; //NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms32 + *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16; SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32; ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf); secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL; @@ -1040,7 +1040,19 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pucchfmt2->nrofSlots=NULL; pucchfmt2->pi2BPSK=NULL; pucchfmt2->simultaneousHARQ_ACK_CSI=NULL; - pucch_Config->schedulingRequestResourceToAddModList=NULL; + + // for scheduling requestresource + pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); + NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); + schedulingRequestResourceConfig->schedulingRequestResourceId = 1; + schedulingRequestResourceConfig->schedulingRequestID = 0; + schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = 7; + schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); + *schedulingRequestResourceConfig->resource = 1; + ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); + pucch_Config->schedulingRequestResourceToReleaseList=NULL; pucch_Config->multi_CSI_PUCCH_ResourceList=NULL; pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); From a8149b5e0e55dd6034a3093a9253271c107b11ce Mon Sep 17 00:00:00 2001 From: imad Date: Sat, 19 Dec 2020 12:47:44 +0100 Subject: [PATCH 14/29] Add functions for SR scheduling --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 151 ++++++++++++++++++ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 + 2 files changed, 157 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 95dfbfc3bf..46602bd981 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1398,3 +1398,154 @@ uint16_t compute_pucch_prb_size(uint8_t format, AssertFatal(1==0,"Not yet implemented"); } } + +void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot) +{ + gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP]; + if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot)) + return; + NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon; + const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + NR_UE_info_t *UE_info = &nrmac->UE_info; + NR_list_t *UE_list = &UE_info->list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; + AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available"); + + for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { + NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id]; + + int SR_period; int SR_offset; + + periodicity__SRR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); + // convert to int to avoid underflow of uint + int sfn_sf = SFN * n_slots_frame + slot; + if ((sfn_sf - SR_offset) % SR_period != 0) + continue; + LOG_D(MAC, "%4d.%2d Scheduling Request identified\n", SFN, slot); + NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource; + + int found = -1; + NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; // set with formats 0,1 + int n_list = pucchresset->resourceList.list.count; + for (int i=0; iresourceList.list.array[i] == *PucchResourceId ) + found = i; + } + AssertFatal(found>-1,"SR resource not found among PUCCH resources"); + + /* loop through nFAPI PUCCH messages: if the UEs is in there in this slot + * with the resource_indicator, it means we already allocated that PUCCH + * resource for AckNack (e.g., the UE has been scheduled often), and we + * just need to add the SR_flag. Otherwise, just allocate in the internal + * PUCCH resource, and nr_schedule_pucch() will handle the rest */ + NR_PUCCH_Resource_t *pucch_res = pucch_Config->resourceToAddModList->list.array[found]; + /* for the moment, can only handle SR on PUCCH Format 0 */ + DevAssert(pucch_res->format.present == NR_PUCCH_Resource__format_PR_format0); + nfapi_nr_ul_tti_request_t *ul_tti_req = &nrmac->UL_tti_req_ahead[0][slot]; + bool nfapi_allocated = false; + for (int i = 0; i < ul_tti_req->n_pdus; ++i) { + if (ul_tti_req->pdus_list[i].pdu_type != NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE) + continue; + nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu; + /* check that it is our PUCCH F0. Assuming there can be only one */ + if (pdu->rnti == UE_info->rnti[UE_id] + && pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0 + && pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift + && pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols + && pdu->start_symbol_index == pucch_res->format.choice.format0->startingSymbolIndex) { + LOG_D(MAC,"%4d.%2d adding SR_flag 1 to PUCCH nFAPI SR for RNTI %04x\n", SFN, slot, pdu->rnti); + pdu->sr_flag = 1; + nfapi_allocated = true; + break; + } + } + + if (nfapi_allocated) // break scheduling resource loop, continue next UE + break; + + /* we did not find it: check if current PUCCH is for the current slot, in + * which case we add the SR to it; otherwise, allocate SR separately */ + NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[0]; + if (curr_pucch->frame == SFN && curr_pucch->ul_slot == slot) { + if (curr_pucch->resource_indicator != found) { + LOG_W(MAC, "%4d.%2d expected PUCCH in this slot to have resource indicator of SR (%d), skipping SR\n", SFN, slot, found); + continue; + } + curr_pucch->sr_flag = true; + } else { + NR_sched_pucch_t sched_sr; + memset(&sched_sr, 0, sizeof(sched_sr)); + sched_sr.frame = SFN; + sched_sr.ul_slot = slot; + sched_sr.resource_indicator = found; + sched_sr.sr_flag = true; + nr_fill_nfapi_pucch(Mod_idP, SFN, slot, &sched_sr, UE_id); + } + } + } +} + + +void periodicity__SRR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset) +{ + NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR P_O = SchedulingReqRec->periodicityAndOffset->present; + switch (P_O){ + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl1: + *period = 1; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl1; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl2: + *period = 2; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl2; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl4: + *period = 4; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl4; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl5: + *period = 5; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl5; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl8: + *period = 8; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl8; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10: + *period = 10; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl10; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl16: + *period = 16; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl16; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20: + *period = 20; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl20; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40: + *period = 40; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl40; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80: + *period = 80; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl80; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160: + *period = 160; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl160; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320: + *period = 320; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl320; + break; + case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640: + *period = 640; + *offset = SchedulingReqRec->periodicityAndOffset->choice.sl640; + break; + default: + AssertFatal(1==0,"No periodicityAndOffset resources found in schedulingrequestresourceconfig"); + } +} + diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 4256097174..4bf82dd002 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -414,4 +414,10 @@ bool nr_find_nb_rb(uint16_t Qm, uint32_t *tbs, uint16_t *nb_rb); +void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); + +void periodicity__SRR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRecconf, + int *period, + int *offset); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ From cba2d9e4134af1ebaf572b07c06dd3c637632f8d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 Jan 2021 14:12:01 +0100 Subject: [PATCH 15/29] Schedule UEs on SR or BSR --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 5 +++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 19 +++++++------------ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 ++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 46602bd981..c1dfbc4fa3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1034,6 +1034,11 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0); } } + + // check scheduling request result, confidence_level == 0 is good + if (uci_01->pduBitmap & 0x1) { + sched_ctrl->SR |= uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0; + } } void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index bc1b6737f3..fe1d670339 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -874,7 +874,6 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static float ul_thr_ue[MAX_MOBILES_PER_GNB]; uint32_t ul_pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient -int bsr0ue = -1; void pf_ul(module_id_t module_id, frame_t frame, sub_frame_t slot, @@ -894,12 +893,6 @@ void pf_ul(module_id_t module_id, int ue_array[MAX_MOBILES_PER_GNB]; NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB }; - /* Hack: currently, we do not have SR, and need to schedule UEs continuously. - * To keep the wasted resources low, we switch UEs to be scheduled in a - * round-robin fashion below, and only schedule a UE with BSR=0 if it is the - * selected one */ - bsr0ue = next_list_entry_looped(UE_list, bsr0ue); - /* Loop UE_list to calculate throughput and coeff */ for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; @@ -931,11 +924,12 @@ void pf_ul(module_id_t module_id, continue; } - /* Check BSR and schedule UE if it is zero to avoid starvation, since we do - * not have SR (yet) */ - if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) { - if (UE_id != bsr0ue) - continue; + if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0 && !sched_ctrl->SR) + continue; + + /* Schedule UE if there is a SR and no data (otherwise, will be scheduled + * baded on data to transmit) */ + if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0 && sched_ctrl->SR) { /* if no data, pre-allocate 5RB */ bool freeCCE = find_free_CCE(module_id, slot, UE_id); if (!freeCCE) { @@ -1225,6 +1219,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) continue; uint16_t rnti = UE_info->rnti[UE_id]; + sched_ctrl->SR = false; int8_t harq_id = sched_pusch->ul_harq_pid; if (harq_id < 0) { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index fa6d978517..9e17883f56 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -561,6 +561,8 @@ typedef struct { int pucch_snrx10; struct CSI_Report CSI_report[MAX_CSI_REPORTS]; + bool SR; + /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; /// HARQ processes that are free From 800330e41c314a51b2633065b351aef139d908d4 Mon Sep 17 00:00:00 2001 From: imad Date: Sat, 19 Dec 2020 12:51:20 +0100 Subject: [PATCH 16/29] Call nr_sr_reporting --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 7175a129ba..36f687b5cd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -402,7 +402,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } // This schedule SR - // TODO + nr_sr_reporting(module_idP, frame, slot); // Schedule CSI measurement reporting: check in slot 0 for the whole frame if (slot == 0) From 81873616157e9b704f603e11011f4675d9ca6ac0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 9 Feb 2021 10:43:24 +0100 Subject: [PATCH 17/29] Schedule UE periodically every 10 frames in UL --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 43 +++++++++++++++++-- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 3 ++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index fe1d670339..259aa1d455 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -745,6 +745,34 @@ long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) { return 3; } +bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t frame, sub_frame_t slot) +{ + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; + const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; + const int n = slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int now = frame * n + slot; + + const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id]; + const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id]; + const int last_ul_sched = sched_ctrl->last_ul_frame * n + sched_ctrl->last_ul_slot; + + const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n); + /* UE is to be scheduled if + * (1) we think the UE has more bytes awaiting than what we scheduled + * (2) there is a scheduling request + * (3) or we did not schedule it in more than 10 frames */ + const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes; + const bool high_inactivity = diff >= 10 * n; + LOG_D(MAC, + "%4d.%2d UL inactivity %d slots has_data %d SR %d\n", + frame, + slot, + diff, + has_data, + sched_ctrl->SR); + return has_data || sched_ctrl->SR || high_inactivity; +} + int next_list_entry_looped(NR_list_t *list, int UE_id) { if (UE_id < 0) @@ -924,12 +952,16 @@ void pf_ul(module_id_t module_id, continue; } - if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0 && !sched_ctrl->SR) + const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes); + /* preprocessor computed sched_frame/sched_slot */ + const bool do_sched = nr_UE_is_to_be_scheduled(module_id, 0, UE_id, sched_pusch->frame, sched_pusch->slot); + + if (B == 0 && !do_sched) continue; - /* Schedule UE if there is a SR and no data (otherwise, will be scheduled - * baded on data to transmit) */ - if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0 && sched_ctrl->SR) { + /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled + * based on data to transmit) */ + if (B == 0 && do_sched) { /* if no data, pre-allocate 5RB */ bool freeCCE = find_free_CCE(module_id, slot, UE_id); if (!freeCCE) { @@ -1212,6 +1244,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; UE_info->mac_stats[UE_id].ulsch_current_bytes = 0; + /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in * every TTI are pre-populated by the preprocessor and used below */ NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; @@ -1276,6 +1309,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) cur_harq->ndi); } UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; + sched_ctrl->last_ul_frame = sched_pusch->frame; + sched_ctrl->last_ul_slot = sched_pusch->slot; LOG_D(MAC, "%4d.%2d RNTI %04x UL sched %4d.%2d start %2d RBS %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d est %6d sched %6d est BSR %6d\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 9e17883f56..0c7fda09e2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -545,6 +545,9 @@ typedef struct { NR_pdsch_semi_static_t pdsch_semi_static; /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI NR_sched_pdsch_t sched_pdsch; + /// For UL synchronization: store last UL scheduling grant + frame_t last_ul_frame; + sub_frame_t last_ul_slot; /// total amount of data awaiting for this UE uint32_t num_total_bytes; From 74fa01463c726c6c052cb6412925e5afdda7be83 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 1 Apr 2021 18:01:52 +0200 Subject: [PATCH 18/29] Do PUCCH TPC only if Acknack or positive SR otherwise, if we only have a (negative) SR, the UE did not send anything, and the PUCCH CQI is invalid --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index c1dfbc4fa3..3e2691150c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1012,12 +1012,6 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, - uci_01->ul_cqi, - 30); - sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; if (((uci_01->pduBitmap >> 1) & 0x01)) { @@ -1036,8 +1030,17 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, } // check scheduling request result, confidence_level == 0 is good - if (uci_01->pduBitmap & 0x1) { - sched_ctrl->SR |= uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0; + if (uci_01->pduBitmap & 0x1 && uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0 && uci_01->ul_cqi >= 148) { + // SR detected with SNR >= 10dB + sched_ctrl->SR |= true; + LOG_D(MAC, "SR UE %04x ul_cqi %d\n", uci_01->rnti, uci_01->ul_cqi); + } + + // tpc (power control) only if we received AckNack or positive SR. For a + // negative SR, the UE won't have sent anything, and the SNR is not valid + if (((uci_01->pduBitmap >> 1) & 0x1) || sched_ctrl->SR) { + sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30); + sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; } } From 821a5e5dfe10e63b4d538a487f50128b6f5722c8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 1 Apr 2021 16:33:28 +0200 Subject: [PATCH 19/29] Correct T310 & N310 to avoid RA --- openair2/RRC/NR/rrc_gNB_reconfig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 7888cb5940..e7e60aa312 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -274,8 +274,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup)); - secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms2000; - secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n10; + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms4000; + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n20; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n311 = NR_RLF_TimersAndConstants__n311_n1; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311 = NR_RLF_TimersAndConstants__ext1__t311_ms30000; From 6c162e3808506dd81296f3fbc1a29cbc30e6e215 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 27 Apr 2021 08:36:43 +0200 Subject: [PATCH 20/29] Remove unused variables --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 3e2691150c..800c23a9a0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1012,8 +1012,6 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; - const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; if (((uci_01->pduBitmap >> 1) & 0x01)) { // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { @@ -1064,8 +1062,6 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, 30); sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; - const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; if ((uci_234->pduBitmap >> 1) & 0x01) { // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { From 31aade2002ddb0fdaf9dec549792ea5aa2c208fd Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 27 Apr 2021 15:48:23 +0200 Subject: [PATCH 21/29] tentative fix for wrong frame caused by rx offset --- executables/nr-ue.c | 6 +++--- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2adf373196..4b04c52ade 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -513,7 +513,7 @@ void *UE_thread(void *arg) { if (UE->is_synchronized) { 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; + decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER; } delNotifiedFIFO_elt(res); } else { @@ -652,9 +652,9 @@ void *UE_thread(void *arg) { pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); } - if ( decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx) + 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", - decoded_frame_rx, curMsg->proc.frame_rx ); + decoded_frame_rx, curMsg->proc.frame_rx); // use previous timing_advance value to compute writeTimestamp writeTimestamp = timestamp+ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index bfef89ea85..88677fc8e5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -308,12 +308,14 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) // every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); - if (ue->ssb_offset < sync_pos_frame) - ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; - else + if (ue->ssb_offset < sync_pos_frame){ + ue->rx_offset = (2*fp->samples_per_frame) - sync_pos_frame + ue->ssb_offset; + ue->init_sync_frame = !is + 2; + } + else{ ue->rx_offset = ue->ssb_offset - sync_pos_frame; - - ue->init_sync_frame = is; + ue->init_sync_frame = !is; + } } /* From cc15ac25b9a8a278537cd239e325d6ac9fb094ed Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 28 Apr 2021 17:49:27 +0200 Subject: [PATCH 22/29] simplification of previous fix --- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 88677fc8e5..ba8c64d9f4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -309,8 +309,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) int n_symb_prefix0 = (ue->symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); if (ue->ssb_offset < sync_pos_frame){ - ue->rx_offset = (2*fp->samples_per_frame) - sync_pos_frame + ue->ssb_offset; - ue->init_sync_frame = !is + 2; + ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; + ue->init_sync_frame = !is + 1; } else{ ue->rx_offset = ue->ssb_offset - sync_pos_frame; From 67b9e92a5c875b0739a5156b7ee3a6da667d6ea2 Mon Sep 17 00:00:00 2001 From: hardy Date: Tue, 27 Apr 2021 16:54:42 +0200 Subject: [PATCH 23/29] improving stats appearance --- ci-scripts/datalog_rt_stats.yaml | 30 ++++++++++++++++ ci-scripts/html.py | 31 +++++++++++++++++ ci-scripts/ran.py | 59 ++++++++++++++++++++++++++------ 3 files changed, 109 insertions(+), 11 deletions(-) create mode 100644 ci-scripts/datalog_rt_stats.yaml diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml new file mode 100644 index 0000000000..692962ed35 --- /dev/null +++ b/ci-scripts/datalog_rt_stats.yaml @@ -0,0 +1,30 @@ +Title : Processing Time (us) +ColNames : + - Metric + - Average + - Max + - Deviation (Avg vs Ref) +Ref : + feprx : 60.0 + feptx_prec : 8.0 + feptx_ofdm : 85.0 + feptx_total : 75.0 + L1 Tx processing : 300.0 + DLSCH encoding : 230.0 + L1 Rx processing : 175.0 + PUSCH inner-receiver : 100.0 + PUSCH decoding : 140.0 + DL & UL scheduling timing stats : 15.0 + UL Indication : 20.0 +Threshold : + feprx : 1.25 + feptx_prec : 1.25 + feptx_ofdm : 1.25 + feptx_total : 1.25 + L1 Tx processing : 1.25 + DLSCH encoding : 1.25 + L1 Rx processing : 1.25 + PUSCH inner-receiver : 1.25 + PUSCH decoding : 1.25 + DL & UL scheduling timing stats : 1.25 + UL Indication : 1.25 \ No newline at end of file diff --git a/ci-scripts/html.py b/ci-scripts/html.py index a0ac638573..aca717c0d4 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -446,6 +446,37 @@ class HTMLManagement(): self.htmlFile.write(' \n') self.htmlFile.close() + #for the moment it is limited to 4 columns, to be made generic later + def CreateHtmlDataLogTable(self, DataLog): + if (self.htmlFooterCreated or (not self.htmlHeaderCreated)): + return + self.htmlFile = open('test_results.html', 'a') + + # TabHeader + self.htmlFile.write(' \n') + self.htmlFile.write(' ---- ' + DataLog['Title'] + ' ---- \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' '+ DataLog['ColNames'][0] +'\n') + self.htmlFile.write(' ' + DataLog['ColNames'][1] + '\n') + self.htmlFile.write(' ' + DataLog['ColNames'][2] + '\n') + self.htmlFile.write(' '+ DataLog['ColNames'][3] +'\n') + self.htmlFile.write(' \n') + + for k in DataLog['Data']: + # TestRow + self.htmlFile.write(' \n') + self.htmlFile.write(' ' + k + ' \n') + self.htmlFile.write(' ' + DataLog['Data'][k][0] + ' \n') + self.htmlFile.write(' ' + DataLog['Data'][k][1] + ' \n') + if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]: + self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') + else: + self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') + self.htmlFile.write(' \n') + self.htmlFile.close() + + def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): self.htmlFile = open('test_results.html', 'a') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index f1f79a2435..8e378afbe9 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -37,6 +37,8 @@ import logging import os import time from multiprocessing import Process, Lock, SimpleQueue +import yaml + #----------------------------------------------------------- # OAI Testing modules @@ -90,6 +92,7 @@ class RANManagement(): self.testCase_id = '' self.epcPcapFile = '' self.runtime_stats= '' + self.datalog_rt_stats={} @@ -633,6 +636,8 @@ class RANManagement(): HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) else: HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + if len(self.datalog_rt_stats)!=0: + HTML.CreateHtmlDataLogTable(self.datalog_rt_stats) self.eNBmbmsEnables[int(self.eNB_instance)] = False self.eNBstatuses[int(self.eNB_instance)] = -1 @@ -699,6 +704,21 @@ class RANManagement(): #count "problem receiving samples" msg pb_receiving_samples_cnt = 0 + #the datalog config file has to be loaded + datalog_rt_stats_file='datalog_rt_stats.yaml' + if (os.path.isfile(datalog_rt_stats_file)): + yaml_file=datalog_rt_stats_file + elif (os.path.isfile('ci-scripts/'+datalog_rt_stats_file)): + yaml_file='ci-scripts/'+datalog_rt_stats_file + else: + logging.error("Datalog RT stats yaml file cannot be found") + sys.exit("Datalog RT stats yaml file cannot be found") + + with open(yaml_file,'r') as f: + datalog_rt_stats = yaml.load(f,Loader=yaml.FullLoader) + rt_keys = datalog_rt_stats['Ref'] #we use the keys from the Ref field + + for line in enb_log_file.readlines(): # Runtime statistics result = re.search('Run time:' ,str(line)) @@ -857,21 +877,21 @@ class RANManagement(): #keys below are the markers we are loooking for, loop over this keys list #everytime these markers are found in the log file, the previous ones are overwritten in the dict #eventually we record and print only the last occurence - keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled', 'scheduling timing stats'} + keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'} for k in keys: result = re.search(k, line) if result is not None: #remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip()) - #real time statistics - #same method as above - keys = {'feprx','feptx_prec','feptx_ofdm','feptx_total','L1 Tx processing','DLSCH encoding','L1 Rx processing','PUSCH inner-receiver','PUSCH decoding'} - for k in keys: + #real time statistics for gNB + for k in rt_keys: result = re.search(k, line) if result is not None: #remove 1- all useless char before relevant info 2- trailing char + line=line.replace('[0m','') tmp=re.match(rf'^.*?(\b{k}\b.*)',line.rstrip()) #from python 3.6 we can use literal string interpolation for the variable k, using rf' in the regex real_time_stats[k]=tmp.group(1) + #count "problem receiving samples" msg result = re.search('\[PHY\]\s+problem receiving samples', str(line)) if result is not None: @@ -920,13 +940,30 @@ class RANManagement(): logging.debug(dlsch_ulsch_stats[key]) htmleNBFailureMsg += statMsg - #real time statistics statistics + #real time statistics (old but working version) + #if len(real_time_stats)!=0: #check if dictionary is not empty + # statMsg='' + # for k in real_time_stats: + # tmp=re.match(r'^(?P.*):\s+(?P\d+\.\d+) us;\s+\d+;\s+(?P\d+\.\d+) us;',real_time_stats[k]) + # if tmp is not None: + # metric=tmp.group('metric') + # avg=tmp.group('avg') + # max=tmp.group('max') + # statMsg += metric + ' : avg = ' + avg + 'us ; max = ' + max +'us\n' + # htmleNBFailureMsg += statMsg + + #real time statistics + datalog_rt_stats['Data']={} if len(real_time_stats)!=0: #check if dictionary is not empty - statMsg='' - for key in real_time_stats: #for each dictionary key - statMsg += real_time_stats[key] + '\n' - logging.debug(real_time_stats[key]) - htmleNBFailureMsg += statMsg + for k in real_time_stats: + tmp=re.match(r'^(?P.*):\s+(?P\d+\.\d+) us;\s+\d+;\s+(?P\d+\.\d+) us;',real_time_stats[k]) + if tmp is not None: + metric=tmp.group('metric') + avg=float(tmp.group('avg')) + max=float(tmp.group('max')) + datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])] + #store the data as a class attribute to build a dedicated HTML table afterward + self.datalog_rt_stats=datalog_rt_stats else: statMsg = 'No real time stats found in the log file\n' logging.debug('No real time stats found in the log file') From ccf6624f79e7736c9053d9979e39fdb315e55381 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 29 Apr 2021 10:26:10 +0200 Subject: [PATCH 24/29] changing col name in html report --- ci-scripts/datalog_rt_stats.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml index 692962ed35..e21cbc4088 100644 --- a/ci-scripts/datalog_rt_stats.yaml +++ b/ci-scripts/datalog_rt_stats.yaml @@ -1,9 +1,12 @@ +#this is a configuration file +#used to build real time processing statistics +#for 5G NR phy test (gNB terminate) Title : Processing Time (us) ColNames : - Metric - Average - Max - - Deviation (Avg vs Ref) + - Average vs Reference Deviation (Acceptability Threshold) Ref : feprx : 60.0 feptx_prec : 8.0 @@ -25,6 +28,6 @@ Threshold : DLSCH encoding : 1.25 L1 Rx processing : 1.25 PUSCH inner-receiver : 1.25 - PUSCH decoding : 1.25 + PUSCH decoding : 1.25 DL & UL scheduling timing stats : 1.25 - UL Indication : 1.25 \ No newline at end of file + UL Indication : 1.25 From d2f1e41bcbf5b2d3be50d5f50320c42eb5029d1f Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 29 Apr 2021 12:02:51 +0200 Subject: [PATCH 25/29] using n_frames to compute init_sync_frame --- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index ba8c64d9f4..df35f14869 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -308,14 +308,15 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) // every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); + // for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync + ue->init_sync_frame = n_frames - 1 - is; + // we also need to take into account the shift by samples_per_frame in case the if is true if (ue->ssb_offset < sync_pos_frame){ ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; - ue->init_sync_frame = !is + 1; + ue->init_sync_frame += 1; } - else{ + else ue->rx_offset = ue->ssb_offset - sync_pos_frame; - ue->init_sync_frame = !is; - } } /* From 37cc4d60331ef4aabb0a2ae61a00feafae921028 Mon Sep 17 00:00:00 2001 From: hardy Date: Wed, 28 Apr 2021 21:00:35 +0200 Subject: [PATCH 26/29] fixing html columns --- ci-scripts/html.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ci-scripts/html.py b/ci-scripts/html.py index aca717c0d4..e51516d606 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -457,7 +457,7 @@ class HTMLManagement(): self.htmlFile.write(' ---- ' + DataLog['Title'] + ' ---- \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' '+ DataLog['ColNames'][0] +'\n') + self.htmlFile.write(' '+ DataLog['ColNames'][0] +'\n') self.htmlFile.write(' ' + DataLog['ColNames'][1] + '\n') self.htmlFile.write(' ' + DataLog['ColNames'][2] + '\n') self.htmlFile.write(' '+ DataLog['ColNames'][3] +'\n') @@ -466,13 +466,13 @@ class HTMLManagement(): for k in DataLog['Data']: # TestRow self.htmlFile.write(' \n') - self.htmlFile.write(' ' + k + ' \n') - self.htmlFile.write(' ' + DataLog['Data'][k][0] + ' \n') - self.htmlFile.write(' ' + DataLog['Data'][k][1] + ' \n') + self.htmlFile.write(' ' + k + ' \n') + self.htmlFile.write(' ' + DataLog['Data'][k][0] + ' \n') + self.htmlFile.write(' ' + DataLog['Data'][k][1] + ' \n') if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]: - self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') + self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') else: - self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') + self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') self.htmlFile.write(' \n') self.htmlFile.close() From 7ca887221625bbef414f976eabc94ce30c3a94f8 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 29 Apr 2021 21:59:47 +0200 Subject: [PATCH 27/29] fix test status fail/pass + test update + cleaning --- ci-scripts/ran.py | 21 +++++++------------ ci-scripts/xml_files/gnb_phytest_usrp_run.xml | 4 ++-- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 8e378afbe9..f5f53c20b7 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -940,18 +940,6 @@ class RANManagement(): logging.debug(dlsch_ulsch_stats[key]) htmleNBFailureMsg += statMsg - #real time statistics (old but working version) - #if len(real_time_stats)!=0: #check if dictionary is not empty - # statMsg='' - # for k in real_time_stats: - # tmp=re.match(r'^(?P.*):\s+(?P\d+\.\d+) us;\s+\d+;\s+(?P\d+\.\d+) us;',real_time_stats[k]) - # if tmp is not None: - # metric=tmp.group('metric') - # avg=tmp.group('avg') - # max=tmp.group('max') - # statMsg += metric + ' : avg = ' + avg + 'us ; max = ' + max +'us\n' - # htmleNBFailureMsg += statMsg - #real time statistics datalog_rt_stats['Data']={} if len(real_time_stats)!=0: #check if dictionary is not empty @@ -962,8 +950,13 @@ class RANManagement(): avg=float(tmp.group('avg')) max=float(tmp.group('max')) datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])] - #store the data as a class attribute to build a dedicated HTML table afterward - self.datalog_rt_stats=datalog_rt_stats + #once all metrics are collected, store the data as a class attribute to build a dedicated HTML table afterward + self.datalog_rt_stats=datalog_rt_stats + #check if there is a fail => will render the test as failed + for k in datalog_rt_stats['Data']: + if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold + #setting prematureExit is ok although not the best option + self.prematureExit=True else: statMsg = 'No real time stats found in the log file\n' logging.debug('No real time stats found in the log file') diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index 00610d430e..9e798afdc4 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -24,7 +24,7 @@ gNB-PHY-Test Run-gNB-PHY-Test tasks - 2 + 3 090101 000001 090109 @@ -40,7 +40,7 @@ IdleSleep Sleep - 180 + 300 From 7050044fcdec39b8e13d03d614bd4dfdcf87b3b0 Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 30 Apr 2021 10:24:44 +0200 Subject: [PATCH 28/29] improve understanding of results --- ci-scripts/datalog_rt_stats.yaml | 2 +- ci-scripts/html.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml index e21cbc4088..3680d2a19b 100644 --- a/ci-scripts/datalog_rt_stats.yaml +++ b/ci-scripts/datalog_rt_stats.yaml @@ -6,7 +6,7 @@ ColNames : - Metric - Average - Max - - Average vs Reference Deviation (Acceptability Threshold) + - Average vs Reference Deviation (Reference Value ; Acceptability Threshold) Ref : feprx : 60.0 feptx_prec : 8.0 diff --git a/ci-scripts/html.py b/ci-scripts/html.py index e51516d606..02ba2eee2c 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -470,9 +470,9 @@ class HTMLManagement(): self.htmlFile.write(' ' + DataLog['Data'][k][0] + ' \n') self.htmlFile.write(' ' + DataLog['Data'][k][1] + ' \n') if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]: - self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') + self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '\n') else: - self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' ('+str(DataLog['Threshold'][k])+') ' + '\n') + self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '\n') self.htmlFile.write(' \n') self.htmlFile.close() From 2319b4e76f02cb453c41862b029dda6ffe205157 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 30 Apr 2021 16:40:59 +0200 Subject: [PATCH 29/29] Introduce configuration for maximum UE ULSCH inactivity --- ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf | 1 + ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf | 1 + openair2/GNB_APP/MACRLC_nr_paramdef.h | 4 +++- openair2/GNB_APP/gnb_config.c | 3 ++- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 3 +++ 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf index f0c1caef7e..8fbbc8a7cd 100644 --- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf @@ -230,6 +230,7 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; + ulsch_max_slots_inactivity = 1; } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index f125dcd3b2..703d6a3bf0 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -211,6 +211,7 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; + ulsch_max_slots_inactivity = 1; } ); diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index 308af2eeb9..60b40cb349 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -55,7 +55,7 @@ #define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" - +#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity" /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* MacRLC configuration parameters */ @@ -79,6 +79,7 @@ {CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \ } #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -97,5 +98,6 @@ #define MACRLC_REMOTE_S_PORTC_IDX 14 #define MACRLC_LOCAL_S_PORTD_IDX 15 #define MACRLC_REMOTE_S_PORTD_IDX 16 +#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index d3dd769807..b9bf141fce 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -53,7 +53,7 @@ //#include "L1_paramdef.h" #include "L1_nr_paramdef.h" -#include "MACRLC_paramdef.h" +#include "MACRLC_nr_paramdef.h" #include "common/config/config_userapi.h" //#include "RRC_config_tools.h" #include "gnb_paramdef.h" @@ -698,6 +698,7 @@ void RCconfig_nr_macrlc() { }else { // other midhaul AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } + RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr); }// for (j=0;j 0 AssertFatal (0,"No " CONFIG_STRING_MACRLC_LIST " configuration found"); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 259aa1d455..323baa48a7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -762,7 +762,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t * (2) there is a scheduling request * (3) or we did not schedule it in more than 10 frames */ const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes; - const bool high_inactivity = diff >= 10 * n; + const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity; LOG_D(MAC, "%4d.%2d UL inactivity %d slots has_data %d SR %d\n", frame, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 0c7fda09e2..52255b8f32 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -721,6 +721,9 @@ typedef struct gNB_MAC_INST_s { /// points to the right UL slot int *preferred_ul_tda[MAX_NUM_BWP]; + /// maximum number of slots before a UE will be scheduled ULSCH automatically + uint32_t ulsch_max_slots_inactivity; + /// DL preprocessor for differentiated scheduling nr_pp_impl_dl pre_processor_dl; /// UL preprocessor for differentiated scheduling