aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-12-21 00:40:09 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2020-01-07 16:04:04 +0100
commitfd99c6ce05e2b62dcba93201e2a2d1ac83b3673d (patch)
tree81cc56117b72c5695795eadd8d1e9f959d6e152e
parente947db8d98fc873b06e7b42abc51f0109810e640 (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.h8
-rw-r--r--Transceiver52M/radioInterfaceMulti.cpp73
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)