diff options
author | Eric <ewild@sysmocom.de> | 2023-05-12 13:00:14 +0200 |
---|---|---|
committer | Eric <ewild@sysmocom.de> | 2023-07-25 18:25:49 +0200 |
commit | c0f78a37ed6fcb900c232eeba41f22f2dffa48d1 (patch) | |
tree | 521ab93b0038f0f4d218a1f8e50d8323cea5e8aa /Transceiver52M/device/common | |
parent | 19e134a626abdb99435d96b0bfcc46b0804715e5 (diff) |
devices: unify band handling
This is basically common, but optional code.
Change-Id: I64f5a462451e967d4750d8e4f1d5832cbab41cff
Diffstat (limited to 'Transceiver52M/device/common')
-rw-r--r-- | Transceiver52M/device/common/Makefile.am | 2 | ||||
-rw-r--r-- | Transceiver52M/device/common/bandmanager.h | 133 |
2 files changed, 134 insertions, 1 deletions
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_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) 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 <info@sysmocom.de> + * All Rights Reserved + * + * Author: Eric Wild <ewild@sysmocom.de> + * + * 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 |