diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2019-12-21 00:40:09 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2020-01-07 16:04:04 +0100 |
commit | fd99c6ce05e2b62dcba93201e2a2d1ac83b3673d (patch) | |
tree | 81cc56117b72c5695795eadd8d1e9f959d6e152e | |
parent | e947db8d98fc873b06e7b42abc51f0109810e640 (diff) |
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
-rw-r--r-- | Transceiver52M/radioInterface.h | 8 | ||||
-rw-r--r-- | Transceiver52M/radioInterfaceMulti.cpp | 73 |
2 files changed, 59 insertions, 22 deletions
diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h index d9fa414..c75a983 100644 --- a/Transceiver52M/radioInterface.h +++ b/Transceiver52M/radioInterface.h @@ -156,16 +156,24 @@ public: void close(); }; +struct freq_cfg_state { + bool set; + double freq_hz; +}; + class RadioInterfaceMulti : public RadioInterface { private: bool pushBuffer(); int pullBuffer(); + bool verify_arfcn_consistency(double freq, size_t chan, bool tx); virtual double setTxGain(double dB, size_t chan); signalVector *outerSendBuffer; signalVector *outerRecvBuffer; std::vector<signalVector *> history; std::vector<bool> active; + std::vector<struct freq_cfg_state> rx_freq_state; + std::vector<struct freq_cfg_state> tx_freq_state; Resampler *dnsampler; Resampler *upsampler; diff --git a/Transceiver52M/radioInterfaceMulti.cpp b/Transceiver52M/radioInterfaceMulti.cpp index 668305c..a0c24b5 100644 --- a/Transceiver52M/radioInterfaceMulti.cpp +++ b/Transceiver52M/radioInterfaceMulti.cpp @@ -73,6 +73,8 @@ void RadioInterfaceMulti::close() powerScaling.resize(0); history.resize(0); active.resize(0); + rx_freq_state.resize(0); + tx_freq_state.resize(0); RadioInterface::close(); } @@ -148,6 +150,8 @@ bool RadioInterfaceMulti::init(int type) mReceiveFIFO.resize(mChans); powerScaling.resize(mChans); history.resize(mChans); + rx_freq_state.resize(mChans); + tx_freq_state.resize(mChans); active.resize(MCHANS, false); inchunk = RESAMP_INRATE * 4; @@ -362,42 +366,67 @@ static bool fltcmp(double a, double b) return fabs(a - b) < FREQ_DELTA_LIMIT ? true : false; } +bool RadioInterfaceMulti::verify_arfcn_consistency(double freq, size_t chan, bool tx) +{ + double freq_i; + std::string str_dir = tx ? "Tx" : "Rx"; + std::vector<struct freq_cfg_state> &v = tx ? tx_freq_state : rx_freq_state; + + for (size_t i = 0; i < mChans; i++) { + if (i == chan) + continue; + if (!v[i].set) + continue; + + freq_i = v[i].freq_hz + (double) ((int)chan - (int)i) * MCBTS_SPACING; + if (!fltcmp(freq, freq_i)) { + LOGCHAN(chan, DMAIN, ERROR) + << "Setting " << str_dir << " frequency " << freq + << " is incompatible: already configured channel " + << i << " uses frequency " << v[i].freq_hz + << " (expected " << freq_i << ")"; + return false; + } + } + v[chan].set = true; + v[chan].freq_hz = freq; + return true; +} + bool RadioInterfaceMulti::tuneTx(double freq, size_t chan) { - if (chan >= mChans) - return false; + double shift; - double shift = (double) getFreqShift(mChans); + if (chan >= mChans) + return false; - if (!chan) - return mDevice->setTxFreq(freq + shift * MCBTS_SPACING); + if (!verify_arfcn_consistency(freq, chan, true)) + return false; - double center = mDevice->getTxFreq(); - if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) { - LOG(NOTICE) << "Channel " << chan << " RF Tx frequency offset is " - << freq / 1e6 << " MHz"; - } + if (chan == 0) { + shift = (double) getFreqShift(mChans); + return mDevice->setTxFreq(freq + shift * MCBTS_SPACING); + } - return true; + return true; } bool RadioInterfaceMulti::tuneRx(double freq, size_t chan) { - if (chan >= mChans) - return false; + double shift; - double shift = (double) getFreqShift(mChans); + if (chan >= mChans) + return false; - if (!chan) - return mDevice->setRxFreq(freq + shift * MCBTS_SPACING); + if (!verify_arfcn_consistency(freq, chan, false)) + return false; - double center = mDevice->getRxFreq(); - if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) { - LOG(NOTICE) << "Channel " << chan << " RF Rx frequency offset is " - << freq / 1e6 << " MHz"; - } + if (chan == 0) { + shift = (double) getFreqShift(mChans); + return mDevice->setRxFreq(freq + shift * MCBTS_SPACING); + } - return true; + return true; } double RadioInterfaceMulti::setRxGain(double db, size_t chan) |