/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2022 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as 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 General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #include #include #include "SWGDeviceState.h" #include "SWGErrorResponse.h" #include "SWGFeatureSettings.h" #include "SWGFeatureReport.h" #include "SWGFeatureActions.h" #include "util/simpleserializer.h" #include "util/serialutil.h" #include "settings/serializable.h" #include "webapi/webapiadapterinterface.h" #include "limerfe.h" MESSAGE_CLASS_DEFINITION(LimeRFE::MsgConfigureLimeRFE, Message) MESSAGE_CLASS_DEFINITION(LimeRFE::MsgReportSetRx, Message) MESSAGE_CLASS_DEFINITION(LimeRFE::MsgReportSetTx, Message) const char* const LimeRFE::m_featureIdURI = "sdrangel.feature.limerfe"; const char* const LimeRFE::m_featureId = "LimeRFE"; const std::map LimeRFE::m_errorCodesMap = { { 0, "OK"}, {-4, "Error synchronizing communication"}, {-3, "Non-configurable GPIO pin specified. Only pins 4 and 5 are configurable."}, {-2, "Problem with .ini configuration file"}, {-1, "Communication error"}, { 1, "Wrong TX connector - not possible to route TX of the selecrted channel to the specified port"}, { 2, "Wrong RX connector - not possible to route RX of the selecrted channel to the specified port"}, { 3, "Mode TXRX not allowed - when the same port is selected for RX and TX, it is not allowed to use mode RX & TX"}, { 4, "Wrong mode for cellular channel - Cellular FDD bands (1, 2, 3, and 7) are only allowed mode RX & TX, while TDD band 38 is allowed only RX or TX mode"}, { 5, "Cellular channels must be the same both for RX and TX"}, { 6, "Requested channel code is wrong"} }; LimeRFE::LimeRFE(WebAPIAdapterInterface *webAPIAdapterInterface) : Feature(m_featureIdURI, webAPIAdapterInterface), m_webAPIAdapterInterface(webAPIAdapterInterface), m_rfeDevice(nullptr) { setObjectName(m_featureId); m_state = StIdle; m_errorMessage = "LimeRFE error"; m_networkManager = new QNetworkAccessManager(); QObject::connect( m_networkManager, &QNetworkAccessManager::finished, this, &LimeRFE::networkManagerFinished ); listComPorts(); } LimeRFE::~LimeRFE() { QObject::disconnect( m_networkManager, &QNetworkAccessManager::finished, this, &LimeRFE::networkManagerFinished ); delete m_networkManager; closeDevice(); } void LimeRFE::start() { qDebug("LimeRFE::start"); m_state = StRunning; } void LimeRFE::stop() { qDebug("LimeRFE::stop"); m_state = StIdle; } void LimeRFE::listComPorts() { m_comPorts.clear(); std::vector comPorts; SerialUtil::getComPorts(comPorts, "ttyUSB[0-9]+"); // regex is for Linux only for (std::vector::const_iterator it = comPorts.begin(); it != comPorts.end(); ++it) { m_comPorts.push_back(QString(it->c_str())); } } void LimeRFE::applySettings(const LimeRFESettings& settings, const QList& settingsKeys, bool force) { qDebug() << "LimeRFE::applySettings:" << settings.getDebugString(settingsKeys, force) << " force:" << force; if (force) { m_settings = settings; } else { m_settings.applySettings(settingsKeys, settings); } } bool LimeRFE::handleMessage(const Message& cmd) { if (MsgConfigureLimeRFE::match(cmd)) { MsgConfigureLimeRFE& cfg = (MsgConfigureLimeRFE&) cmd; qDebug() << "LimeRFE::handleMessage: MsgConfigureLimeRFE"; applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce()); return true; } return false; } QByteArray LimeRFE::serialize() const { SimpleSerializer s(1); s.writeBlob(1, m_settings.serialize()); return s.final(); } bool LimeRFE::deserialize(const QByteArray& data) { SimpleDeserializer d(data); if (!d.isValid()) { m_settings.resetToDefaults(); return false; } if (d.getVersion() == 1) { QByteArray bytetmp; d.readBlob(1, &bytetmp); if (m_settings.deserialize(bytetmp)) { MsgConfigureLimeRFE *msg = MsgConfigureLimeRFE::create(m_settings, QList(), true); m_inputMessageQueue.push(msg); return true; } else { m_settings.resetToDefaults(); MsgConfigureLimeRFE *msg = MsgConfigureLimeRFE::create(m_settings, QList(), true); m_inputMessageQueue.push(msg); return false; } } else { return false; } } int LimeRFE::openDevice(const std::string& serialDeviceName) { closeDevice(); rfe_dev_t *rfeDevice = RFE_Open(serialDeviceName.c_str(), nullptr); if (rfeDevice != (void *) -1) { m_rfeDevice = rfeDevice; return 0; } else { return -1; } } void LimeRFE::closeDevice() { if (m_rfeDevice) { RFE_Close(m_rfeDevice); m_rfeDevice = nullptr; } } int LimeRFE::configure() { if (!m_rfeDevice) { return -1; } qDebug() << "LimeRFE::configure: " << "attValue: " << (int) m_rfeBoardState.attValue << "channelIDRX: " << (int) m_rfeBoardState.channelIDRX << "channelIDTX: " << (int) m_rfeBoardState.channelIDTX << "mode: " << (int) m_rfeBoardState.mode << "notchOnOff: " << (int) m_rfeBoardState.notchOnOff << "selPortRX: " << (int) m_rfeBoardState.selPortRX << "selPortTX: " << (int) m_rfeBoardState.selPortTX << "enableSWR: " << (int) m_rfeBoardState.enableSWR << "sourceSWR: " << (int) m_rfeBoardState.sourceSWR; int rc = RFE_ConfigureState(m_rfeDevice, m_rfeBoardState); if (rc != 0) { qInfo("LimeRFE::configure: %s", getError(rc).c_str()); } else { qDebug() << "LimeRFE::configure: done"; } return rc; } int LimeRFE::getState() { if (!m_rfeDevice) { return -1; } int rc = RFE_GetState(m_rfeDevice, &m_rfeBoardState); qDebug() << "LimeRFE::getState: " << "attValue: " << (int) m_rfeBoardState.attValue << "channelIDRX: " << (int) m_rfeBoardState.channelIDRX << "channelIDTX: " << (int) m_rfeBoardState.channelIDTX << "mode: " << (int) m_rfeBoardState.mode << "notchOnOff: " << (int) m_rfeBoardState.notchOnOff << "selPortRX: " << (int) m_rfeBoardState.selPortRX << "selPortTX: " << (int) m_rfeBoardState.selPortTX << "enableSWR: " << (int) m_rfeBoardState.enableSWR << "sourceSWR: " << (int) m_rfeBoardState.sourceSWR; if (rc != 0) { qInfo("LimeRFE::getState: %s", getError(rc).c_str()); } if (m_rfeBoardState.mode == RFE_MODE_RX) { m_rxOn = true; m_txOn = false; } else if (m_rfeBoardState.mode == RFE_MODE_TX) { m_rxOn = false; m_txOn = true; } else if (m_rfeBoardState.mode == RFE_MODE_NONE) { m_rxOn = false; m_txOn = false; } else if (m_rfeBoardState.mode == RFE_MODE_TXRX) { m_rxOn = true; m_txOn = true; } return rc; } std::string LimeRFE::getError(int errorCode) { std::map::const_iterator it = m_errorCodesMap.find(errorCode); if (it == m_errorCodesMap.end()) { return "Unknown error"; } else { return it->second; } } int LimeRFE::setRx(bool rxOn) { if (!m_rfeDevice) { return -1; } int mode = RFE_MODE_NONE; if (rxOn) { if (m_txOn) { mode = RFE_MODE_TXRX; } else { mode = RFE_MODE_RX; } } else { if (m_txOn) { mode = RFE_MODE_TX; } } int rc = RFE_Mode(m_rfeDevice, mode); if (rc == 0) { m_rxOn = rxOn; m_rfeBoardState.mode = mode; qDebug("LimeRFE::setRx: switch %s mode: %d", rxOn ? "on" : "off", mode); } else { qInfo("LimeRFE::setRx %s: %s", rxOn ? "on" : "off", getError(rc).c_str()); } return rc; } int LimeRFE::setTx(bool txOn) { if (!m_rfeDevice) { return -1; } int mode = RFE_MODE_NONE; if (txOn) { if (m_rxOn) { mode = RFE_MODE_TXRX; } else { mode = RFE_MODE_TX; } } else { if (m_rxOn) { mode = RFE_MODE_RX; } } int rc = RFE_Mode(m_rfeDevice, mode); if (rc == 0) { m_txOn = txOn; m_rfeBoardState.mode = mode; qDebug("LimeRFE::setTx: switch %s mode: %d", txOn ? "on" : "off", mode); } else { qInfo("LimeRFE::setTx %s: %s", txOn ? "on" : "off", getError(rc).c_str()); } return rc; } bool LimeRFE::turnDevice(int deviceSetIndex, bool on) { qDebug("LimeRFE::turnDevice %d: %s", deviceSetIndex, on ? "on" : "off"); SWGSDRangel::SWGDeviceState response; SWGSDRangel::SWGErrorResponse error; int httpCode; if (on) { httpCode = m_webAPIAdapterInterface->devicesetDeviceRunPost(deviceSetIndex, response, error); } else { httpCode = m_webAPIAdapterInterface->devicesetDeviceRunDelete(deviceSetIndex, response, error); } if (httpCode/100 == 2) { qDebug("LimeRFE::turnDevice: %s success", on ? "on" : "off"); return true; } else { qWarning("LimeRFE::turnDevice: error: %s", qPrintable(*error.getMessage())); return false; } } int LimeRFE::getFwdPower(int& powerDB) { if (!m_rfeDevice) { return -1; } int power; int rc = RFE_ReadADC(m_rfeDevice, RFE_ADC1, &power); if (rc == 0) { powerDB = power; } return rc; } int LimeRFE::getRefPower(int& powerDB) { if (!m_rfeDevice) { return -1; } int power; int rc = RFE_ReadADC(m_rfeDevice, RFE_ADC2, &power); if (rc == 0) { powerDB = power; } return rc; } void LimeRFE::settingsToState(const LimeRFESettings& settings) { if (settings.m_rxChannels == LimeRFESettings::ChannelGroups::ChannelsCellular) { if (settings.m_rxCellularChannel == LimeRFESettings::CellularChannel::CellularBand1) { m_rfeBoardState.channelIDRX = RFE_CID_CELL_BAND01; m_rfeBoardState.mode = RFE_MODE_TXRX; } else if (settings.m_rxCellularChannel == LimeRFESettings::CellularChannel::CellularBand2) { m_rfeBoardState.channelIDRX = RFE_CID_CELL_BAND02; m_rfeBoardState.mode = RFE_MODE_TXRX; } else if (settings.m_rxCellularChannel == LimeRFESettings::CellularChannel::CellularBand3) { m_rfeBoardState.channelIDRX = RFE_CID_CELL_BAND03; m_rfeBoardState.mode = RFE_MODE_TXRX; } else if (settings.m_rxCellularChannel == LimeRFESettings::CellularChannel::CellularBand38) { m_rfeBoardState.channelIDRX = RFE_CID_CELL_BAND38; } else if (settings.m_rxCellularChannel == LimeRFESettings::CellularChannel::CellularBand7) { m_rfeBoardState.channelIDRX = RFE_CID_CELL_BAND07; m_rfeBoardState.mode = RFE_MODE_TXRX; } m_rfeBoardState.selPortRX = RFE_PORT_1; m_rfeBoardState.selPortTX = RFE_PORT_1; m_rfeBoardState.channelIDTX = m_rfeBoardState.channelIDRX; } else { if (settings.m_rxChannels == LimeRFESettings::ChannelGroups::ChannelsWideband) { if (settings.m_rxWidebandChannel == LimeRFESettings::WidebandChannel::WidebandLow) { m_rfeBoardState.channelIDRX = RFE_CID_WB_1000; } else if (settings.m_rxWidebandChannel == LimeRFESettings::WidebandChannel::WidebandHigh) { m_rfeBoardState.channelIDRX = RFE_CID_WB_4000; } } else if (settings.m_rxChannels == LimeRFESettings::ChannelGroups::ChannelsHAM) { if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_30M) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_0030; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_50_70MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_0070; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_144_146MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_0145; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_220_225MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_0220; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_430_440MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_0435; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_902_928MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_0920; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_1240_1325MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_1280; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_2300_2450MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_2400; } else if (settings.m_rxHAMChannel == LimeRFESettings::HAMChannel::HAM_3300_3500MHz) { m_rfeBoardState.channelIDRX = RFE_CID_HAM_3500; } } if (settings.m_rxPort == LimeRFESettings::RxPort::RxPortJ3) { m_rfeBoardState.selPortRX = RFE_PORT_1; } else if (settings.m_rxPort == LimeRFESettings::RxPort::RxPortJ5) { m_rfeBoardState.selPortRX = RFE_PORT_3; } if (settings.m_txRxDriven) { m_rfeBoardState.channelIDTX = m_rfeBoardState.channelIDRX; } else { if (settings.m_txChannels == LimeRFESettings::ChannelGroups::ChannelsWideband) { if (settings.m_txWidebandChannel == LimeRFESettings::WidebandChannel::WidebandLow) { m_rfeBoardState.channelIDTX = RFE_CID_WB_1000; } else if (settings.m_txWidebandChannel == LimeRFESettings::WidebandChannel::WidebandHigh) { m_rfeBoardState.channelIDTX = RFE_CID_WB_4000; } } else if (settings.m_txChannels == LimeRFESettings::ChannelGroups::ChannelsHAM) { if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_30M) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_0030; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_50_70MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_0070; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_144_146MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_0145; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_220_225MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_0220; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_430_440MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_0435; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_902_928MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_0920; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_1240_1325MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_1280; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_2300_2450MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_2400; } else if (settings.m_txHAMChannel == LimeRFESettings::HAMChannel::HAM_3300_3500MHz) { m_rfeBoardState.channelIDTX = RFE_CID_HAM_3500; } } } if (settings.m_txPort == LimeRFESettings::TxPort::TxPortJ3) { m_rfeBoardState.selPortTX = RFE_PORT_1; } else if (settings.m_txPort == LimeRFESettings::TxPort::TxPortJ4) { m_rfeBoardState.selPortTX = RFE_PORT_2; } else if (settings.m_txPort == LimeRFESettings::TxPort::TxPortJ5) { m_rfeBoardState.selPortTX = RFE_PORT_3; } } m_rfeBoardState.attValue = settings.m_attenuationFactor > 7 ? 7 : settings.m_attenuationFactor; m_rfeBoardState.notchOnOff = settings.m_amfmNotch; m_rfeBoardState.enableSWR = settings.m_swrEnable ? RFE_SWR_ENABLE : RFE_SWR_DISABLE; if (settings.m_swrSource == LimeRFESettings::SWRSource::SWRExternal) { m_rfeBoardState.sourceSWR = RFE_SWR_SRC_EXT; } else if (settings.m_swrSource == LimeRFESettings::SWRSource::SWRCellular) { m_rfeBoardState.sourceSWR = RFE_SWR_SRC_CELL; } } void LimeRFE::stateToSettings(LimeRFESettings& settings, QList& settingsKeys) { if (m_rfeBoardState.channelIDRX == RFE_CID_CELL_BAND01) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_rxCellularChannel = LimeRFESettings::CellularChannel::CellularBand1; settingsKeys.append("rxChannels"); settingsKeys.append("rxCellularChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_CELL_BAND02) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_rxCellularChannel = LimeRFESettings::CellularChannel::CellularBand2; settingsKeys.append("rxChannels"); settingsKeys.append("rxCellularChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_CELL_BAND03) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_rxCellularChannel = LimeRFESettings::CellularChannel::CellularBand3; settingsKeys.append("rxChannels"); settingsKeys.append("rxCellularChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_CELL_BAND07) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_rxCellularChannel = LimeRFESettings::CellularChannel::CellularBand7; settingsKeys.append("rxChannels"); settingsKeys.append("rxCellularChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_CELL_BAND38) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_rxCellularChannel = LimeRFESettings::CellularChannel::CellularBand38; settingsKeys.append("rxChannels"); settingsKeys.append("rxCellularChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_WB_1000) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsWideband; settings.m_rxWidebandChannel = LimeRFESettings::WidebandChannel::WidebandLow; settingsKeys.append("rxChannels"); settingsKeys.append("rxWidebandChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_WB_4000) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsWideband; settings.m_rxWidebandChannel = LimeRFESettings::WidebandChannel::WidebandHigh; settingsKeys.append("rxChannels"); settingsKeys.append("rxWidebandChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_0030) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_30M; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_0070) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_50_70MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_0145) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_144_146MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_0220) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_220_225MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_0435) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_430_440MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_0920) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_902_928MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_1280) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_1240_1325MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_2400) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_2300_2450MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } else if (m_rfeBoardState.channelIDRX == RFE_CID_HAM_3500) { settings.m_rxChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_rxHAMChannel = LimeRFESettings::HAMChannel::HAM_3300_3500MHz; settingsKeys.append("rxChannels"); settingsKeys.append("rxHAMChannel"); } if (m_rfeBoardState.selPortRX == RFE_PORT_1) { settings.m_rxPort = LimeRFESettings::RxPort::RxPortJ3; } else if (m_rfeBoardState.selPortRX == RFE_PORT_3) { settings.m_rxPort = LimeRFESettings::RxPort::RxPortJ5; } settingsKeys.append("rxPort"); if (m_rfeBoardState.channelIDTX == RFE_CID_CELL_BAND01) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_txCellularChannel = LimeRFESettings::CellularChannel::CellularBand1; settingsKeys.append("txChannels"); settingsKeys.append("txCellularChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_CELL_BAND02) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_txCellularChannel = LimeRFESettings::CellularChannel::CellularBand2; settingsKeys.append("txChannels"); settingsKeys.append("txCellularChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_CELL_BAND03) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_txCellularChannel = LimeRFESettings::CellularChannel::CellularBand3; settingsKeys.append("txChannels"); settingsKeys.append("txCellularChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_CELL_BAND07) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_txCellularChannel = LimeRFESettings::CellularChannel::CellularBand7; settingsKeys.append("txChannels"); settingsKeys.append("txCellularChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_CELL_BAND38) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsCellular; settings.m_txCellularChannel = LimeRFESettings::CellularChannel::CellularBand38; settingsKeys.append("txChannels"); settingsKeys.append("txCellularChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_WB_1000) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsWideband; settings.m_txWidebandChannel = LimeRFESettings::WidebandChannel::WidebandLow; settingsKeys.append("txChannels"); settingsKeys.append("txWidebandChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_WB_4000) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsWideband; settings.m_txWidebandChannel = LimeRFESettings::WidebandChannel::WidebandHigh; settingsKeys.append("txChannels"); settingsKeys.append("txWidebandChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_0030) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_30M; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_0070) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_50_70MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_0145) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_144_146MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_0220) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_220_225MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_0435) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_430_440MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_0920) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_902_928MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_1280) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_1240_1325MHz; } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_2400) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_2300_2450MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } else if (m_rfeBoardState.channelIDTX == RFE_CID_HAM_3500) { settings.m_txChannels = LimeRFESettings::ChannelGroups::ChannelsHAM; settings.m_txHAMChannel = LimeRFESettings::HAMChannel::HAM_3300_3500MHz; settingsKeys.append("txChannels"); settingsKeys.append("txHAMChannel"); } if (m_rfeBoardState.selPortTX == RFE_PORT_1) { settings.m_txPort = LimeRFESettings::TxPort::TxPortJ3; } else if (m_rfeBoardState.selPortTX == RFE_PORT_2) { settings.m_txPort = LimeRFESettings::TxPort::TxPortJ4; } else if (m_rfeBoardState.selPortTX == RFE_PORT_3) { settings.m_txPort = LimeRFESettings::TxPort::TxPortJ5; } settingsKeys.append("txPort"); settingsKeys.append("attenuationFactor"); settingsKeys.append("amfmNotch"); settingsKeys.append("swrEnable"); settingsKeys.append("swrSource"); settings.m_attenuationFactor = m_rfeBoardState.attValue; settings.m_amfmNotch = m_rfeBoardState.notchOnOff == RFE_NOTCH_ON; settings.m_swrEnable = m_rfeBoardState.enableSWR == RFE_SWR_ENABLE; settings.m_swrSource = m_rfeBoardState.sourceSWR == RFE_SWR_SRC_CELL ? LimeRFESettings::SWRSource::SWRCellular : LimeRFESettings::SWRSource::SWRExternal; } void LimeRFE::networkManagerFinished(QNetworkReply *reply) { QNetworkReply::NetworkError replyError = reply->error(); if (replyError) { qWarning() << "LimeRFE::networkManagerFinished:" << " error(" << (int) replyError << "): " << replyError << ": " << reply->errorString(); } else { QString answer = reply->readAll(); answer.chop(1); // remove last \n qDebug("LimeRFE::networkManagerFinished: reply:\n%s", answer.toStdString().c_str()); } reply->deleteLater(); } int LimeRFE::webapiSettingsGet( SWGSDRangel::SWGFeatureSettings& response, QString& errorMessage) { (void) errorMessage; response.setLimeRfeSettings(new SWGSDRangel::SWGLimeRFESettings()); response.getLimeRfeSettings()->init(); webapiFormatFeatureSettings(response, m_settings); return 200; } int LimeRFE::webapiSettingsPutPatch( bool force, const QStringList& featureSettingsKeys, SWGSDRangel::SWGFeatureSettings& response, QString& errorMessage) { (void) errorMessage; LimeRFESettings settings = m_settings; webapiUpdateFeatureSettings(settings, featureSettingsKeys, response); MsgConfigureLimeRFE *msg = MsgConfigureLimeRFE::create(settings, featureSettingsKeys, force); m_inputMessageQueue.push(msg); qDebug("LimeRFE::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue); if (m_guiMessageQueue) // forward to GUI if any { MsgConfigureLimeRFE *msgToGUI = MsgConfigureLimeRFE::create(settings, featureSettingsKeys, true); m_guiMessageQueue->push(msgToGUI); } webapiFormatFeatureSettings(response, settings); return 200; } int LimeRFE::webapiReportGet( SWGSDRangel::SWGFeatureReport& response, QString& errorMessage) { response.setLimeRfeReport(new SWGSDRangel::SWGLimeRFEReport()); response.getLimeRfeReport()->init(); return webapiFormatFeatureReport(response, errorMessage); } int LimeRFE::webapiActionsPost( const QStringList& featureActionsKeys, SWGSDRangel::SWGFeatureActions& query, QString& errorMessage) { SWGSDRangel::SWGLimeRFEActions *swgLimeRFEActions = query.getLimeRfeActions(); if (swgLimeRFEActions) { bool unknownAction = true; int channel = -1; int deviceSetIndex = -1; if (featureActionsKeys.contains("selectChannel")) { channel = swgLimeRFEActions->getSelectChannel(); unknownAction = false; } if (featureActionsKeys.contains("deviceSetIndex")) { deviceSetIndex = swgLimeRFEActions->getDeviceSetIndex(); unknownAction = false; } if (featureActionsKeys.contains("openCloseDevice") && (swgLimeRFEActions->getOpenCloseDevice() != 0)) { int rc = openDevice(m_settings.m_devicePath.toStdString()); unknownAction = false; if (rc != 0) { errorMessage = QString("Open %1: %2").arg(m_settings.m_devicePath).arg(getError(rc).c_str()); return 500; } } if (featureActionsKeys.contains("getState") && (swgLimeRFEActions->getGetState() != 0)) { int rc = getState(); unknownAction = false; if (rc != 0) { errorMessage = QString("Get state %1: %2").arg(m_settings.m_devicePath).arg(getError(rc).c_str()); return 500; } } if (featureActionsKeys.contains("fromToSettings") && (swgLimeRFEActions->getFromToSettings() != 0)) { settingsToState(m_settings); unknownAction = false; } if ((channel >= 0) && featureActionsKeys.contains("switchChannel")) { if (channel == 0) { bool on = swgLimeRFEActions->getSwitchChannel() != 0; int rc = setRx(on); if (rc != 0) { errorMessage = QString("Set Rx %1 %2: %3").arg(m_settings.m_devicePath).arg(on).arg(getError(rc).c_str()); return 500; } if (getMessageQueueToGUI()) { MsgReportSetRx *msg = MsgReportSetRx::create(on); getMessageQueueToGUI()->push(msg); } } else { bool on = swgLimeRFEActions->getSwitchChannel() != 0; int rc = setTx(on); if (rc != 0) { errorMessage = QString("Set Tx %1 %2: %3").arg(m_settings.m_devicePath).arg(on).arg(getError(rc).c_str()); return 500; } if (getMessageQueueToGUI()) { MsgReportSetTx *msg = MsgReportSetTx::create(on); getMessageQueueToGUI()->push(msg); } } if (deviceSetIndex >= 0) { turnDevice(deviceSetIndex, swgLimeRFEActions->getSwitchChannel() != 0); } unknownAction = false; } if (featureActionsKeys.contains("fromToSettings") && (swgLimeRFEActions->getFromToSettings() == 0)) { QList settingsKeys; stateToSettings(m_settings, settingsKeys); unknownAction = false; if (getMessageQueueToGUI()) { MsgConfigureLimeRFE *msg = MsgConfigureLimeRFE::create(m_settings, settingsKeys, false); getMessageQueueToGUI()->push(msg); } } if (featureActionsKeys.contains("openCloseDevice") && (swgLimeRFEActions->getOpenCloseDevice() == 0)) { closeDevice(); unknownAction = false; } if (featureActionsKeys.contains("setRx")) { int rc = setRx(swgLimeRFEActions->getSetRx() != 0); unknownAction = false; if (rc == 0) { if (getMessageQueueToGUI()) { MsgReportSetRx *msg = MsgReportSetRx::create(swgLimeRFEActions->getSetRx() != 0); getMessageQueueToGUI()->push(msg); } } else { errorMessage = QString("Cannot switch Rx"); return 500; } } if (featureActionsKeys.contains("setTx")) { int rc = setTx(swgLimeRFEActions->getSetTx() != 0); unknownAction = false; if (rc == 0) { if (getMessageQueueToGUI()) { MsgReportSetTx *msg = MsgReportSetTx::create(swgLimeRFEActions->getSetTx() != 0); getMessageQueueToGUI()->push(msg); } } else { errorMessage = QString("Cannot switch Tx"); return 500; } } if (unknownAction) { errorMessage = "Unknown action"; return 400; } else { return 202; } } else { errorMessage = "Missing SimplePTTActions in query"; return 400; } } void LimeRFE::webapiFormatFeatureSettings( SWGSDRangel::SWGFeatureSettings& response, const LimeRFESettings& settings) { if (response.getLimeRfeSettings()->getTitle()) { *response.getLimeRfeSettings()->getTitle() = settings.m_title; } else { response.getLimeRfeSettings()->setTitle(new QString(settings.m_title)); } response.getLimeRfeSettings()->setRgbColor(settings.m_rgbColor); response.getLimeRfeSettings()->setDevicePath(new QString(settings.m_devicePath)); response.getLimeRfeSettings()->setRxChannels((int) settings.m_rxChannels); response.getLimeRfeSettings()->setRxWidebandChannel((int) settings.m_rxWidebandChannel); response.getLimeRfeSettings()->setRxHamChannel((int) settings.m_rxHAMChannel); response.getLimeRfeSettings()->setRxCellularChannel((int) settings.m_rxCellularChannel); response.getLimeRfeSettings()->setRxPort((int) settings.m_rxPort); response.getLimeRfeSettings()->setAmfmNotch(settings.m_amfmNotch ? 1 : 0); response.getLimeRfeSettings()->setAttenuationFactor(settings.m_attenuationFactor); response.getLimeRfeSettings()->setTxChannels((int) settings.m_txChannels); response.getLimeRfeSettings()->setTxWidebandChannel((int) settings.m_txWidebandChannel); response.getLimeRfeSettings()->setTxHamChannel((int) settings.m_txHAMChannel); response.getLimeRfeSettings()->setTxCellularChannel((int) settings.m_txCellularChannel); response.getLimeRfeSettings()->setTxPort((int) settings.m_txPort); response.getLimeRfeSettings()->setSwrEnable(settings.m_swrEnable ? 1 : 0); response.getLimeRfeSettings()->setSwrSource((int) settings.m_swrSource); response.getLimeRfeSettings()->setTxRxDriven(settings.m_txRxDriven ? 1 : 0); response.getLimeRfeSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getLimeRfeSettings()->getReverseApiAddress()) { *response.getLimeRfeSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; } else { response.getLimeRfeSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); } response.getLimeRfeSettings()->setReverseApiPort(settings.m_reverseAPIPort); response.getLimeRfeSettings()->setReverseApiFeatureSetIndex(settings.m_reverseAPIFeatureSetIndex); response.getLimeRfeSettings()->setReverseApiFeatureIndex(settings.m_reverseAPIFeatureIndex); if (settings.m_rollupState) { if (response.getLimeRfeSettings()->getRollupState()) { settings.m_rollupState->formatTo(response.getLimeRfeSettings()->getRollupState()); } else { SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState(); settings.m_rollupState->formatTo(swgRollupState); response.getLimeRfeSettings()->setRollupState(swgRollupState); } } } void LimeRFE::webapiUpdateFeatureSettings( LimeRFESettings& settings, const QStringList& featureSettingsKeys, SWGSDRangel::SWGFeatureSettings& response) { if (featureSettingsKeys.contains("title")) { settings.m_title = *response.getLimeRfeSettings()->getTitle(); } if (featureSettingsKeys.contains("rgbColor")) { settings.m_rgbColor = response.getLimeRfeSettings()->getRgbColor(); } if (featureSettingsKeys.contains("devicePath")) { settings.m_devicePath = *response.getLimeRfeSettings()->getDevicePath(); } if (featureSettingsKeys.contains("rxChannels")) { settings.m_rxChannels = (LimeRFESettings::ChannelGroups) response.getLimeRfeSettings()->getRxChannels(); } if (featureSettingsKeys.contains("rxWidebandChannel")) { settings.m_rxWidebandChannel = (LimeRFESettings::WidebandChannel) response.getLimeRfeSettings()->getRxWidebandChannel(); } if (featureSettingsKeys.contains("rxHAMChannel")) { settings.m_rxHAMChannel = (LimeRFESettings::HAMChannel) response.getLimeRfeSettings()->getRxHamChannel(); } if (featureSettingsKeys.contains("rxCellularChannel")) { settings.m_rxCellularChannel = (LimeRFESettings::CellularChannel) response.getLimeRfeSettings()->getRxCellularChannel(); } if (featureSettingsKeys.contains("rxPort")) { settings.m_rxPort = (LimeRFESettings::RxPort) response.getLimeRfeSettings()->getRxPort(); } if (featureSettingsKeys.contains("amfmNotch")) { settings.m_amfmNotch = response.getLimeRfeSettings()->getAmfmNotch() != 0; } if (featureSettingsKeys.contains("attenuationFactor")) { settings.m_attenuationFactor = response.getLimeRfeSettings()->getAttenuationFactor(); } if (featureSettingsKeys.contains("txChannels")) { settings.m_txChannels = (LimeRFESettings::ChannelGroups) response.getLimeRfeSettings()->getTxChannels(); } if (featureSettingsKeys.contains("txWidebandChannel")) { settings.m_txWidebandChannel = (LimeRFESettings::WidebandChannel) response.getLimeRfeSettings()->getTxWidebandChannel(); } if (featureSettingsKeys.contains("txHAMChannel")) { settings.m_txHAMChannel = (LimeRFESettings::HAMChannel) response.getLimeRfeSettings()->getTxHamChannel(); } if (featureSettingsKeys.contains("txCellularChannel")) { settings.m_txCellularChannel = (LimeRFESettings::CellularChannel) response.getLimeRfeSettings()->getTxCellularChannel(); } if (featureSettingsKeys.contains("txPort")) { settings.m_txPort = (LimeRFESettings::TxPort) response.getLimeRfeSettings()->getTxPort(); } if (featureSettingsKeys.contains("swrEnable")) { settings.m_swrEnable = response.getLimeRfeSettings()->getSwrEnable() != 0; } if (featureSettingsKeys.contains("swrSource")) { settings.m_swrSource = (LimeRFESettings::SWRSource) response.getLimeRfeSettings()->getSwrSource(); } if (featureSettingsKeys.contains("txRxDriven")) { settings.m_txRxDriven = response.getLimeRfeSettings()->getTxRxDriven() != 0; } if (featureSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getLimeRfeSettings()->getUseReverseApi() != 0; } if (featureSettingsKeys.contains("reverseAPIAddress")) { settings.m_reverseAPIAddress = *response.getLimeRfeSettings()->getReverseApiAddress(); } if (featureSettingsKeys.contains("reverseAPIPort")) { settings.m_reverseAPIPort = response.getLimeRfeSettings()->getReverseApiPort(); } if (featureSettingsKeys.contains("reverseAPIFeatureSetIndex")) { settings.m_reverseAPIFeatureSetIndex = response.getLimeRfeSettings()->getReverseApiFeatureSetIndex(); } if (featureSettingsKeys.contains("reverseAPIFeatureIndex")) { settings.m_reverseAPIFeatureIndex = response.getLimeRfeSettings()->getReverseApiFeatureIndex(); } if (settings.m_rollupState && featureSettingsKeys.contains("rollupState")) { settings.m_rollupState->updateFrom(featureSettingsKeys, response.getLimeRfeSettings()->getRollupState()); } } int LimeRFE::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response, QString& errorMessage) { response.getLimeRfeReport()->setRxOn(m_rxOn ? 1 : 0); response.getLimeRfeReport()->setTxOn(m_txOn ? 1 : 0); int fwdPower; int rc = getFwdPower(fwdPower); if (rc != 0) { errorMessage = QString("Error getting forward power from LimeRFE device %1: %2") .arg(m_settings.m_devicePath).arg(getError(rc).c_str()); return 500; } int refPower; rc = getRefPower(refPower); if (rc != 0) { errorMessage = QString("Error getting reflected power from LimeRFE device %1: %2") .arg(m_settings.m_devicePath).arg(getError(rc).c_str()); return 500; } response.getLimeRfeReport()->setForwardPower(fwdPower); response.getLimeRfeReport()->setReflectedPower(refPower); return 200; }