From 848f78465beb7eab74bb54450065edcb48bd711e Mon Sep 17 00:00:00 2001
From: Raymond Knopp <raymond.knopp@eurecom.fr>
Date: Fri, 13 Jan 2017 19:49:22 +0100
Subject: [PATCH] addition of IF4p5 ULTICK packet for TDD fronthaul

---
 openair1/PHY/LTE_TRANSPORT/if4_tools.c        | 67 +++++++++++--------
 openair1/PHY/LTE_TRANSPORT/if4_tools.h        |  3 +-
 targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c |  2 +
 targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c |  2 +
 targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h |  2 +
 targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp  | 12 +++-
 targets/RT/USER/lte-enb.c                     | 44 ++++++------
 7 files changed, 83 insertions(+), 49 deletions(-)

diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 3ffc50efb9..6878ae2684 100755
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -100,7 +100,8 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
       slotoffsetF  += fp->ofdm_symbol_size;
       blockoffsetF += fp->ofdm_symbol_size;    
     }
-  } else if (packet_type == IF4p5_PULFFT) {
+  } else if ((packet_type == IF4p5_PULFFT)||
+	     (packet_type == IF4p5_PULTICK)){
     db_fulllength = 12*fp->N_RB_UL;
     db_halflength = (db_fulllength)>>1;
     slotoffsetF = 1;
@@ -113,33 +114,45 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
       packet_header = (IF4p5_header_t *)(tx_buffer);
       data_block = (uint16_t*)(tx_buffer + sizeof_IF4p5_header_t);
     }
-    gen_IF4p5_ul_header(packet_header, frame, subframe);
-
-    for (symbol_id=0; 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];
-        data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
-
-        i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
-        data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);        
-      }
-       			
-      packet_header->frame_status &= ~(0x000f<<26);
-      packet_header->frame_status |= (symbol_id&0x000f)<<26; 
-			
+    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++) {			
+	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];
+	  data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
+	  
+	  i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
+	  data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);        
+	}
+       	
+	packet_header->frame_status &= ~(0x000f<<26);
+	packet_header->frame_status |= (symbol_id&0x000f)<<26; 
+	
+	if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
+					  symbol_id,
+					  &tx_buffer,
+					  db_fulllength,
+					  1,
+					  IF4p5_PULFFT)) < 0) {
+	  perror("ETHERNET write for IF4p5_PULFFT\n");
+	}
+	
+	slotoffsetF  += fp->ofdm_symbol_size;
+	blockoffsetF += fp->ofdm_symbol_size;
+      }    
+    }
+    else {
       if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
-                                        symbol_id,
-                                        &tx_buffer,
-                                        db_fulllength,
+					0,
+					&tx_buffer,
+					0,
 					1,
-                                        IF4p5_PULFFT)) < 0) {
-        perror("ETHERNET write for IF4p5_PULFFT\n");
+					IF4p5_PULTICK)) < 0) {
+	perror("ETHERNET write for IF4p5_PULFFT\n");
       }
-
-      slotoffsetF  += fp->ofdm_symbol_size;
-      blockoffsetF += fp->ofdm_symbol_size;    
-    }		
+    }
   } else if (packet_type == IF4p5_PRACH) {
     // FIX: hard coded prach samples length
     LOG_D(PHY,"IF4p5_PRACH: frame %d, subframe %d\n",frame,subframe);
@@ -303,10 +316,10 @@ void gen_IF4p5_dl_header(IF4p5_header_t *dl_packet, int frame, int subframe) {
 }
 
 
-void gen_IF4p5_ul_header(IF4p5_header_t *ul_packet, int frame, int subframe) {  
+void gen_IF4p5_ul_header(IF4p5_header_t *ul_packet, uint16_t packet_subtype, int frame, int subframe) {  
 
   ul_packet->type = IF4p5_PACKET_TYPE; 
-  ul_packet->sub_type = IF4p5_PULFFT;
+  ul_packet->sub_type = packet_subtype;
 
   ul_packet->rsvd = 0;
   
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.h b/openair1/PHY/LTE_TRANSPORT/if4_tools.h
index 1f78e7f77a..e2d4f1f7de 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.h
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.h
@@ -37,6 +37,7 @@
 #define IF4p5_PULFFT 0x0019 
 #define IF4p5_PDLFFT 0x0020
 #define IF4p5_PRACH 0x0021
+#define IF4p5_PULTICK 0x0022
 
 struct IF4p5_header {  
   /// Type
@@ -55,7 +56,7 @@ typedef struct IF4p5_header IF4p5_header_t;
 
 void gen_IF4p5_dl_header(IF4p5_header_t*, int, int);
 
-void gen_IF4p5_ul_header(IF4p5_header_t*, int, int);
+void gen_IF4p5_ul_header(IF4p5_header_t*, uint16_t, int, int);
 
 void gen_IF4p5_prach_header(IF4p5_header_t*, int, int);
 
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
index ec09550323..3ed1945add 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -198,6 +198,8 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
     packet_size = RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks);    
   } else if (flags == IF4p5_PULFFT) {
     packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);    
+  } else if (flags == IF4p5_PULTICK) {
+    packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;    
   } else if (flags == IF5_MOBIPASS) {
     packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
   } else {
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
index ae7c0c9d7b..898382cf6a 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
@@ -206,6 +206,8 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
     packet_size = UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks);    
   } else if (flags == IF4p5_PULFFT) {
     packet_size = UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks); 
+  } else if (flags == IF4p5_PULTICK) {
+    packet_size = UDP_IF4p5_PULTICK_SIZE_BYTES; 
   } else if (flags == IF4p5_PRACH) {  
     packet_size = UDP_IF4p5_PRACH_SIZE_BYTES;   
   } else {
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
index 421c2639c6..68b153392b 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
@@ -61,9 +61,11 @@
  
 #define RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))  
 #define RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))  
+#define RAW_IF4p5_PULTICK_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t)  
 #define RAW_IF4p5_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
 #define UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))  
 #define UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks) (sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))  
+#define UDP_IF4p5_PULTICK_SIZE_BYTES (sizeof_IF4p5_header_t)  
 #define UDP_IF4p5_PRACH_SIZE_BYTES (sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
 
 // Mobipass packet sizes
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 3d0674c73e..00d4f220b9 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -181,6 +181,16 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
     s->tx_md.has_time_spec = true;
   else
     s->tx_md.has_time_spec = false;
+
+  if (device->openair0_cfg[0].tx_freq[0] == device->openair0_cfg[0].rx_freq[0]) {
+    // for TDD each write should be considered as a burst to trigger the switch on GPIO
+    s->tx_md.start_of_burst = true;
+    s->tx_md.end_of_burst = true;
+  }
+  else {
+    s->tx_md.start_of_burst = false;
+    s->tx_md.end_of_burst = false;
+  }
   
   if (cc>1) {
     std::vector<void *> buff_ptrs;
@@ -190,7 +200,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
   else
     ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3);
 
-  s->tx_md.start_of_burst = false;
+
 
   if (ret != nsamps) {
     printf("[xmit] tx samples %d != %d\n",ret,nsamps);
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 99e05a39bf..0ababcc7aa 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -875,29 +875,33 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
     // Transmit TX buffer based on timestamp from RX
     //    printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff );
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
     // prepare tx buffer pointers
 	
-    for (i=0; i<fp->nb_antennas_tx; i++)
-      txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti]; 
-    
-    txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
-				       proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
-				       txp,
-				       fp->samples_per_tti,
-				       fp->nb_antennas_tx,
-				       1);
-    
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
-    
-    
-    
-    if (txs !=  fp->samples_per_tti) {
-      LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
-      exit_fun( "problem transmitting samples" );
-    }	
+    if ((subframe_select(fp,proc->subframe_rx+tx_sfoffset) == SF_DL) ||
+	(subframe_select(fp,proc->subframe_rx+tx_sfoffset) == SF_S)) {
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
+
+      for (i=0; i<fp->nb_antennas_tx; i++)
+	txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti]; 
+      
+      txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
+					 proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
+					 txp,
+					 fp->samples_per_tti,
+					 fp->nb_antennas_tx,
+					 1);
+      
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
+      
+      
+      
+      if (txs !=  fp->samples_per_tti) {
+	LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
+	exit_fun( "problem transmitting samples" );
+      }	
+    }
   }
-  
+
   for (i=0; i<fp->nb_antennas_rx; i++)
     rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti];
   
-- 
GitLab