blob: edebae25919baa9c864e4464607d0dc91cba77e7 [file] [log] [blame]
dburgessb3a0ca42011-10-12 07:44:40 +00001/*
2* Copyright 2008, 2009 Free Software Foundation, Inc.
3*
4* This software is distributed under the terms of the GNU Affero Public License.
5* See the COPYING file in the main directory for details.
6*
7* This use of this software may be subject to additional restrictions.
8* See the LEGAL file in the main directory for details.
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23*/
24
dburgessb3a0ca42011-10-12 07:44:40 +000025#include "radioInterface.h"
Thomas Tsouc1f7c422013-10-11 13:49:55 -040026#include "Resampler.h"
dburgessb3a0ca42011-10-12 07:44:40 +000027#include <Logger.h>
Alexander Chemerisf28d7222015-07-11 12:51:37 -040028#include <iomanip>
dburgessb3a0ca42011-10-12 07:44:40 +000029
Thomas Tsou9471d762013-08-20 21:24:24 -040030extern "C" {
31#include "convert.h"
32}
33
Thomas Tsou3952d802013-10-15 15:12:24 -040034#define CHUNK 625
35#define NUMCHUNKS 4
kurtis.heimerl9b557832011-11-26 03:18:34 +000036
dburgessb3a0ca42011-10-12 07:44:40 +000037RadioInterface::RadioInterface(RadioDevice *wRadio,
Thomas Tsoue90a42b2013-11-13 23:38:09 -050038 size_t sps, size_t chans, size_t diversity,
39 int wReceiveOffset, GSM::Time wStartTime)
40 : mRadio(wRadio), mSPSTx(sps), mSPSRx(1), mChans(chans), mMIMO(diversity),
Thomas Tsou204a9f12013-10-29 18:34:16 -040041 sendCursor(0), recvCursor(0), underrun(false), overrun(false),
Thomas Tsou477b77c2013-11-15 16:13:59 -050042 receiveOffset(wReceiveOffset), mOn(false)
dburgessb3a0ca42011-10-12 07:44:40 +000043{
dburgessb3a0ca42011-10-12 07:44:40 +000044 mClock.set(wStartTime);
dburgessb3a0ca42011-10-12 07:44:40 +000045}
46
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040047RadioInterface::~RadioInterface(void)
48{
49 close();
50}
kurtis.heimerl54354042011-11-26 03:18:49 +000051
Thomas Tsoufe269fe2013-10-14 23:56:51 -040052bool RadioInterface::init(int type)
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040053{
Thomas Tsoue90a42b2013-11-13 23:38:09 -050054 if ((type != RadioDevice::NORMAL) || (mMIMO > 1) || !mChans) {
55 LOG(ALERT) << "Invalid configuration";
Thomas Tsou204a9f12013-10-29 18:34:16 -040056 return false;
57 }
58
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040059 close();
60
Thomas Tsou204a9f12013-10-29 18:34:16 -040061 sendBuffer.resize(mChans);
62 recvBuffer.resize(mChans);
63 convertSendBuffer.resize(mChans);
64 convertRecvBuffer.resize(mChans);
65 mReceiveFIFO.resize(mChans);
Thomas Tsoucb269a32013-11-15 14:15:47 -050066 powerScaling.resize(mChans);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040067
Thomas Tsou204a9f12013-10-29 18:34:16 -040068 for (size_t i = 0; i < mChans; i++) {
69 sendBuffer[i] = new signalVector(CHUNK * mSPSTx);
70 recvBuffer[i] = new signalVector(NUMCHUNKS * CHUNK * mSPSRx);
71
72 convertSendBuffer[i] = new short[sendBuffer[i]->size() * 2];
73 convertRecvBuffer[i] = new short[recvBuffer[i]->size() * 2];
74 }
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040075
76 sendCursor = 0;
77 recvCursor = 0;
78
79 return true;
80}
81
82void RadioInterface::close()
83{
Thomas Tsou204a9f12013-10-29 18:34:16 -040084 for (size_t i = 0; i < sendBuffer.size(); i++)
85 delete sendBuffer[i];
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040086
Thomas Tsou204a9f12013-10-29 18:34:16 -040087 for (size_t i = 0; i < recvBuffer.size(); i++)
88 delete recvBuffer[i];
89
90 for (size_t i = 0; i < convertSendBuffer.size(); i++)
91 delete convertSendBuffer[i];
92
93 for (size_t i = 0; i < convertRecvBuffer.size(); i++)
94 delete convertRecvBuffer[i];
95
96 sendBuffer.resize(0);
97 recvBuffer.resize(0);
98 convertSendBuffer.resize(0);
99 convertRecvBuffer.resize(0);
dburgessb3a0ca42011-10-12 07:44:40 +0000100}
101
102double RadioInterface::fullScaleInputValue(void) {
103 return mRadio->fullScaleInputValue();
104}
105
106double RadioInterface::fullScaleOutputValue(void) {
107 return mRadio->fullScaleOutputValue();
108}
109
Tom Tsoua4d1a412014-11-25 15:46:56 -0800110int RadioInterface::setPowerAttenuation(int atten, size_t chan)
dburgessb3a0ca42011-10-12 07:44:40 +0000111{
kurtis.heimerl16c65402011-11-26 03:18:11 +0000112 double rfGain, digAtten;
kurtis.heimerlee5347a2011-11-26 03:18:05 +0000113
Thomas Tsou204a9f12013-10-29 18:34:16 -0400114 if (chan >= mChans) {
115 LOG(ALERT) << "Invalid channel requested";
Tom Tsoua4d1a412014-11-25 15:46:56 -0800116 return -1;
Thomas Tsou204a9f12013-10-29 18:34:16 -0400117 }
118
Tom Tsoua4d1a412014-11-25 15:46:56 -0800119 if (atten < 0.0)
120 atten = 0.0;
121
122 rfGain = mRadio->setTxGain(mRadio->maxTxGain() - (double) atten, chan);
123 digAtten = (double) atten - mRadio->maxTxGain() + rfGain;
kurtis.heimerlee5347a2011-11-26 03:18:05 +0000124
125 if (digAtten < 1.0)
Thomas Tsoucb269a32013-11-15 14:15:47 -0500126 powerScaling[chan] = 1.0;
kurtis.heimerlee5347a2011-11-26 03:18:05 +0000127 else
Thomas Tsoucb269a32013-11-15 14:15:47 -0500128 powerScaling[chan] = 1.0 / sqrt(pow(10, digAtten / 10.0));
Tom Tsoua4d1a412014-11-25 15:46:56 -0800129
130 return atten;
dburgessb3a0ca42011-10-12 07:44:40 +0000131}
132
kurtis.heimerl9b557832011-11-26 03:18:34 +0000133int RadioInterface::radioifyVector(signalVector &wVector,
134 float *retVector,
kurtis.heimerl9b557832011-11-26 03:18:34 +0000135 bool zero)
dburgessb3a0ca42011-10-12 07:44:40 +0000136{
kurtis.heimerl9b557832011-11-26 03:18:34 +0000137 if (zero) {
138 memset(retVector, 0, wVector.size() * 2 * sizeof(float));
139 return wVector.size();
dburgessb3a0ca42011-10-12 07:44:40 +0000140 }
141
Thomas Tsou9471d762013-08-20 21:24:24 -0400142 memcpy(retVector, wVector.begin(), wVector.size() * 2 * sizeof(float));
kurtis.heimerl9b557832011-11-26 03:18:34 +0000143
144 return wVector.size();
dburgessb3a0ca42011-10-12 07:44:40 +0000145}
146
kurtis.heimerl9b557832011-11-26 03:18:34 +0000147int RadioInterface::unRadioifyVector(float *floatVector,
148 signalVector& newVector)
dburgessb3a0ca42011-10-12 07:44:40 +0000149{
dburgessb3a0ca42011-10-12 07:44:40 +0000150 signalVector::iterator itr = newVector.begin();
kurtis.heimerl9b557832011-11-26 03:18:34 +0000151
Thomas Tsou9471d762013-08-20 21:24:24 -0400152 if (newVector.size() > recvCursor) {
153 LOG(ALERT) << "Insufficient number of samples in receive buffer";
154 return -1;
155 }
156
Thomas Tsou3f32ab52013-11-15 16:32:54 -0500157 for (size_t i = 0; i < newVector.size(); i++) {
kurtis.heimerl9b557832011-11-26 03:18:34 +0000158 *itr++ = Complex<float>(floatVector[2 * i + 0],
159 floatVector[2 * i + 1]);
dburgessb3a0ca42011-10-12 07:44:40 +0000160 }
161
kurtis.heimerl9b557832011-11-26 03:18:34 +0000162 return newVector.size();
dburgessb3a0ca42011-10-12 07:44:40 +0000163}
164
Thomas Tsou204a9f12013-10-29 18:34:16 -0400165bool RadioInterface::tuneTx(double freq, size_t chan)
dburgessb3a0ca42011-10-12 07:44:40 +0000166{
Thomas Tsou204a9f12013-10-29 18:34:16 -0400167 return mRadio->setTxFreq(freq, chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000168}
169
Thomas Tsou204a9f12013-10-29 18:34:16 -0400170bool RadioInterface::tuneRx(double freq, size_t chan)
dburgessb3a0ca42011-10-12 07:44:40 +0000171{
Thomas Tsou204a9f12013-10-29 18:34:16 -0400172 return mRadio->setRxFreq(freq, chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000173}
174
Tom Tsoueb54bdd2014-11-25 16:06:32 -0800175bool RadioInterface::start()
dburgessb3a0ca42011-10-12 07:44:40 +0000176{
Tom Tsoueb54bdd2014-11-25 16:06:32 -0800177 if (mOn)
178 return true;
179
180 LOG(INFO) << "Starting radio device";
Thomas Tsouf2293b82013-04-08 13:35:36 -0400181#ifdef USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000182 mAlignRadioServiceLoopThread.start((void * (*)(void*))AlignRadioServiceLoopAdapter,
183 (void*)this);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400184#endif
Tom Tsoueb54bdd2014-11-25 16:06:32 -0800185
186 if (!mRadio->start())
187 return false;
188
Tom Tsoud7610cf2015-05-07 17:39:49 -0700189 recvCursor = 0;
190 sendCursor = 0;
191
dburgessb3a0ca42011-10-12 07:44:40 +0000192 writeTimestamp = mRadio->initialWriteTimestamp();
193 readTimestamp = mRadio->initialReadTimestamp();
Alexander Chemerisf28d7222015-07-11 12:51:37 -0400194 configureTimestamp = readTimestamp;
Thomas Tsou18d3b832014-02-13 14:55:23 -0500195
196 mRadio->updateAlignment(writeTimestamp-10000);
dburgessb3a0ca42011-10-12 07:44:40 +0000197 mRadio->updateAlignment(writeTimestamp-10000);
198
dburgessb3a0ca42011-10-12 07:44:40 +0000199 mOn = true;
Thomas Tsou18d3b832014-02-13 14:55:23 -0500200 LOG(INFO) << "Radio started";
Tom Tsoueb54bdd2014-11-25 16:06:32 -0800201 return true;
202}
203
204/*
205 * Stop the radio device
206 *
207 * This is a pass-through call to the device interface. Because the underlying
208 * stop command issuance generally doesn't return confirmation on device status,
209 * this call will only return false if the device is already stopped.
210 */
211bool RadioInterface::stop()
212{
213 if (!mOn || !mRadio->stop())
214 return false;
215
216 mOn = false;
217 return true;
dburgessb3a0ca42011-10-12 07:44:40 +0000218}
219
Thomas Tsouf2293b82013-04-08 13:35:36 -0400220#ifdef USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000221void *AlignRadioServiceLoopAdapter(RadioInterface *radioInterface)
222{
223 while (1) {
224 radioInterface->alignRadio();
225 pthread_testcancel();
226 }
227 return NULL;
228}
229
230void RadioInterface::alignRadio() {
231 sleep(60);
232 mRadio->updateAlignment(writeTimestamp+ (TIMESTAMP) 10000);
233}
Thomas Tsouf2293b82013-04-08 13:35:36 -0400234#endif
dburgessb3a0ca42011-10-12 07:44:40 +0000235
Thomas Tsou204a9f12013-10-29 18:34:16 -0400236void RadioInterface::driveTransmitRadio(std::vector<signalVector *> &bursts,
237 std::vector<bool> &zeros)
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400238{
239 if (!mOn)
240 return;
dburgessb3a0ca42011-10-12 07:44:40 +0000241
Thomas Tsou204a9f12013-10-29 18:34:16 -0400242 for (size_t i = 0; i < mChans; i++) {
243 radioifyVector(*bursts[i],
244 (float *) (sendBuffer[i]->begin() + sendCursor), zeros[i]);
245 }
dburgessb3a0ca42011-10-12 07:44:40 +0000246
Thomas Tsou204a9f12013-10-29 18:34:16 -0400247 sendCursor += bursts[0]->size();
dburgessb3a0ca42011-10-12 07:44:40 +0000248
249 pushBuffer();
250}
251
Thomas Tsou204a9f12013-10-29 18:34:16 -0400252bool RadioInterface::driveReceiveRadio()
253{
254 radioVector *burst = NULL;
dburgessb3a0ca42011-10-12 07:44:40 +0000255
Thomas Tsou204a9f12013-10-29 18:34:16 -0400256 if (!mOn)
257 return false;
dburgessb3a0ca42011-10-12 07:44:40 +0000258
259 pullBuffer();
260
261 GSM::Time rcvClock = mClock.get();
262 rcvClock.decTN(receiveOffset);
263 unsigned tN = rcvClock.TN();
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500264 int recvSz = recvCursor;
dburgessb3a0ca42011-10-12 07:44:40 +0000265 int readSz = 0;
266 const int symbolsPerSlot = gSlotLen + 8;
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500267 int burstSize = (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx;
dburgessb3a0ca42011-10-12 07:44:40 +0000268
Thomas Tsoud0f3ca32013-11-09 22:05:23 -0500269 /*
270 * Pre-allocate head room for the largest correlation size
271 * so we can later avoid a re-allocation and copy
272 * */
273 size_t head = GSM::gRACHSynchSequence.size();
274
275 /*
276 * Form receive bursts and pass up to transceiver. Use repeating
277 * pattern of 157-156-156-156 symbols per timeslot
278 */
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500279 while (recvSz > burstSize) {
Alexander Chemerisf28d7222015-07-11 12:51:37 -0400280// updateBurstRxParameters();
281
Thomas Tsou204a9f12013-10-29 18:34:16 -0400282 for (size_t i = 0; i < mChans; i++) {
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500283 burst = new radioVector(rcvClock, burstSize, head, mMIMO);
Thomas Tsou204a9f12013-10-29 18:34:16 -0400284
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500285 for (size_t n = 0; n < mMIMO; n++) {
286 unRadioifyVector((float *)
287 (recvBuffer[mMIMO * i + n]->begin() + readSz),
288 *burst->getVector(n));
289 }
290
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500291 if (mReceiveFIFO[i].size() < 32)
Thomas Tsou204a9f12013-10-29 18:34:16 -0400292 mReceiveFIFO[i].write(burst);
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500293 else
Thomas Tsou204a9f12013-10-29 18:34:16 -0400294 delete burst;
dburgessb3a0ca42011-10-12 07:44:40 +0000295 }
Thomas Tsou204a9f12013-10-29 18:34:16 -0400296
297 mClock.incTN();
dburgessb3a0ca42011-10-12 07:44:40 +0000298 rcvClock.incTN();
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500299 readSz += burstSize;
300 recvSz -= burstSize;
Alexander Chemerisf28d7222015-07-11 12:51:37 -0400301 configureTimestamp += burstSize;
dburgessb3a0ca42011-10-12 07:44:40 +0000302
303 tN = rcvClock.TN();
Thomas Tsoue0fa2bf2013-11-09 02:46:29 -0500304
305 burstSize = (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx;
dburgessb3a0ca42011-10-12 07:44:40 +0000306 }
307
kurtis.heimerl9b557832011-11-26 03:18:34 +0000308 if (readSz > 0) {
Thomas Tsou204a9f12013-10-29 18:34:16 -0400309 for (size_t i = 0; i < recvBuffer.size(); i++) {
310 memmove(recvBuffer[i]->begin(),
311 recvBuffer[i]->begin() + readSz,
312 (recvCursor - readSz) * 2 * sizeof(float));
313 }
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400314
315 recvCursor -= readSz;
dburgessb3a0ca42011-10-12 07:44:40 +0000316 }
Thomas Tsou204a9f12013-10-29 18:34:16 -0400317
318 return true;
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000319}
320
321bool RadioInterface::isUnderrun()
322{
323 bool retVal = underrun;
324 underrun = false;
325
326 return retVal;
327}
328
Thomas Tsou204a9f12013-10-29 18:34:16 -0400329VectorFIFO* RadioInterface::receiveFIFO(size_t chan)
330{
331 if (chan >= mReceiveFIFO.size())
332 return NULL;
333
334 return &mReceiveFIFO[chan];
335}
336
337double RadioInterface::setRxGain(double dB, size_t chan)
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000338{
339 if (mRadio)
Thomas Tsou204a9f12013-10-29 18:34:16 -0400340 return mRadio->setRxGain(dB, chan);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000341 else
342 return -1;
343}
344
Thomas Tsou204a9f12013-10-29 18:34:16 -0400345double RadioInterface::getRxGain(size_t chan)
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000346{
347 if (mRadio)
Thomas Tsou204a9f12013-10-29 18:34:16 -0400348 return mRadio->getRxGain(chan);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000349 else
350 return -1;
351}
Thomas Tsoucb69f082013-04-08 14:18:26 -0400352
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400353/* Receive a timestamped chunk from the device */
Thomas Tsoucb69f082013-04-08 14:18:26 -0400354void RadioInterface::pullBuffer()
355{
356 bool local_underrun;
Thomas Tsou3952d802013-10-15 15:12:24 -0400357 int num_recv;
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400358 float *output;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400359
Thomas Tsou204a9f12013-10-29 18:34:16 -0400360 if (recvCursor > recvBuffer[0]->size() - CHUNK)
Thomas Tsou3952d802013-10-15 15:12:24 -0400361 return;
362
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400363 /* Outer buffer access size is fixed */
Thomas Tsou9471d762013-08-20 21:24:24 -0400364 num_recv = mRadio->readSamples(convertRecvBuffer,
Thomas Tsou3952d802013-10-15 15:12:24 -0400365 CHUNK,
Thomas Tsou9471d762013-08-20 21:24:24 -0400366 &overrun,
367 readTimestamp,
368 &local_underrun);
Thomas Tsou3952d802013-10-15 15:12:24 -0400369 if (num_recv != CHUNK) {
Thomas Tsou9471d762013-08-20 21:24:24 -0400370 LOG(ALERT) << "Receive error " << num_recv;
371 return;
372 }
Thomas Tsoucb69f082013-04-08 14:18:26 -0400373
Thomas Tsou204a9f12013-10-29 18:34:16 -0400374 for (size_t i = 0; i < mChans; i++) {
375 output = (float *) (recvBuffer[i]->begin() + recvCursor);
376 convert_short_float(output, convertRecvBuffer[i], 2 * num_recv);
377 }
Thomas Tsoucb69f082013-04-08 14:18:26 -0400378
379 underrun |= local_underrun;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400380
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400381 readTimestamp += num_recv;
Thomas Tsou9471d762013-08-20 21:24:24 -0400382 recvCursor += num_recv;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400383}
384
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400385/* Send timestamped chunk to the device with arbitrary size */
Thomas Tsoucb69f082013-04-08 14:18:26 -0400386void RadioInterface::pushBuffer()
387{
Thomas Tsou9471d762013-08-20 21:24:24 -0400388 int num_sent;
389
Thomas Tsou3952d802013-10-15 15:12:24 -0400390 if (sendCursor < CHUNK)
Thomas Tsoucb69f082013-04-08 14:18:26 -0400391 return;
392
Thomas Tsou204a9f12013-10-29 18:34:16 -0400393 if (sendCursor > sendBuffer[0]->size())
Thomas Tsou3952d802013-10-15 15:12:24 -0400394 LOG(ALERT) << "Send buffer overflow";
395
Thomas Tsou204a9f12013-10-29 18:34:16 -0400396 for (size_t i = 0; i < mChans; i++) {
397 convert_float_short(convertSendBuffer[i],
398 (float *) sendBuffer[i]->begin(),
Thomas Tsoucb269a32013-11-15 14:15:47 -0500399 powerScaling[i], 2 * sendCursor);
Thomas Tsou204a9f12013-10-29 18:34:16 -0400400 }
Thomas Tsoucb69f082013-04-08 14:18:26 -0400401
Thomas Tsou9471d762013-08-20 21:24:24 -0400402 /* Send the all samples in the send buffer */
403 num_sent = mRadio->writeSamples(convertSendBuffer,
404 sendCursor,
405 &underrun,
406 writeTimestamp);
Thomas Tsou9471d762013-08-20 21:24:24 -0400407 writeTimestamp += num_sent;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400408 sendCursor = 0;
409}
Alexander Chemerisf28d7222015-07-11 12:51:37 -0400410
411void RadioInterface::updateBurstRxParameters(const GSM::Time &gsmTime, size_t chan)
412{
413 if (chan != 0) return;
414
415 TIMESTAMP curTs = mRadio->getCurrentTimestampRx();
416
417 // TODO: Choose a proper value
418 const int burstAdvance = 8*3;
419
420 // Get TN of the burst to update
421 GSM::Time rcvClock = gsmTime;
422// rcvClock.decTN(receiveOffset);
423 rcvClock.incTN(burstAdvance);
424 unsigned tN = rcvClock.TN();
425 unsigned fN = rcvClock.FN();
426
427 const double symbolsPerSlot = gSlotLen + 8.25;
428 // TODO: Properly take into account 156/157 burst sizes
429 //const double burstSize = (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx;
430 const TIMESTAMP burstTimestamp = configureTimestamp + symbolsPerSlot*mSPSRx*burstAdvance;
431
432 LOG(INFO) << "chan=" << chan << " " << rcvClock << " current_rx_timestamp=" << curTs
433 << " configureTimestamp=" << configureTimestamp << " (" << std::setw(5) << int(configureTimestamp)-int(curTs) << ")"
434 << " burstTimestamp=" << burstTimestamp << " (" << std::setw(5) << int(burstTimestamp)-int(curTs) << ")";
435
436// if (tN != 2 && tN != 3)
437 if (tN != 0)
438 return;
439
440 // TODO: real decision making
441 bool diversity = false;
442// mRadio->set_diversity(((fN%2==0) != (tN%2==0))?false:true, burstTimestamp, chan);
443// if (tN==2)
444 diversity = (fN%2==0)?false:true;
445 LOG(INFO) << "chan=" << chan << " " << rcvClock << " diversity=" << diversity;
446 mRadio->set_diversity(diversity, burstTimestamp, chan);
447// }
448}