/*
* Copyright 2008, 2009 Free Software Foundation, Inc.
*
* This software is distributed under the terms of the GNU Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    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.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


/*
	Compilation Flags

	SWLOOPBACK	compile for software loopback testing
*/ 


#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "Threads.h"
#include "DummyLoad.h"

#include <Logger.h>


using namespace std;



int DummyLoad::loadBurst(short *wDummyBurst, int len) {
  dummyBurst = wDummyBurst;
  dummyBurstSz = len;
}


DummyLoad::DummyLoad (double _desiredSampleRate) 
{
  LOG(INFO) << "creating USRP device...";
  sampleRate = _desiredSampleRate;
}

void DummyLoad::updateTime(void) {
    gettimeofday(&currTime,NULL);
    double timeElapsed = (currTime.tv_sec - startTime.tv_sec)*1.0e6 + 
      (currTime.tv_usec - startTime.tv_usec);
    currstamp = (TIMESTAMP) floor(timeElapsed/(1.0e6/sampleRate));
}

bool DummyLoad::make(bool wSkipRx) 
{

  samplesRead = 0;
  samplesWritten = 0;
  return true;
}

bool DummyLoad::start() 
{
  LOG(INFO) << "starting USRP...";
  underrun = false;
  gettimeofday(&startTime,NULL);
  dummyBurstCursor = 0;
  return true;
}

bool DummyLoad::stop() 
{
  return true;
}


// NOTE: Assumes sequential reads
int DummyLoad::readSamples(short *buf, int len, bool *overrun, 
			    TIMESTAMP timestamp,
			    bool *wUnderrun,
			    unsigned *RSSI) 
{
  updateTime();
  underrunLock.lock();
  *wUnderrun = underrun;
  underrunLock.unlock();
  if (currstamp+len < timestamp) {
	usleep(100); 
	return NULL;
  } 
  else if (currstamp < timestamp) {
	usleep(100);
	return NULL;
  }
  else if (timestamp+len < currstamp) {
	memcpy(buf,dummyBurst+dummyBurstCursor*2,sizeof(short)*2*(dummyBurstSz-dummyBurstCursor));
	int retVal = dummyBurstSz-dummyBurstCursor;
	dummyBurstCursor = 0;
	return retVal;
  }
  else if (timestamp + len > currstamp) {
	int amount = timestamp + len - currstamp;
	if (amount < dummyBurstSz-dummyBurstCursor) {
	        memcpy(buf,dummyBurst+dummyBurstCursor*2,sizeof(short)*2*amount);
        	dummyBurstCursor += amount;
        	return amount;
	}
	else {
        	memcpy(buf,dummyBurst+dummyBurstCursor*2,sizeof(short)*2*(dummyBurstSz-dummyBurstCursor));
        	int retVal = dummyBurstSz-dummyBurstCursor;
        	dummyBurstCursor = 0;
        	return retVal;
        }
  }
  return 0;
}

int DummyLoad::writeSamples(short *buf, int len, bool *wUnderrun, 
			     unsigned long long timestamp,
			     bool isControl) 
{
  updateTime();
  underrunLock.lock();
  underrun |= (currstamp+len < timestamp); 
  underrunLock.unlock();
  return len;
}

bool DummyLoad::updateAlignment(TIMESTAMP timestamp) 
{
  return true;
}

bool DummyLoad::setTxFreq(double wFreq) { return true;};
bool DummyLoad::setRxFreq(double wFreq) { return true;};
