From 9ee29fb0b2295a92448f28b47838253a2fe25e41 Mon Sep 17 00:00:00 2001
From: "Raymond.Knopp" <raymond.knopp@eurecom.fr>
Date: Sat, 14 Jan 2017 14:35:19 +0100
Subject: [PATCH] changes for S-subframe support in fronthaul

---
 openair1/PHY/INIT/lte_parms.c           | 23 ++++++++++++++++++++++-
 openair1/PHY/LTE_TRANSPORT/if4_tools.c  | 17 ++++++++++++++---
 openair1/PHY/impl_defs_lte.h            |  6 ++++++
 openair1/SCHED/phy_procedures_lte_eNb.c |  9 ++++++---
 targets/RT/USER/lte-enb.c               | 16 ++++++++++++++--
 5 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c
index cd879b1a90..f0c63df9e6 100644
--- a/openair1/PHY/INIT/lte_parms.c
+++ b/openair1/PHY/INIT/lte_parms.c
@@ -22,6 +22,23 @@
 #include "defs.h"
 #include "log.h"
 
+uint16_t dl_S_table_normal[10]={3,9,10,11,12,3,9,10,11,6};
+uint16_t dl_S_table_extended[10]={3,8,9,10,3,8,9,5,0,0};
+
+void set_S_config(LTE_DL_FRAME_PARMS *fp) {
+
+  int X = fp->srsX;
+
+  fp->ul_symbols_in_S_subframe=(1+X);
+
+  if ((fp->Ncp==EXTENDED) && (fp->tdd_config_S>7))
+    AssertFatal(1==0,"Illegal S subframe configuration for Extended Prefix mode\n");
+
+  fp->dl_symbols_in_S_subframe = (fp->Ncp==NORMAL)?dl_S_table_normal[fp->tdd_config_S] : dl_S_table_extended[fp->tdd_config_S];
+
+  
+}
+
 int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
 {
 
@@ -29,7 +46,7 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
 
   LOG_I(PHY,"Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
 
-  if (frame_parms->Ncp==1) {
+  if (frame_parms->Ncp==EXTENDED) {
     frame_parms->nb_prefix_samples0=512;
     frame_parms->nb_prefix_samples = 512;
     frame_parms->symbols_per_tti = 12;
@@ -37,8 +54,10 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
     frame_parms->nb_prefix_samples0 = 160;
     frame_parms->nb_prefix_samples = 144;
     frame_parms->symbols_per_tti = 14;
+      
   }
 
+
   switch(osf) {
   case 1:
     log2_osf = 0;
@@ -167,6 +186,8 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
 
   printf("lte_parms.c: Setting N_RB_DL to %d, ofdm_symbol_size %d\n",frame_parms->N_RB_DL, frame_parms->ofdm_symbol_size);
 
+  if (frame_parms->frame_type == TDD) set_S_config(frame_parms);
+
   //  frame_parms->tdd_config=3;
   return(0);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 6878ae2684..924eef11b9 100755
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -33,6 +33,7 @@
 #include "PHY/defs.h"
 #include "PHY/TOOLS/alaw_lut.h"
 #include "PHY/extern.h"
+#include "SCHED/defs.h"
 
 //#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
@@ -54,11 +55,14 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
 
   IF4p5_header_t *packet_header=NULL;
   eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);
-
+  int nsym = fp->symbols_per_tti;
   
   if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );   
 
   if (packet_type == IF4p5_PDLFFT) {
+    if (subframe_select(fp,subframe)==SF_S)
+      nsym=fp->dl_symbols_in_S_subframe;
+
     db_fulllength = 12*fp->N_RB_DL;
     db_halflength = (db_fulllength)>>1;
     slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
@@ -74,7 +78,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
     }    
     gen_IF4p5_dl_header(packet_header, frame, subframe);
 		    
-    for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
+    for (symbol_id=0; symbol_id<nsym; symbol_id++) {
       if (eNB->CC_id==1) LOG_I(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,frame,subframe,symbol_id);
       
       for (element_id=0; element_id<db_halflength; element_id++) {
@@ -107,6 +111,12 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
     slotoffsetF = 1;
     blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; 
 
+    if (subframe_select(fp,subframe)==SF_S) {
+      nsym=fp->ul_symbols_in_S_subframe;
+      slotoffsetF  += (fp->ofdm_symbol_size*(fp->symbols_per_tti-nsym));
+      blockoffsetF += (fp->ofdm_symbol_size*(fp->symbols_per_tti-nsym));
+    }
+
     if (eth->flags == ETH_RAW_IF4p5_MODE) {
       packet_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
       data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
@@ -117,7 +127,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
     gen_IF4p5_ul_header(packet_header, packet_type, frame, subframe);
 
     if (packet_type == IF4p5_PULFFT) {
-      for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {			
+      for (symbol_id=fp->symbols_per_tti-nsym; symbol_id<fp->symbols_per_tti; symbol_id++) {			
 	LOG_D(PHY,"IF4p5_PULFFT: frame %d, subframe %d, symbol %d\n",frame,subframe,symbol_id);
 	for (element_id=0; element_id<db_halflength; element_id++) {
 	  i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id];
@@ -293,6 +303,7 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t
              (int16_t*) (rx_buffer+sizeof_IF4p5_header_t),
              PRACH_BLOCK_SIZE_BYTES);
     }
+  } else if (*packet_type == IF4p5_PULTICK) {
 
   } else {
     AssertFatal(1==0, "recv_IF4p5 - Unknown packet_type %x", *packet_type);            
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 7a30bff6ab..577cc4a41b 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -504,6 +504,8 @@ typedef struct {
   uint8_t tdd_config;
   /// TDD S-subframe configuration (0-9)
   uint8_t tdd_config_S;
+  /// srs extra symbol flag for TDD
+  uint8_t srsX;
   /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0).
   uint8_t node_id;
   /// Frequency index of CBMIMO1 card
@@ -542,6 +544,10 @@ typedef struct {
   uint32_t samples_per_tti;
   /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
   uint16_t symbols_per_tti;
+  /// Number of OFDM symbols in DL portion of S-subframe
+  uint16_t dl_symbols_in_S_subframe;
+  /// Number of SC-FDMA symbols in UL portion of S-subframe
+  uint16_t ul_symbols_in_S_subframe;
   /// Number of Physical transmit antennas in node
   uint8_t nb_antennas_tx;
   /// Number of Receive antennas in node
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 50fd920262..5f0b44a5f3 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -2817,12 +2817,15 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc){
   const int frame        = proc->frame_rx;
   int offset             = (eNB->single_thread_flag==1) ? 0 : (subframe&1);
 
-  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return;
+
 
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB+offset, proc->frame_rx );
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB+offset, proc->subframe_rx );
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 1 );
-  
+
+
+  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; 
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 1 ); 
   start_meas(&eNB->phy_proc_rx);
   LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe);
 
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 219d9c5d48..5959c1953d 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -768,8 +768,18 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
   int subframe_tx,frame_tx;
 
   symbol_number = 0;
-  symbol_mask_full = (1<<fp->symbols_per_tti)-1;
-
+  symbol_mask_full = (subframe_select(fp,*subframe) == SF_S) ? (1<<fp->dl_symbols_in_S_subframe) : (1<<fp->symbols_per_tti)-1;
+
+  // correct for TDD
+  if (fp->frame_type == TDD) {
+    while (subframe_select(fp,*subframe) == SF_UL) {
+      *subframe=*subframe+1;
+      if (*subframe==10) {
+	*subframe=0;
+	*frame=*frame+1;
+      }
+    }
+  }
   do {   // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
     recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number);
     if (proc->first_tx != 0) {
@@ -1033,6 +1043,8 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
       LOG_D(PHY,"rx_fh:if4p5: frame %d, subframe %d, PULFFT symbol %d\n",f,sf,symbol_number);
 
       proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number);
+    } else if (packet_type == IF4p5_PULTICK) {
+      break;
     } else if (packet_type == IF4p5_PRACH) {
       LOG_D(PHY,"rx_fh:if4p5: frame %d, subframe %d, PRACH\n",f,sf);
       // wakeup prach processing
-- 
2.26.2