/*
* Copyright 2008 Free Software Foundation, Inc.
*
* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

*/



#include "sigProcLib.h"  
#include "GSMCommon.h"
#include "LinkedLists.h"
#include "radioDevice.h"

/** samples per GSM symbol */
#define SAMPSPERSYM 1 
#define INCHUNK    (625)
#define OUTCHUNK   (625)

/** class used to organize GSM bursts by GSM timestamps */
class radioVector : public signalVector {

private:

  GSM::Time mTime;   ///< the burst's GSM timestamp 

public:
  /** constructor */
  radioVector(const signalVector& wVector,
              GSM::Time& wTime): signalVector(wVector),mTime(wTime) {};

  /** timestamp read and write operators */
  GSM::Time time() const { return mTime;}
  void time(const GSM::Time& wTime) { mTime = wTime;}

  /** comparison operator, used for sorting */
  bool operator>(const radioVector& other) const {return mTime > other.mTime;}

};

/** a priority queue of radioVectors, i.e. GSM bursts, sorted so that earliest element is at top */
class VectorQueue : public InterthreadPriorityQueue<radioVector> {

public:

  /** the top element of the queue */
  GSM::Time nextTime() const;

  /**
    Get stale burst, if any.
    @param targTime The target time.
    @return Pointer to burst older than target time, removed from queue, or NULL.
  */
  radioVector* getStaleBurst(const GSM::Time& targTime);

  /**
    Get current burst, if any.
    @param targTime The target time.
    @return Pointer to burst at the target time, removed from queue, or NULL.
  */
  radioVector* getCurrentBurst(const GSM::Time& targTime);


};

/** a FIFO of radioVectors */
class VectorFIFO {

private:

      PointerFIFO mQ;
      Mutex      mLock;

public:

      unsigned size() {return mQ.size();}

      void put(radioVector *ptr) {ScopedLock lock(mLock); mQ.put((void*) ptr);}

      radioVector *get() { ScopedLock lock(mLock); return (radioVector*) mQ.get();}

};


/** the basestation clock class */
class RadioClock {

private:

  GSM::Time mClock;
  Mutex mLock;
  Signal updateSignal;

public:

  /** Set clock */
  //void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.signal();}
  void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.broadcast();;}

  /** Increment clock */
  //void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.signal();}
  void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.broadcast();}

  /** Get clock value */
  GSM::Time get() { ScopedLock lock(mLock); return mClock; }

  /** Wait until clock has changed */
  //void wait() {ScopedLock lock(mLock); updateSignal.wait(mLock,1);}
  // FIXME -- If we take away the timeout, a lot of threads don't start.  Why?
  void wait() {ScopedLock lock(mLock); updateSignal.wait(mLock);}

};


/** class to interface the transceiver with the USRP */
class RadioInterface {

private:

  Thread mAlignRadioServiceLoopThread;	      ///< thread that synchronizes transmit and receive sections

  VectorFIFO  mReceiveFIFO;		      ///< FIFO that holds receive  bursts

  RadioDevice *mRadio;			      ///< the USRP object
 
  short *sendBuffer; //[2*2*INCHUNK];
  unsigned sendCursor;

  short *rcvBuffer; //[2*2*OUTCHUNK];
  unsigned rcvCursor;
 
  bool underrun;			      ///< indicates writes to USRP are too slow
  bool overrun;				      ///< indicates reads from USRP are too slow
  TIMESTAMP writeTimestamp;		      ///< sample timestamp of next packet written to USRP
  TIMESTAMP readTimestamp;		      ///< sample timestamp of next packet read from USRP

  RadioClock mClock;                          ///< the basestation clock!

  int samplesPerSymbol;			      ///< samples per GSM symbol
  int receiveOffset;                          ///< offset b/w transmit and receive GSM timestamps, in timeslots
  int mRadioOversampling;
  int mTransceiverOversampling;

  bool mOn;				      ///< indicates radio is on

  double powerScaling;

  bool loadTest;
  int mNumARFCNs;
  signalVector *finalVec, *finalVec9;

  /** format samples to USRP */ 
  short *radioifyVector(signalVector &wVector,
                        short *shortVector,
                        float scale,
                        bool zeroOut);

  /** format samples from USRP */
  void unRadioifyVector(short *shortVector, signalVector &wVector);

  /** push GSM bursts into the transmit buffer */
  void pushBuffer(void);

  /** pull GSM bursts from the receive buffer */
  void pullBuffer(void);

public:

  /** start the interface */
  void start();

  /** constructor */
  RadioInterface(RadioDevice* wRadio = NULL,
		 int receiveOffset = 3,
		 int wRadioOversampling = SAMPSPERSYM,
		 int wTransceiverOversampling = SAMPSPERSYM,
		 GSM::Time wStartTime = GSM::Time(0));
    
  /** destructor */
  ~RadioInterface();

  void setSamplesPerSymbol(int wSamplesPerSymbol) {if (!mOn) samplesPerSymbol = wSamplesPerSymbol;}

  int getSamplesPerSymbol() { return samplesPerSymbol;}

  /** check for underrun, resets underrun value */
  bool isUnderrun() { bool retVal = underrun; underrun = false; return retVal;}
  
  /** attach an existing USRP to this interface */
  void attach(RadioDevice *wRadio, int wRadioOversampling) {if (!mOn) {mRadio = wRadio; mRadioOversampling = SAMPSPERSYM;} }

  /** return the receive FIFO */
  VectorFIFO* receiveFIFO() { return &mReceiveFIFO;}

  /** return the basestation clock */
  RadioClock* getClock(void) { return &mClock;};

 /** set receive gain */
  double setRxGain(double dB) {if (mRadio) return mRadio->setRxGain(dB); else return -1;}

  /** get receive gain */
  double getRxGain(void) {if (mRadio) return mRadio->getRxGain(); else return -1;}


  /** set transmit frequency */
  bool tuneTx(double freq);

  /** set receive frequency */
  bool tuneRx(double freq);

  /** drive transmission of GSM bursts */
  void driveTransmitRadio(signalVector &radioBurst, bool zeroBurst);

  /** drive reception of GSM bursts */
  void driveReceiveRadio();

  void setPowerAttenuation(double atten);

  /** returns the full-scale transmit amplitude **/
  double fullScaleInputValue();

  /** returns the full-scale receive amplitude **/
  double fullScaleOutputValue();

  /** set thread priority on current thread */
  void setPriority() { mRadio->setPriority(); }

protected:

  /** drive synchronization of Tx/Rx of USRP */
  void alignRadio();

  /** reset the interface */
  void reset();

  friend void *AlignRadioServiceLoopAdapter(RadioInterface*);

};

/** synchronization thread loop */
void *AlignRadioServiceLoopAdapter(RadioInterface*);
