Change in osmo-trx[master]: Calculate RSSI offset based on RxGain configuration

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Wed Oct 14 11:25:40 UTC 2020


pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-trx/+/20639 )

Change subject: Calculate RSSI offset based on RxGain configuration
......................................................................

Calculate RSSI offset based on RxGain configuration

Prior to this patch, osmo-trx relied totally on proper VTY configuration
being set in "rssi-offset" together with the RxGain set through TRXC in
order to provide correct Uplink RSSI measurements to bts-trx.

With this patch, RSSI is now by default calculated (in LMS and UHD
backends) based on the currently set RxGain, by providing empirically
discovered values. Still, for backward compatibility, the old
"rssi-offset" command will overwrite completely the per-default
calculated rssi offset.
A new optional parameter "relative" is added at the end of the
"rssi-offset" VTY command to flag the value as relative to the newly
per-default calculated value. This way specific setups (like adding a
LNA / RF fronted) can still be expressed while still keeping the
automatic per-default offset.

Related: OS#4468
Change-Id: I8ef78fd20c22c60d61bfb18d80a4a36df4fd6c20
---
M CommonLibs/config_defs.h
M CommonLibs/trx_vty.c
M Transceiver52M/Transceiver.cpp
M Transceiver52M/Transceiver.h
M Transceiver52M/device/common/radioDevice.h
M Transceiver52M/device/ipc/IPCDevice.h
M Transceiver52M/device/lms/LMSDevice.cpp
M Transceiver52M/device/lms/LMSDevice.h
M Transceiver52M/device/uhd/UHDDevice.cpp
M Transceiver52M/device/uhd/UHDDevice.h
M Transceiver52M/device/usrp1/USRPDevice.h
M Transceiver52M/osmo-trx.cpp
M Transceiver52M/radioInterface.cpp
M Transceiver52M/radioInterface.h
M Transceiver52M/radioInterfaceMulti.cpp
M doc/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg
16 files changed, 187 insertions(+), 70 deletions(-)

Approvals:
  fixeria: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/CommonLibs/config_defs.h b/CommonLibs/config_defs.h
index 7d501cd..a9ed25e 100644
--- a/CommonLibs/config_defs.h
+++ b/CommonLibs/config_defs.h
@@ -47,6 +47,7 @@
 	bool multi_arfcn;
 	double offset;
 	double rssi_offset;
+	bool force_rssi_offset; /* Force value set in VTY? */
 	bool swap_channels;
 	bool ext_rach;
 	bool egprs;
diff --git a/CommonLibs/trx_vty.c b/CommonLibs/trx_vty.c
index cf36547..fd6faed 100644
--- a/CommonLibs/trx_vty.c
+++ b/CommonLibs/trx_vty.c
@@ -231,13 +231,15 @@
 }
 
 DEFUN(cfg_rssi_offset, cfg_rssi_offset_cmd,
-	"rssi-offset FLOAT",
+	"rssi-offset FLOAT [relative]",
 	"Set the RSSI to dBm offset in dB (default=0)\n"
-	"RSSI to dBm offset in dB\n")
+	"RSSI to dBm offset in dB\n"
+	"Add to the default rssi-offset value instead of completely replacing it\n")
 {
 	struct trx_ctx *trx = trx_from_vty(vty);
 
 	trx->cfg.rssi_offset = atof(argv[0]);
+	trx->cfg.force_rssi_offset = (argc == 1);
 
 	return CMD_SUCCESS;
 }
@@ -580,8 +582,9 @@
 	vty_out(vty, " multi-arfcn %s%s", trx->cfg.multi_arfcn ? "enable" : "disable", VTY_NEWLINE);
 	if (trx->cfg.offset != 0)
 		vty_out(vty, " offset %f%s", trx->cfg.offset, VTY_NEWLINE);
-	if (trx->cfg.rssi_offset != 0)
-		vty_out(vty, " rssi-offset %f%s", trx->cfg.rssi_offset, VTY_NEWLINE);
+	if (!(trx->cfg.rssi_offset == 0 && !trx->cfg.force_rssi_offset))
+		vty_out(vty, " rssi-offset %f%s%s", trx->cfg.rssi_offset,
+			trx->cfg.force_rssi_offset ? " relative": "", VTY_NEWLINE);
 	vty_out(vty, " swap-channels %s%s", trx->cfg.swap_channels ? "enable" : "disable", VTY_NEWLINE);
 	vty_out(vty, " egprs %s%s", trx->cfg.egprs ? "enable" : "disable", VTY_NEWLINE);
 	vty_out(vty, " ext-rach %s%s", trx->cfg.ext_rach ? "enable" : "disable", VTY_NEWLINE);
@@ -716,6 +719,7 @@
 	trx->cfg.tx_sps = DEFAULT_TX_SPS;
 	trx->cfg.rx_sps = DEFAULT_RX_SPS;
 	trx->cfg.filler = FILLER_ZERO;
+	trx->cfg.rssi_offset = 0.0f;
 
 	return trx;
 }
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index c697234..6e40be5 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -612,6 +612,13 @@
   outfile.close();
 }
 
+double Transceiver::rssiOffset(size_t chan)
+{
+  if (cfg->force_rssi_offset)
+        return cfg->rssi_offset;
+  return mRadioInterface->rssiOffset(chan) + cfg->rssi_offset;
+}
+
 /*
  * Pull bursts from the FIFO and handle according to the slot
  * and burst correlation type. Equalzation is currently disabled.
@@ -631,6 +638,7 @@
   SoftVector *rxBurst;
   TransceiverState *state = &mStates[chan];
   bool ctr_changed = false;
+  double rssi_offset;
 
   /* Blocking FIFO read */
   radioVector *radio_burst = mReceiveFIFO[chan]->read();
@@ -700,8 +708,9 @@
     state->mNoiseLev = state->mNoises.avg();
   }
 
-  bi->rssi = 20.0 * log10(rxFullScale / avg) + cfg->rssi_offset;
-  bi->noise = 20.0 * log10(rxFullScale / state->mNoiseLev) + cfg->rssi_offset;
+  rssi_offset = rssiOffset(chan);
+  bi->rssi = 20.0 * log10(rxFullScale / avg) + rssi_offset;
+  bi->noise = 20.0 * log10(rxFullScale / state->mNoiseLev) + rssi_offset;
 
   if (type == IDLE)
     goto ret_idle;
@@ -1153,11 +1162,13 @@
     else os << "-";
   }
 
+  double rssi_offset = rssiOffset(chan);
+
   LOGCHAN(chan, DTRXDUL, DEBUG) << std::fixed << std::right
     << " time: "   << unsigned(bi->tn) << ":" << bi->fn
-    << " RSSI: "   << std::setw(5) << std::setprecision(1) << (bi->rssi - cfg->rssi_offset)
+    << " RSSI: "   << std::setw(5) << std::setprecision(1) << (bi->rssi - rssi_offset)
                    << "dBFS/" << std::setw(6) << -bi->rssi << "dBm"
-    << " noise: "  << std::setw(5) << std::setprecision(1) << (bi->noise - cfg->rssi_offset)
+    << " noise: "  << std::setw(5) << std::setprecision(1) << (bi->noise - rssi_offset)
                    << "dBFS/" << std::setw(6) << -bi->noise << "dBm"
     << " TOA: "    << std::setw(5) << std::setprecision(2) << bi->toa
     << " C/I: "    << std::setw(5) << std::setprecision(2) << bi->ci << "dB"
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 42a780e..45a4159 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -260,7 +260,7 @@
   friend void *RxLowerLoopAdapter(Transceiver *transceiver);
   friend void *TxLowerLoopAdapter(Transceiver *transceiver);
 
-
+  double rssiOffset(size_t chan);
   void reset();
 
   void logRxBurst(size_t chan, const struct trx_ul_burst_ind *bi);
diff --git a/Transceiver52M/device/common/radioDevice.h b/Transceiver52M/device/common/radioDevice.h
index 45fcdad..3f5da1f 100644
--- a/Transceiver52M/device/common/radioDevice.h
+++ b/Transceiver52M/device/common/radioDevice.h
@@ -125,6 +125,9 @@
   /** return minimum Rx Gain **/
   virtual double minRxGain(void) = 0;
 
+  /** return base RSSI offset to apply for received samples **/
+  virtual double rssiOffset(size_t chan) = 0;
+
   /** returns the Nominal transmit output power of the transceiver in dBm, negative on error **/
   virtual int getNominalTxPower(size_t chan = 0) = 0;
 
diff --git a/Transceiver52M/device/ipc/IPCDevice.h b/Transceiver52M/device/ipc/IPCDevice.h
index a7618f9..35279a2 100644
--- a/Transceiver52M/device/ipc/IPCDevice.h
+++ b/Transceiver52M/device/ipc/IPCDevice.h
@@ -198,6 +198,9 @@
 	/** return minimum Rx Gain **/
 	virtual double minRxGain(void) override;
 
+	/* FIXME: return rx_gains[chan] ? receive factor from IPC Driver? */
+	double rssiOffset(size_t chan) { return 0.0f; };
+
 	double setPowerAttenuation(int atten, size_t chan) override;
 	double getPowerAttenuation(size_t chan = 0) override;
 
diff --git a/Transceiver52M/device/lms/LMSDevice.cpp b/Transceiver52M/device/lms/LMSDevice.cpp
index 20b9856..ac7323e 100644
--- a/Transceiver52M/device/lms/LMSDevice.cpp
+++ b/Transceiver52M/device/lms/LMSDevice.cpp
@@ -85,27 +85,20 @@
 };
 
 typedef std::tuple<lms_dev_type, enum gsm_band> dev_band_key;
-/* Maximum LimeSuite Tx Gain which can be set/used without distorting the output
- * signal, and the resulting real output power measured when that gain is used.
- */
-struct dev_band_desc {
-	double nom_lms_tx_gain;  /* dB */
-	double nom_out_tx_power; /* dBm */
-};
 typedef std::map<dev_band_key, dev_band_desc>::const_iterator dev_band_map_it;
 static const std::map<dev_band_key, dev_band_desc> dev_band_nom_power_param_map {
-	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_850),	{ 73.0, 11.2 } },
-	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_900),	{ 73.0, 10.8 } },
-	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_1800),	{ 65.0, -3.5 } }, /* FIXME: OS#4583: 1800Mhz is failing above TxGain=65, which is around -3.5dBm (already < 0 dBm) */
-	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_1900),	{ 73.0, 1.7 } }, /* FIXME: OS#4583: 1900MHz is failing in all TxGain values */
-	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_850),	{ 66.0, 3.1 } }, /* FIXME: OS#4583: Ensure BAND2 is used at startup */
-	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_900),	{ 66.0, 2.8 } }, /* FIXME: OS#4583: Ensure BAND2 is used at startup */
-	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_1800),	{ 66.0, -11.6 } }, /* OS#4583: Any of BAND1 or BAND2 is fine */
-	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_1900),	{ 66.0, -9.2 } }, /* FIXME: OS#4583: Ensure BAND1 is used at startup */
-	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_850),	{ 71.0, 6.8 } },
-	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_900),	{ 71.0, 6.8 } },
-	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_1800),	{ 65.0, -10.5 } }, /* OS#4583: TxGain=71 (-4.4dBm) FAIL rms phase errors ~10° */
-	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_1900),	{ 71.0, -6.3 } }, /* FIXME: OS#4583: all FAIL, BAND1/BAND2 rms phase errors >23° */
+	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_850),	{ 73.0, 11.2,  -6.0  } },
+	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_900),	{ 73.0, 10.8,  -6.0  } },
+	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_1800),	{ 65.0, -3.5,  -17.0 } }, /* FIXME: OS#4583: 1800Mhz is failing above TxGain=65, which is around -3.5dBm (already < 0 dBm) */
+	{ std::make_tuple(LMS_DEV_SDR_USB, GSM_BAND_1900),	{ 73.0, 1.7,   -17.0 } }, /* FIXME: OS#4583: 1900MHz is failing in all TxGain values */
+	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_850),	{ 66.0, 3.1,   -6.0  } }, /* FIXME: OS#4583: Ensure BAND2 is used at startup */
+	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_900),	{ 66.0, 2.8,   -6.0  } }, /* FIXME: OS#4583: Ensure BAND2 is used at startup */
+	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_1800),	{ 66.0, -11.6, -17.0 } }, /* OS#4583: Any of BAND1 or BAND2 is fine */
+	{ std::make_tuple(LMS_DEV_SDR_MINI, GSM_BAND_1900),	{ 66.0, -9.2,  -17.0 } }, /* FIXME: OS#4583: Ensure BAND1 is used at startup */
+	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_850),	{ 71.0, 6.8,   -6.0  } },
+	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_900),	{ 71.0, 6.8,   -6.0  } },
+	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_1800),	{ 65.0, -10.5, -17.0 } }, /* OS#4583: TxGain=71 (-4.4dBm) FAIL rms phase errors ~10° */
+	{ std::make_tuple(LMS_DEV_NET_MICRO, GSM_BAND_1900),	{ 71.0, -6.3,  -17.0 } }, /* FIXME: OS#4583: all FAIL, BAND1/BAND2 rms phase errors >23° */
 };
 
 /* So far measurements done for B210 show really close to linear relationship
@@ -231,15 +224,10 @@
 	return -1;
 }
 
-void LMSDevice::get_dev_band_desc(dev_band_desc& desc)
+void LMSDevice::assign_band_desc(enum gsm_band req_band)
 {
 	dev_band_map_it it;
-	enum gsm_band req_band = band;
 
-	if (req_band == 0) {
-		LOGC(DDEV, ERROR) << "Nominal Tx Power requested before Tx Frequency was set! Providing band 900 by default... ";
-		req_band = GSM_BAND_900;
-	}
 	it = dev_band_nom_power_param_map.find(dev_band_key(m_dev_type, req_band));
 	if (it == dev_band_nom_power_param_map.end()) {
 		dev_desc desc = dev_param_map.at(m_dev_type);
@@ -249,7 +237,29 @@
 		it = dev_band_nom_power_param_map.find(dev_band_key(LMS_DEV_SDR_USB, req_band));
 	}
 	OSMO_ASSERT(it != dev_band_nom_power_param_map.end())
-	desc = it->second;
+	band_desc = it->second;
+}
+
+bool LMSDevice::set_band(enum gsm_band req_band)
+{
+	if (band != 0 && req_band != band) {
+		LOGC(DDEV, ALERT) << "Requesting band " << gsm_band_name(req_band)
+				  << " different from previous band " << gsm_band_name(band);
+		return false;
+	}
+
+	band = req_band;
+	assign_band_desc(band);
+	return true;
+}
+
+void LMSDevice::get_dev_band_desc(dev_band_desc& desc)
+{
+	if (band == 0) {
+		LOGC(DDEV, ERROR) << "Power parameters requested before Tx Frequency was set! Providing band 900 by default...";
+		assign_band_desc(GSM_BAND_900);
+	}
+	desc = band_desc;
 }
 
 int LMSDevice::open(const std::string &args, int ref, bool swap_channels)
@@ -561,6 +571,21 @@
 	return rx_gains[chan];
 }
 
+double LMSDevice::rssiOffset(size_t chan)
+{
+	double rssiOffset;
+	dev_band_desc desc;
+
+	if (chan >= rx_gains.size()) {
+		LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
+		return 0.0f;
+	}
+
+	get_dev_band_desc(desc);
+	rssiOffset = rx_gains[chan] + desc.rxgain2rssioffset_rel;
+	return rssiOffset;
+}
+
 double LMSDevice::setPowerAttenuation(int atten, size_t chan)
 {
 	double tx_power, dB;
diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h
index 7af09e2..4ce8ed6 100644
--- a/Transceiver52M/device/lms/LMSDevice.h
+++ b/Transceiver52M/device/lms/LMSDevice.h
@@ -52,7 +52,22 @@
 	LMS_DEV_UNKNOWN,
 };
 
-struct dev_band_desc;
+struct dev_band_desc {
+	/* Maximum LimeSuite Tx Gain which can be set/used without distorting
+	   the output * signal, and the resulting real output power measured
+	   when that gain is used.
+	 */
+	double nom_lms_tx_gain;  /* dB */
+	double nom_out_tx_power; /* dBm */
+	/* Factor used to infer base real RSSI offset on the Rx path based on current
+	   configured RxGain. The resulting rssiOffset is added to the per burst
+	   calculated energy in upper layers. These values were empirically
+	   found and may change based on multiple factors, see OS#4468.
+	   Correct measured values only provided for LimeSDR-USB so far.
+	   rssiOffset = rxGain + rxgain2rssioffset_rel;
+	*/
+	double rxgain2rssioffset_rel; /* dB */
+};
 
 /** A class to handle a LimeSuite supported device */
 class LMSDevice:public RadioDevice {
@@ -73,6 +88,7 @@
 
 	std::vector<double> tx_gains, rx_gains;
 	enum gsm_band band;
+	struct dev_band_desc band_desc;
 
 	enum lms_dev_type m_dev_type;
 
@@ -85,7 +101,8 @@
 	void update_stream_stats_tx(size_t chan, bool *underrun);
 	bool do_clock_src_freq(enum ReferenceType ref, double freq);
 	void get_dev_band_desc(dev_band_desc& desc);
-
+	bool set_band(enum gsm_band req_band);
+	void assign_band_desc(enum gsm_band req_band);
 public:
 
 	/** Object constructor */
@@ -173,6 +190,7 @@
 	/** return minimum Rx Gain **/
 	double minRxGain(void);
 
+	double rssiOffset(size_t chan);
 
 	double setPowerAttenuation(int atten, size_t chan);
 	double getPowerAttenuation(size_t chan = 0);
diff --git a/Transceiver52M/device/uhd/UHDDevice.cpp b/Transceiver52M/device/uhd/UHDDevice.cpp
index 143a061..010fa8c 100644
--- a/Transceiver52M/device/uhd/UHDDevice.cpp
+++ b/Transceiver52M/device/uhd/UHDDevice.cpp
@@ -130,23 +130,16 @@
 };
 
 typedef std::tuple<uhd_dev_type, enum gsm_band> dev_band_key;
-/* Maximum UHD Tx Gain which can be set/used without distorting the
-   output signal, and the resulting real output power measured when that
-   gain is used. Correct measured values only provided for B210 so far. */
-struct dev_band_desc {
-	double nom_uhd_tx_gain;  /* dB */
-	double nom_out_tx_power; /* dBm */
-};
 typedef std::map<dev_band_key, dev_band_desc>::const_iterator dev_band_map_it;
 static const std::map<dev_band_key, dev_band_desc> dev_band_nom_power_param_map {
-	{ std::make_tuple(B200, GSM_BAND_850),	{ 89.75, 13.3 } },
-	{ std::make_tuple(B200, GSM_BAND_900),	{ 89.75, 13.3 } },
-	{ std::make_tuple(B200, GSM_BAND_1800),	{ 89.75, 7.5 } },
-	{ std::make_tuple(B200, GSM_BAND_1900),	{ 89.75, 7.7 } },
-	{ std::make_tuple(B210, GSM_BAND_850),	{ 89.75, 13.3 } },
-	{ std::make_tuple(B210, GSM_BAND_900),	{ 89.75, 13.3 } },
-	{ std::make_tuple(B210, GSM_BAND_1800),	{ 89.75, 7.5 } },
-	{ std::make_tuple(B210, GSM_BAND_1900),	{ 89.75, 7.7 } },
+	{ std::make_tuple(B200, GSM_BAND_850),	{ 89.75, 13.3, -7.5  } },
+	{ std::make_tuple(B200, GSM_BAND_900),	{ 89.75, 13.3, -7.5  } },
+	{ std::make_tuple(B200, GSM_BAND_1800),	{ 89.75, 7.5,  -11.0 } },
+	{ std::make_tuple(B200, GSM_BAND_1900),	{ 89.75, 7.7,  -11.0 } },
+	{ std::make_tuple(B210, GSM_BAND_850),	{ 89.75, 13.3, -7.5  } },
+	{ std::make_tuple(B210, GSM_BAND_900),	{ 89.75, 13.3, -7.5  } },
+	{ std::make_tuple(B210, GSM_BAND_1800),	{ 89.75, 7.5,  -11.0 } },
+	{ std::make_tuple(B210, GSM_BAND_1900),	{ 89.75, 7.7,  -11.0 } },
 };
 
 void *async_event_loop(uhd_device *dev)
@@ -247,25 +240,42 @@
 		delete rx_buffers[i];
 }
 
-void uhd_device::get_dev_band_desc(dev_band_desc& desc)
+void uhd_device::assign_band_desc(enum gsm_band req_band)
 {
 	dev_band_map_it it;
-	enum gsm_band req_band = band;
 
-	if (req_band == 0) {
-		LOGC(DDEV, ERROR) << "Nominal Tx Power requested before Tx Frequency was set! Providing band 900 by default... ";
-		req_band = GSM_BAND_900;
-	}
 	it = dev_band_nom_power_param_map.find(dev_band_key(dev_type, req_band));
 	if (it == dev_band_nom_power_param_map.end()) {
 		dev_desc desc = dev_param_map.at(dev_key(dev_type, tx_sps, rx_sps));
-		LOGC(DDEV, ERROR) << "No Tx Power measurements exist for device "
+		LOGC(DDEV, ERROR) << "No Power parameters exist for device "
 				    << desc.str << " on band " << gsm_band_name(req_band)
 				    << ", using B210 ones as fallback";
 		it = dev_band_nom_power_param_map.find(dev_band_key(B210, req_band));
 	}
 	OSMO_ASSERT(it != dev_band_nom_power_param_map.end())
-	desc = it->second;
+	band_desc = it->second;
+}
+
+bool uhd_device::set_band(enum gsm_band req_band)
+{
+	if (band != 0 && req_band != band) {
+		LOGC(DDEV, ALERT) << "Requesting band " << gsm_band_name(req_band)
+				  << " different from previous band " << gsm_band_name(band);
+		return false;
+	}
+
+	band = req_band;
+	assign_band_desc(band);
+	return true;
+}
+
+void uhd_device::get_dev_band_desc(dev_band_desc& desc)
+{
+	if (band == 0) {
+		LOGC(DDEV, ERROR) << "Power parameters requested before Tx Frequency was set! Providing band 900 by default...";
+		assign_band_desc(GSM_BAND_900);
+	}
+	desc = band_desc;
 }
 
 void uhd_device::init_gains()
@@ -360,6 +370,21 @@
 	return rx_gains[chan];
 }
 
+double uhd_device::rssiOffset(size_t chan)
+{
+	double rssiOffset;
+	dev_band_desc desc;
+
+	if (chan >= rx_gains.size()) {
+		LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
+		return 0.0f;
+	}
+
+	get_dev_band_desc(desc);
+	rssiOffset = rx_gains[chan] + desc.rxgain2rssioffset_rel;
+	return rssiOffset;
+}
+
 double uhd_device::setPowerAttenuation(int atten, size_t chan) {
 	double tx_power, db;
 	dev_band_desc desc;
@@ -1052,16 +1077,12 @@
 		return false;
 	}
 
-	if (band != 0 && req_band != band) {
-		LOGCHAN(chan, DDEV, ALERT) << "Requesting Tx Frequency " << wFreq
-					   << " Hz different from previous band " << gsm_band_name(band);
+	if (!set_band(req_band))
 		return false;
-	}
 
 	if (!set_freq(wFreq, chan, true))
 		return false;
 
-	band = req_band;
 	return true;
 }
 
diff --git a/Transceiver52M/device/uhd/UHDDevice.h b/Transceiver52M/device/uhd/UHDDevice.h
index c159e63..995b43c 100644
--- a/Transceiver52M/device/uhd/UHDDevice.h
+++ b/Transceiver52M/device/uhd/UHDDevice.h
@@ -56,7 +56,20 @@
 	LIMESDR,
 };
 
-struct dev_band_desc;
+struct dev_band_desc {
+	/* Maximum UHD Tx Gain which can be set/used without distorting the
+	   output signal, and the resulting real output power measured when that
+	   gain is used. Correct measured values only provided for B210 so far. */
+	double nom_uhd_tx_gain;  /* dB */
+	double nom_out_tx_power; /* dBm */
+	/* Factor used to infer base real RSSI offset on the Rx path based on current
+	   configured RxGain. The resulting rssiOffset is added to the per burst
+	   calculated energy in upper layers. These values were empirically
+	   found and may change based on multiple factors, see OS#4468.
+	   rssiOffset = rxGain + rxgain2rssioffset_rel;
+	*/
+	double rxgain2rssioffset_rel; /* dB */
+};
 
 /*
     uhd_device - UHD implementation of the Device interface. Timestamped samples
@@ -100,6 +113,7 @@
 	double getRxGain(size_t chan);
 	double maxRxGain(void) { return rx_gain_max; }
 	double minRxGain(void) { return rx_gain_min; }
+	double rssiOffset(size_t chan);
 
 	double setPowerAttenuation(int atten, size_t chan);
 	double getPowerAttenuation(size_t chan = 0);
@@ -147,6 +161,7 @@
 	std::vector<double> tx_gains, rx_gains;
 	std::vector<double> tx_freqs, rx_freqs;
 	enum gsm_band band;
+	struct dev_band_desc band_desc;
 	size_t tx_spp, rx_spp;
 
 	bool started;
@@ -176,6 +191,8 @@
 	uhd::tune_request_t select_freq(double wFreq, size_t chan, bool tx);
 	bool set_freq(double freq, size_t chan, bool tx);
 	void get_dev_band_desc(dev_band_desc& desc);
+	bool set_band(enum gsm_band req_band);
+	void assign_band_desc(enum gsm_band req_band);
 
 	Thread *async_event_thrd;
 	Mutex tune_lock;
diff --git a/Transceiver52M/device/usrp1/USRPDevice.h b/Transceiver52M/device/usrp1/USRPDevice.h
index f761dc0..aa8dc69 100644
--- a/Transceiver52M/device/usrp1/USRPDevice.h
+++ b/Transceiver52M/device/usrp1/USRPDevice.h
@@ -174,6 +174,8 @@
   /** return minimum Rx Gain **/
   double minRxGain(void);
 
+  double rssiOffset(size_t chan) { return 0.0f;  } /* FIXME: not implemented */
+
   double setPowerAttenuation(int atten, size_t chan);
   double getPowerAttenuation(size_t chan=0);
 
diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp
index ec949c8..ec1d660 100644
--- a/Transceiver52M/osmo-trx.cpp
+++ b/Transceiver52M/osmo-trx.cpp
@@ -354,6 +354,7 @@
 		case 'R':
 			print_deprecated(option);
 			trx->cfg.rssi_offset = atof(optarg);
+			trx->cfg.force_rssi_offset = true;
 			break;
 		case 'S':
 			print_deprecated(option);
@@ -477,7 +478,7 @@
 	ost << "   Filler Burst RACH Delay. " << trx->cfg.rach_delay << std::endl;
 	ost << "   Multi-Carrier........... " << trx->cfg.multi_arfcn << std::endl;
 	ost << "   Tuning offset........... " << trx->cfg.offset << std::endl;
-	ost << "   RSSI to dBm offset...... " << trx->cfg.rssi_offset << std::endl;
+	ost << "   RSSI to dBm offset...... " << trx->cfg.rssi_offset << (trx->cfg.force_rssi_offset ? "" : " (relative)") << std::endl;
 	ost << "   Swap channels........... " << trx->cfg.swap_channels << std::endl;
 	ost << "   Tx Antennas.............";
 	for (i = 0; i < trx->cfg.num_chans; i++) {
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index 64a6f21..875245d 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -322,6 +322,11 @@
   return mDevice->setRxGain(dB, chan);
 }
 
+double RadioInterface::rssiOffset(size_t chan)
+{
+	return mDevice->rssiOffset(chan);
+}
+
 /* Receive a timestamped chunk from the device */
 int RadioInterface::pullBuffer()
 {
diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h
index 8e5f4c1..efe5606 100644
--- a/Transceiver52M/radioInterface.h
+++ b/Transceiver52M/radioInterface.h
@@ -109,6 +109,9 @@
   /** set receive gain */
   virtual double setRxGain(double dB, size_t chan = 0);
 
+  /** return base RSSI offset to apply for received samples **/
+  virtual double rssiOffset(size_t chan = 0);
+
   /** drive transmission of GSM bursts */
   void driveTransmitRadio(std::vector<signalVector *> &bursts,
                           std::vector<bool> &zeros);
@@ -190,4 +193,5 @@
   bool tuneTx(double freq, size_t chan);
   bool tuneRx(double freq, size_t chan);
   virtual double setRxGain(double dB, size_t chan);
+  virtual double rssiOffset(size_t chan = 0);
 };
diff --git a/Transceiver52M/radioInterfaceMulti.cpp b/Transceiver52M/radioInterfaceMulti.cpp
index 1ca3fbb..465fd41 100644
--- a/Transceiver52M/radioInterfaceMulti.cpp
+++ b/Transceiver52M/radioInterfaceMulti.cpp
@@ -446,6 +446,11 @@
 		return mDevice->getRxGain();
 }
 
+double RadioInterfaceMulti::rssiOffset(size_t chan)
+{
+	return mDevice->rssiOffset(0);
+}
+
 int RadioInterfaceMulti::setPowerAttenuation(int atten, size_t chan)
 {
 	return RadioInterface::setPowerAttenuation(atten, 0);
diff --git a/doc/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg b/doc/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg
index a924122..9eeb395 100644
--- a/doc/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg
+++ b/doc/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg
@@ -15,9 +15,6 @@
  bind-ip 127.0.0.1
  remote-ip 127.0.0.1
  egprs disable
- ! 28 dB offset below is valid only for the B2xx in 1800 MHz band, see
- ! https://osmocom.org/issues/4468 for more details
- rssi-offset 28.000000
  tx-sps 4
  rx-sps 4
  clock-ref external

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-trx/+/20639
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Change-Id: I8ef78fd20c22c60d61bfb18d80a4a36df4fd6c20
Gerrit-Change-Number: 20639
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: tnt <tnt at 246tNt.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201014/e5950e59/attachment.htm>


More information about the gerrit-log mailing list