From 0705e71ffc72db255fedbf853f72332c36c402d0 Mon Sep 17 00:00:00 2001
From: hbilel <haithem.bilel@alcatelonetouch.com>
Date: Wed, 12 Oct 2016 14:29:48 +0200
Subject: [PATCH]   [OAI-UE] SRS feature            1- Implement SRS procedures

---
 cmake_targets/CMakeLists.txt                  |   1 +
 openair1/PHY/INIT/lte_init.c                  |  41 +++
 openair1/PHY/LTE_TRANSPORT/defs.h             |   2 +
 openair1/PHY/extern.h                         |  12 +
 openair1/PHY/impl_defs_lte.h                  |   4 +
 openair1/SCHED/Makefile.inc                   |   1 +
 openair1/SCHED/defs.h                         |   9 +
 openair1/SCHED/phy_procedures_lte_ue.c        | 243 +++++++++++++++++-
 openair1/SCHED/srs_pc.c                       |  99 +++++++
 openair2/RRC/LITE/MESSAGES/asn1_msg.c         |  18 +-
 openair2/RRC/LITE/rrc_eNB.c                   |   2 +-
 ...band7.tm1.generic.oaisim.local_no_mme.conf |  10 +-
 targets/SIMU/USER/oaisim_functions.c          |   4 +-
 13 files changed, 421 insertions(+), 25 deletions(-)
 create mode 100644 openair1/SCHED/srs_pc.c

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 5e86d5937..d47389e7b 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -931,6 +931,7 @@ set(SCHED_SRC
   ${OPENAIR1_DIR}/SCHED/phy_mac_stub.c
   ${OPENAIR1_DIR}/SCHED/pucch_pc.c
   ${OPENAIR1_DIR}/SCHED/pusch_pc.c
+  ${OPENAIR1_DIR}/SCHED/srs_pc.c
 )
 add_library(SCHED_LIB ${SCHED_SRC})
 
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index a2e4fa874..d358329b6 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -489,6 +489,26 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB)
 
       }
 
+      if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) {
+        if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SchedulingRequestConfig_PR_setup) {
+
+          eNB->soundingrs_ul_config_dedicated[UE_id].duration             = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration;
+          eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift          = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;
+          eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition   = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
+          eNB->soundingrs_ul_config_dedicated[UE_id].srs_Bandwidth        = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
+          eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex      = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
+          eNB->soundingrs_ul_config_dedicated[UE_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;
+          eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb     = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
+
+
+          LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex);
+
+        }
+
+        LOG_D(PHY,"------------------------------------------------------------\n");
+
+      }
+
       eNB->physicalConfigDedicated[UE_id] = NULL;
     }
   }
@@ -859,6 +879,27 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
 
     }
 
+    if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) {
+
+      if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SchedulingRequestConfig_PR_setup) {
+
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration             = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift          = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition   = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth        = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex      = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb     = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
+
+
+        LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex);
+      }
+
+      LOG_D(PHY,"------------------------------------------------------------\n");
+
+    }
+
+
 #ifdef CBA
 
     if (physicalConfigDedicated->pusch_CBAConfigDedicated_vlola) {
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index 26e2d4046..be6cd4f5a 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -341,6 +341,8 @@ typedef struct {
   int16_t Po_PUSCH;
   /// PHR - current power headroom (based on last PUSCH transmission)
   int16_t PHR;
+  /// Po_SRS - target output power for SRS
+  int16_t Po_SRS;
   /// num active cba group
   uint8_t num_active_cba_groups;
   /// num dci found for cba
diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h
index 867f980e5..2ce2d03ff 100755
--- a/openair1/PHY/extern.h
+++ b/openair1/PHY/extern.h
@@ -118,5 +118,17 @@ extern char eNB_timing[2][20];
 extern int16_t unscrambling_lut[65536*16];
 extern uint8_t scrambling_lut[65536*16];
 
+extern unsigned short msrsb_6_40[8][4];
+extern unsigned short msrsb_41_60[8][4];
+extern unsigned short msrsb_61_80[8][4];
+extern unsigned short msrsb_81_110[8][4];
+extern unsigned short Nb_6_40[8][4];
+extern unsigned short Nb_41_60[8][4];
+extern unsigned short Nb_61_80[8][4];
+extern unsigned short Nb_81_110[8][4];
+
+extern uint16_t hundred_times_log10_NPRB[100];
+extern uint8_t alpha_lut[8];
+
 #endif /*__PHY_EXTERN_H__ */
 
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index bed205780..6813fe058 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -319,6 +319,10 @@ typedef struct {
   uint16_t srs_ConfigIndex;
   /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value.
   uint8_t cyclicShift;
+  // Parameter: cell srs subframe for internal implementation
+  uint8_t srsCellSubframe;
+  // Parameter: ue srs subframe for internal implementation
+  uint8_t srsUeSubframe;
 } SOUNDINGRS_UL_CONFIG_DEDICATED;
 
 /// UplinkPowerControlDedicated Information Element from 36.331 RRC spec
diff --git a/openair1/SCHED/Makefile.inc b/openair1/SCHED/Makefile.inc
index e3fd877e5..559d3dca3 100644
--- a/openair1/SCHED/Makefile.inc
+++ b/openair1/SCHED/Makefile.inc
@@ -3,3 +3,4 @@ SCHED_OBJS += $(TOP_DIR)/SCHED/phy_procedures_lte_ue.o
 SCHED_OBJS += $(TOP_DIR)/SCHED/phy_procedures_lte_eNb.o
 SCHED_OBJS += $(TOP_DIR)/SCHED/pusch_pc.o
 SCHED_OBJS += $(TOP_DIR)/SCHED/pucch_pc.o
+SCHED_OBJS += $(TOP_DIR)/SCHED/srs_pc.o
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index f9ebd3b3b..10a0cf6e4 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -444,6 +444,15 @@ int8_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,ui
  */
 void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag);
 
+/*! \brief This function implements the power control mechanism for SRS from 36.213.
+    @param phy_vars_ue PHY variables
+    @param proc Pointer to proc descriptor
+    @param eNB_id Index of eNB
+    @param j index of type of PUSCH (SPS, Normal, Msg3)
+    @returns Transmit power
+ */
+void srs_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag);
+
 int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
 
 #ifdef LOCALIZATION
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 5fa9f9f2f..f15e4768c 100755
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -205,6 +205,7 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb
   int gain_dB = power_dBm - power_max_dBm;
   double gain_lin;
 
+  LOG_I(PHY,"Get Tx Amp; Gain[dB]: %d, AMP: %d\n",gain_dB,AMP);
   if (gain_dB < -20)
     return(AMP/10);
 
@@ -385,6 +386,180 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
   return(0);
 }
 
+void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset)
+{
+    if(TDD == frameType)
+    {
+        if(isrs<10)
+        {
+            mac_xface->macphy_exit("2 ms SRS periodicity not supported");
+        }
+
+        if((isrs>9)&&(isrs<15))
+        {
+            *psrsPeriodicity=5;
+            *psrsOffset=isrs-10;
+        }
+        if((isrs>14)&&(isrs<25))
+        {
+            *psrsPeriodicity=10;
+            *psrsOffset=isrs-15;
+        }
+        if((isrs>24)&&(isrs<45))
+        {
+            *psrsPeriodicity=20;
+            *psrsOffset=isrs-25;
+        }
+        if((isrs>44)&&(isrs<85))
+        {
+            *psrsPeriodicity=40;
+            *psrsOffset=isrs-45;
+        }
+        if((isrs>84)&&(isrs<165))
+        {
+            *psrsPeriodicity=80;
+            *psrsOffset=isrs-85;
+        }
+        if((isrs>164)&&(isrs<325))
+        {
+            *psrsPeriodicity=160;
+            *psrsOffset=isrs-165;
+        }
+        if((isrs>324)&&(isrs<645))
+        {
+            *psrsPeriodicity=320;
+            *psrsOffset=isrs-325;
+        }
+
+        if(isrs>644)
+        {
+            mac_xface->macphy_exit("Isrs out of range");
+        }
+
+    }
+    else
+    {
+        if(isrs<2)
+        {
+            *psrsPeriodicity=2;
+            *psrsOffset=isrs;
+        }
+        if((isrs>1)&&(isrs<7))
+        {
+            *psrsPeriodicity=5;
+            *psrsOffset=isrs-2;
+        }
+        if((isrs>6)&&(isrs<17))
+        {
+            *psrsPeriodicity=10;
+            *psrsOffset=isrs-7;
+        }
+        if((isrs>16)&&(isrs<37))
+        {
+            *psrsPeriodicity=20;
+            *psrsOffset=isrs-17;
+        }
+        if((isrs>36)&&(isrs<77))
+        {
+            *psrsPeriodicity=40;
+            *psrsOffset=isrs-37;
+        }
+        if((isrs>76)&&(isrs<157))
+        {
+            *psrsPeriodicity=80;
+            *psrsOffset=isrs-77;
+        }
+        if((isrs>156)&&(isrs<317))
+        {
+            *psrsPeriodicity=160;
+            *psrsOffset=isrs-157;
+        }
+        if((isrs>316)&&(isrs<637))
+        {
+            *psrsPeriodicity=320;
+            *psrsOffset=isrs-317;
+        }
+        if(isrs>636)
+        {
+            mac_xface->macphy_exit("Isrs out of range");
+        }
+    }
+}
+
+void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+    LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+    int frame_tx    = proc->frame_tx;
+    int subframe_tx = proc->subframe_tx;
+    uint8_t isSubframeSRS   = 0; // SRS Cell Occasion
+    uint8_t isSubframeSRSTx = 0; // SRS UE Occasion
+
+    SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+
+  // check for SRS opportunity
+  pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
+  pSoundingrs_ul_config_dedicated->srsCellSubframe = 0;
+  if(frame_parms->soundingrs_ul_config_common.enabled_flag)
+  {
+
+      LOG_D(PHY," SRS SUBFRAMECONFIG: %d, Isrs: %d \n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig, pSoundingrs_ul_config_dedicated->srs_ConfigIndex);
+
+      uint8_t  TSFC;
+      uint16_t deltaTSFC; // bitmap
+      uint8_t  srs_SubframeConfig;
+      uint16_t srsPeriodicity;
+      uint16_t srsOffset;
+
+      // table resuming TSFC (Period) and deltaSFC (offset)
+      const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} };      // Table 5.5.3.3-2 3GPP 36.211 FDD
+      const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
+
+      srs_SubframeConfig = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig;
+      if (FDD == frame_parms->frame_type)
+      {
+          // srs_SubframeConfig =< 14
+          deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
+          TSFC      = deltaTSFCTabType1[srs_SubframeConfig][1];
+      }
+      else
+      {
+          // srs_SubframeConfig =< 13
+          deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
+          TSFC      = deltaTSFCTabType2[srs_SubframeConfig][1];
+      }
+
+      LOG_D(PHY," ISTDD: %d, TSFC: %d, deltaTSFC: %d, AbsSubframeTX: %d\n", frame_parms->frame_type, TSFC, deltaTSFC, (((int)frame_tx*10)+(int)subframe_tx));
+
+      // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
+      uint16_t tmp = (subframe_tx %  TSFC);
+      if((1<<tmp) & deltaTSFC)
+      {
+          // This is a Sounding reference signal subframes
+          isSubframeSRS = 1;
+          pSoundingrs_ul_config_dedicated->srsCellSubframe  = 1;
+      }
+
+
+      compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset);
+
+      // transmit SRS if the four following constraints are respected:
+      // - UE is configured to transmit SRS
+      // - SRS are configured in current subframe
+      // - UE is configured to send SRS in this subframe
+      // - CQI is not scheduled in PUCCH transmission  - TO BE ADDED
+      // - simultaneous transmission of SRS and ACKNACK is authorised - TO BE CHECKED
+      if( isSubframeSRS  &&
+          (((10*frame_tx+subframe_tx) % srsPeriodicity) == srsOffset)
+              //(! is_pucch_per_cqi_report))
+      )
+      {
+          isSubframeSRSTx = 1;
+          pSoundingrs_ul_config_dedicated->srsUeSubframe = 1;
+      }
+      LOG_D(PHY," isSubframeSRS: %d, isSubframeSRSTx: %d \n", isSubframeSRS, isSubframeSRSTx);
+  }
+}
+
 uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 		      UE_rxtx_proc_t *proc,
                       uint8_t eNB_id,
@@ -1086,6 +1261,49 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
   } // subframe_scheduling_flag==1
 }
 
+void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag)
+{
+
+  //LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  //int8_t  frame_tx    = proc->frame_tx;
+  int8_t  subframe_tx = proc->subframe_tx;
+  int16_t tx_amp;
+  int16_t Po_SRS;
+  uint8_t nb_rb_srs;
+
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+  uint8_t isSrsTxOccasion = pSoundingrs_ul_config_dedicated->srsUeSubframe;
+
+  if(isSrsTxOccasion)
+  {
+    ue->generate_ul_signal[eNB_id] = 1;
+    if (ue->mac_enabled==1)
+    {
+      srs_power_cntl(ue,proc,eNB_id, (uint8_t*)(&nb_rb_srs), abstraction_flag);
+      Po_SRS = ue->ulsch[eNB_id]->Po_SRS;
+    }
+    else
+    {
+      Po_SRS = ue->tx_power_max_dBm;
+    }
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+    tx_amp = get_tx_amp(Po_SRS,
+                        ue->tx_power_max_dBm,
+                        ue->frame_parms.N_RB_UL,
+                        nb_rb_srs);
+#else
+      tx_amp = AMP;
+#endif
+    LOG_I(PHY,"SRS PROC; TX_MAX_POWER %d, Po_SRS %d, NB_RB_UL %d, NB_RB_SRS %d TX_AMPL %d\n",ue->tx_power_max_dBm,
+            Po_SRS,
+            ue->frame_parms.N_RB_UL,
+            nb_rb_srs,
+            tx_amp);
+
+    generate_srs_tx(ue, eNB_id, tx_amp, subframe_tx);
+  }
+}
 
 void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
 
@@ -1103,6 +1321,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   int tx_amp;
   int8_t Po_PUCCH;
 
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+  uint8_t isShortenPucch = pSoundingrs_ul_config_dedicated->srsCellSubframe;
+
   bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
   
   if ((frame_parms->frame_type==FDD) ||
@@ -1175,19 +1396,21 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
 	    
     if (SR_payload>0) {
-      LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), n1_pucch %d, Po_PUCCH, amp %d\n",
+      LOG_I(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), shorten_pucch %d, n1_pucch %d, Po_PUCCH, amp %d\n",
 	    Mod_id,
 	    ue->dlsch[eNB_id][0]->rnti,
+	    isShortenPucch,
 	    frame_tx, subframe_tx,
 	    pucch_ack_payload[0],pucch_ack_payload[1],
 	    ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
 	    Po_PUCCH,
 	    tx_amp);
     } else {
-      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
+      LOG_I(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
 	    Mod_id,
 	    ue->dlsch[eNB_id][0]->rnti,
 	    frame_tx, subframe_tx,
+	    isShortenPucch,
 	    n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
 	    Po_PUCCH,
 	    tx_amp);
@@ -1201,7 +1424,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 		       format,
 		       &ue->pucch_config_dedicated[eNB_id],
 		       n1_pucch,
-		       1,  // shortened format
+		       isShortenPucch,  // shortened format
 		       pucch_ack_payload,
 		       tx_amp,
 		       subframe_tx);
@@ -1236,10 +1459,11 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #else
     tx_amp = AMP;
 #endif
-    LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), n1_pucch %d, Po_PUCCH %d\n",
+    LOG_I(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
 	  Mod_id,
 	  ue->dlsch[eNB_id][0]->rnti,
 	  frame_tx, subframe_tx,
+	  isShortenPucch,
 	  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
 	  Po_PUCCH);
 	    
@@ -1251,7 +1475,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 		       pucch_format1,
 		       &ue->pucch_config_dedicated[eNB_id],
 		       ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
-		       1,  // shortened format
+		       isShortenPucch,  // shortened format
 		       pucch_ack_payload,  // this is ignored anyway, we just need a pointer
 		       tx_amp,
 		       subframe_tx);
@@ -1306,8 +1530,13 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
 
   }
   	  
-  if (ue->UE_mode[eNB_id] == PUSCH) { // check if we need to use PUCCH 1a/1b
-	  ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
+  if (ue->UE_mode[eNB_id] == PUSCH) {
+      // check cell srs subframe and ue srs subframe
+      ue_compute_srs_occasion(ue,proc,eNB_id);
+      // check if we need to use PUCCH 1a/1b
+      ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
+      // check if we need to use SRS
+      ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
   } // UE_mode==PUSCH
 	
   	
diff --git a/openair1/SCHED/srs_pc.c b/openair1/SCHED/srs_pc.c
new file mode 100644
index 000000000..dc9b8fef4
--- /dev/null
+++ b/openair1/SCHED/srs_pc.c
@@ -0,0 +1,99 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+
+/*! \file srs_pc.c
+ * \brief Implementation of UE SRS Power Control procedures from 36.213 LTE specifications (Section
+ * \author H. Bilel
+ * \date 2016
+ * \version 0.1
+ * \company TCL
+ * \email: haithem.bilel@alcatelOneTouch.com
+ * \note
+ * \warning
+ */
+
+#include "PHY/defs.h"
+#include "PHY/LTE_TRANSPORT/proto.h"
+#include "PHY/extern.h"
+
+void srs_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag)
+{
+
+  int16_t PL;
+  int8_t  P_opusch;
+  int8_t  Psrs_offset;
+  int16_t P_srs;
+  int16_t f_pusch;
+  uint8_t alpha;
+  uint8_t Msrs = 0;
+  
+
+  SOUNDINGRS_UL_CONFIG_DEDICATED *psoundingrs_ul_config_dedicated = &ue->soundingrs_ul_config_dedicated[eNB_id];
+  LTE_DL_FRAME_PARMS             *pframe_parms                    = &ue->frame_parms;
+  
+  uint8_t Bsrs  = psoundingrs_ul_config_dedicated->srs_Bandwidth;
+  uint8_t Csrs  = pframe_parms->soundingrs_ul_config_common.srs_BandwidthConfig;
+  LOG_I(PHY," SRS Power Control; AbsSubframe %d.%d, eNB_id %d, srs_Bandwidth %d, srs_BandwidthConfig %d \n",proc->frame_tx,proc->subframe_tx,eNB_id,Bsrs,Csrs);
+  
+  if (pframe_parms->N_RB_UL < 41)
+  {
+    Msrs    = Nb_6_40[Csrs][Bsrs];
+  } 
+  else if (pframe_parms->N_RB_UL < 61)
+  {
+    Msrs    = Nb_41_60[Csrs][Bsrs];
+  } 
+  else if (pframe_parms->N_RB_UL < 81)
+  {
+    Msrs    = Nb_61_80[Csrs][Bsrs];
+  } 
+  else if (pframe_parms->N_RB_UL <111)
+  {
+    Msrs    = Nb_81_110[Csrs][Bsrs];
+  }
+
+  // SRS Power control 36.213 5.1.3.1
+  // P_srs   =  P_srs_offset+ 10log10(Msrs) + P_opusch(j) + alpha*PL + f(i))
+
+  Psrs_offset = (ue->ul_power_control_dedicated[eNB_id].pSRS_Offset - 3);
+  P_opusch    = ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
+  f_pusch     = ue->ulsch[eNB_id]->f_pusch;
+  alpha       = alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha];
+  PL          = get_PL(ue->Mod_id,ue->CC_id,eNB_id);
+
+  LOG_I(PHY," SRS Power Control; eNB_id %d, p0_NominalPUSCH %d, alpha %d \n",eNB_id,P_opusch,alpha);
+  LOG_I(PHY," SRS Power Control; eNB_id %d, pSRS_Offset %d, Msrs %d, PL %d, f_pusch %d \n",eNB_id,Psrs_offset,Msrs,PL,f_pusch);
+
+  P_srs  = P_opusch + Psrs_offset + f_pusch;
+  P_srs += (((int32_t)alpha * (int32_t)PL) + hundred_times_log10_NPRB[Msrs-1])/100 ;
+  
+  ue->ulsch[eNB_id]->Po_SRS = P_srs;
+  pnb_rb_srs[0]             = Msrs;
+  LOG_I(PHY," SRS Power Control; eNB_id %d, P_srs[dBm] %d\n",eNB_id,P_srs);
+}
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index 13cfae80d..e0556b92b 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -1496,7 +1496,7 @@ do_RRCConnectionSetup(
   physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH         = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH));
   physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH         = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
   physicalConfigDedicated2->cqi_ReportConfig              = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL;//CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
   physicalConfigDedicated2->antennaInfo                   = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo));
   physicalConfigDedicated2->schedulingRequestConfig       = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
 #ifdef CBA
@@ -1582,19 +1582,17 @@ do_RRCConnectionSetup(
     */
 
   //soundingRS-UL-ConfigDedicated
-  /*
   physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = SoundingRS_UL_ConfigDedicated_PR_setup;
-  assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth,
-        SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0);
-  assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth,
-        SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0);
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth =
+                                                           SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0;
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth =
+        SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0;
   physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0;
   physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1;
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=1;
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=45;
   physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0;
-  assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift,
-        SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0);
-  */
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift=
+        SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0;
 
 
   //AntennaInfoDedicated
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 5807ababf..517e35416 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -2621,7 +2621,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
   physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH =
     CALLOC(1, sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
   physicalConfigDedicated2->cqi_ReportConfig = NULL;  //CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; //CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
   physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo));
   physicalConfigDedicated2->schedulingRequestConfig =
     CALLOC(1, sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
index ef7c1cc19..a79cb2cae 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
@@ -62,11 +62,11 @@ eNBs =
         pusch_nDMRS1                              = 0;
         phich_duration                            = "NORMAL";
         phich_resource                            = "ONESIXTH";
-        srs_enable                                = "DISABLE";
-        /*  srs_BandwidthConfig                   =;
-        srs_SubframeConfig                        =;
-        srs_ackNackST                             =;
-        srs_MaxUpPts                              =;*/
+        srs_enable                                = "ENABLE";
+        srs_BandwidthConfig                       =2;
+        srs_SubframeConfig                        =13;
+        srs_ackNackST                             ="DISABLE";
+        srs_MaxUpPts                              ="DISABLE";
 
         pusch_p0_Nominal                          = -108;
         pusch_alpha                               = "AL1";
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index 2b19e30a9..c49308696 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -1283,7 +1283,7 @@ void init_openair1(void)
   for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
       
-      PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=23;
+      PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=10;
       
       PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB=100;
 
@@ -1525,7 +1525,7 @@ void update_ocm()
           //calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,0);
           UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB = eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB;
           //    if (frame % 50 == 0)
-          LOG_I(OCM,"Path loss (CCid %d) between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n",
+          LOG_D(OCM,"Path loss (CCid %d) between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n",
                 CC_id,eNB_id,enb_data[eNB_id]->x,enb_data[eNB_id]->y,UE_id,ue_data[UE_id]->x,ue_data[UE_id]->y,
                 eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB, eNB2UE[eNB_id][UE_id][CC_id]->aoa);
           //double dx, dy, distance;
-- 
GitLab