Transceiver52M: Allow setting gain before POWERON

There is no reason gain settings should not be modifiable when the radio
is running or not.

Signed-off-by: Tom Tsou <tom@tsou.cc>
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 415505c..f8b34b3 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -43,7 +43,7 @@
 #define NOISE_CNT			20
 
 TransceiverState::TransceiverState()
-  : mRetrans(false), mNoiseLev(0.0), mNoises(NOISE_CNT)
+  : mRetrans(false), mNoiseLev(0.0), mNoises(NOISE_CNT), mPower(0.0)
 {
   for (int i = 0; i < 8; i++) {
     chanType[i] = Transceiver::NONE;
@@ -91,7 +91,7 @@
   : mBasePort(wBasePort), mAddr(TRXAddress),
     mTransmitLatency(wTransmitLatency), mClockSocket(NULL),
     mRadioInterface(wRadioInterface), mSPSTx(wSPS), mSPSRx(1), mChans(wChans),
-    mOn(false), mTxFreq(0.0), mRxFreq(0.0), mPower(-10), mMaxExpectedDelay(0)
+    mOn(false), mTxFreq(0.0), mRxFreq(0.0), mMaxExpectedDelay(0)
 {
   GSM::Time startTime(random() % gHyperframe,0);
 
@@ -585,7 +585,6 @@
       sprintf(response,"RSP POWERON 0");
       if (!chan && !mOn) {
         // Prepare for thread start
-        mPower = -20;
         mRadioInterface->start();
 
         // Start radio interface threads.
@@ -634,28 +633,19 @@
     }
   }
   else if (!strcmp(command, "SETPOWER")) {
-    // set output power in dB
-    int dbPwr;
-    sscanf(buffer, "%3s %s %d", cmdcheck, command, &dbPwr);
-    if (!mOn)
-      sprintf(response, "RSP SETPOWER 1 %d", dbPwr);
-    else {
-      mPower = dbPwr;
-      mRadioInterface->setPowerAttenuation(mPower, chan);
-      sprintf(response, "RSP SETPOWER 0 %d", dbPwr);
-    }
+    int power;
+    sscanf(buffer, "%3s %s %d", cmdcheck, command, &power);
+    power = mRadioInterface->setPowerAttenuation(power, chan);
+    mStates[chan].mPower = power;
+    sprintf(response, "RSP SETPOWER 0 %d", power);
   }
   else if (!strcmp(command,"ADJPOWER")) {
-    // adjust power in dB steps
-    int dbStep;
-    sscanf(buffer, "%3s %s %d", cmdcheck, command, &dbStep);
-    if (!mOn)
-      sprintf(response, "RSP ADJPOWER 1 %d", mPower);
-    else {
-      mPower += dbStep;
-      mRadioInterface->setPowerAttenuation(mPower, chan);
-      sprintf(response, "RSP ADJPOWER 0 %d", mPower);
-    }
+    int power, step;
+    sscanf(buffer, "%3s %s %d", cmdcheck, command, &step);
+    power = mStates[chan].mPower + step;
+    power = mRadioInterface->setPowerAttenuation(power, chan);
+    mStates[chan].mPower = power;
+    sprintf(response, "RSP ADJPOWER 0 %d", power);
   }
   else if (strcmp(command,"RXTUNE")==0) {
     // tune receiver
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index df029a6..56f9115 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -81,6 +81,9 @@
   /* Received noise energy levels */
   float mNoiseLev;
   noiseVector mNoises;
+
+  /* Shadowed downlink attenuation */
+  int mPower;
 };
 
 /** The Transceiver class, responsible for physical layer of basestation */
@@ -165,7 +168,6 @@
   bool mOn;			       ///< flag to indicate that transceiver is powered on
   double mTxFreq;                      ///< the transmit frequency
   double mRxFreq;                      ///< the receive frequency
-  int mPower;                          ///< the transmit power in dB
   unsigned mTSC;                       ///< the midamble sequence code
   unsigned mMaxExpectedDelay;            ///< maximum expected time-of-arrival offset in GSM symbols
 
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index 1329ef1..d67b486 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -106,23 +106,27 @@
   return mRadio->fullScaleOutputValue();
 }
 
-
-void RadioInterface::setPowerAttenuation(double atten, size_t chan)
+int RadioInterface::setPowerAttenuation(int atten, size_t chan)
 {
   double rfGain, digAtten;
 
   if (chan >= mChans) {
     LOG(ALERT) << "Invalid channel requested";
-    return;
+    return -1;
   }
 
-  rfGain = mRadio->setTxGain(mRadio->maxTxGain() - atten, chan);
-  digAtten = atten - mRadio->maxTxGain() + rfGain;
+  if (atten < 0.0)
+    atten = 0.0;
+
+  rfGain = mRadio->setTxGain(mRadio->maxTxGain() - (double) atten, chan);
+  digAtten = (double) atten - mRadio->maxTxGain() + rfGain;
 
   if (digAtten < 1.0)
     powerScaling[chan] = 1.0;
   else
     powerScaling[chan] = 1.0 / sqrt(pow(10, digAtten / 10.0));
+
+  return atten;
 }
 
 int RadioInterface::radioifyVector(signalVector &wVector,
diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h
index b88fe6b..877102f 100644
--- a/Transceiver52M/radioInterface.h
+++ b/Transceiver52M/radioInterface.h
@@ -120,7 +120,7 @@
   /** drive reception of GSM bursts */
   bool driveReceiveRadio();
 
-  void setPowerAttenuation(double atten, size_t chan = 0);
+  int setPowerAttenuation(int atten, size_t chan = 0);
 
   /** returns the full-scale transmit amplitude **/
   double fullScaleInputValue();