2011-10-12 07:44:40 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2008 Free Software Foundation, Inc.
|
|
|
|
*
|
2019-10-13 17:08:00 +00:00
|
|
|
* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribution.
|
2011-10-12 07:44:40 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-09-03 14:42:04 +00:00
|
|
|
#include "sigProcLib.h"
|
2011-10-12 07:44:40 +00:00
|
|
|
#include "GSMCommon.h"
|
|
|
|
#include "LinkedLists.h"
|
|
|
|
#include "radioDevice.h"
|
2011-11-26 03:18:30 +00:00
|
|
|
#include "radioVector.h"
|
|
|
|
#include "radioClock.h"
|
2015-08-22 02:32:58 +00:00
|
|
|
#include "radioBuffer.h"
|
2013-11-14 04:38:09 +00:00
|
|
|
#include "Resampler.h"
|
2016-06-24 21:25:39 +00:00
|
|
|
#include "Channelizer.h"
|
|
|
|
#include "Synthesis.h"
|
2011-10-12 07:44:40 +00:00
|
|
|
|
2013-06-16 10:30:58 +00:00
|
|
|
static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
|
|
|
|
|
2011-10-12 07:44:40 +00:00
|
|
|
/** class to interface the transceiver with the USRP */
|
|
|
|
class RadioInterface {
|
|
|
|
|
2013-04-08 18:18:26 +00:00
|
|
|
protected:
|
2022-07-19 19:18:21 +00:00
|
|
|
size_t mSPSTx;
|
|
|
|
size_t mSPSRx;
|
|
|
|
size_t mChans;
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
|
|
|
|
|
2013-10-29 22:34:16 +00:00
|
|
|
std::vector<VectorFIFO> mReceiveFIFO; ///< FIFO that holds receive bursts
|
2011-10-12 07:44:40 +00:00
|
|
|
|
2019-09-13 13:59:29 +00:00
|
|
|
RadioDevice *mDevice; ///< the USRP object
|
2013-10-11 17:49:55 +00:00
|
|
|
|
2015-08-22 02:32:58 +00:00
|
|
|
std::vector<RadioBuffer *> sendBuffer;
|
|
|
|
std::vector<RadioBuffer *> recvBuffer;
|
2013-08-21 00:54:54 +00:00
|
|
|
|
2013-10-29 22:34:16 +00:00
|
|
|
std::vector<short *> convertRecvBuffer;
|
|
|
|
std::vector<short *> convertSendBuffer;
|
2013-11-15 19:15:47 +00:00
|
|
|
std::vector<float> powerScaling;
|
2019-09-13 16:56:08 +00:00
|
|
|
int underrun; ///< indicates writes to USRP are too slow
|
2011-10-12 07:44:40 +00:00
|
|
|
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 receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
|
|
|
|
|
|
|
|
bool mOn; ///< indicates radio is on
|
|
|
|
|
2013-04-08 18:18:26 +00:00
|
|
|
private:
|
|
|
|
|
2015-08-22 02:32:58 +00:00
|
|
|
/** format samples to USRP */
|
|
|
|
int radioifyVector(signalVector &wVector, size_t chan, bool zero);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** format samples from USRP */
|
2015-08-22 02:32:58 +00:00
|
|
|
int unRadioifyVector(signalVector *wVector, size_t chan);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** push GSM bursts into the transmit buffer */
|
2015-08-22 02:32:58 +00:00
|
|
|
virtual bool pushBuffer(void);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** pull GSM bursts from the receive buffer */
|
2018-09-03 14:45:15 +00:00
|
|
|
virtual int pullBuffer(void);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/** start the interface */
|
2023-07-25 16:44:03 +00:00
|
|
|
virtual bool start();
|
2014-11-26 00:06:32 +00:00
|
|
|
bool stop();
|
2011-10-12 07:44:40 +00:00
|
|
|
|
2019-10-13 17:08:00 +00:00
|
|
|
/** initialization */
|
2013-10-15 03:56:51 +00:00
|
|
|
virtual bool init(int type);
|
2013-08-21 00:54:54 +00:00
|
|
|
virtual void close();
|
|
|
|
|
2011-10-12 07:44:40 +00:00
|
|
|
/** constructor */
|
2019-09-13 13:59:29 +00:00
|
|
|
RadioInterface(RadioDevice* wDevice, size_t tx_sps, size_t rx_sps,
|
2017-03-31 00:22:58 +00:00
|
|
|
size_t chans = 1, int receiveOffset = 3,
|
|
|
|
GSM::Time wStartTime = GSM::Time(0));
|
2013-10-29 22:34:16 +00:00
|
|
|
|
2011-10-12 07:44:40 +00:00
|
|
|
/** destructor */
|
2013-08-21 00:54:54 +00:00
|
|
|
virtual ~RadioInterface();
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** check for underrun, resets underrun value */
|
2011-11-26 03:18:46 +00:00
|
|
|
bool isUnderrun();
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** return the receive FIFO */
|
2013-10-29 22:34:16 +00:00
|
|
|
VectorFIFO* receiveFIFO(size_t chan = 0);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** return the basestation clock */
|
|
|
|
RadioClock* getClock(void) { return &mClock;};
|
|
|
|
|
|
|
|
/** set transmit frequency */
|
2016-06-24 21:25:39 +00:00
|
|
|
virtual bool tuneTx(double freq, size_t chan = 0);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** set receive frequency */
|
2013-11-14 04:38:09 +00:00
|
|
|
virtual bool tuneRx(double freq, size_t chan = 0);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
2011-11-26 03:18:46 +00:00
|
|
|
/** set receive gain */
|
2019-09-16 15:20:46 +00:00
|
|
|
virtual double setRxGain(double dB, size_t chan = 0);
|
2011-11-26 03:18:46 +00:00
|
|
|
|
2020-10-13 15:03:37 +00:00
|
|
|
/** return base RSSI offset to apply for received samples **/
|
|
|
|
virtual double rssiOffset(size_t chan = 0);
|
|
|
|
|
2011-10-12 07:44:40 +00:00
|
|
|
/** drive transmission of GSM bursts */
|
2013-10-29 22:34:16 +00:00
|
|
|
void driveTransmitRadio(std::vector<signalVector *> &bursts,
|
|
|
|
std::vector<bool> &zeros);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
2018-09-03 14:45:15 +00:00
|
|
|
/** drive reception of GSM bursts. -1: Error. 0: Radio off. 1: Received something. */
|
|
|
|
int driveReceiveRadio();
|
2011-10-12 07:44:40 +00:00
|
|
|
|
2020-06-08 11:44:24 +00:00
|
|
|
/** set transmit power attenuation */
|
|
|
|
virtual int setPowerAttenuation(int atten, size_t chan = 0);
|
2020-05-29 14:39:07 +00:00
|
|
|
int getNominalTxPower(size_t chan = 0);
|
2011-10-12 07:44:40 +00:00
|
|
|
|
|
|
|
/** returns the full-scale transmit amplitude **/
|
|
|
|
double fullScaleInputValue();
|
|
|
|
|
|
|
|
/** returns the full-scale receive amplitude **/
|
|
|
|
double fullScaleOutputValue();
|
|
|
|
|
2018-09-03 14:42:04 +00:00
|
|
|
/** get transport window type of attached device */
|
2019-09-13 13:59:29 +00:00
|
|
|
enum RadioDevice::TxWindowType getWindowType() { return mDevice->getWindowType(); }
|
2011-11-26 03:18:55 +00:00
|
|
|
|
2018-04-24 16:43:51 +00:00
|
|
|
/** Minimum latency that the device can achieve */
|
2019-09-13 13:59:29 +00:00
|
|
|
GSM::Time minLatency() { return mDevice->minLatency(); }
|
2018-04-24 16:43:51 +00:00
|
|
|
|
2011-10-12 07:44:40 +00:00
|
|
|
protected:
|
|
|
|
/** drive synchronization of Tx/Rx of USRP */
|
|
|
|
void alignRadio();
|
|
|
|
|
|
|
|
friend void *AlignRadioServiceLoopAdapter(RadioInterface*);
|
|
|
|
};
|
|
|
|
|
2013-04-08 18:18:26 +00:00
|
|
|
class RadioInterfaceResamp : public RadioInterface {
|
|
|
|
private:
|
2013-08-21 00:54:54 +00:00
|
|
|
signalVector *outerSendBuffer;
|
|
|
|
signalVector *outerRecvBuffer;
|
2013-04-08 18:18:26 +00:00
|
|
|
|
2015-08-22 02:32:58 +00:00
|
|
|
bool pushBuffer();
|
2018-09-03 14:45:15 +00:00
|
|
|
int pullBuffer();
|
2013-04-08 18:18:26 +00:00
|
|
|
|
|
|
|
public:
|
2019-09-13 13:59:29 +00:00
|
|
|
RadioInterfaceResamp(RadioDevice* wDevice, size_t tx_sps, size_t rx_sps);
|
2023-07-25 16:44:03 +00:00
|
|
|
virtual ~RadioInterfaceResamp();
|
2013-08-21 00:54:54 +00:00
|
|
|
|
2013-10-15 03:56:51 +00:00
|
|
|
bool init(int type);
|
2013-08-21 00:54:54 +00:00
|
|
|
void close();
|
2013-04-08 18:18:26 +00:00
|
|
|
};
|
2013-11-14 04:38:09 +00:00
|
|
|
|
radioInterfaceMulti: Fail to tune on freq not following multi-arfcn restrictions
multi-arfcn feature uses a hardcoded disposition of logical channels on
a physical channel. Logical channels in the phisical channel are
separated by MCBTS_SPACING Hz, that is 4 GSM ARFCNs.
As a result, multi-arfcn restricts the TRX ARFCN setup to the following:
ARFCN(TRX0)=N, ARFCN(TRX1)=N+1*4, ARFCN(TRX2)=N+2*4, ...
Let's make sure radioInterfaceMulti verifies the requested Rx/Tx
frequencies for each logical channel over TRXC match the restriction
explained above. It will check freq going to be set is indeed separated
by MCBTS_SPACING from already set channels, making sure the ARFCN series
is consistent.
Otherwise, before this patch, one could set in osmo-bsc:
ARFCN(TRX0)=N, ARFCN(TRX1)=N+2
and osmo-trx would silently ack the related Rx/TxTUNE TRXC commands, but
actually still transmit on ARFCN N+4 instead. As a result, in this
scenario TRX!=0 were unusable with multi-arfcn.
Related: OS#4207
Change-Id: I2f3d66a611d3a489b3e4d9431994f4ec77b4460f
2019-12-20 23:40:09 +00:00
|
|
|
struct freq_cfg_state {
|
|
|
|
bool set;
|
|
|
|
double freq_hz;
|
|
|
|
};
|
|
|
|
|
2016-06-24 21:25:39 +00:00
|
|
|
class RadioInterfaceMulti : public RadioInterface {
|
|
|
|
private:
|
|
|
|
bool pushBuffer();
|
2018-09-03 14:45:15 +00:00
|
|
|
int pullBuffer();
|
radioInterfaceMulti: Fail to tune on freq not following multi-arfcn restrictions
multi-arfcn feature uses a hardcoded disposition of logical channels on
a physical channel. Logical channels in the phisical channel are
separated by MCBTS_SPACING Hz, that is 4 GSM ARFCNs.
As a result, multi-arfcn restricts the TRX ARFCN setup to the following:
ARFCN(TRX0)=N, ARFCN(TRX1)=N+1*4, ARFCN(TRX2)=N+2*4, ...
Let's make sure radioInterfaceMulti verifies the requested Rx/Tx
frequencies for each logical channel over TRXC match the restriction
explained above. It will check freq going to be set is indeed separated
by MCBTS_SPACING from already set channels, making sure the ARFCN series
is consistent.
Otherwise, before this patch, one could set in osmo-bsc:
ARFCN(TRX0)=N, ARFCN(TRX1)=N+2
and osmo-trx would silently ack the related Rx/TxTUNE TRXC commands, but
actually still transmit on ARFCN N+4 instead. As a result, in this
scenario TRX!=0 were unusable with multi-arfcn.
Related: OS#4207
Change-Id: I2f3d66a611d3a489b3e4d9431994f4ec77b4460f
2019-12-20 23:40:09 +00:00
|
|
|
bool verify_arfcn_consistency(double freq, size_t chan, bool tx);
|
2020-06-08 11:44:24 +00:00
|
|
|
virtual int setPowerAttenuation(int atten, size_t chan = 0);
|
2016-06-24 21:25:39 +00:00
|
|
|
|
|
|
|
signalVector *outerSendBuffer;
|
|
|
|
signalVector *outerRecvBuffer;
|
|
|
|
std::vector<signalVector *> history;
|
|
|
|
std::vector<bool> active;
|
radioInterfaceMulti: Fail to tune on freq not following multi-arfcn restrictions
multi-arfcn feature uses a hardcoded disposition of logical channels on
a physical channel. Logical channels in the phisical channel are
separated by MCBTS_SPACING Hz, that is 4 GSM ARFCNs.
As a result, multi-arfcn restricts the TRX ARFCN setup to the following:
ARFCN(TRX0)=N, ARFCN(TRX1)=N+1*4, ARFCN(TRX2)=N+2*4, ...
Let's make sure radioInterfaceMulti verifies the requested Rx/Tx
frequencies for each logical channel over TRXC match the restriction
explained above. It will check freq going to be set is indeed separated
by MCBTS_SPACING from already set channels, making sure the ARFCN series
is consistent.
Otherwise, before this patch, one could set in osmo-bsc:
ARFCN(TRX0)=N, ARFCN(TRX1)=N+2
and osmo-trx would silently ack the related Rx/TxTUNE TRXC commands, but
actually still transmit on ARFCN N+4 instead. As a result, in this
scenario TRX!=0 were unusable with multi-arfcn.
Related: OS#4207
Change-Id: I2f3d66a611d3a489b3e4d9431994f4ec77b4460f
2019-12-20 23:40:09 +00:00
|
|
|
std::vector<struct freq_cfg_state> rx_freq_state;
|
|
|
|
std::vector<struct freq_cfg_state> tx_freq_state;
|
2016-06-24 21:25:39 +00:00
|
|
|
|
|
|
|
Resampler *dnsampler;
|
|
|
|
Resampler *upsampler;
|
|
|
|
Channelizer *channelizer;
|
|
|
|
Synthesis *synthesis;
|
|
|
|
|
|
|
|
public:
|
|
|
|
RadioInterfaceMulti(RadioDevice* radio, size_t tx_sps,
|
|
|
|
size_t rx_sps, size_t chans = 1);
|
2023-07-25 16:44:03 +00:00
|
|
|
virtual ~RadioInterfaceMulti();
|
2016-06-24 21:25:39 +00:00
|
|
|
|
|
|
|
bool init(int type);
|
|
|
|
void close();
|
|
|
|
|
|
|
|
bool tuneTx(double freq, size_t chan);
|
|
|
|
bool tuneRx(double freq, size_t chan);
|
2019-09-16 15:20:46 +00:00
|
|
|
virtual double setRxGain(double dB, size_t chan);
|
2020-10-13 15:03:37 +00:00
|
|
|
virtual double rssiOffset(size_t chan = 0);
|
2016-06-24 21:25:39 +00:00
|
|
|
};
|