mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
synced 2025-11-02 05:03:18 +00:00
The dev type was set too early, but the actual dev is only being discovered during open, so update it. This broke the gain to power mapping by defaulting to a wrong device. Change-Id: I1dda6023ca6f15bc063c3dfbc704db2410ff7c98
137 lines
4.0 KiB
C++
137 lines
4.0 KiB
C++
#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;
|
|
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 update_band_dev(devkeyt dev_type) {
|
|
m_dev_type = dev_type;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}; |