transceiver: Add an option to emulate a RACH delay in random filler mode.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index c7f484b..cb191d5 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -71,7 +71,7 @@
   }
 }
 
-bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc)
+bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc, unsigned rach_delay)
 {
   signalVector *burst;
 
@@ -91,7 +91,7 @@
         burst = generateEdgeBurst(rtsc);
         break;
       case Transceiver::FILLER_ACCESS_RAND:
-        burst = genRandAccessBurst(sps, n);
+        burst = genRandAccessBurst(rach_delay, sps, n);
         break;
       case Transceiver::FILLER_ZERO:
       default:
@@ -160,7 +160,7 @@
  * are still expected to report clock indications through control channel
  * activity.
  */
-bool Transceiver::init(int filler, size_t rtsc)
+bool Transceiver::init(int filler, size_t rtsc, unsigned rach_delay)
 {
   int d_srcport, d_dstport, c_srcport, c_dstport;
 
@@ -216,7 +216,7 @@
     if (i && filler == FILLER_DUMMY)
       filler = FILLER_ZERO;
 
-    mStates[i].init(filler, mSPSTx, txFullScale, rtsc);
+    mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);
   }
 
   return true;
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 99db34d..f6f4526 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -54,7 +54,7 @@
   ~TransceiverState();
 
   /* Initialize a multiframe slot in the filler table */
-  bool init(int filler, size_t sps, float scale, size_t rtsc);
+  bool init(int filler, size_t sps, float scale, size_t rtsc, unsigned rach_delay);
 
   int chanType[8];
 
@@ -107,7 +107,7 @@
   ~Transceiver();
 
   /** Start the control loop */
-  bool init(int filler, size_t rtsc);
+  bool init(int filler, size_t rtsc, unsigned rach_delay);
 
   /** attach the radioInterface receive FIFO */
   bool receiveFIFO(VectorFIFO *wFIFO, size_t chan)
diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp
index d56b5c6..f4b585e 100644
--- a/Transceiver52M/osmo-trx.cpp
+++ b/Transceiver52M/osmo-trx.cpp
@@ -70,6 +70,7 @@
 	unsigned rx_sps;
 	unsigned chans;
 	unsigned rtsc;
+	unsigned rach_delay;
 	bool extref;
 	Transceiver::FillerType filler;
 	bool diversity;
@@ -265,7 +266,7 @@
 	trx = new Transceiver(config->port, config->addr.c_str(),
 			      config->tx_sps, config->rx_sps, config->chans,
 			      GSM::Time(3,0), radio, config->rssi_offset);
-	if (!trx->init(config->filler, config->rtsc)) {
+	if (!trx->init(config->filler, config->rtsc, config->rach_delay)) {
 		LOG(ALERT) << "Failed to initialize transceiver";
 		delete trx;
 		return NULL;
@@ -317,8 +318,8 @@
 		"  -c    Number of ARFCN channels (default=1)\n"
 		"  -f    Enable C0 filler table\n"
 		"  -o    Set baseband frequency offset (default=auto)\n"
-		"  -r    Random burst test mode with TSC\n"
-		"  -A    Random burst test mode with Access Bursts\n"
+		"  -r    Random Normal Burst test mode with TSC\n"
+		"  -A    Random Access Burst test mode with delay\n"
 		"  -R    RSSI to dBm offset in dB (default=0)\n"
 		"  -S    Swap channels (UmTRX only)\n",
 		"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
@@ -333,6 +334,7 @@
 	config->rx_sps = DEFAULT_RX_SPS;
 	config->chans = DEFAULT_CHANS;
 	config->rtsc = 0;
+	config->rach_delay = 0;
 	config->extref = false;
 	config->filler = Transceiver::FILLER_ZERO;
 	config->diversity = false;
@@ -341,7 +343,7 @@
 	config->swap_channels = false;
 	config->edge = false;
 
-	while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:AR:Se")) != -1) {
+	while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:A:R:Se")) != -1) {
 		switch (option) {
 		case 'h':
 			print_help();
@@ -382,6 +384,7 @@
 			config->filler = Transceiver::FILLER_NORM_RAND;
 			break;
 		case 'A':
+			config->rach_delay = atoi(optarg);
 			config->filler = Transceiver::FILLER_ACCESS_RAND;
 			break;
 		case 'R':
@@ -420,6 +423,12 @@
 		print_help();
 		exit(0);
 	}
+
+	if (config->rach_delay > 68) {
+		printf("RACH delay is too big %i\n\n", config->rach_delay);
+		print_help();
+		exit(0);
+	}
 }
 
 int main(int argc, char *argv[])
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index 434bbaf..477449f 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -1017,30 +1017,36 @@
 /*
  * Generate a random GSM access burst.
  */
-signalVector *genRandAccessBurst(int sps, int tn)
+signalVector *genRandAccessBurst(int delay, int sps, int tn)
 {
   if ((tn < 0) || (tn > 7))
     return NULL;
   if ((sps != 1) && (sps != 4))
     return NULL;
+  if (delay > 68)
+    return NULL;
 
   int i = 0;
-  BitVector *bits = new BitVector(88);
+  BitVector *bits = new BitVector(88+delay);
   signalVector *burst;
 
+  /* delay */
+  for (; i < delay; i++)
+    (*bits)[i] = 0;
+
   /* head and synch bits */
-  for (int n = 0; i < 49; i++, n++)
+  for (int n = 0; i < 49+delay; i++, n++)
     (*bits)[i] = gRACHBurst[n];
 
   /* Random bits */
-  for (; i < 85; i++)
+  for (; i < 85+delay; i++)
     (*bits)[i] = rand() % 2;
 
   /* Tail bits */
-  for (; i < 88; i++)
+  for (; i < 88+delay; i++)
     (*bits)[i] = 0;
 
-  int guard = 68 + !(tn % 4);
+  int guard = 68-delay + !(tn % 4);
   burst = modulateBurst(*bits, guard, sps);
   delete bits;
 
diff --git a/Transceiver52M/sigProcLib.h b/Transceiver52M/sigProcLib.h
index 7af58e7..b4aee93 100644
--- a/Transceiver52M/sigProcLib.h
+++ b/Transceiver52M/sigProcLib.h
@@ -123,7 +123,7 @@
 signalVector *genRandNormalBurst(int tsc, int sps, int tn);
 
 /** Generate an access GSM burst with random payload - 4 or 1 SPS */
-signalVector *genRandAccessBurst(int sps, int tn);
+signalVector *genRandAccessBurst(int delay, int sps, int tn);
 
 /** Generate a dummy GSM burst - 4 or 1 SPS */
 signalVector *generateDummyBurst(int sps, int tn);