From 84178469f407b06e46f9af50eedea81f6a874705 Mon Sep 17 00:00:00 2001
From: "vr.devendra" <vr.devendra@globaledgesoft.com>
Date: Thu, 13 Aug 2020 12:07:53 +0530
Subject: [PATCH] updated TCI handling apis

---
 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 153 +++++++++++++--------
 1 file changed, 92 insertions(+), 61 deletions(-)

diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index b0bd1aec42..f7835d8604 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -111,21 +111,80 @@ int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
     return MIN_RSRP_VALUE;
 }
 
-int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t) {
-  //Need to implement once configuration is received
-  return 0;
+int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, int UE_id) {
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
+  NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id] ;
+  int nb_tci_states = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
+  NR_TCI_State_t *tci =NULL;
+  int i;
+
+  for(i=0; i<nb_tci_states && i<64; i++) {
+    tci = (NR_TCI_State_t *)secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i];
+
+    if(tci != NULL) {
+      if(tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
+        if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t)
+          return tci->tci_StateId;  // returned TCI state ID
+      }
+      // if type2 is configured
+      else if(tci->qcl_Type2 != NULL && tci->qcl_Type2->referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
+        if(tci->qcl_Type2->referenceSignal.choice.ssb == ssb_index_t)
+          return tci->tci_StateId; // returned TCI state ID
+      } else LOG_I(MAC,"SSB index is not found in first 64 TCI states of TCI_statestoAddModList[%d]", i);
+    }
+  }
+
+  // tci state not identified in first 64 TCI States of PDSCH Config
+  return -1;
 }
 
-int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t) {
-  //Need to implement once configuration is received
-  return 0;
+int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_id) {
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
+  NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id] ;
+  int nb_tci_states = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
+  NR_TCI_State_t *tci =NULL;
+  NR_TCI_StateId_t *tci_id = NULL;
+  int bwp_id = 1;
+  NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+  NR_ControlResourceSet_t *coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[bwp_id-1];
+  int i;
+  int flag = 0;
+  int tci_stateID = -1;
+
+  for(i=0; i<nb_tci_states && i<128; i++) {
+    tci = (NR_TCI_State_t *)secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i];
+
+    if(tci != NULL && tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
+      if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t) {
+        flag = 1;
+        tci_stateID = tci->tci_StateId;
+        break;
+      } else if(tci->qcl_Type2 != NULL && tci->qcl_Type2->referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
+        flag = 1;
+        tci_stateID = tci->tci_StateId;
+        break;
+      }
+    }
+
+    if(flag != 0 && tci_stateID != -1 && coreset != NULL) {
+      for(i=0; i<64 && i<coreset->tci_StatesPDCCH_ToAddList->list.count; i++) {
+        tci_id = coreset->tci_StatesPDCCH_ToAddList->list.array[i];
+
+        if(tci_id != NULL && *tci_id == tci_stateID)
+          return tci_stateID;
+      }
+    }
+  }
+
+  // Need to implement once configuration is received
+  return -1;
 }
 
 int ssb_index_sorted[MAX_NUM_SSB] = {0};
 int ssb_rsrp_sorted[MAX_NUM_SSB] = {0};
 //Sorts ssb_index and ssb_rsrp array data and keeps in ssb_index_sorted and
 //ssb_rsrp_sorted respectively
-int ssb_rsrp_sort(int *ssb_index, int *ssb_rsrp) {
+void ssb_rsrp_sort(int *ssb_index, int *ssb_rsrp) {
   int i, j;
 
   for(i = 0; *(ssb_index+i) != 0; i++) {
@@ -137,7 +196,6 @@ int ssb_rsrp_sort(int *ssb_index, int *ssb_rsrp) {
     }
   }
 }
-
 //identifies the target SSB Beam index
 //keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally
 //handles triggering of PDCCH and PDSCH MAC CEs
@@ -265,7 +323,7 @@ void tci_handling(int Mod_idP, int UE_id, int CC_id, NR_UE_sched_ctrl_t *sched_c
     The length of the field is 7 bits
      */
     if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId == 0) {
-      int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index]);
+      int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id);
 
       if( tci_state_id != -1)
         sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -275,7 +333,7 @@ void tci_handling(int Mod_idP, int UE_id, int CC_id, NR_UE_sched_ctrl_t *sched_c
         int flag = 0;
 
         for(i =0; ssb_index_sorted[i]!=0; i++) {
-          tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i]);
+          tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i], Mod_idP, UE_id) ;
 
           if(tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
             sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -289,7 +347,7 @@ void tci_handling(int Mod_idP, int UE_id, int CC_id, NR_UE_sched_ctrl_t *sched_c
         }
       }
     } else {
-      int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index]);
+      int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id);
 
       if (tci_state_id !=-1)
         sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -299,7 +357,7 @@ void tci_handling(int Mod_idP, int UE_id, int CC_id, NR_UE_sched_ctrl_t *sched_c
         int flag = 0;
 
         for(i =0; ssb_index_sorted[i]!=0; i++) {
-          tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i]);
+          tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], Mod_idP, UE_id);
 
           if( tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
             sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -349,40 +407,32 @@ void tci_handling(int Mod_idP, int UE_id, int CC_id, NR_UE_sched_ctrl_t *sched_c
     }//tci_presentInDCI
   }//is-triggering_beam_switch
 }//tci handling
-
-void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
+void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
                                 int CC_idP,
                                 frame_t frameP,
-                                sub_frame_t slotP){
-
+                                sub_frame_t slotP) {
   nfapi_nr_dl_tti_request_t    *DL_req = &gNB->DL_req[0];
   nfapi_nr_ul_tti_request_t    *UL_tti_req = &gNB->UL_tti_req[0];
   nfapi_nr_ul_dci_request_t    *UL_dci_req = &gNB->UL_dci_req[0];
   nfapi_nr_tx_data_request_t   *TX_req = &gNB->TX_req[0];
-
   gNB->pdu_index[CC_idP] = 0;
 
   if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF
-
     DL_req[CC_idP].SFN                                   = frameP;
     DL_req[CC_idP].Slot                                  = slotP;
     DL_req[CC_idP].dl_tti_request_body.nPDUs             = 0;
     DL_req[CC_idP].dl_tti_request_body.nGroup            = 0;
     //DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich           = 6000;
-
     UL_dci_req[CC_idP].SFN                         = frameP;
     UL_dci_req[CC_idP].Slot                        = slotP;
     UL_dci_req[CC_idP].numPdus                     = 0;
-
     UL_tti_req[CC_idP].SFN                         = frameP;
     UL_tti_req[CC_idP].Slot                        = slotP;
     UL_tti_req[CC_idP].n_pdus                      = 0;
     UL_tti_req[CC_idP].n_ulsch                     = 0;
     UL_tti_req[CC_idP].n_ulcch                     = 0;
     UL_tti_req[CC_idP].n_group                     = 0;
-
     TX_req[CC_idP].Number_of_PDUs                  = 0;
-
   }
 }
 /*
@@ -545,8 +595,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
   }
 }
 */
-
-
 /*
 void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
 {
@@ -575,31 +623,29 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
   }
 }
 */
-
 void nr_schedule_pucch(int Mod_idP,
                        int UE_id,
                        frame_t frameP,
                        sub_frame_t slotP) {
-
   uint16_t O_uci;
   uint16_t O_ack;
   uint8_t SR_flag = 0; // no SR in PUCCH implemented for now
   NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
   NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
   AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id);
-
   NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
   int bwp_id=1;
   NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
   nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
-
   NR_sched_pucch *curr_pucch;
   int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+
   if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
     nr_ulmix_slots++;
 
   for (int k=0; k<nr_ulmix_slots; k++) {
     curr_pucch = &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k];
+
     if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
       UL_tti_req->SFN = frameP;
       UL_tti_req->Slot = slotP;
@@ -610,58 +656,47 @@ void nr_schedule_pucch(int Mod_idP,
       UL_tti_req->n_pdus+=1;
       O_ack = curr_pucch->dai_c;
       O_uci = O_ack; // for now we are just sending acknacks in pucch
-
       LOG_I(MAC, "Scheduling pucch reception for frame %d slot %d\n", frameP, slotP);
-
       nr_configure_pucch(pucch_pdu,
-			 scc,
-			 ubwp,
+                         scc,
+                         ubwp,
                          curr_pucch->resource_indicator,
                          O_uci,
                          O_ack,
                          SR_flag);
-
       curr_pucch->dai_c = 0;
     }
   }
 }
-
-bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){
-
+bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
   if((bitmap>>slot)&0x01)
     return true;
   else
     return false;
 }
-
 void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
                                frame_t frame_rxP,
                                sub_frame_t slot_rxP,
                                frame_t frame_txP,
-                               sub_frame_t slot_txP){
-
+                               sub_frame_t slot_txP) {
   //printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP);
-			       
   protocol_ctxt_t   ctxt;
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame_txP, slot_txP,module_idP);
- 
   int CC_id;
   int UE_id;
   uint64_t *dlsch_in_slot_bitmap=NULL;
   uint64_t *ulsch_in_slot_bitmap=NULL;
   int pucch_sched;
-
   UE_id=0;
   int bwp_id = 1;
-
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_UE_list_t *UE_list = &gNB->UE_list;
   NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
   NR_COMMON_channels_t *cc = gNB->common_channels;
   NR_ServingCellConfigCommon_t        *scc     = cc->ServingCellConfigCommon;
   int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
-
   int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+
   if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
     nr_ulmix_slots++;
 
@@ -675,13 +710,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
 
   start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
-
   pdcp_run(&ctxt);
   //rrc_rx_tx(&ctxt, CC_id);
-
   RC.nrmac[module_idP]->frame    = frame_rxP;
   RC.nrmac[module_idP]->slot     = slot_rxP;
-
   dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap;  // static bitmap signaling which slot in a tdd period contains dlsch
   ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap;  // static bitmap signaling which slot in a tdd period contains ulsch
 
@@ -701,17 +733,16 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
       *ulsch_in_slot_bitmap = 0x00;
   }
 
-  // Check if there are downlink symbols in the slot, 
+  // Check if there are downlink symbols in the slot,
   if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)) {
     memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
     memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
+
     for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
       //mbsfn_status[CC_id] = 0;
-
       // clear vrb_maps
       memset(cc[CC_id].vrb_map, 0, 100);
       memset(cc[CC_id].vrb_map_UL, 0, 100);
-
       clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP);
     }
 
@@ -720,17 +751,15 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
       if (UE_list->active[i]) {
 
-        nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];      
-      
+        nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
+
         rnti = 0;//UE_RNTI(module_idP, i);
         CC_id = 0;//UE_PCCID(module_idP, i);
 
       } //END if (UE_list->active[i])
     } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
     */
-
     // This schedules MIB
-
     schedule_nr_mib(module_idP, frame_txP, slot_txP);
 
     if (get_softmodem_params()->phy_test == 0)
@@ -741,7 +770,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     // Phytest scheduling
 
     if (get_softmodem_params()->phy_test) {
-
       // TbD once RACH is available, start ta_timer when UE is connected
       if (ue_sched_ctl->ta_timer)
         ue_sched_ctl->ta_timer--;
@@ -761,6 +789,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) {
       ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd;
       nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,&pucch_sched);
+#ifdef GES_SUPPORT
+      tci_handling(module_idP, UE_id, CC_id, &ue_sched_ctl, frame, slot)
+#endif
       nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
       // resetting ta flag
       gNB->ta_len = 0;
@@ -771,26 +802,26 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
       allocate_CCEs(module_idP, CC_id, subframeP, 0);
     */
-
   } //is_nr_DL_slot
 
-  if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { 
-
+  if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) {
     if (get_softmodem_params()->phy_test == 0) {
       if (UE_list->fiveG_connected[UE_id])
         nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP);
+
       schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP);
       nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP);
     }
-    if (get_softmodem_params()->phy_test){
+
+    if (get_softmodem_params()->phy_test) {
       nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP);
-      if (is_xlsch_in_slot(*ulsch_in_slot_bitmap,slot_rxP%num_slots_per_tdd)){
+
+      if (is_xlsch_in_slot(*ulsch_in_slot_bitmap,slot_rxP%num_slots_per_tdd)) {
         nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP);
       }
     }
   }
 
   stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
-  
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
 }
-- 
2.26.2