blob: b05af78771d0ab8d8614cba53537dd51a25d29af [file] [log] [blame]
dburgessb3a0ca42011-10-12 07:44:40 +00001/*
2* Copyright 2008 Free Software Foundation, Inc.
3*
Martin Hauke066fd042019-10-13 19:08:00 +02004* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribution.
dburgessb3a0ca42011-10-12 07:44:40 +00005*
6* This use of this software may be subject to additional restrictions.
7* See the LEGAL file in the main directory for details.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13*/
14
15
16
Pau Espin Pedrol46444632018-09-03 16:42:04 +020017#include "sigProcLib.h"
dburgessb3a0ca42011-10-12 07:44:40 +000018#include "GSMCommon.h"
19#include "LinkedLists.h"
20#include "radioDevice.h"
kurtis.heimerl8aea56e2011-11-26 03:18:30 +000021#include "radioVector.h"
22#include "radioClock.h"
Tom Tsou28670fb2015-08-21 19:32:58 -070023#include "radioBuffer.h"
Thomas Tsoue90a42b2013-11-13 23:38:09 -050024#include "Resampler.h"
Tom Tsou76764272016-06-24 14:25:39 -070025#include "Channelizer.h"
26#include "Synthesis.h"
dburgessb3a0ca42011-10-12 07:44:40 +000027
Alexander Chemerisd734e2d2013-06-16 14:30:58 +040028static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
29
dburgessb3a0ca42011-10-12 07:44:40 +000030/** class to interface the transceiver with the USRP */
31class RadioInterface {
32
Thomas Tsoucb69f082013-04-08 14:18:26 -040033protected:
Eric5561f112022-07-19 21:18:21 +020034 size_t mSPSTx;
35 size_t mSPSRx;
36 size_t mChans;
dburgessb3a0ca42011-10-12 07:44:40 +000037
38 Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
39
Thomas Tsou204a9f12013-10-29 18:34:16 -040040 std::vector<VectorFIFO> mReceiveFIFO; ///< FIFO that holds receive bursts
dburgessb3a0ca42011-10-12 07:44:40 +000041
Pau Espin Pedrola801ae52019-09-13 15:59:29 +020042 RadioDevice *mDevice; ///< the USRP object
Thomas Tsouc1f7c422013-10-11 13:49:55 -040043
Tom Tsou28670fb2015-08-21 19:32:58 -070044 std::vector<RadioBuffer *> sendBuffer;
45 std::vector<RadioBuffer *> recvBuffer;
dburgessb3a0ca42011-10-12 07:44:40 +000046
Thomas Tsou204a9f12013-10-29 18:34:16 -040047 std::vector<short *> convertRecvBuffer;
48 std::vector<short *> convertSendBuffer;
Thomas Tsoucb269a32013-11-15 14:15:47 -050049 std::vector<float> powerScaling;
Pau Espin Pedrole503c982019-09-13 18:56:08 +020050 int underrun; ///< indicates writes to USRP are too slow
dburgessb3a0ca42011-10-12 07:44:40 +000051 bool overrun; ///< indicates reads from USRP are too slow
52 TIMESTAMP writeTimestamp; ///< sample timestamp of next packet written to USRP
53 TIMESTAMP readTimestamp; ///< sample timestamp of next packet read from USRP
54
55 RadioClock mClock; ///< the basestation clock!
56
dburgessb3a0ca42011-10-12 07:44:40 +000057 int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
dburgessb3a0ca42011-10-12 07:44:40 +000058
59 bool mOn; ///< indicates radio is on
60
Thomas Tsoucb69f082013-04-08 14:18:26 -040061private:
62
Tom Tsou28670fb2015-08-21 19:32:58 -070063 /** format samples to USRP */
64 int radioifyVector(signalVector &wVector, size_t chan, bool zero);
dburgessb3a0ca42011-10-12 07:44:40 +000065
66 /** format samples from USRP */
Tom Tsou28670fb2015-08-21 19:32:58 -070067 int unRadioifyVector(signalVector *wVector, size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +000068
69 /** push GSM bursts into the transmit buffer */
Tom Tsou28670fb2015-08-21 19:32:58 -070070 virtual bool pushBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000071
72 /** pull GSM bursts from the receive buffer */
Pau Espin Pedrol8e498bf2018-09-03 16:45:15 +020073 virtual int pullBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000074
75public:
76
77 /** start the interface */
Ericcca5d932023-07-25 18:44:03 +020078 virtual bool start();
Tom Tsoueb54bdd2014-11-25 16:06:32 -080079 bool stop();
dburgessb3a0ca42011-10-12 07:44:40 +000080
Martin Hauke066fd042019-10-13 19:08:00 +020081 /** initialization */
Thomas Tsoufe269fe2013-10-14 23:56:51 -040082 virtual bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040083 virtual void close();
84
dburgessb3a0ca42011-10-12 07:44:40 +000085 /** constructor */
Pau Espin Pedrola801ae52019-09-13 15:59:29 +020086 RadioInterface(RadioDevice* wDevice, size_t tx_sps, size_t rx_sps,
Tom Tsoud6ae8642017-03-30 17:22:58 -070087 size_t chans = 1, int receiveOffset = 3,
88 GSM::Time wStartTime = GSM::Time(0));
Thomas Tsou204a9f12013-10-29 18:34:16 -040089
dburgessb3a0ca42011-10-12 07:44:40 +000090 /** destructor */
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040091 virtual ~RadioInterface();
dburgessb3a0ca42011-10-12 07:44:40 +000092
dburgessb3a0ca42011-10-12 07:44:40 +000093 /** check for underrun, resets underrun value */
kurtis.heimerle724d6d2011-11-26 03:18:46 +000094 bool isUnderrun();
dburgessb3a0ca42011-10-12 07:44:40 +000095
96 /** return the receive FIFO */
Thomas Tsou204a9f12013-10-29 18:34:16 -040097 VectorFIFO* receiveFIFO(size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +000098
99 /** return the basestation clock */
100 RadioClock* getClock(void) { return &mClock;};
101
dburgessb3a0ca42011-10-12 07:44:40 +0000102 /** set transmit frequency */
Tom Tsou76764272016-06-24 14:25:39 -0700103 virtual bool tuneTx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000104
105 /** set receive frequency */
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500106 virtual bool tuneRx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000107
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000108 /** set receive gain */
Pau Espin Pedrol80d053a2019-09-16 17:20:46 +0200109 virtual double setRxGain(double dB, size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000110
Pau Espin Pedrole91544d2020-10-13 17:03:37 +0200111 /** return base RSSI offset to apply for received samples **/
112 virtual double rssiOffset(size_t chan = 0);
113
dburgessb3a0ca42011-10-12 07:44:40 +0000114 /** drive transmission of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400115 void driveTransmitRadio(std::vector<signalVector *> &bursts,
116 std::vector<bool> &zeros);
dburgessb3a0ca42011-10-12 07:44:40 +0000117
Pau Espin Pedrol8e498bf2018-09-03 16:45:15 +0200118 /** drive reception of GSM bursts. -1: Error. 0: Radio off. 1: Received something. */
119 int driveReceiveRadio();
dburgessb3a0ca42011-10-12 07:44:40 +0000120
Pau Espin Pedrol992c9bd2020-06-08 13:44:24 +0200121 /** set transmit power attenuation */
122 virtual int setPowerAttenuation(int atten, size_t chan = 0);
Pau Espin Pedrol0e09e7c2020-05-29 16:39:07 +0200123 int getNominalTxPower(size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000124
125 /** returns the full-scale transmit amplitude **/
126 double fullScaleInputValue();
127
128 /** returns the full-scale receive amplitude **/
129 double fullScaleOutputValue();
130
Pau Espin Pedrol46444632018-09-03 16:42:04 +0200131 /** get transport window type of attached device */
Pau Espin Pedrola801ae52019-09-13 15:59:29 +0200132 enum RadioDevice::TxWindowType getWindowType() { return mDevice->getWindowType(); }
kurtis.heimerle380af32011-11-26 03:18:55 +0000133
Pau Espin Pedrole564f0f2018-04-24 18:43:51 +0200134 /** Minimum latency that the device can achieve */
Pau Espin Pedrola801ae52019-09-13 15:59:29 +0200135 GSM::Time minLatency() { return mDevice->minLatency(); }
Pau Espin Pedrole564f0f2018-04-24 18:43:51 +0200136
dburgessb3a0ca42011-10-12 07:44:40 +0000137protected:
dburgessb3a0ca42011-10-12 07:44:40 +0000138 /** drive synchronization of Tx/Rx of USRP */
139 void alignRadio();
140
dburgessb3a0ca42011-10-12 07:44:40 +0000141 friend void *AlignRadioServiceLoopAdapter(RadioInterface*);
dburgessb3a0ca42011-10-12 07:44:40 +0000142};
143
Thomas Tsoucb69f082013-04-08 14:18:26 -0400144class RadioInterfaceResamp : public RadioInterface {
Thomas Tsoucb69f082013-04-08 14:18:26 -0400145private:
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400146 signalVector *outerSendBuffer;
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400147 signalVector *outerRecvBuffer;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400148
Tom Tsou28670fb2015-08-21 19:32:58 -0700149 bool pushBuffer();
Pau Espin Pedrol8e498bf2018-09-03 16:45:15 +0200150 int pullBuffer();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400151
152public:
Pau Espin Pedrola801ae52019-09-13 15:59:29 +0200153 RadioInterfaceResamp(RadioDevice* wDevice, size_t tx_sps, size_t rx_sps);
Ericcca5d932023-07-25 18:44:03 +0200154 virtual ~RadioInterfaceResamp();
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400155
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400156 bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400157 void close();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400158};
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500159
Pau Espin Pedrolfd99c6c2019-12-21 00:40:09 +0100160struct freq_cfg_state {
161 bool set;
162 double freq_hz;
163};
164
Tom Tsou76764272016-06-24 14:25:39 -0700165class RadioInterfaceMulti : public RadioInterface {
166private:
167 bool pushBuffer();
Pau Espin Pedrol8e498bf2018-09-03 16:45:15 +0200168 int pullBuffer();
Pau Espin Pedrolfd99c6c2019-12-21 00:40:09 +0100169 bool verify_arfcn_consistency(double freq, size_t chan, bool tx);
Pau Espin Pedrol992c9bd2020-06-08 13:44:24 +0200170 virtual int setPowerAttenuation(int atten, size_t chan = 0);
Tom Tsou76764272016-06-24 14:25:39 -0700171
172 signalVector *outerSendBuffer;
173 signalVector *outerRecvBuffer;
174 std::vector<signalVector *> history;
175 std::vector<bool> active;
Pau Espin Pedrolfd99c6c2019-12-21 00:40:09 +0100176 std::vector<struct freq_cfg_state> rx_freq_state;
177 std::vector<struct freq_cfg_state> tx_freq_state;
Tom Tsou76764272016-06-24 14:25:39 -0700178
179 Resampler *dnsampler;
180 Resampler *upsampler;
181 Channelizer *channelizer;
182 Synthesis *synthesis;
183
184public:
185 RadioInterfaceMulti(RadioDevice* radio, size_t tx_sps,
186 size_t rx_sps, size_t chans = 1);
Ericcca5d932023-07-25 18:44:03 +0200187 virtual ~RadioInterfaceMulti();
Tom Tsou76764272016-06-24 14:25:39 -0700188
189 bool init(int type);
190 void close();
191
192 bool tuneTx(double freq, size_t chan);
193 bool tuneRx(double freq, size_t chan);
Pau Espin Pedrol80d053a2019-09-16 17:20:46 +0200194 virtual double setRxGain(double dB, size_t chan);
Pau Espin Pedrole91544d2020-10-13 17:03:37 +0200195 virtual double rssiOffset(size_t chan = 0);
Tom Tsou76764272016-06-24 14:25:39 -0700196};