Transceiver: Add support for OsmoBTS style handover.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 63102a1..526153e 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -156,6 +156,11 @@
 {
   txFullScale = mRadioInterface->fullScaleInputValue();
   rxFullScale = mRadioInterface->fullScaleOutputValue();
+
+  for (int i = 0; i < 8; i++) {
+    for (int j = 0; j < 8; j++)
+      mHandover[i][j] = false;
+  }
 }
 
 Transceiver::~Transceiver()
@@ -463,9 +468,15 @@
 Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
                                                     size_t chan)
 {
+  static int tchh_subslot[26] = { 0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,1 };
+  static int sdcch4_subslot[102] = { 3,3,3,3,0,0,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2,
+                                     3,3,3,3,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2 };
+  static int sdcch8_subslot[102] = { 5,5,5,5,6,6,6,6,7,7,7,7,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,0,0,0,0,
+                                     1,1,1,1,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,4,4,4,4 };
   TransceiverState *state = &mStates[chan];
   unsigned burstTN = currTime.TN();
   unsigned burstFN = currTime.FN();
+  int subch;
 
   switch (state->chanType[burstTN]) {
   case NONE:
@@ -475,16 +486,25 @@
     return IDLE;
     break;
   case I:
+    // TODO: Are we expecting RACH on an IDLE frame?
+/*    if (burstFN % 26 == 25)
+      return IDLE;*/
+    if (mHandover[burstTN][0])
+      return RACH;
     return TSC;
-    /*if (burstFN % 26 == 25) 
-      return IDLE;
-    else
-      return TSC;*/
     break;
   case II:
+    subch = tchh_subslot[burstFN % 26];
+    if (subch == 1)
+      return IDLE;
+    if (mHandover[burstTN][0])
+      return RACH;
     return TSC;
     break;
   case III:
+    subch = tchh_subslot[burstFN % 26];
+    if (mHandover[burstTN][subch])
+      return RACH;
     return TSC;
     break;
   case IV:
@@ -499,6 +519,8 @@
       return RACH;
     else if ((mod51 == 45) || (mod51 == 46))
       return RACH;
+    else if (mHandover[burstTN][sdcch4_subslot[burstFN % 102]])
+      return RACH;
     else
       return TSC;
     break;
@@ -506,6 +528,8 @@
   case VII:
     if ((burstFN % 51 <= 14) && (burstFN % 51 >= 12))
       return IDLE;
+    else if (mHandover[burstTN][sdcch8_subslot[burstFN % 102]])
+      return RACH;
     else
       return TSC;
     break;
@@ -782,6 +806,24 @@
       sprintf(response,"RSP POWERON 1");
     else
       sprintf(response,"RSP POWERON 0");
+      for (int i = 0; i < 8; i++) {
+        for (int j = 0; j < 8; j++)
+          mHandover[i][j] = false;
+      }
+  }
+  else if (strcmp(command,"HANDOVER")==0){
+    int ts=0,ss=0;
+    sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&ts,&ss);
+    mHandover[ts][ss] = true;
+    LOG(WARNING) << "HANDOVER RACH at timeslot " << ts << " subslot " << ss;
+    sprintf(response,"RSP HANDOVER 0 %d %d",ts,ss);
+  }
+  else if (strcmp(command,"NOHANDOVER")==0){
+    int ts=0,ss=0;
+    sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&ts,&ss);
+    mHandover[ts][ss] = false;
+    LOG(WARNING) << "NOHANDOVER at timeslot " << ts << " subslot " << ss;
+    sprintf(response,"RSP NOHANDOVER 0 %d %d",ts,ss);
   }
   else if (strcmp(command,"SETMAXDLY")==0) {
     //set expected maximum time-of-arrival