1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-05 07:24:44 -04:00

Meshtastic: some Sonar fixes

This commit is contained in:
f4exb
2026-03-27 21:17:46 +01:00
parent 66dfc3a0c8
commit efa232db88
12 changed files with 292 additions and 398 deletions
@@ -262,10 +262,10 @@ void MeshtasticDemod::applyPipelineRuntimeSettings(PipelineRuntime& runtime, con
if (runtime.decoder)
{
runtime.decoder->setCodingScheme(settings.m_codingScheme);
runtime.decoder->setCodingScheme(MeshtasticDemodSettings::m_codingScheme);
runtime.decoder->setNbSymbolBits(settings.m_spreadFactor, settings.m_deBits);
runtime.decoder->setLoRaHasHeader(settings.m_hasHeader);
runtime.decoder->setLoRaHasCRC(settings.m_hasCRC);
runtime.decoder->setLoRaHasHeader(MeshtasticDemodSettings::m_hasHeader);
runtime.decoder->setLoRaHasCRC(MeshtasticDemodSettings::m_hasCRC);
runtime.decoder->setLoRaParityBits(settings.m_nbParityBits);
runtime.decoder->setLoRaPacketLength(settings.m_packetLength);
runtime.decoder->setLoRaBandwidth(MeshtasticDemodSettings::bandwidths[settings.m_bandwidthIndex]);
@@ -512,12 +512,10 @@ void MeshtasticDemod::start()
}
qDebug() << "MeshtasticDemod::start";
m_pipelineConfigs.push_back(PipelineConfig());
m_pipelineConfigs.emplace_back();
m_currentPipelineId = 0;
makePipelineConfigFromSettings(m_currentPipelineId, m_pipelineConfigs.back(), m_settings);
startPipelines(m_pipelineConfigs);
// const std::vector<PipelineConfig> configs = buildPipelineConfigs(m_settings);
// startPipelines(configs);
SpectrumSettings spectrumSettings = m_spectrumVis.getSettings();
spectrumSettings.m_ssb = true;
@@ -553,7 +551,7 @@ bool MeshtasticDemod::handleMessage(const Message& cmd)
else if (MsgSetExtraPipelineSettings::match(cmd))
{
qDebug() << "MeshtasticDemod::handleMessage: MsgSetExtraPipelineSettings";
const MsgSetExtraPipelineSettings& msg = static_cast<const MsgSetExtraPipelineSettings&>(cmd);
const auto& msg = static_cast<const MsgSetExtraPipelineSettings&>(cmd);
applyExtraPipelineSettings(msg.getSettingsList(), false);
return true;
}
@@ -567,132 +565,112 @@ bool MeshtasticDemod::handleMessage(const Message& cmd)
m_lastMsgSyncWord = msg.getSyncWord();
m_lastMsgTimestamp = msg.getMsgTimestamp();
if (m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa)
m_lastMsgBytes = msg.getBytes();
m_lastMsgPacketLength = msg.getPacketSize();
m_lastMsgNbParityBits = msg.getNbParityBits();
m_lastMsgHasCRC = msg.getHasCRC();
m_lastMsgNbSymbols = msg.getNbSymbols();
m_lastMsgNbCodewords = msg.getNbCodewords();
m_lastMsgEarlyEOM = msg.getEarlyEOM();
m_lastMsgHeaderCRC = msg.getHeaderCRCStatus();
m_lastMsgHeaderParityStatus = msg.getHeaderParityStatus();
m_lastMsgPayloadCRC = msg.getPayloadCRCStatus();
m_lastMsgPayloadParityStatus = msg.getPayloadParityStatus();
m_lastMsgPipelineName = msg.getPipelineName();
m_lastFrameType = QStringLiteral("LORA_FRAME");
QByteArray bytesCopy(m_lastMsgBytes);
bytesCopy.truncate(m_lastMsgPacketLength);
bytesCopy.replace('\0', " ");
m_lastMsgString = QString(bytesCopy.toStdString().c_str());
if (m_settings.m_sendViaUDP)
{
m_lastMsgBytes = msg.getBytes();
m_lastMsgPacketLength = msg.getPacketSize();
m_lastMsgNbParityBits = msg.getNbParityBits();
m_lastMsgHasCRC = msg.getHasCRC();
m_lastMsgNbSymbols = msg.getNbSymbols();
m_lastMsgNbCodewords = msg.getNbCodewords();
m_lastMsgEarlyEOM = msg.getEarlyEOM();
m_lastMsgHeaderCRC = msg.getHeaderCRCStatus();
m_lastMsgHeaderParityStatus = msg.getHeaderParityStatus();
m_lastMsgPayloadCRC = msg.getPayloadCRCStatus();
m_lastMsgPayloadParityStatus = msg.getPayloadParityStatus();
m_lastMsgPipelineName = msg.getPipelineName();
m_lastFrameType = QStringLiteral("LORA_FRAME");
uint8_t *bytes = reinterpret_cast<uint8_t*>(m_lastMsgBytes.data());
m_udpSink.writeUnbuffered(bytes, m_lastMsgPacketLength);
}
QByteArray bytesCopy(m_lastMsgBytes);
bytesCopy.truncate(m_lastMsgPacketLength);
bytesCopy.replace('\0', " ");
m_lastMsgString = QString(bytesCopy.toStdString().c_str());
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new MeshtasticDemodMsg::MsgReportDecodeBytes(msg)); // make a copy
}
if (m_settings.m_sendViaUDP)
modemmeshtastic::DecodeResult meshResult;
if (modemmeshtastic::Packet::decodeFrame(m_lastMsgBytes, meshResult, m_settings.m_meshtasticKeySpecList))
{
m_lastMsgString = meshResult.summary;
for (const modemmeshtastic::DecodeResult::Field& field : meshResult.fields)
{
uint8_t *bytes = reinterpret_cast<uint8_t*>(m_lastMsgBytes.data());
m_udpSink.writeUnbuffered(bytes, m_lastMsgPacketLength);
}
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new MeshtasticDemodMsg::MsgReportDecodeBytes(msg)); // make a copy
}
modemmeshtastic::DecodeResult meshResult;
if (modemmeshtastic::Packet::decodeFrame(m_lastMsgBytes, meshResult, m_settings.m_meshtasticKeySpecList))
{
m_lastMsgString = meshResult.summary;
for (const modemmeshtastic::DecodeResult::Field& field : meshResult.fields)
if (field.path == QStringLiteral("data.port_name"))
{
if (field.path == QStringLiteral("data.port_name"))
{
m_lastFrameType = field.value;
break;
}
}
qInfo() << "MeshtasticDemod::handleMessage:" << meshResult.summary;
if (meshResult.dataDecoded && getMessageQueueToGUI())
{
MeshtasticDemodMsg::MsgReportDecodeString *meshMsg = MeshtasticDemodMsg::MsgReportDecodeString::create(meshResult.summary);
meshMsg->setFrameId(msg.getFrameId());
meshMsg->setSyncWord(msg.getSyncWord());
meshMsg->setSignalDb(msg.getSingalDb());
meshMsg->setNoiseDb(msg.getNoiseDb());
meshMsg->setMsgTimestamp(msg.getMsgTimestamp());
meshMsg->setPipelineMetadata(msg.getPipelineId(), msg.getPipelineName(), msg.getPipelinePreset());
QVector<QPair<QString, QString>> structuredFields;
structuredFields.reserve(meshResult.fields.size());
for (const modemmeshtastic::DecodeResult::Field& field : meshResult.fields) {
structuredFields.append(qMakePair(field.path, field.value));
}
meshMsg->setStructuredFields(structuredFields);
getMessageQueueToGUI()->push(meshMsg);
m_lastFrameType = field.value;
break;
}
}
// Is this an APRS packet?
// As per: https://github.com/oe3cjb/TTGO-T-Beam-LoRa-APRS/blob/master/lib/BG_RF95/BG_RF95.cpp
// There is a 3 byte header for LoRa APRS packets. Addressing follows in ASCII: srccall>dst:
int colonIdx = m_lastMsgBytes.indexOf(':');
int greaterThanIdx = m_lastMsgBytes.indexOf('>');
if ( (m_lastMsgBytes[0] == '<')
&& (greaterThanIdx != -1)
&& (colonIdx != -1)
&& ((m_lastMsgHasCRC && m_lastMsgPayloadCRC) || !m_lastMsgHasCRC)
)
qInfo() << "MeshtasticDemod::handleMessage:" << meshResult.summary;
if (meshResult.dataDecoded && getMessageQueueToGUI())
{
QByteArray packet;
MeshtasticDemodMsg::MsgReportDecodeString *meshMsg = MeshtasticDemodMsg::MsgReportDecodeString::create(meshResult.summary);
meshMsg->setFrameId(msg.getFrameId());
meshMsg->setSyncWord(msg.getSyncWord());
meshMsg->setSignalDb(msg.getSingalDb());
meshMsg->setNoiseDb(msg.getNoiseDb());
meshMsg->setMsgTimestamp(msg.getMsgTimestamp());
meshMsg->setPipelineMetadata(msg.getPipelineId(), msg.getPipelineName(), msg.getPipelinePreset());
QVector<QPair<QString, QString>> structuredFields;
structuredFields.reserve(meshResult.fields.size());
// Extract addresses
const char *d = m_lastMsgBytes.data();
QString srcString = QString::fromLatin1(d + 3, greaterThanIdx - 3);
QString dstString = QString::fromLatin1(d + greaterThanIdx + 1, colonIdx - greaterThanIdx - 1);
// Convert to AX.25 format
packet.append(AX25Packet::encodeAddress(dstString));
packet.append(AX25Packet::encodeAddress(srcString, 1));
packet.append(3);
packet.append(-16); // 0xf0
packet.append(m_lastMsgBytes.mid(colonIdx+1));
if (!m_lastMsgHasCRC)
{
packet.append((char)0); // dummy crc
packet.append((char)0);
for (const modemmeshtastic::DecodeResult::Field& field : meshResult.fields) {
structuredFields.append(qMakePair(field.path, field.value));
}
// Forward to APRS and other packet features
QList<ObjectPipe*> packetsPipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "packets", packetsPipes);
meshMsg->setStructuredFields(structuredFields);
getMessageQueueToGUI()->push(meshMsg);
}
}
for (const auto& pipe : packetsPipes)
{
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
MainCore::MsgPacket *msg = MainCore::MsgPacket::create(this, packet, QDateTime::currentDateTime());
messageQueue->push(msg);
}
// Is this an APRS packet?
// As per: https://github.com/oe3cjb/TTGO-T-Beam-LoRa-APRS/blob/master/lib/BG_RF95/BG_RF95.cpp
// There is a 3 byte header for LoRa APRS packets. Addressing follows in ASCII: srccall>dst:
int colonIdx = m_lastMsgBytes.indexOf(':');
int greaterThanIdx = m_lastMsgBytes.indexOf('>');
if ( (m_lastMsgBytes[0] == '<')
&& (greaterThanIdx != -1)
&& (colonIdx != -1)
&& ((m_lastMsgHasCRC && m_lastMsgPayloadCRC) || !m_lastMsgHasCRC)
)
{
QByteArray packet;
// Extract addresses
const char *d = m_lastMsgBytes.data();
QString srcString = QString::fromLatin1(d + 3, greaterThanIdx - 3);
QString dstString = QString::fromLatin1(d + greaterThanIdx + 1, colonIdx - greaterThanIdx - 1);
// Convert to AX.25 format
packet.append(AX25Packet::encodeAddress(dstString));
packet.append(AX25Packet::encodeAddress(srcString, 1));
packet.append(3);
packet.append(-16); // 0xf0
packet.append(m_lastMsgBytes.mid(colonIdx+1));
if (!m_lastMsgHasCRC)
{
packet.append((char)0); // dummy crc
packet.append((char)0);
}
// In explicit-header LoRa mode, frame length is already derived from header
// and may legitimately vary across packets. Auto-clamping nbSymbolsMax to the
// first short frame breaks subsequent longer frames.
if (m_settings.m_autoNbSymbolsMax
&& !((m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa) && m_settings.m_hasHeader))
{
MeshtasticDemodSettings settings = m_settings;
settings.m_nbSymbolsMax = m_lastMsgNbSymbols;
applySettings(settings);
// Forward to APRS and other packet features
QList<ObjectPipe*> packetsPipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "packets", packetsPipes);
if (getMessageQueueToGUI()) // forward to GUI if any
{
MsgConfigureMeshtasticDemod *msgToGUI = MsgConfigureMeshtasticDemod::create(settings, false);
getMessageQueueToGUI()->push(msgToGUI);
}
for (const auto& pipe : packetsPipes)
{
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
MainCore::MsgPacket *msg = MainCore::MsgPacket::create(this, packet, QDateTime::currentDateTime());
messageQueue->push(msg);
}
}
@@ -799,12 +777,12 @@ void MeshtasticDemod::applySettings(MeshtasticDemodSettings settings, bool force
<< " m_bandwidthIndex: " << settings.m_bandwidthIndex
<< " m_spreadFactor: " << settings.m_spreadFactor
<< " m_deBits: " << settings.m_deBits
<< " m_codingScheme: " << settings.m_codingScheme
<< " m_hasHeader: " << settings.m_hasHeader
<< " m_hasCRC: " << settings.m_hasCRC
<< " m_codingScheme: " << MeshtasticDemodSettings::m_codingScheme
<< " m_hasHeader: " << MeshtasticDemodSettings::m_hasHeader
<< " m_hasCRC: " << MeshtasticDemodSettings::m_hasCRC
<< " m_nbParityBits: " << settings.m_nbParityBits
<< " m_packetLength: " << settings.m_packetLength
<< " m_autoNbSymbolsMax: " << settings.m_autoNbSymbolsMax
<< " m_autoNbSymbolsMax: " << MeshtasticDemodSettings::m_autoNbSymbolsMax
<< " m_sendViaUDP: " << settings.m_sendViaUDP
<< " m_udpAddress: " << settings.m_udpAddress
<< " m_udpPort: " << settings.m_udpPort
@@ -917,7 +895,6 @@ void MeshtasticDemod::applySettings(MeshtasticDemodSettings settings, bool force
// settings so that m_settings and the GUI stay in sync with what was actually applied.
// Skip for USER preset: those parameters are controlled entirely by the user via the GUI.
if (m_running && !m_pipelineConfigs.empty() &&
settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa &&
settings.m_meshtasticPresetName.trimmed().compare("USER", Qt::CaseInsensitive) != 0)
{
const MeshtasticDemodSettings& derived = m_pipelineConfigs[0].settings;
@@ -932,7 +909,7 @@ void MeshtasticDemod::applySettings(MeshtasticDemodSettings settings, bool force
if (bwChanged)
{
DSPSignalNotification *bwMsg = new DSPSignalNotification(
auto *bwMsg = new DSPSignalNotification(
MeshtasticDemodSettings::bandwidths[settings.m_bandwidthIndex], 0);
m_spectrumVis.getInputMessageQueue()->push(bwMsg);
}
@@ -59,7 +59,7 @@ public:
}
private:
QVector<MeshtasticDemodSettings> m_settingsList;
MsgSetExtraPipelineSettings(const QVector<MeshtasticDemodSettings>& settingsList) :
explicit MsgSetExtraPipelineSettings(const QVector<MeshtasticDemodSettings>& settingsList) :
Message(), m_settingsList(settingsList)
{ }
};
@@ -201,20 +201,13 @@ bool MeshtasticDemodGUI::handleMessage(const Message& message)
// Populates the upper unstructured view including raw bytes in hex
const MeshtasticDemodMsg::MsgReportDecodeBytes& msg = (MeshtasticDemodMsg::MsgReportDecodeBytes&) message;
handleMeshAutoLockObservation(msg);
if (m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa) {
showLoRaMessage(message);
}
showLoRaMessage(message);
return true;
}
else if (MeshtasticDemodMsg::MsgReportDecodeString::match(message))
{
// Populates the lower structured tree view with decoded fields
if ((m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa)) {
showTextMessage(message);
}
showTextMessage(message);
return true;
}
else if (MeshtasticDemod::MsgConfigureMeshtasticDemod::match(message))
@@ -465,18 +458,7 @@ void MeshtasticDemodGUI::startMeshAutoLock()
return;
}
if (m_settings.m_codingScheme != MeshtasticDemodSettings::CodingLoRa)
{
displayStatus(tr("MESH LOCK|switch decoder scheme to LoRa before auto-lock"));
ui->meshAutoLock->blockSignals(true);
ui->meshAutoLock->setChecked(false);
ui->meshAutoLock->blockSignals(false);
return;
}
const int bandwidthHz = MeshtasticDemodSettings::bandwidths[m_settings.m_bandwidthIndex];
const int bandwidthHz = MeshtasticDemodSettings::bandwidths[m_settings.m_bandwidthIndex];
const int sf = std::max(1, m_settings.m_spreadFactor);
const int symbolBins = 1 << std::min(15, sf);
const int stepHz = std::max(100, bandwidthHz / symbolBins);
@@ -1064,7 +1046,7 @@ void MeshtasticDemodGUI::pushExtraPipelineSettingsToDemod()
void MeshtasticDemodGUI::on_conf_valueChanged(int value)
{
const int maxFocus = static_cast<int>(m_extraPipelineSettings.size());
const auto maxFocus = static_cast<int>(m_extraPipelineSettings.size());
const int newFocus = std::clamp(value, 0, maxFocus);
if (newFocus == m_focusedPipelineIndex) {
@@ -1928,7 +1910,7 @@ void MeshtasticDemodGUI::applySettings(bool force)
void MeshtasticDemodGUI::updateControlAvailabilityHints()
{
const bool loRaMode = m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa;
const bool explicitHeaderMode = loRaMode && m_settings.m_hasHeader;
const bool explicitHeaderMode = loRaMode && MeshtasticDemodSettings::m_hasHeader;
const QString fftWindowEnabledTip = tr("FFT window used by the de-chirping stage.");
const QString fftWindowDisabledTip = tr("Ignored in LoRa mode. The LoRa demodulator uses a fixed internal FFT window.");
@@ -1969,7 +1951,7 @@ void MeshtasticDemodGUI::updateControlAvailabilityHints()
setSliderDimmed(ui->deBits, !isUserPreset);
setSliderDimmed(ui->preambleChirps, !isUserPreset);
const bool headerControlsEnabled = !m_settings.m_hasHeader;
const bool headerControlsEnabled = !MeshtasticDemodSettings::m_hasHeader;
ui->fecParity->setEnabled(headerControlsEnabled);
ui->packetLength->setEnabled(headerControlsEnabled);
@@ -2029,15 +2011,6 @@ void MeshtasticDemodGUI::displaySettings()
ui->udpSend->setChecked(m_settings.m_sendViaUDP);
ui->udpAddress->setText(m_settings.m_udpAddress);
ui->udpPort->setText(tr("%1").arg(m_settings.m_udpPort));
if (!m_settings.m_hasHeader)
{
ui->fecParity->setValue(m_settings.m_nbParityBits);
ui->fecParityText->setText(tr("%1").arg(m_settings.m_nbParityBits));
ui->packetLength->setValue(m_settings.m_packetLength);
ui->spectrumGUI->setFFTSize(m_settings.m_spreadFactor);
}
ui->invertRamps->setChecked(s.m_invertRamps);
displaySquelch();
@@ -2116,19 +2089,19 @@ void MeshtasticDemodGUI::displaySquelch()
void MeshtasticDemodGUI::displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus)
{
if (m_settings.m_hasHeader && (headerParityStatus == (int) MeshtasticDemodSettings::ParityOK)) {
if (MeshtasticDemodSettings::m_hasHeader && (headerParityStatus == (int) MeshtasticDemodSettings::ParityOK)) {
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : green; }");
} else if (m_settings.m_hasHeader && (headerParityStatus == (int) MeshtasticDemodSettings::ParityError)) {
} else if (MeshtasticDemodSettings::m_hasHeader && (headerParityStatus == (int) MeshtasticDemodSettings::ParityError)) {
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : red; }");
} else if (m_settings.m_hasHeader && (headerParityStatus == (int) MeshtasticDemodSettings::ParityCorrected)) {
} else if (MeshtasticDemodSettings::m_hasHeader && (headerParityStatus == (int) MeshtasticDemodSettings::ParityCorrected)) {
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : blue; }");
} else {
ui->headerHammingStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
}
if (m_settings.m_hasHeader && headerCRCStatus) {
if (MeshtasticDemodSettings::m_hasHeader && headerCRCStatus) {
ui->headerCRCStatus->setStyleSheet("QLabel { background-color : green; }");
} else if (m_settings.m_hasHeader && !headerCRCStatus) {
} else if (MeshtasticDemodSettings::m_hasHeader && !headerCRCStatus) {
ui->headerCRCStatus->setStyleSheet("QLabel { background-color : red; }");
} else {
ui->headerCRCStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
@@ -3142,18 +3115,11 @@ void MeshtasticDemodGUI::showLoRaMessage(const Message& message)
ui->snrText->setText(tr("%1").arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1));
unsigned int packetLength;
if (m_settings.m_hasHeader)
{
ui->fecParity->setValue(msg.getNbParityBits());
ui->fecParityText->setText(tr("%1").arg(msg.getNbParityBits()));
ui->packetLength->setValue(msg.getPacketSize());
ui->packetLengthText->setText(tr("%1").arg(msg.getPacketSize()));
packetLength = msg.getPacketSize();
}
else
{
packetLength = m_settings.m_packetLength;
}
ui->fecParity->setValue(msg.getNbParityBits());
ui->fecParityText->setText(tr("%1").arg(msg.getNbParityBits()));
ui->packetLength->setValue(msg.getPacketSize());
ui->packetLengthText->setText(tr("%1").arg(msg.getPacketSize()));
packetLength = msg.getPacketSize();
QDateTime dt = QDateTime::currentDateTime();
QString dateStr = dt.toString("HH:mm:ss");
@@ -3257,7 +3223,7 @@ void MeshtasticDemodGUI::showTextMessage(const Message& message)
const QString messageBaseKey = buildPipelineMessageBaseKey(pipelineId, msg.getFrameId(), msg.getMsgTimestamp());
QString messageKey = resolvePipelineMessageKey(messageBaseKey);
if (messageKey.isEmpty() && (m_settings.m_codingScheme != MeshtasticDemodSettings::CodingLoRa)) {
if (messageKey.isEmpty()) {
messageKey = allocatePipelineMessageKey(messageBaseKey);
}
@@ -34,22 +34,6 @@
#include "meshtasticdemoddecoderlora.h"
#include "meshtasticdemodsink.h"
// namespace { // For [LOOPBACK] debug only
// QString symbolPreview(const std::vector<unsigned short>& symbols, unsigned int maxCount)
// {
// QStringList parts;
// const unsigned int count = std::min<unsigned int>(maxCount, static_cast<unsigned int>(symbols.size()));
// for (unsigned int i = 0; i < count; i++) {
// parts.append(QString::number(symbols[i]));
// }
// return parts.join(",");
// }
// } // namespace
MeshtasticDemodSink::MeshtasticDemodSink() :
m_decodeMsg(nullptr),
m_decoderMsgQueue(nullptr),
@@ -209,7 +193,7 @@ void MeshtasticDemodSink::feed(const SampleVector::const_iterator& begin, const
if (m_interpolator.decimate(&m_sampleDistanceRemain, c, &ci))
{
if (m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa)
if (MeshtasticDemodSettings::m_codingScheme == MeshtasticDemodSettings::CodingLoRa)
{
processSampleLoRa(ci);
}
@@ -443,7 +427,7 @@ bool MeshtasticDemodSink::sendLoRaHeaderProbe()
const std::vector<unsigned short>& symbols = m_decodeMsg->getSymbols();
if (symbols.size() < 8U || !m_settings.m_hasHeader) {
if (symbols.size() < 8U) {
return false;
}
@@ -462,21 +446,11 @@ bool MeshtasticDemodSink::sendLoRaHeaderProbe()
headerNbSymbolBits,
m_settings.m_spreadFactor,
static_cast<unsigned int>(std::max(1, m_bandwidth)),
m_settings.m_hasHeader,
m_settings.m_hasCRC
MeshtasticDemodSettings::m_hasHeader,
MeshtasticDemodSettings::m_hasCRC
);
m_decoderMsgQueue->push(probe);
// qDebug().noquote() << QString(
// "[LOOPBACK][RX] header_probe token=%1 frameId=%2 sf=%3 de=%4 bw=%5 headerSymbols=[%6]"
// )
// .arg(m_loRaFrameId)
// .arg(m_loRaFrameId)
// .arg(m_settings.m_spreadFactor)
// .arg(m_settings.m_deBits)
// .arg(m_bandwidth)
// .arg(symbolPreview(headerSymbols, 8U));
return true;
}
@@ -495,8 +469,7 @@ void MeshtasticDemodSink::applyLoRaHeaderFeedback(
(void) ldro;
(void) headerParityStatus;
if ((m_settings.m_codingScheme != MeshtasticDemodSettings::CodingLoRa)
|| (m_loRaState != LoRaStateSFOCompensation))
if (m_loRaState != LoRaStateSFOCompensation)
{
return;
}
@@ -525,14 +498,6 @@ void MeshtasticDemodSink::applyLoRaHeaderFeedback(
m_expectedSymbols = expectedSymbols;
m_headerLocked = true;
m_loRaReceivedHeader = true;
// qDebug("[LOOPBACK][RX] header_lock token=%u frameId=%u len=%u cr=%u expected=%u frameSymbols=%u",
// frameId,
// frameId,
// packetLength,
// nbParityBits,
// expectedSymbols,
// m_loRaFrameSymbolCount);
}
int MeshtasticDemodSink::loRaMod(int a, int b) const
@@ -551,9 +516,7 @@ int MeshtasticDemodSink::loRaRound(float number) const
void MeshtasticDemodSink::resetLoRaFrameSync()
{
if ((m_settings.m_codingScheme == MeshtasticDemodSettings::CodingLoRa)
&& m_decodeMsg
&& (m_loRaState != LoRaStateDetect))
if (m_decodeMsg && (m_loRaState != LoRaStateDetect))
{
delete m_decodeMsg;
m_decodeMsg = nullptr;
@@ -799,12 +762,6 @@ void MeshtasticDemodSink::finalizeLoRaFrame()
return;
}
// const bool hitExpected = m_headerLocked && (m_loRaFrameSymbolCount >= m_expectedSymbols);
// const bool hitMax = (!m_headerLocked) && (m_loRaFrameSymbolCount >= m_settings.m_nbSymbolsMax);
// const char *endReason = hitExpected
// ? "expected"
// : (hitMax ? "max" : "other");
qDebug(
"MeshtasticDemodSink::finalizeLoRaFrame: frameId=%u symbols=%u headerLocked=%d expected=%u",
m_loRaFrameId,
@@ -813,15 +770,6 @@ void MeshtasticDemodSink::finalizeLoRaFrame()
m_expectedSymbols
);
// qDebug("[LOOPBACK][RX] frame_finalize token=%u frameId=%u reason=%s locked=%d expected=%u actual=%u waitHeader=%d",
// m_loRaFrameId,
// m_loRaFrameId,
// endReason,
// m_headerLocked ? 1 : 0,
// m_expectedSymbols,
// m_loRaFrameSymbolCount,
// m_waitHeaderFeedback ? 1 : 0);
m_decodeMsg->setSignalDb(CalcDb::dbPower(m_magsqOnAvg.asDouble() / (1 << m_settings.m_spreadFactor)));
m_decodeMsg->setNoiseDb(CalcDb::dbPower(m_magsqOffAvg.asDouble() / (1 << m_settings.m_spreadFactor)));
@@ -1205,7 +1153,7 @@ int MeshtasticDemodSink::processLoRaFrameSyncStep()
std::vector<float> symbolMags;
const unsigned int rawSymbol = getLoRaSymbolVal(m_loRaInDown.data(), m_loRaPayloadDownchirp.data(), &symbolMags, true);
const bool headerSymbol = m_settings.m_hasHeader && (m_loRaFrameSymbolCount < 8U);
const bool headerSymbol = m_loRaFrameSymbolCount < 8U;
const unsigned short symbol = evalSymbol(rawSymbol, headerSymbol) % m_nbSymbolsEff;
m_decodeMsg->pushBackSymbol(symbol);
m_decodeMsg->pushBackMagnitudes(symbolMags);
@@ -1237,7 +1185,6 @@ int MeshtasticDemodSink::processLoRaFrameSyncStep()
m_loRaFrameSymbolCount++;
if (!m_headerLocked
&& m_settings.m_hasHeader
&& (m_loRaFrameSymbolCount >= 8U))
{
tryHeaderLock();
@@ -1,3 +1,19 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019-2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
// //
// 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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QMessageBox>
#include "meshtastickeysdialog.h"
@@ -1,3 +1,19 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019-2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
// //
// 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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_MESHTASTICKEYSDIALOG_H
#define INCLUDE_MESHTASTICKEYSDIALOG_H
@@ -13,7 +29,7 @@ class MeshtasticKeysDialog : public QDialog
public:
explicit MeshtasticKeysDialog(QWidget* parent = nullptr);
~MeshtasticKeysDialog();
~MeshtasticKeysDialog() override;
void setKeySpecList(const QString& keySpecList);
QString getKeySpecList() const;
@@ -218,11 +218,11 @@ void MeshtasticMod::applySettings(const MeshtasticModSettings& incomingSettings,
<< " m_bytesMessage: " << settings.m_bytesMessage.toHex()
<< " m_spreadFactor: " << settings.m_spreadFactor
<< " m_deBits: " << settings.m_deBits
<< " m_codingScheme: " << settings.m_codingScheme
<< " m_codingScheme: " << MeshtasticModSettings::m_codingScheme
<< " m_nbParityBits: " << settings.m_nbParityBits
<< " m_hasCRC: " << settings.m_hasCRC
<< " m_hasHeader: " << settings.m_hasHeader
<< " m_messageType: " << settings.m_messageType
<< " m_hasCRC: " << MeshtasticModSettings::m_hasCRC
<< " m_hasHeader: " << MeshtasticModSettings::m_hasHeader
<< " m_messageType: " << MeshtasticModSettings::m_messageType
<< " m_preambleChirps: " << settings.m_preambleChirps
<< " m_quietMillis: " << settings.m_quietMillis
<< " m_messageRepeat: " << settings.m_messageRepeat
@@ -153,7 +153,7 @@ void MeshtasticModGUI::handleSourceMessages()
QString MeshtasticModGUI::getActivePayloadText() const
{
switch (m_settings.m_messageType)
switch (MeshtasticModSettings::m_messageType)
{
case MeshtasticModSettings::MessageText:
return m_settings.m_textMessage;
@@ -528,7 +528,7 @@ void MeshtasticModGUI::on_repeatMessage_valueChanged(int value)
void MeshtasticModGUI::on_messageText_editingFinished()
{
if (m_settings.m_messageType == MeshtasticModSettings::MessageText) {
if (MeshtasticModSettings::m_messageType == MeshtasticModSettings::MessageText) {
m_settings.m_textMessage = ui->messageText->toPlainText();
}
@@ -809,7 +809,7 @@ void MeshtasticModGUI::displaySettings()
displayCurrentPayloadMessage();
displayBinaryMessage();
ui->fecParity->setEnabled(m_settings.m_codingScheme == MeshtasticModSettings::CodingLoRa);
ui->fecParity->setEnabled(MeshtasticModSettings::m_codingScheme == MeshtasticModSettings::CodingLoRa);
blockApplySettings(true);
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
@@ -874,7 +874,7 @@ void MeshtasticModGUI::displayCurrentPayloadMessage()
{
ui->messageText->blockSignals(true);
if (m_settings.m_messageType == MeshtasticModSettings::MessageText) {
if (MeshtasticModSettings::m_messageType == MeshtasticModSettings::MessageText) {
ui->messageText->setText(m_settings.m_textMessage);
}
@@ -20,22 +20,6 @@
#include "meshtasticmodsource.h"
// namespace { // For [LOOPBACK] debug only
// QString symbolPreview(const std::vector<unsigned short>& symbols, unsigned int maxCount)
// {
// QStringList parts;
// const unsigned int count = std::min<unsigned int>(maxCount, static_cast<unsigned int>(symbols.size()));
// for (unsigned int i = 0; i < count; i++) {
// parts.append(QString::number(symbols[i]));
// }
// return parts.join(",");
// }
// } // namespace
const int MeshtasticModSource::m_levelNbSamples = 480; // every 10ms
MeshtasticModSource::MeshtasticModSource() :
@@ -300,7 +284,7 @@ void MeshtasticModSource::modulateSample()
{
m_fftCounter = 0;
m_chirpCount = 0;
m_chirp0 = encodeSymbol(m_symbols[m_chirpCount], m_settings.m_hasHeader && (m_chirpCount < 8U));
m_chirp0 = encodeSymbol(m_symbols[m_chirpCount], MeshtasticModSettings::m_hasHeader && (m_chirpCount < 8U));
m_txFrameToken++;
std::vector<unsigned short> mappedPreview;
@@ -308,21 +292,9 @@ void MeshtasticModSource::modulateSample()
mappedPreview.reserve(previewCount);
for (unsigned int i = 0; i < previewCount; i++) {
mappedPreview.push_back(encodeSymbol(m_symbols[i], m_settings.m_hasHeader && (i < 8U)));
mappedPreview.push_back(encodeSymbol(m_symbols[i], MeshtasticModSettings::m_hasHeader && (i < 8U)));
}
// qDebug().noquote() << QString(
// "[LOOPBACK][TX] frame_start token=%1 sf=%2 de=%3 bw=%4 preamble=%5 symbols=%6 hdrRaw=[%7] hdrMapped=[%8]"
// )
// .arg(m_txFrameToken)
// .arg(m_settings.m_spreadFactor)
// .arg(m_settings.m_deBits)
// .arg(m_bandwidth)
// .arg(m_settings.m_preambleChirps)
// .arg(m_symbols.size())
// .arg(symbolPreview(m_symbols, previewCount))
// .arg(symbolPreview(mappedPreview, previewCount));
m_chirp = (m_chirp0 + m_fftLength)*MeshtasticModSettings::oversampling - 1;
m_state = ChirpChatStatePayload;
}
@@ -344,7 +316,7 @@ void MeshtasticModSource::modulateSample()
}
else
{
m_chirp0 = encodeSymbol(m_symbols[m_chirpCount], m_settings.m_hasHeader && (m_chirpCount < 8U));
m_chirp0 = encodeSymbol(m_symbols[m_chirpCount], MeshtasticModSettings::m_hasHeader && (m_chirpCount < 8U));
m_chirp = (m_chirp0 + m_fftLength)*MeshtasticModSettings::oversampling - 1;
m_fftCounter = 0;
}
@@ -363,9 +335,9 @@ void MeshtasticModSource::modulateSample()
}
}
unsigned short MeshtasticModSource::encodeSymbol(unsigned short symbol, bool headerSymbol)
unsigned short MeshtasticModSource::encodeSymbol(unsigned short symbol, bool headerSymbol) const
{
unsigned int deBits = static_cast<unsigned int>(std::max(0, m_settings.m_deBits));
auto deBits = static_cast<unsigned int>(std::max(0, m_settings.m_deBits));
if (headerSymbol && deBits < 2U) {
deBits = 2U;
@@ -108,7 +108,7 @@ private:
void reset();
void calculateLevel(Real& sample);
void modulateSample();
unsigned short encodeSymbol(unsigned short symbol, bool headerSymbol); //!< Encodes symbol with payload/header DE spacing
unsigned short encodeSymbol(unsigned short symbol, bool headerSymbol) const; //!< Encodes symbol with payload/header DE spacing
};
#endif // INCLUDE_MESHTASTICMODSOURCE_H