diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 51a1e9e074..1e58bd2812 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -142,19 +142,15 @@ void dump_pusch_stats(PHY_VARS_gNB *gNB) { for (int i=0;iulsch[i][0]->rnti>0) - LOG_I(PHY,"ULSCH RNTI %x: round_trials %d(%1.1e)/%d(%1.1e)/%d(%1.1e)/%d/%d/%d/%d/%d, current_Qm %d, current_RI %d, total_bytes RX/TX %d/%d\n", + LOG_I(PHY,"ULSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes RX/SCHED %d/%d\n", gNB->ulsch[i][0]->rnti, gNB->ulsch[i][0]->stats.round_trials[0], (double)gNB->ulsch[i][0]->stats.round_trials[1]/gNB->ulsch[i][0]->stats.round_trials[0], gNB->ulsch[i][0]->stats.round_trials[1], - (double)gNB->ulsch[i][0]->stats.round_trials[2]/gNB->ulsch[i][0]->stats.round_trials[1], + (double)gNB->ulsch[i][0]->stats.round_trials[2]/gNB->ulsch[i][0]->stats.round_trials[0], gNB->ulsch[i][0]->stats.round_trials[2], - (double)gNB->ulsch[i][0]->stats.round_trials[3]/gNB->ulsch[i][0]->stats.round_trials[2], + (double)gNB->ulsch[i][0]->stats.round_trials[3]/gNB->ulsch[i][0]->stats.round_trials[0], gNB->ulsch[i][0]->stats.round_trials[3], - gNB->ulsch[i][0]->stats.round_trials[4], - gNB->ulsch[i][0]->stats.round_trials[5], - gNB->ulsch[i][0]->stats.round_trials[6], - gNB->ulsch[i][0]->stats.round_trials[7], gNB->ulsch[i][0]->stats.current_Qm, gNB->ulsch[i][0]->stats.current_RI, gNB->ulsch[i][0]->stats.total_bytes_rx, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 8ca24306dc..ae2b27183c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -88,4 +88,6 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, uint8_t harq_pid); int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); +void dump_pusch_stats(PHY_VARS_gNB *gNB); +void clear_pusch_stats(PHY_VARS_gNB *gNB); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 02d2a6b718..aef693eff2 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -574,7 +574,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } } } - if ((frame_rx&127) == 0) dump_pusch_stats(gNB); + // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS + if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 40b4d345c8..d949a029f8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -62,6 +62,32 @@ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; +void clear_mac_stats(gNB_MAC_INST *gNB) { + memset((void*)gNB->UE_list.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); +} + +void dump_mac_stats(gNB_MAC_INST *gNB) { + + NR_UE_list_t *UE_list = &gNB->UE_list; + NR_mac_stats_t *stats; + int lc_id; + + for (int UE_id=0;UE_idactive[UE_id] == TRUE) { + LOG_I(MAC,"UE %x\n",UE_list->rnti[UE_id]); + stats = &UE_list->mac_stats[UE_id]; + LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors); + LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes); + LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors); + LOG_I(MAC,"ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",stats->ulsch_total_bytes_scheduled,stats->ulsch_total_bytes_rx); + for (lc_id=0;lc_id<63;lc_id++) { + if (stats->lc_bytes_tx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes TX\n",lc_id,stats->lc_bytes_tx[lc_id]); + if (stats->lc_bytes_rx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes RX\n",lc_id,stats->lc_bytes_rx[lc_id]); + } + } + } +} + void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, @@ -458,6 +484,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) */ + if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]); // This schedules MIB if((slot == 0) && (frame & 7) == 0){ schedule_nr_mib(module_idP, frame, slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index cf2323f571..6461d27392 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -76,6 +76,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, //NR_CellGroupConfig_t *config = UE_list->secondaryCellGroup[UE_id]; ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]); + NR_mac_stats_t *mac_stats = &(UE_list->mac_stats[UE_id]); + // 1) Compute MAC CE and related subheaders // DRX command subheader (MAC CE size 0) @@ -112,6 +114,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); ce_ptr += mac_ce_size; mac_pdu_ptr += (unsigned char) mac_ce_size; + + } // Contention resolution fixed subheader and MAC CE @@ -324,6 +328,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]); dlsch_buffer_ptr += sdu_lengths[i]; mac_pdu_ptr += sdu_lengths[i]; + + mac_stats->lc_bytes_tx[sdu_lcids[i]] += sdu_lengths[i]; } // 4) Compute final offset for padding diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 15da44ca84..f786db8ba9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -320,7 +320,7 @@ int configure_fapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; // Point A - + UE_list->mac_stats[UE_id].dlsch_rounds[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++; pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; @@ -455,6 +455,9 @@ int configure_fapi_dl_pdu(int Mod_idP, // Hardcode it for now TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; + if (UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0) + UE_list->mac_stats[UE_id].dlsch_total_bytes += TBS; + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", pdsch_pdu_rel15->rbStart, pdsch_pdu_rel15->rbSize, @@ -1031,6 +1034,8 @@ void schedule_fapi_ul_pdu(int Mod_idP, 0, pusch_pdu->nrOfLayers)>>3; + UE_list->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; + if (cur_harq->round == 0) UE_list->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size; pusch_pdu->pusch_data.num_cb = 0; //CBG not supported //pusch_pdu->pusch_data.cb_present_and_position; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9e8a82b37e..403234b25a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -211,7 +211,8 @@ void nr_process_mac_pdu( } LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); - + int UE_id = find_nr_UE_id(module_idP, rnti); + RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); @@ -291,6 +292,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE_id != -1) { UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", gnb_mod_idP, harq_pid, @@ -326,6 +328,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(MAC, "Received PDU at MAC gNB \n"); nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); } + else { + + } } else { // random access pusch with TC-RNTI diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 9fb0162a8d..bd8f0208c6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -304,11 +304,25 @@ typedef struct NR_preamble_ue { uint8_t *preamble_list; } NR_preamble_ue; +typedef struct { + + int lc_bytes_tx[64]; + int lc_bytes_rx[64]; + int dlsch_rounds[8]; + int dlsch_errors; + int dlsch_total_bytes; + int ulsch_rounds[8]; + int ulsch_errors; + int ulsch_total_bytes_scheduled; + int ulsch_total_bytes_rx; +} NR_mac_stats_t; + /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ typedef struct { DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB]; /// scheduling control info NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; + NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; int next[MAX_MOBILES_PER_GNB]; int head; int next_ul[MAX_MOBILES_PER_GNB]; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 324f9fec15..5e650b82ec 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -83,6 +83,8 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int tar int max_harq_rounds = 4; // TODO define macro int num_ucis = UL_info->uci_ind.num_ucis; nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; + uint16_t rnti; + int UE_id; for (int i = 0; i < num_ucis; i++) { switch (uci_list[i].pdu_type) { @@ -93,6 +95,9 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int tar nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; // handle harq int harq_idx_s = 0; + rnti = uci_pdu->rnti; + UE_id = find_nr_UE_id(0,rnti); + sched_ctrl+=UE_id; // tpc (power control) sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); // iterate over received harq bits @@ -137,11 +142,13 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int tar UL_info->uci_ind.num_ucis = 0; } -void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, nfapi_nr_crc_t crc_pdu) { +void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu) { int max_harq_rounds = 4; // TODO define macro uint8_t hrq_id = crc_pdu.harq_id; NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id]; + int UE_id = find_nr_UE_id(0,crc_pdu.rnti); + stats+=UE_id; if (cur_harq->state==ACTIVE_SCHED) { if (!crc_pdu.tb_crc_status) { cur_harq->ndi ^= 1; @@ -162,9 +169,8 @@ void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, nfapi_nr_c cur_harq->ndi ^= 1; cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive cur_harq->round = 0; -#ifdef UL_HARQ_PRINT - printf("[HARQ HANDLER] Ulharq id %d crc failed in all round, freeing it for scheduler\n",hrq_id); -#endif + LOG_D(MAC,"[HARQ HANDLER] RNTI %x: Ulharq id %d crc failed in all round, freeing it for scheduler\n",crc_pdu.rnti,hrq_id); + stats->ulsch_errors++; } return; } else @@ -172,7 +178,7 @@ void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, nfapi_nr_c } -void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) { +void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) { if(nfapi_mode == 1) { if (UL_info->crc_ind.number_crcs>0) { //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); @@ -199,7 +205,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) { UL_info->rx_ind.pdu_list[i].rnti) { LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status); - handle_nr_ul_harq(UL_info->slot, sched_ctrl, UL_info->crc_ind.crc_list[j]); + handle_nr_ul_harq(UL_info->slot, sched_ctrl, stats, UL_info->crc_ind.crc_list[j]); if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot); @@ -253,7 +259,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; NR_IF_Module_t *ifi = if_inst[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id]; - LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n", UL_info->frame,UL_info->slot, module_id,CC_id, UL_info->rach_ind.number_of_pdus, @@ -274,10 +279,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { // clear DL/UL info for new scheduling round clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot); handle_nr_rach(UL_info); + handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],mac->pucch_target_snrx10); // clear HI prior to handling ULSCH mac->UL_dci_req[CC_id].numPdus = 0; - handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0]); + handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0]); if (nfapi_mode != 1) { if (ifi->CC_mask == ((1<