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

 (

10 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted 
one.
 )Change subject: devices: unify band handling
......................................................................

devices: unify band handling

This is basically common, but optional code.

Change-Id: I64f5a462451e967d4750d8e4f1d5832cbab41cff
---
M Transceiver52M/device/bladerf/bladerf.cpp
M Transceiver52M/device/bladerf/bladerf.h
M Transceiver52M/device/common/Makefile.am
A Transceiver52M/device/common/bandmanager.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
8 files changed, 242 insertions(+), 326 deletions(-)

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




diff --git a/Transceiver52M/device/bladerf/bladerf.cpp 
b/Transceiver52M/device/bladerf/bladerf.cpp
index 3d9aab9..3e830b1 100644
--- a/Transceiver52M/device/bladerf/bladerf.cpp
+++ b/Transceiver52M/device/bladerf/bladerf.cpp
@@ -47,25 +47,11 @@
                        LOGC(DDEV, ERROR) << bladerf_strerror(status);          
                                       \
        }

-/* Device Type, Tx-SPS, Rx-SPS */
-typedef std::tuple<blade_dev_type, int, int> dev_key;
-
-/* Device parameter descriptor */
-struct dev_desc {
-       unsigned channels;
-       double mcr;
-       double rate;
-       double offset;
-       std::string str;
-};
-
-static const std::map<dev_key, dev_desc> dev_param_map{
+static const dev_map_t dev_param_map{
        { std::make_tuple(blade_dev_type::BLADE2, 4, 4), { 1, 26e6, GSMRATE, 
B2XX_TIMING_4_4SPS, "B200 4 SPS" } },
 };

-typedef std::tuple<blade_dev_type, enum gsm_band> dev_band_key;
-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{
+static const power_map_t dev_band_nom_power_param_map{
        { std::make_tuple(blade_dev_type::BLADE2, GSM_BAND_850), { 89.75, 13.3, 
-7.5 } },
        { std::make_tuple(blade_dev_type::BLADE2, GSM_BAND_900), { 89.75, 13.3, 
-7.5 } },
        { std::make_tuple(blade_dev_type::BLADE2, GSM_BAND_1800), { 89.75, 7.5, 
-11.0 } },
@@ -85,9 +71,9 @@
 }

 blade_device::blade_device(InterfaceType iface, const struct trx_cfg *cfg)
-       : RadioDevice(iface, cfg), dev(nullptr), rx_gain_min(0.0), 
rx_gain_max(0.0), band_ass_curr_sess(false),
-         band((enum gsm_band)0), tx_spp(0), rx_spp(0), started(false), 
aligned(false), drop_cnt(0), prev_ts(0),
-         ts_initial(0), ts_offset(0), async_event_thrd(NULL)
+       : RadioDevice(iface, cfg), band_manager(dev_band_nom_power_param_map, 
dev_param_map), dev(nullptr),
+         rx_gain_min(0.0), rx_gain_max(0.0), tx_spp(0), rx_spp(0), 
started(false), aligned(false), drop_cnt(0),
+         prev_ts(0), ts_initial(0), ts_offset(0), async_event_thrd(NULL)
 {
 }

@@ -104,47 +90,6 @@
                delete rx_buffers[i];
 }

-void blade_device::assign_band_desc(enum gsm_band req_band)
-{
-       dev_band_map_it it;
-
-       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 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(blade_dev_type::BLADE2, 
req_band));
-       }
-       OSMO_ASSERT(it != dev_band_nom_power_param_map.end())
-       band_desc = it->second;
-}
-
-bool blade_device::set_band(enum gsm_band req_band)
-{
-       if (band_ass_curr_sess && req_band != band) {
-               LOGC(DDEV, ALERT) << "Requesting band " << 
gsm_band_name(req_band) << " different from previous band "
-                                 << gsm_band_name(band);
-               return false;
-       }
-
-       if (req_band != band) {
-               band = req_band;
-               assign_band_desc(band);
-       }
-       band_ass_curr_sess = true;
-       return true;
-}
-
-void blade_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 blade_device::init_gains()
 {
        double tx_gain_min, tx_gain_max;
@@ -457,7 +402,7 @@
        for (size_t i = 0; i < rx_buffers.size(); i++)
                rx_buffers[i]->reset();

-       band_ass_curr_sess = false;
+       band_reset();

        started = false;
        return true;
@@ -580,27 +525,13 @@

 bool blade_device::setTxFreq(double wFreq, size_t chan)
 {
-       uint16_t req_arfcn;
-       enum gsm_band req_band;
-
        if (chan >= tx_freqs.size()) {
                LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
                return false;
        }
        ScopedLock lock(tune_lock);

-       req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100, 0);
-       if (req_arfcn == 0xffff) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown ARFCN for Tx Frequency " 
<< wFreq / 1000 << " kHz";
-               return false;
-       }
-       if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
-               LOGCHAN(chan, DDEV, ALERT)
-                       << "Unknown GSM band for Tx Frequency " << wFreq << " 
Hz (ARFCN " << req_arfcn << " )";
-               return false;
-       }
-
-       if (!set_band(req_band))
+       if (!update_band_from_freq(wFreq, chan, true))
                return false;

        if (!set_freq(wFreq, chan, true))
@@ -611,27 +542,13 @@

 bool blade_device::setRxFreq(double wFreq, size_t chan)
 {
-       uint16_t req_arfcn;
-       enum gsm_band req_band;
-
        if (chan >= rx_freqs.size()) {
                LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
                return false;
        }
        ScopedLock lock(tune_lock);

-       req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100, 1);
-       if (req_arfcn == 0xffff) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown ARFCN for Rx Frequency " 
<< wFreq / 1000 << " kHz";
-               return false;
-       }
-       if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
-               LOGCHAN(chan, DDEV, ALERT)
-                       << "Unknown GSM band for Rx Frequency " << wFreq << " 
Hz (ARFCN " << req_arfcn << " )";
-               return false;
-       }
-
-       if (!set_band(req_band))
+       if (!update_band_from_freq(wFreq, chan, false))
                return false;

        return set_freq(wFreq, chan, false);
diff --git a/Transceiver52M/device/bladerf/bladerf.h 
b/Transceiver52M/device/bladerf/bladerf.h
index 4db2569..e32581e 100644
--- a/Transceiver52M/device/bladerf/bladerf.h
+++ b/Transceiver52M/device/bladerf/bladerf.h
@@ -22,10 +22,12 @@

 #pragma once

+#include <map>
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif

+#include "bandmanager.h"
 #include "radioDevice.h"
 #include "smpl_buf.h"

@@ -33,8 +35,6 @@
 #include <osmocom/gsm/gsm_utils.h>
 }

-#include <bladerf.h>
-
 enum class blade_dev_type { BLADE1, BLADE2 };

 struct dev_band_desc {
@@ -52,7 +52,21 @@
        double rxgain2rssioffset_rel; /* dB */
 };

-class blade_device : public RadioDevice {
+/* Device parameter descriptor */
+struct dev_desc {
+       unsigned channels;
+       double mcr;
+       double rate;
+       double offset;
+       std::string desc_str;
+};
+
+using dev_key = std::tuple<blade_dev_type, int, int>;
+using dev_band_key = std::tuple<blade_dev_type, enum gsm_band>;
+using power_map_t = std::map<dev_band_key, dev_band_desc>;
+using dev_map_t = std::map<dev_key, dev_desc>;
+
+class blade_device : public RadioDevice, public band_manager<power_map_t, 
dev_map_t> {
     public:
        blade_device(InterfaceType iface, const struct trx_cfg *cfg);
        ~blade_device();
@@ -153,9 +167,6 @@

        std::vector<double> tx_gains, rx_gains;
        std::vector<double> tx_freqs, rx_freqs;
-       bool band_ass_curr_sess; /* true if  "band" was set after last POWEROFF 
*/
-       enum gsm_band band;
-       struct dev_band_desc band_desc;
        size_t tx_spp, rx_spp;

        bool started;
@@ -178,9 +189,6 @@
        bool flush_recv(size_t num_pkts);

        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/common/Makefile.am 
b/Transceiver52M/device/common/Makefile.am
index 4d29e98..1a33592 100644
--- a/Transceiver52M/device/common/Makefile.am
+++ b/Transceiver52M/device/common/Makefile.am
@@ -4,7 +4,7 @@
 AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS)


-noinst_HEADERS = radioDevice.h smpl_buf.h
+noinst_HEADERS = radioDevice.h smpl_buf.h bandmanager.h

 noinst_LTLIBRARIES = libdevice_common.la

diff --git a/Transceiver52M/device/common/bandmanager.h 
b/Transceiver52M/device/common/bandmanager.h
new file mode 100644
index 0000000..a198937
--- /dev/null
+++ b/Transceiver52M/device/common/bandmanager.h
@@ -0,0 +1,133 @@
+#pragma once
+/*
+ * (C) 2022 by sysmocom s.f.m.c. GmbH <[email protected]>
+ * All Rights Reserved
+ *
+ * Author: Eric Wild <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string>
+#include <tuple>
+
+#include "Logger.h"
+
+extern "C" {
+#include <osmocom/gsm/gsm_utils.h>
+}
+
+template <typename powermapt, typename devmapt>
+class band_manager {
+       using powerkeyt = typename powermapt::key_type;
+       using powermappedt = typename powermapt::mapped_type;
+       using devkeyt = typename devmapt::key_type;
+       const devkeyt &m_dev_type;
+       const powermapt &m_power_map;
+       const devmapt &m_dev_map;
+       powerkeyt m_fallback;
+       enum gsm_band m_band;
+       powermappedt m_band_desc;
+       bool band_ass_curr_sess{}; /* true if  "band" was set after last 
POWEROFF */
+
+       // looks up either first tuple element (->enum) or straight enum
+       template <typename T, typename 
std::enable_if<std::is_enum<T>::value>::type *dummy = nullptr>
+       auto key_helper(T &t) -> T
+       {
+               return t;
+       }
+
+       template <typename T>
+       auto key_helper(T t) -> typename std::tuple_element<0, T>::type
+       {
+               return std::get<0>(t);
+       }
+
+       void assign_band_desc(enum gsm_band req_band)
+       {
+               auto key = key_helper(m_dev_type);
+               auto fallback_key = key_helper(m_fallback);
+               auto it = m_power_map.find({ key, req_band });
+               if (it == m_power_map.end()) {
+                       auto desc = m_dev_map.at(m_dev_type);
+                       LOGC(DDEV, ERROR) << "No Tx Power measurements exist 
for device " << desc.desc_str
+                                         << " on band " << 
gsm_band_name(req_band) << ", using fallback..";
+                       it = m_power_map.find({ fallback_key, req_band });
+               }
+               OSMO_ASSERT(it != m_power_map.end());
+               m_band_desc = it->second;
+       }
+
+       bool set_band(enum gsm_band req_band)
+       {
+               if (band_ass_curr_sess && req_band != m_band) {
+                       LOGC(DDEV, ALERT) << "Requesting band " << 
gsm_band_name(req_band)
+                                         << " different from previous band " 
<< gsm_band_name(m_band);
+                       return false;
+               }
+
+               if (req_band != m_band) {
+                       m_band = req_band;
+                       assign_band_desc(m_band);
+               }
+               band_ass_curr_sess = true;
+               return true;
+       }
+
+    public:
+       band_manager(const devkeyt &dev_type, const powermapt &power_map, const 
devmapt &dev_map, powerkeyt fallback)
+               : m_dev_type(dev_type), m_power_map(power_map), 
m_dev_map(dev_map), m_fallback(fallback),
+                 m_band((enum gsm_band)0)
+       {
+       }
+       band_manager(const powermapt &power_map, const devmapt &dev_map)
+               : m_dev_type(dev_map.begin()->first), m_power_map(power_map), 
m_dev_map(dev_map),
+                 m_fallback(m_power_map.begin()->first), m_band((enum 
gsm_band)0)
+       {
+       }
+       void band_reset()
+       {
+               band_ass_curr_sess = false;
+       }
+
+       void get_dev_band_desc(powermappedt &desc)
+       {
+               if (m_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 = m_band_desc;
+       }
+
+       bool update_band_from_freq(double wFreq, int chan, bool is_tx)
+       {
+               enum gsm_band req_band;
+               auto dirstr = is_tx ? "Tx" : "Rx";
+               auto req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100, !is_tx);
+               if (req_arfcn == 0xffff) {
+                       LOGCHAN(chan, DDEV, ALERT)
+                               << "Unknown ARFCN for " << dirstr << " 
Frequency " << wFreq / 1000 << " kHz";
+                       return false;
+               }
+               if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
+                       LOGCHAN(chan, DDEV, ALERT) << "Unknown GSM band for " 
<< dirstr << " Frequency " << wFreq
+                                                  << " Hz (ARFCN " << 
req_arfcn << " )";
+                       return false;
+               }
+
+               return set_band(req_band);
+       }
+};
\ No newline at end of file
diff --git a/Transceiver52M/device/lms/LMSDevice.cpp 
b/Transceiver52M/device/lms/LMSDevice.cpp
index e336e77..451d2b9 100644
--- a/Transceiver52M/device/lms/LMSDevice.cpp
+++ b/Transceiver52M/device/lms/LMSDevice.cpp
@@ -52,39 +52,16 @@
 #define LMS_DEV_SDR_MINI_PREFIX_NAME "LimeSDR-Mini"
 #define LMS_DEV_NET_MICRO_PREFIX_NAME "LimeNET-Micro"

-/* Device parameter descriptor */
-struct dev_desc {
-       /* Does LimeSuite allow switching the clock source for this device?
-        * LimeSDR-Mini does not have switches but needs soldering to select
-        * external/internal clock. Any call to LMS_SetClockFreq() will fail.
-        */
-       bool clock_src_switchable;
-       /* Does LimeSuite allow using REF_INTERNAL for this device?
-        * LimeNET-Micro does not like selecting internal clock
-        */
-       bool clock_src_int_usable;
-       /* Sample rate coef (without having TX/RX samples per symbol into 
account) */
-       double rate;
-       /* Sample rate coef (without having TX/RX samples per symbol into 
account), if multi-arfcn is enabled */
-       double rate_multiarfcn;
-       /* Coefficient multiplied by TX sample rate in order to shift Tx time */
-       double ts_offset_coef;
-       /* Coefficient multiplied by TX sample rate in order to shift Tx time, 
if multi-arfcn is enabled */
-       double ts_offset_coef_multiarfcn;
-       /* Device Name Prefix as presented by LimeSuite API LMS_GetDeviceInfo() 
*/
-       std::string name_prefix;
-};

-static const std::map<enum lms_dev_type, struct dev_desc> dev_param_map {
+
+static const dev_map_t dev_param_map {
        { LMS_DEV_SDR_USB,   { true,  true,  GSMRATE, MCBTS_SPACING, 8.9e-5, 
7.9e-5, LMS_DEV_SDR_USB_PREFIX_NAME } },
        { LMS_DEV_SDR_MINI,  { false, true,  GSMRATE, MCBTS_SPACING, 8.9e-5, 
8.2e-5, LMS_DEV_SDR_MINI_PREFIX_NAME } },
        { LMS_DEV_NET_MICRO, { true,  false, GSMRATE, MCBTS_SPACING, 8.9e-5, 
7.9e-5, LMS_DEV_NET_MICRO_PREFIX_NAME } },
        { LMS_DEV_UNKNOWN,   { true,  true,  GSMRATE, MCBTS_SPACING, 8.9e-5, 
7.9e-5, "UNKNOWN" } },
 };

-typedef std::tuple<lms_dev_type, enum gsm_band> dev_band_key;
-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 {
+static const power_map_t dev_band_nom_power_param_map {
        { 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) */
@@ -122,8 +99,8 @@
                enum lms_dev_type dev_type = it->first;
                struct dev_desc desc = it->second;

-               if (strncmp(device_info->deviceName, desc.name_prefix.c_str(), 
desc.name_prefix.length()) == 0) {
-                       LOGC(DDEV, INFO) << "Device identified as " << 
desc.name_prefix;
+               if (strncmp(device_info->deviceName, desc.desc_str.c_str(), 
desc.desc_str.length()) == 0) {
+                       LOGC(DDEV, INFO) << "Device identified as " << 
desc.desc_str;
                        return dev_type;
                }
                it++;
@@ -132,8 +109,9 @@
 }

 LMSDevice::LMSDevice(InterfaceType iface, const struct trx_cfg *cfg)
-       : RadioDevice(iface, cfg), m_lms_dev(NULL), started(false), 
band_ass_curr_sess(false), band((enum gsm_band)0),
-         m_dev_type(LMS_DEV_UNKNOWN)
+       : RadioDevice(iface, cfg),
+         band_manager(m_dev_type, dev_band_nom_power_param_map, dev_param_map, 
{LMS_DEV_SDR_USB, GSM_BAND_850}), m_lms_dev(NULL),
+         started(false), m_dev_type(LMS_DEV_UNKNOWN)
 {
        LOGC(DDEV, INFO) << "creating LMS device...";

@@ -220,47 +198,6 @@
        return -1;
 }

-void LMSDevice::assign_band_desc(enum gsm_band req_band)
-{
-       dev_band_map_it it;
-
-       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);
-               LOGC(DDEV, ERROR) << "No Tx Power measurements exist for device 
"
-                                   << desc.name_prefix << " on band " << 
gsm_band_name(req_band)
-                                   << ", using LimeSDR-USB ones as fallback";
-               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());
-       band_desc = it->second;
-}
-
-bool LMSDevice::set_band(enum gsm_band req_band)
-{
-       if (band_ass_curr_sess && req_band != band) {
-               LOGC(DDEV, ALERT) << "Requesting band " << 
gsm_band_name(req_band)
-                                 << " different from previous band " << 
gsm_band_name(band);
-               return false;
-       }
-
-       if (req_band != band) {
-               band = req_band;
-               assign_band_desc(band);
-       }
-       band_ass_curr_sess = true;
-       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()
 {
        lms_info_str_t* info_list;
@@ -466,7 +403,7 @@
                LMS_DestroyStream(m_lms_dev, &m_lms_stream_rx[i]);
        }

-       band_ass_curr_sess = false;
+       band_reset();

        started = false;
        return true;
@@ -483,8 +420,8 @@
                break;
        case REF_INTERNAL:
                if (!dev_desc.clock_src_int_usable) {
-                       LOGC(DDEV, ERROR) << "Device type " << 
dev_desc.name_prefix
-                                         << " doesn't support internal 
reference clock";
+                       LOGC(DDEV, ERROR)
+                               << "Device type " << dev_desc.desc_str << " 
doesn't support internal reference clock";
                        return false;
                }
                /* According to lms using LMS_CLOCK_EXTREF with a
@@ -502,8 +439,8 @@
                if (LMS_SetClockFreq(m_lms_dev, lms_clk_id, freq) < 0)
                        return false;
        } else {
-               LOGC(DDEV, INFO) << "Device type " << dev_desc.name_prefix
-                                << " doesn't support switching clock source 
through SW";
+               LOGC(DDEV, INFO)
+                       << "Device type " << dev_desc.desc_str << " doesn't 
support switching clock source through SW";
        }
 
        return true;
@@ -996,9 +933,6 @@

 bool LMSDevice::setTxFreq(double wFreq, size_t chan)
 {
-       uint16_t req_arfcn;
-       enum gsm_band req_band;
-
        if (chan >= chans) {
                LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
                return false;
@@ -1006,18 +940,7 @@

        LOGCHAN(chan, DDEV, NOTICE) << "Setting Tx Freq to " << wFreq << " Hz";

-       req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100 , 0);
-       if (req_arfcn == 0xffff) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown ARFCN for Tx Frequency " 
<< wFreq / 1000 << " kHz";
-               return false;
-       }
-       if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown GSM band for Tx 
Frequency " << wFreq
-                                          << " Hz (ARFCN " << req_arfcn << " 
)";
-               return false;
-       }
-
-       if (!set_band(req_band))
+       if (!update_band_from_freq(wFreq, chan, true))
                return false;

        if (LMS_SetLOFrequency(m_lms_dev, LMS_CH_TX, chan, wFreq) < 0) {
@@ -1030,23 +953,9 @@

 bool LMSDevice::setRxFreq(double wFreq, size_t chan)
 {
-       uint16_t req_arfcn;
-       enum gsm_band req_band;
-
        LOGCHAN(chan, DDEV, NOTICE) << "Setting Rx Freq to " << wFreq << " Hz";

-       req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100, 1);
-       if (req_arfcn == 0xffff) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown ARFCN for Rx Frequency " 
<< wFreq / 1000 << " kHz";
-               return false;
-       }
-       if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown GSM band for Rx 
Frequency " << wFreq
-                                          << " Hz (ARFCN " << req_arfcn << " 
)";
-               return false;
-       }
-
-       if (!set_band(req_band))
+       if (!update_band_from_freq(wFreq, chan, false))
                return false;

        if (LMS_SetLOFrequency(m_lms_dev, LMS_CH_RX, chan, wFreq) < 0) {
diff --git a/Transceiver52M/device/lms/LMSDevice.h 
b/Transceiver52M/device/lms/LMSDevice.h
index 75d11cf..2e5ca4c 100644
--- a/Transceiver52M/device/lms/LMSDevice.h
+++ b/Transceiver52M/device/lms/LMSDevice.h
@@ -18,11 +18,13 @@
 #ifndef _LMS_DEVICE_H_
 #define _LMS_DEVICE_H_

+#include <map>
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif

 #include "radioDevice.h"
+#include "bandmanager.h"
 #include "smpl_buf.h"

 #include <sys/time.h>
@@ -69,8 +71,35 @@
        double rxgain2rssioffset_rel; /* dB */
 };

+/* Device parameter descriptor */
+struct dev_desc {
+       /* Does LimeSuite allow switching the clock source for this device?
+        * LimeSDR-Mini does not have switches but needs soldering to select
+        * external/internal clock. Any call to LMS_SetClockFreq() will fail.
+        */
+       bool clock_src_switchable;
+       /* Does LimeSuite allow using REF_INTERNAL for this device?
+        * LimeNET-Micro does not like selecting internal clock
+        */
+       bool clock_src_int_usable;
+       /* Sample rate coef (without having TX/RX samples per symbol into 
account) */
+       double rate;
+       /* Sample rate coef (without having TX/RX samples per symbol into 
account), if multi-arfcn is enabled */
+       double rate_multiarfcn;
+       /* Coefficient multiplied by TX sample rate in order to shift Tx time */
+       double ts_offset_coef;
+       /* Coefficient multiplied by TX sample rate in order to shift Tx time, 
if multi-arfcn is enabled */
+       double ts_offset_coef_multiarfcn;
+       /* Device Name Prefix as presented by LimeSuite API LMS_GetDeviceInfo() 
*/
+       std::string desc_str;
+};
+
+using dev_band_key_t = std::tuple<lms_dev_type, gsm_band>;
+using power_map_t = std::map<dev_band_key_t, dev_band_desc>;
+using dev_map_t = std::map<lms_dev_type, struct dev_desc>;
+
 /** A class to handle a LimeSuite supported device */
-class LMSDevice:public RadioDevice {
+class LMSDevice:public RadioDevice, public band_manager<power_map_t, 
dev_map_t> {

 private:
        lms_device_t *m_lms_dev;
@@ -87,9 +116,6 @@
        TIMESTAMP ts_initial, ts_offset;

        std::vector<double> tx_gains, rx_gains;
-       bool band_ass_curr_sess; /* true if  "band" was set after last POWEROFF 
*/
-       enum gsm_band band;
-       struct dev_band_desc band_desc;

        enum lms_dev_type m_dev_type;

@@ -101,9 +127,6 @@
        void update_stream_stats_rx(size_t chan, bool *overrun);
        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 */
diff --git a/Transceiver52M/device/uhd/UHDDevice.cpp 
b/Transceiver52M/device/uhd/UHDDevice.cpp
index a0021db..95ea8e7 100644
--- a/Transceiver52M/device/uhd/UHDDevice.cpp
+++ b/Transceiver52M/device/uhd/UHDDevice.cpp
@@ -91,19 +91,7 @@
  *   USRP1 with timestamps is not supported by UHD.
  */

-/* Device Type, Tx-SPS, Rx-SPS */
-typedef std::tuple<uhd_dev_type, int, int> dev_key;
-
-/* Device parameter descriptor */
-struct dev_desc {
-       unsigned channels;
-       double mcr;
-       double rate;
-       double offset;
-       std::string str;
-};
-
-static const std::map<dev_key, dev_desc> dev_param_map {
+static const dev_map_t dev_param_map {
        { std::make_tuple(USRP2, 1, 1), { 1, 0.0,  390625,  1.2184e-4,  "N2XX 1 
SPS"         } },
        { std::make_tuple(USRP2, 4, 1), { 1, 0.0,  390625,  7.6547e-5,  "N2XX 
4/1 Tx/Rx SPS" } },
        { std::make_tuple(USRP2, 4, 4), { 1, 0.0,  390625,  4.6080e-5,  "N2XX 4 
SPS"         } },
@@ -129,9 +117,7 @@
        { std::make_tuple(B2XX_MCBTS, 4, 4), { 1, 51.2e6, MCBTS_SPACING*4, 
B2XX_TIMING_MCBTS, "B200/B210 4 SPS Multi-ARFCN" } },
 };

-typedef std::tuple<uhd_dev_type, enum gsm_band> dev_band_key;
-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 {
+static const power_map_t dev_band_nom_power_param_map {
        { 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 } },
@@ -221,8 +207,8 @@
 }

 uhd_device::uhd_device(InterfaceType iface, const struct trx_cfg *cfg)
-       : RadioDevice(iface, cfg), rx_gain_min(0.0), rx_gain_max(0.0), 
band_ass_curr_sess(false),
-         band((enum gsm_band)0), tx_spp(0), rx_spp(0), started(false), 
aligned(false), drop_cnt(0), prev_ts(0, 0),
+       : RadioDevice(iface, cfg), band_manager(dev_band_nom_power_param_map, 
dev_param_map), rx_gain_min(0.0),
+         rx_gain_max(0.0), tx_spp(0), rx_spp(0), started(false), 
aligned(false), drop_cnt(0), prev_ts(0, 0),
          ts_initial(0), ts_offset(0), async_event_thrd(NULL)
 {
 }
@@ -235,47 +221,6 @@
                delete rx_buffers[i];
 }

-void uhd_device::assign_band_desc(enum gsm_band req_band)
-{
-       dev_band_map_it it;
-
-       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 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())
-       band_desc = it->second;
-}
-
-bool uhd_device::set_band(enum gsm_band req_band)
-{
-       if (band_ass_curr_sess && req_band != band) {
-               LOGC(DDEV, ALERT) << "Requesting band " << 
gsm_band_name(req_band)
-                                 << " different from previous band " << 
gsm_band_name(band);
-               return false;
-       }
-
-       if (req_band != band) {
-               band = req_band;
-               assign_band_desc(band);
-       }
-       band_ass_curr_sess = true;
-       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()
 {
        double tx_gain_min, tx_gain_max;
@@ -340,7 +285,7 @@
        rx_rate = usrp_dev->get_rx_rate();

        ts_offset = static_cast<TIMESTAMP>(desc.offset * rx_rate);
-       LOGC(DDEV, INFO) << "Rates configured for " << desc.str;
+       LOGC(DDEV, INFO) << "Rates configured for " << desc.desc_str;
 }

 double uhd_device::setRxGain(double db, size_t chan)
@@ -791,7 +736,7 @@
        for (size_t i = 0; i < rx_buffers.size(); i++)
                rx_buffers[i]->reset();

-       band_ass_curr_sess = false;
+       band_reset();

        started = false;
        return true;
@@ -1031,17 +976,19 @@
 {
        std::vector<double> freqs;
        uhd::tune_result_t tres;
+       std::string str_dir = tx ? "Tx" : "Rx";
+
+       if (!update_band_from_freq(freq, chan, tx))
+               return false;
+
        uhd::tune_request_t treq = select_freq(freq, chan, tx);
-       std::string str_dir;

        if (tx) {
                tres = usrp_dev->set_tx_freq(treq, chan);
                tx_freqs[chan] = usrp_dev->get_tx_freq(chan);
-               str_dir = "Tx";
        } else {
                tres = usrp_dev->set_rx_freq(treq, chan);
                rx_freqs[chan] = usrp_dev->get_rx_freq(chan);
-               str_dir = "Rx";
        }
        LOGCHAN(chan, DDEV, INFO) << "set_freq(" << freq << ", " << str_dir << 
"): " << tres.to_pp_string() << std::endl;

@@ -1071,59 +1018,20 @@

 bool uhd_device::setTxFreq(double wFreq, size_t chan)
 {
-       uint16_t req_arfcn;
-       enum gsm_band req_band;
-
        if (chan >= tx_freqs.size()) {
                LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
                return false;
        }
-       ScopedLock lock(tune_lock);

-       req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100 , 0);
-       if (req_arfcn == 0xffff) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown ARFCN for Tx Frequency " 
<< wFreq / 1000 << " kHz";
-               return false;
-       }
-       if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown GSM band for Tx 
Frequency " << wFreq
-                                          << " Hz (ARFCN " << req_arfcn << " 
)";
-               return false;
-       }
-
-       if (!set_band(req_band))
-               return false;
-
-       if (!set_freq(wFreq, chan, true))
-               return false;
-
-       return true;
+       return set_freq(wFreq, chan, true);
 }

 bool uhd_device::setRxFreq(double wFreq, size_t chan)
 {
-       uint16_t req_arfcn;
-       enum gsm_band req_band;
-
        if (chan >= rx_freqs.size()) {
                LOGC(DDEV, ALERT) << "Requested non-existent channel " << chan;
                return false;
        }
-       ScopedLock lock(tune_lock);
-
-       req_arfcn = gsm_freq102arfcn(wFreq / 1000 / 100, 1);
-       if (req_arfcn == 0xffff) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown ARFCN for Rx Frequency " 
<< wFreq / 1000 << " kHz";
-               return false;
-       }
-       if (gsm_arfcn2band_rc(req_arfcn, &req_band) < 0) {
-               LOGCHAN(chan, DDEV, ALERT) << "Unknown GSM band for Rx 
Frequency " << wFreq
-                                          << " Hz (ARFCN " << req_arfcn << " 
)";
-               return false;
-       }
-
-       if (!set_band(req_band))
-               return false;

        return set_freq(wFreq, chan, false);
 }
diff --git a/Transceiver52M/device/uhd/UHDDevice.h 
b/Transceiver52M/device/uhd/UHDDevice.h
index 299d98c..f5e5232 100644
--- a/Transceiver52M/device/uhd/UHDDevice.h
+++ b/Transceiver52M/device/uhd/UHDDevice.h
@@ -30,6 +30,7 @@
 #include "config.h"
 #endif

+#include "bandmanager.h"
 #include "radioDevice.h"
 #include "smpl_buf.h"

@@ -71,6 +72,19 @@
        double rxgain2rssioffset_rel; /* dB */
 };

+struct dev_desc {
+       unsigned channels;
+       double mcr;
+       double rate;
+       double offset;
+       std::string desc_str;
+};
+
+using dev_key = std::tuple<uhd_dev_type, int, int>;
+using dev_band_key = std::tuple<uhd_dev_type, enum gsm_band>;
+using power_map_t = std::map<dev_band_key, dev_band_desc>;
+using dev_map_t = std::map<dev_key, dev_desc>;
+
 /*
     uhd_device - UHD implementation of the Device interface. Timestamped 
samples
                 are sent to and received from the device. An intermediate 
buffer
@@ -78,7 +92,7 @@
                 Events and errors such as underruns are reported asynchronously
                 by the device and received in a separate thread.
 */
-class uhd_device : public RadioDevice {
+class uhd_device : public RadioDevice, public band_manager<power_map_t, 
dev_map_t> {
 public:
     uhd_device(InterfaceType iface, const struct trx_cfg *cfg);
     ~uhd_device();
@@ -160,9 +174,6 @@

        std::vector<double> tx_gains, rx_gains;
        std::vector<double> tx_freqs, rx_freqs;
-       bool band_ass_curr_sess; /* true if  "band" was set after last POWEROFF 
*/
-       enum gsm_band band;
-       struct dev_band_desc band_desc;
        size_t tx_spp, rx_spp;

        bool started;
@@ -191,10 +202,6 @@

        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;
 };

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

Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Change-Id: I64f5a462451e967d4750d8e4f1d5832cbab41cff
Gerrit-Change-Number: 32763
Gerrit-PatchSet: 11
Gerrit-Owner: Hoernchen <[email protected]>
Gerrit-Reviewer: Hoernchen <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to