mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
ChirpChat demod: implemented FT decoding
This commit is contained in:
parent
a02d1839ef
commit
3c9f74aeb5
10
ft8/ft8.cpp
10
ft8/ft8.cpp
@ -2566,8 +2566,14 @@ int FT8::decode(const float ll174[], int a174[], FT8Params& _params, int use_osd
|
|||||||
if (OSD::check_crc(a174)) {
|
if (OSD::check_crc(a174)) {
|
||||||
// success!
|
// success!
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
comment = "CRC fail";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
comment = "LDPC fail";
|
||||||
|
}
|
||||||
|
|
||||||
if (use_osd && _params.osd_depth >= 0 && ldpc_ok >= _params.osd_ldpc_thresh)
|
if (use_osd && _params.osd_depth >= 0 && ldpc_ok >= _params.osd_ldpc_thresh)
|
||||||
{
|
{
|
||||||
@ -2582,6 +2588,10 @@ int FT8::decode(const float ll174[], int a174[], FT8Params& _params, int use_osd
|
|||||||
OSD::ldpc_encode(oplain, a174);
|
OSD::ldpc_encode(oplain, a174);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
comment = "OSD fail";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -934,11 +934,11 @@ bool Packing::packfree(int a77[], const std::string& msg)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packing::pack1(int a77[], int c28_1, int c28_2, int g15, int report)
|
void Packing::pack1(int a77[], int c28_1, int c28_2, int g15, int reply)
|
||||||
{
|
{
|
||||||
pa64(a77, 0, 28, c28_1);
|
pa64(a77, 0, 28, c28_1);
|
||||||
pa64(a77, 28+1, 28, c28_2);
|
pa64(a77, 28+1, 28, c28_2);
|
||||||
a77[28+1+28+1] = report;
|
a77[28+1+28+1] = reply;
|
||||||
pa64(a77, 28+1+28+2, 15, g15);
|
pa64(a77, 28+1+28+2, 15, g15);
|
||||||
pa64(a77, 28+1+28+2+15, 3, 1);
|
pa64(a77, 28+1+28+2+15, 3, 1);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
static bool packcall_std(int& c28, const std::string& callstr);
|
static bool packcall_std(int& c28, const std::string& callstr);
|
||||||
static bool packgrid(int& g15, const std::string& locstr);
|
static bool packgrid(int& g15, const std::string& locstr);
|
||||||
static bool packfree(int a77[], const std::string& msg);
|
static bool packfree(int a77[], const std::string& msg);
|
||||||
static void pack1(int a77[], int c28_1, int c28_2, int g15, int report);
|
static void pack1(int a77[], int c28_1, int c28_2, int g15, int reply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int ihashcall(std::string call, int m);
|
static int ihashcall(std::string call, int m);
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
project(chirpchat)
|
project(chirpchat)
|
||||||
|
|
||||||
|
if (FT8_SUPPORT)
|
||||||
|
set(chirpchatmod_FT8_LIB ft8)
|
||||||
|
set(chirpchatmod_FT8_INCLUDE ${CMAKE_SOURCE_DIR}/ft8)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(chirpchat_SOURCES
|
set(chirpchat_SOURCES
|
||||||
chirpchatdemod.cpp
|
chirpchatdemod.cpp
|
||||||
chirpchatdemodsettings.cpp
|
chirpchatdemodsettings.cpp
|
||||||
@ -10,6 +15,7 @@ set(chirpchat_SOURCES
|
|||||||
chirpchatdemoddecodertty.cpp
|
chirpchatdemoddecodertty.cpp
|
||||||
chirpchatdemoddecoderascii.cpp
|
chirpchatdemoddecoderascii.cpp
|
||||||
chirpchatdemoddecoderlora.cpp
|
chirpchatdemoddecoderlora.cpp
|
||||||
|
chirpchatdemoddecoderft.cpp
|
||||||
chirpchatdemodmsg.cpp
|
chirpchatdemodmsg.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,12 +28,14 @@ set(chirpchat_HEADERS
|
|||||||
chirpchatdemoddecodertty.h
|
chirpchatdemoddecodertty.h
|
||||||
chirpchatdemoddecoderascii.h
|
chirpchatdemoddecoderascii.h
|
||||||
chirpchatdemoddecoderlora.h
|
chirpchatdemoddecoderlora.h
|
||||||
|
chirpchatdemoddecoderft.h
|
||||||
chirpchatdemodmsg.h
|
chirpchatdemodmsg.h
|
||||||
chirpchatplugin.h
|
chirpchatplugin.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||||
|
${chirpchatmod_FT8_INCLUDE}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT SERVER_MODE)
|
if(NOT SERVER_MODE)
|
||||||
@ -61,6 +69,7 @@ target_link_libraries(${TARGET_NAME}
|
|||||||
sdrbase
|
sdrbase
|
||||||
${TARGET_LIB_GUI}
|
${TARGET_LIB_GUI}
|
||||||
swagger
|
swagger
|
||||||
|
${chirpchatmod_FT8_LIB}
|
||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||||
|
@ -318,6 +318,29 @@ bool ChirpChatDemod::handleMessage(const Message& cmd)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (ChirpChatDemodMsg::MsgReportDecodeFT::match(cmd))
|
||||||
|
{
|
||||||
|
qDebug() << "ChirpChatDemod::handleMessage: MsgReportDecodeFT";
|
||||||
|
ChirpChatDemodMsg::MsgReportDecodeFT& msg = (ChirpChatDemodMsg::MsgReportDecodeFT&) cmd;
|
||||||
|
m_lastMsgSignalDb = msg.getSingalDb();
|
||||||
|
m_lastMsgNoiseDb = msg.getNoiseDb();
|
||||||
|
m_lastMsgSyncWord = msg.getSyncWord();
|
||||||
|
m_lastMsgTimestamp = msg.getMsgTimestamp();
|
||||||
|
m_lastMsgString = msg.getMessage(); // for now we do not handle message components (call1, ...)
|
||||||
|
|
||||||
|
if (m_settings.m_sendViaUDP)
|
||||||
|
{
|
||||||
|
const QByteArray& byteArray = m_lastMsgString.toUtf8();
|
||||||
|
const uint8_t *bytes = reinterpret_cast<const uint8_t*>(byteArray.data());
|
||||||
|
m_udpSink.writeUnbuffered(bytes, byteArray.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getMessageQueueToGUI()) {
|
||||||
|
getMessageQueueToGUI()->push(new ChirpChatDemodMsg::MsgReportDecodeFT(msg)); // make a copy
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (DSPSignalNotification::match(cmd))
|
else if (DSPSignalNotification::match(cmd))
|
||||||
{
|
{
|
||||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "chirpchatdemoddecodertty.h"
|
#include "chirpchatdemoddecodertty.h"
|
||||||
#include "chirpchatdemoddecoderascii.h"
|
#include "chirpchatdemoddecoderascii.h"
|
||||||
#include "chirpchatdemoddecoderlora.h"
|
#include "chirpchatdemoddecoderlora.h"
|
||||||
|
#include "chirpchatdemoddecoderft.h"
|
||||||
#include "chirpchatdemodmsg.h"
|
#include "chirpchatdemodmsg.h"
|
||||||
|
|
||||||
ChirpChatDemodDecoder::ChirpChatDemodDecoder() :
|
ChirpChatDemodDecoder::ChirpChatDemodDecoder() :
|
||||||
@ -60,7 +61,7 @@ void ChirpChatDemodDecoder::decodeSymbols(const std::vector<unsigned short>& sym
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ChirpChatDemodSettings::CodingASCII:
|
case ChirpChatDemodSettings::CodingASCII:
|
||||||
if (m_nbSymbolBits == 5) {
|
if (m_nbSymbolBits == 7) {
|
||||||
ChirpChatDemodDecoderASCII::decodeSymbols(symbols, str);
|
ChirpChatDemodDecoderASCII::decodeSymbols(symbols, str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -106,6 +107,33 @@ void ChirpChatDemodDecoder::decodeSymbols(const std::vector<unsigned short>& sym
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChirpChatDemodDecoder::decodeSymbols( //!< For FT coding scheme
|
||||||
|
const std::vector<std::vector<float>>& mags, // vector of symbols magnitudes
|
||||||
|
int nbSymbolBits, //!< number of bits per symbol
|
||||||
|
std::string& msg, //!< formatted message
|
||||||
|
std::string& call1, //!< 1st callsign or shorthand
|
||||||
|
std::string& call2, //!< 2nd callsign
|
||||||
|
std::string& loc, //!< locator, report or shorthand
|
||||||
|
bool& reply //!< true if message is a reply report
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (m_codingScheme != ChirpChatDemodSettings::CodingFT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChirpChatDemodDecoderFT::decodeSymbols(
|
||||||
|
mags,
|
||||||
|
nbSymbolBits,
|
||||||
|
msg,
|
||||||
|
call1,
|
||||||
|
call2,
|
||||||
|
loc,
|
||||||
|
reply,
|
||||||
|
m_payloadParityStatus,
|
||||||
|
m_payloadCRCStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bool ChirpChatDemodDecoder::handleMessage(const Message& cmd)
|
bool ChirpChatDemodDecoder::handleMessage(const Message& cmd)
|
||||||
{
|
{
|
||||||
if (ChirpChatDemodMsg::MsgDecodeSymbols::match(cmd))
|
if (ChirpChatDemodMsg::MsgDecodeSymbols::match(cmd))
|
||||||
@ -145,7 +173,34 @@ bool ChirpChatDemodDecoder::handleMessage(const Message& cmd)
|
|||||||
}
|
}
|
||||||
else if (m_codingScheme == ChirpChatDemodSettings::CodingFT)
|
else if (m_codingScheme == ChirpChatDemodSettings::CodingFT)
|
||||||
{
|
{
|
||||||
|
std::string fmsg, call1, call2, loc;
|
||||||
|
bool reply;
|
||||||
|
decodeSymbols(
|
||||||
|
msg.getMagnitudes(),
|
||||||
|
m_nbSymbolBits,
|
||||||
|
fmsg,
|
||||||
|
call1,
|
||||||
|
call2,
|
||||||
|
loc,
|
||||||
|
reply
|
||||||
|
);
|
||||||
|
|
||||||
|
if (m_outputMessageQueue)
|
||||||
|
{
|
||||||
|
ChirpChatDemodMsg::MsgReportDecodeFT *outputMsg = ChirpChatDemodMsg::MsgReportDecodeFT::create();
|
||||||
|
outputMsg->setSyncWord(msgSyncWord);
|
||||||
|
outputMsg->setSignalDb(msgSignalDb);
|
||||||
|
outputMsg->setNoiseDb(msgNoiseDb);
|
||||||
|
outputMsg->setMsgTimestamp(msgTimestamp);
|
||||||
|
outputMsg->setMessage(QString(fmsg.c_str()));
|
||||||
|
outputMsg->setCall1(QString(call1.c_str()));
|
||||||
|
outputMsg->setCall2(QString(call2.c_str()));
|
||||||
|
outputMsg->setLoc(QString(loc.c_str()));
|
||||||
|
outputMsg->setReply(reply);
|
||||||
|
outputMsg->setPayloadParityStatus(getPayloadParityStatus());
|
||||||
|
outputMsg->setPayloadCRCStatus(getPayloadCRCStatus());
|
||||||
|
m_outputMessageQueue->push(outputMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -40,8 +40,22 @@ public:
|
|||||||
void setLoRaHasHeader(bool hasHeader) { m_hasHeader = hasHeader; }
|
void setLoRaHasHeader(bool hasHeader) { m_hasHeader = hasHeader; }
|
||||||
void setLoRaHasCRC(bool hasCRC) { m_hasCRC = hasCRC; }
|
void setLoRaHasCRC(bool hasCRC) { m_hasCRC = hasCRC; }
|
||||||
void setLoRaPacketLength(unsigned int packetLength) { m_packetLength = packetLength; }
|
void setLoRaPacketLength(unsigned int packetLength) { m_packetLength = packetLength; }
|
||||||
|
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||||
|
void setOutputMessageQueue(MessageQueue *messageQueue) { m_outputMessageQueue = messageQueue; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool handleMessage(const Message& cmd);
|
||||||
void decodeSymbols(const std::vector<unsigned short>& symbols, QString& str); //!< For ASCII and TTY
|
void decodeSymbols(const std::vector<unsigned short>& symbols, QString& str); //!< For ASCII and TTY
|
||||||
void decodeSymbols(const std::vector<unsigned short>& symbols, QByteArray& bytes); //!< For raw bytes (original LoRa)
|
void decodeSymbols(const std::vector<unsigned short>& symbols, QByteArray& bytes); //!< For raw bytes (original LoRa)
|
||||||
|
void decodeSymbols( //!< For FT coding scheme
|
||||||
|
const std::vector<std::vector<float>>& mags, // vector of symbols magnitudes
|
||||||
|
int nbSymbolBits, //!< number of bits per symbol
|
||||||
|
std::string& msg, //!< formatted message
|
||||||
|
std::string& call1, //!< 1st callsign or shorthand
|
||||||
|
std::string& call2, //!< 2nd callsign
|
||||||
|
std::string& loc, //!< locator, report or shorthand
|
||||||
|
bool& reply //!< true if message is a reply report
|
||||||
|
);
|
||||||
unsigned int getNbParityBits() const { return m_nbParityBits; }
|
unsigned int getNbParityBits() const { return m_nbParityBits; }
|
||||||
unsigned int getPacketLength() const { return m_packetLength; }
|
unsigned int getPacketLength() const { return m_packetLength; }
|
||||||
bool getHasCRC() const { return m_hasCRC; }
|
bool getHasCRC() const { return m_hasCRC; }
|
||||||
@ -52,11 +66,6 @@ public:
|
|||||||
bool getHeaderCRCStatus() const { return m_headerCRCStatus; }
|
bool getHeaderCRCStatus() const { return m_headerCRCStatus; }
|
||||||
int getPayloadParityStatus() const { return m_payloadParityStatus; }
|
int getPayloadParityStatus() const { return m_payloadParityStatus; }
|
||||||
bool getPayloadCRCStatus() const { return m_payloadCRCStatus; }
|
bool getPayloadCRCStatus() const { return m_payloadCRCStatus; }
|
||||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
|
||||||
void setOutputMessageQueue(MessageQueue *messageQueue) { m_outputMessageQueue = messageQueue; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool handleMessage(const Message& cmd);
|
|
||||||
|
|
||||||
ChirpChatDemodSettings::CodingScheme m_codingScheme;
|
ChirpChatDemodSettings::CodingScheme m_codingScheme;
|
||||||
unsigned int m_spreadFactor;
|
unsigned int m_spreadFactor;
|
||||||
|
111
plugins/channelrx/demodchirpchat/chirpchatdemoddecoderft.cpp
Normal file
111
plugins/channelrx/demodchirpchat/chirpchatdemoddecoderft.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2024 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 "chirpchatdemodsettings.h"
|
||||||
|
#include "chirpchatdemoddecoderft.h"
|
||||||
|
|
||||||
|
#ifndef HAS_FT8
|
||||||
|
void ChirpChatDemodDecoderFT::decodeSymbols(
|
||||||
|
const std::vector<std::vector<float>>& mags, // vector of symbols magnitudes
|
||||||
|
int nbSymbolBits, //!< number of bits per symbol
|
||||||
|
QString& msg, //!< formatted message
|
||||||
|
QString& call1, //!< 1st callsign or shorthand
|
||||||
|
QString& call2, //!< 2nd callsign
|
||||||
|
QString& loc, //!< locator, report or shorthand
|
||||||
|
bool& reply //!< true if message is a reply report
|
||||||
|
)
|
||||||
|
{
|
||||||
|
qWarning("ChirpChatDemodDecoderFT::decodeSymbols: not implemented");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "ft8.h"
|
||||||
|
#include "packing.h"
|
||||||
|
|
||||||
|
void ChirpChatDemodDecoderFT::decodeSymbols(
|
||||||
|
const std::vector<std::vector<float>>& mags, // vector of symbols magnitudes
|
||||||
|
int nbSymbolBits, //!< number of bits per symbol
|
||||||
|
std::string& msg, //!< formatted message
|
||||||
|
std::string& call1, //!< 1st callsign or shorthand
|
||||||
|
std::string& call2, //!< 2nd callsign
|
||||||
|
std::string& loc, //!< locator, report or shorthand
|
||||||
|
bool& reply, //!< true if message is a reply report
|
||||||
|
int& payloadParityStatus,
|
||||||
|
bool& payloadCRCStatus
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (mags.size()*nbSymbolBits < 174)
|
||||||
|
{
|
||||||
|
qWarning("ChirpChatDemodDecoderFT::decodeSymbols: insufficient number of symbols for FT payload");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float *lls = new float[mags.size()*nbSymbolBits]; // bits log likelihoods (>0 for 0, <0 for 1)
|
||||||
|
std::fill(lls, lls+mags.size()*nbSymbolBits, 0.0);
|
||||||
|
FT8::FT8Params params;
|
||||||
|
FT8::FT8::soft_decode_mags(params, mags, nbSymbolBits, lls);
|
||||||
|
int r174[174];
|
||||||
|
std::string comments;
|
||||||
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityOK;
|
||||||
|
payloadCRCStatus = false;
|
||||||
|
|
||||||
|
if (FT8::FT8::decode(lls, r174, params, 0, comments) == 0)
|
||||||
|
{
|
||||||
|
if (comments == "LDPC fail")
|
||||||
|
{
|
||||||
|
qWarning("ChirpChatDemodDecoderFT::decodeSymbols: LDPC failed");
|
||||||
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityError;
|
||||||
|
}
|
||||||
|
else if (comments == "OSD fail")
|
||||||
|
{
|
||||||
|
qWarning("ChirpChatDemodDecoderFT::decodeSymbols: OSD failed");
|
||||||
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityError;
|
||||||
|
}
|
||||||
|
else if (comments == "CRC fail")
|
||||||
|
{
|
||||||
|
qWarning("ChirpChatDemodDecoderFT::decodeSymbols: CRC failed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("ChirpChatDemodDecoderFT::decodeSymbols: decode failed for unknown reason");
|
||||||
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
payloadCRCStatus = true;
|
||||||
|
FT8::Packing packing;
|
||||||
|
std::string msgType;
|
||||||
|
msg = packing.unpack(r174, call1, call2, loc, msgType);
|
||||||
|
reply = false;
|
||||||
|
|
||||||
|
if ((msgType == "0.3") || (msgType == "0.3")) {
|
||||||
|
reply = r174[56] != 0;
|
||||||
|
}
|
||||||
|
if ((msgType == "1") || (msgType == "2")) {
|
||||||
|
reply = r174[58] != 0;
|
||||||
|
}
|
||||||
|
if ((msgType == "3")) {
|
||||||
|
reply = r174[57] != 0;
|
||||||
|
}
|
||||||
|
if ((msgType == "5")) {
|
||||||
|
reply = r174[34] != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAS_FT8
|
49
plugins/channelrx/demodchirpchat/chirpchatdemoddecoderft.h
Normal file
49
plugins/channelrx/demodchirpchat/chirpchatdemoddecoderft.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2024 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_CHIRPCHATDEMODDECODERFT_H
|
||||||
|
#define INCLUDE_CHIRPCHATDEMODDECODERFT_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ChirpChatDemodDecoderFT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ParityStatus
|
||||||
|
{
|
||||||
|
ParityUndefined,
|
||||||
|
ParityError,
|
||||||
|
ParityCorrected,
|
||||||
|
ParityOK
|
||||||
|
};
|
||||||
|
|
||||||
|
static void decodeSymbols(
|
||||||
|
const std::vector<std::vector<float>>& mags, // vector of symbols magnitudes
|
||||||
|
int nbSymbolBits, //!< number of bits per symbol
|
||||||
|
std::string& msg, //!< formatted message
|
||||||
|
std::string& call1, //!< 1st callsign or shorthand
|
||||||
|
std::string& call2, //!< 2nd callsign
|
||||||
|
std::string& loc, //!< locator, report or shorthand
|
||||||
|
bool& reply , //!< true if message is a reply report
|
||||||
|
int& payloadParityStatus,
|
||||||
|
bool& payloadCRCStatus
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -17,6 +17,7 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "chirpchatdemodsettings.h"
|
||||||
#include "chirpchatdemoddecoderlora.h"
|
#include "chirpchatdemoddecoderlora.h"
|
||||||
|
|
||||||
void ChirpChatDemodDecoderLoRa::decodeHeader(
|
void ChirpChatDemodDecoderLoRa::decodeHeader(
|
||||||
@ -71,14 +72,14 @@ void ChirpChatDemodDecoderLoRa::decodeHeader(
|
|||||||
|
|
||||||
if (bad)
|
if (bad)
|
||||||
{
|
{
|
||||||
headerParityStatus = (int) ParityError;
|
headerParityStatus = (int) ChirpChatDemodSettings::ParityError;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error) {
|
||||||
headerParityStatus = (int) ParityCorrected;
|
headerParityStatus = (int) ChirpChatDemodSettings::ParityCorrected;
|
||||||
} else {
|
} else {
|
||||||
headerParityStatus = (int) ParityOK;
|
headerParityStatus = (int) ChirpChatDemodSettings::ParityOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes[2] != 0) {
|
if (bytes[2] != 0) {
|
||||||
@ -300,11 +301,11 @@ void ChirpChatDemodDecoderLoRa::decodeBytes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bad) {
|
if (bad) {
|
||||||
payloadParityStatus = (int) ParityError;
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityError;
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
payloadParityStatus = (int) ParityCorrected;
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityCorrected;
|
||||||
} else {
|
} else {
|
||||||
payloadParityStatus = (int) ParityOK;
|
payloadParityStatus = (int) ChirpChatDemodSettings::ParityOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization:
|
// finalization:
|
||||||
|
@ -26,14 +26,6 @@
|
|||||||
class ChirpChatDemodDecoderLoRa
|
class ChirpChatDemodDecoderLoRa
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum ParityStatus
|
|
||||||
{
|
|
||||||
ParityUndefined,
|
|
||||||
ParityError,
|
|
||||||
ParityCorrected,
|
|
||||||
ParityOK
|
|
||||||
};
|
|
||||||
|
|
||||||
static void decodeBytes(
|
static void decodeBytes(
|
||||||
QByteArray& bytes,
|
QByteArray& bytes,
|
||||||
const std::vector<unsigned short>& inSymbols,
|
const std::vector<unsigned short>& inSymbols,
|
||||||
|
@ -121,6 +121,14 @@ bool ChirpChatDemodGUI::handleMessage(const Message& message)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (ChirpChatDemodMsg::MsgReportDecodeFT::match(message))
|
||||||
|
{
|
||||||
|
if (m_settings.m_codingScheme == ChirpChatDemodSettings::CodingFT) {
|
||||||
|
showFTMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (ChirpChatDemod::MsgConfigureChirpChatDemod::match(message))
|
else if (ChirpChatDemod::MsgConfigureChirpChatDemod::match(message))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatDemodGUI::handleMessage: NFMDemod::MsgConfigureChirpChatDemod");
|
qDebug("ChirpChatDemodGUI::handleMessage: NFMDemod::MsgConfigureChirpChatDemod");
|
||||||
@ -544,11 +552,11 @@ void ChirpChatDemodGUI::displaySquelch()
|
|||||||
|
|
||||||
void ChirpChatDemodGUI::displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus)
|
void ChirpChatDemodGUI::displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus)
|
||||||
{
|
{
|
||||||
if (m_settings.m_hasHeader && (headerParityStatus == (int) ParityOK)) {
|
if (m_settings.m_hasHeader && (headerParityStatus == (int) ChirpChatDemodSettings::ParityOK)) {
|
||||||
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : green; }");
|
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : green; }");
|
||||||
} else if (m_settings.m_hasHeader && (headerParityStatus == (int) ParityError)) {
|
} else if (m_settings.m_hasHeader && (headerParityStatus == (int) ChirpChatDemodSettings::ParityError)) {
|
||||||
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : red; }");
|
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : red; }");
|
||||||
} else if (m_settings.m_hasHeader && (headerParityStatus == (int) ParityCorrected)) {
|
} else if (m_settings.m_hasHeader && (headerParityStatus == (int) ChirpChatDemodSettings::ParityCorrected)) {
|
||||||
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : blue; }");
|
ui->headerHammingStatus->setStyleSheet("QLabel { background-color : blue; }");
|
||||||
} else {
|
} else {
|
||||||
ui->headerHammingStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
ui->headerHammingStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||||
@ -562,11 +570,11 @@ void ChirpChatDemodGUI::displayLoRaStatus(int headerParityStatus, bool headerCRC
|
|||||||
ui->headerCRCStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
ui->headerCRCStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadParityStatus == (int) ParityOK) {
|
if (payloadParityStatus == (int) ChirpChatDemodSettings::ParityOK) {
|
||||||
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : green; }");
|
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : green; }");
|
||||||
} else if (payloadParityStatus == (int) ParityError) {
|
} else if (payloadParityStatus == (int) ChirpChatDemodSettings::ParityError) {
|
||||||
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : red; }");
|
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : red; }");
|
||||||
} else if (payloadParityStatus == (int) ParityCorrected) {
|
} else if (payloadParityStatus == (int) ChirpChatDemodSettings::ParityCorrected) {
|
||||||
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : blue; }");
|
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : blue; }");
|
||||||
} else {
|
} else {
|
||||||
ui->payloadFECStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
ui->payloadFECStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||||
@ -589,6 +597,25 @@ void ChirpChatDemodGUI::resetLoRaStatus()
|
|||||||
ui->nbCodewordsText->setText("---");
|
ui->nbCodewordsText->setText("---");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChirpChatDemodGUI::displayFTStatus(int payloadParityStatus, bool payloadCRCStatus)
|
||||||
|
{
|
||||||
|
if (payloadParityStatus == (int) ChirpChatDemodSettings::ParityOK) {
|
||||||
|
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : green; }");
|
||||||
|
} else if (payloadParityStatus == (int) ChirpChatDemodSettings::ParityError) {
|
||||||
|
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : red; }");
|
||||||
|
} else if (payloadParityStatus == (int) ChirpChatDemodSettings::ParityCorrected) {
|
||||||
|
ui->payloadFECStatus->setStyleSheet("QLabel { background-color : blue; }");
|
||||||
|
} else {
|
||||||
|
ui->payloadFECStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payloadCRCStatus) {
|
||||||
|
ui->payloadCRCStatus->setStyleSheet("QLabel { background-color : green; }");
|
||||||
|
} else {
|
||||||
|
ui->payloadCRCStatus->setStyleSheet("QLabel { background-color : red; }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChirpChatDemodGUI::setBandwidths()
|
void ChirpChatDemodGUI::setBandwidths()
|
||||||
{
|
{
|
||||||
int maxBandwidth = m_basebandSampleRate/ChirpChatDemodSettings::oversampling;
|
int maxBandwidth = m_basebandSampleRate/ChirpChatDemodSettings::oversampling;
|
||||||
@ -644,7 +671,7 @@ void ChirpChatDemodGUI::showLoRaMessage(const Message& message)
|
|||||||
.arg(msg.getHeaderCRCStatus() ? "ok" : "err");
|
.arg(msg.getHeaderCRCStatus() ? "ok" : "err");
|
||||||
|
|
||||||
displayStatus(loRaStatus);
|
displayStatus(loRaStatus);
|
||||||
displayLoRaStatus(msg.getHeaderParityStatus(), msg.getHeaderCRCStatus(), (int) ParityUndefined, true);
|
displayLoRaStatus(msg.getHeaderParityStatus(), msg.getHeaderCRCStatus(), (int) ChirpChatDemodSettings::ParityUndefined, true);
|
||||||
ui->payloadCRCStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }"); // reset payload CRC
|
ui->payloadCRCStatus->setStyleSheet("QLabel { background:rgb(79,79,79); }"); // reset payload CRC
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -694,6 +721,27 @@ void ChirpChatDemodGUI::showTextMessage(const Message& message)
|
|||||||
displayText(msg.getString());
|
displayText(msg.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChirpChatDemodGUI::showFTMessage(const Message& message)
|
||||||
|
{
|
||||||
|
const ChirpChatDemodMsg::MsgReportDecodeFT& msg = (ChirpChatDemodMsg::MsgReportDecodeFT&) message;
|
||||||
|
|
||||||
|
QDateTime dt = QDateTime::currentDateTime();
|
||||||
|
QString dateStr = dt.toString("HH:mm:ss");
|
||||||
|
ui->sText->setText(tr("%1").arg(msg.getSingalDb(), 0, 'f', 1));
|
||||||
|
ui->snrText->setText(tr("%1").arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1));
|
||||||
|
|
||||||
|
QString status = tr("%1 S:%2 SN:%3 FEC:%4 CRC:%5")
|
||||||
|
.arg(dateStr)
|
||||||
|
.arg(msg.getSingalDb(), 0, 'f', 1)
|
||||||
|
.arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1)
|
||||||
|
.arg(getParityStr(msg.getPayloadParityStatus()))
|
||||||
|
.arg(msg.getPayloadCRCStatus() ? "ok" : "err");
|
||||||
|
|
||||||
|
displayStatus(status);
|
||||||
|
displayText(msg.getMessage()); // We do not show constituents of the message (call1, ...)
|
||||||
|
displayFTStatus(msg.getPayloadParityStatus(), msg.getPayloadCRCStatus());
|
||||||
|
}
|
||||||
|
|
||||||
void ChirpChatDemodGUI::displayText(const QString& text)
|
void ChirpChatDemodGUI::displayText(const QString& text)
|
||||||
{
|
{
|
||||||
QTextCursor cursor = ui->messageText->textCursor();
|
QTextCursor cursor = ui->messageText->textCursor();
|
||||||
@ -754,11 +802,11 @@ void ChirpChatDemodGUI::displayStatus(const QString& status)
|
|||||||
|
|
||||||
QString ChirpChatDemodGUI::getParityStr(int parityStatus)
|
QString ChirpChatDemodGUI::getParityStr(int parityStatus)
|
||||||
{
|
{
|
||||||
if (parityStatus == (int) ParityError) {
|
if (parityStatus == (int) ChirpChatDemodSettings::ParityError) {
|
||||||
return "err";
|
return "err";
|
||||||
} else if (parityStatus == (int) ParityCorrected) {
|
} else if (parityStatus == (int) ChirpChatDemodSettings::ParityCorrected) {
|
||||||
return "fix";
|
return "fix";
|
||||||
} else if (parityStatus == (int) ParityOK) {
|
} else if (parityStatus == (int) ChirpChatDemodSettings::ParityOK) {
|
||||||
return "ok";
|
return "ok";
|
||||||
} else {
|
} else {
|
||||||
return "n/a";
|
return "n/a";
|
||||||
|
@ -89,14 +89,6 @@ private slots:
|
|||||||
void tick();
|
void tick();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum ParityStatus // matches decoder status
|
|
||||||
{
|
|
||||||
ParityUndefined,
|
|
||||||
ParityError,
|
|
||||||
ParityCorrected,
|
|
||||||
ParityOK
|
|
||||||
};
|
|
||||||
|
|
||||||
Ui::ChirpChatDemodGUI* ui;
|
Ui::ChirpChatDemodGUI* ui;
|
||||||
PluginAPI* m_pluginAPI;
|
PluginAPI* m_pluginAPI;
|
||||||
DeviceUISet* m_deviceUISet;
|
DeviceUISet* m_deviceUISet;
|
||||||
@ -120,12 +112,14 @@ private:
|
|||||||
void displaySettings();
|
void displaySettings();
|
||||||
void displaySquelch();
|
void displaySquelch();
|
||||||
void setBandwidths();
|
void setBandwidths();
|
||||||
void showLoRaMessage(const Message& message);
|
void showLoRaMessage(const Message& message); //!< For LoRa coding scheme
|
||||||
void showTextMessage(const Message& message); //!< For TTY and ASCII
|
void showTextMessage(const Message& message); //!< For TTY and ASCII
|
||||||
|
void showFTMessage(const Message& message); //!< For FT coding scheme
|
||||||
void displayText(const QString& text);
|
void displayText(const QString& text);
|
||||||
void displayBytes(const QByteArray& bytes);
|
void displayBytes(const QByteArray& bytes);
|
||||||
void displayStatus(const QString& status);
|
void displayStatus(const QString& status);
|
||||||
void displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus);
|
void displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus);
|
||||||
|
void displayFTStatus(int payloadParityStatus, bool payloadCRCStatus);
|
||||||
QString getParityStr(int parityStatus);
|
QString getParityStr(int parityStatus);
|
||||||
void resetLoRaStatus();
|
void resetLoRaStatus();
|
||||||
bool handleMessage(const Message& message);
|
bool handleMessage(const Message& message);
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
|
||||||
|
#include "chirpchatdemodsettings.h"
|
||||||
|
|
||||||
namespace ChirpChatDemodMsg
|
namespace ChirpChatDemodMsg
|
||||||
{
|
{
|
||||||
class MsgDecodeSymbols : public Message {
|
class MsgDecodeSymbols : public Message {
|
||||||
@ -178,7 +180,7 @@ namespace ChirpChatDemodMsg
|
|||||||
m_earlyEOM(false),
|
m_earlyEOM(false),
|
||||||
m_headerParityStatus(false),
|
m_headerParityStatus(false),
|
||||||
m_headerCRCStatus(false),
|
m_headerCRCStatus(false),
|
||||||
m_payloadParityStatus(false),
|
m_payloadParityStatus((int) ChirpChatDemodSettings::ParityUndefined),
|
||||||
m_payloadCRCStatus(false)
|
m_payloadCRCStatus(false)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@ -240,6 +242,8 @@ namespace ChirpChatDemodMsg
|
|||||||
float getSingalDb() const { return m_signalDb; }
|
float getSingalDb() const { return m_signalDb; }
|
||||||
float getNoiseDb() const { return m_noiseDb; }
|
float getNoiseDb() const { return m_noiseDb; }
|
||||||
const QString& getMsgTimestamp() const { return m_msgTimestamp; }
|
const QString& getMsgTimestamp() const { return m_msgTimestamp; }
|
||||||
|
int getPayloadParityStatus() const { return m_payloadParityStatus; }
|
||||||
|
bool getPayloadCRCStatus() const { return m_payloadCRCStatus; }
|
||||||
|
|
||||||
static MsgReportDecodeFT* create()
|
static MsgReportDecodeFT* create()
|
||||||
{
|
{
|
||||||
@ -275,6 +279,12 @@ namespace ChirpChatDemodMsg
|
|||||||
void setMsgTimestamp(const QString& ts) {
|
void setMsgTimestamp(const QString& ts) {
|
||||||
m_msgTimestamp = ts;
|
m_msgTimestamp = ts;
|
||||||
}
|
}
|
||||||
|
void setPayloadParityStatus(int payloadParityStatus) {
|
||||||
|
m_payloadParityStatus = payloadParityStatus;
|
||||||
|
}
|
||||||
|
void setPayloadCRCStatus(bool payloadCRCStatus) {
|
||||||
|
m_payloadCRCStatus = payloadCRCStatus;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_message;
|
QString m_message;
|
||||||
@ -287,6 +297,8 @@ namespace ChirpChatDemodMsg
|
|||||||
float m_signalDb;
|
float m_signalDb;
|
||||||
float m_noiseDb;
|
float m_noiseDb;
|
||||||
QString m_msgTimestamp;
|
QString m_msgTimestamp;
|
||||||
|
int m_payloadParityStatus;
|
||||||
|
bool m_payloadCRCStatus;
|
||||||
|
|
||||||
MsgReportDecodeFT() :
|
MsgReportDecodeFT() :
|
||||||
Message(),
|
Message(),
|
||||||
@ -294,7 +306,9 @@ namespace ChirpChatDemodMsg
|
|||||||
m_freeText(false),
|
m_freeText(false),
|
||||||
m_syncWord(0),
|
m_syncWord(0),
|
||||||
m_signalDb(0.0),
|
m_signalDb(0.0),
|
||||||
m_noiseDb(0.0)
|
m_noiseDb(0.0),
|
||||||
|
m_payloadParityStatus((int) ChirpChatDemodSettings::ParityUndefined),
|
||||||
|
m_payloadCRCStatus(false)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,14 @@ struct ChirpChatDemodSettings
|
|||||||
CodingFT //!< FT8/4 scheme (payload 174 bits LDPC)
|
CodingFT //!< FT8/4 scheme (payload 174 bits LDPC)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ParityStatus
|
||||||
|
{
|
||||||
|
ParityUndefined,
|
||||||
|
ParityError,
|
||||||
|
ParityCorrected,
|
||||||
|
ParityOK
|
||||||
|
};
|
||||||
|
|
||||||
int m_inputFrequencyOffset;
|
int m_inputFrequencyOffset;
|
||||||
int m_bandwidthIndex;
|
int m_bandwidthIndex;
|
||||||
int m_spreadFactor;
|
int m_spreadFactor;
|
||||||
|
@ -96,7 +96,7 @@ void ChirpChatModEncoderFT::encodeTextMsg(const QString& text, int a174[])
|
|||||||
std::fill(a77, a77 + 77, 0);
|
std::fill(a77, a77 + 77, 0);
|
||||||
QString sentMsg = text.rightJustified(13, ' ', true);
|
QString sentMsg = text.rightJustified(13, ' ', true);
|
||||||
|
|
||||||
if (!FT8::Packing::packfree(a77, sentMsg.toStdString()))
|
if (!FT8::Packing::packfree(a77, sentMsg.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeTextMsg: failed to encode free text message (%s)", qPrintable(sentMsg));
|
qDebug("ChirpChatModEncoderFT::encodeTextMsg: failed to encode free text message (%s)", qPrintable(sentMsg));
|
||||||
return;
|
return;
|
||||||
@ -109,21 +109,27 @@ void ChirpChatModEncoderFT::encodeMsgBeaconOrCQ(const QString& myCall, const QSt
|
|||||||
{
|
{
|
||||||
int c28_1, c28_2, g15;
|
int c28_1, c28_2, g15;
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_1, shorthand.toStdString())) //
|
if (!FT8::Packing::packcall_std(c28_1, shorthand.toUpper().toStdString())) //
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call1 (%s)", qPrintable(shorthand));
|
qDebug("ChirpChatModEncoderFT::encodeMsgBeaconOrCQ: failed to encode call1 (%s)", qPrintable(shorthand));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_2, myCall.toStdString()))
|
if (!FT8::Packing::packcall_std(c28_2, myCall.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call2 (%s)", qPrintable(myCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgBeaconOrCQ: failed to encode call2 (%s)", qPrintable(myCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packgrid(g15, myLocator.toStdString()))
|
if (myLocator.size() < 4)
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode locator (%s)", qPrintable(myLocator));
|
qDebug("ChirpChatModEncoderFT::encodeMsgBeaconOrCQ: locator invalid (%s)", qPrintable(myLocator));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FT8::Packing::packgrid(g15, myLocator.left(4).toUpper().toStdString()))
|
||||||
|
{
|
||||||
|
qDebug("ChirpChatModEncoderFT::encodeMsgBeaconOrCQ: failed to encode locator (%s)", qPrintable(myLocator));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,21 +143,27 @@ void ChirpChatModEncoderFT::encodeMsgReply(const QString& myCall, const QString&
|
|||||||
{
|
{
|
||||||
int c28_1, c28_2, g15;
|
int c28_1, c28_2, g15;
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_1, urCall.toStdString())) //
|
if (!FT8::Packing::packcall_std(c28_1, urCall.toUpper().toStdString())) //
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call1 (%s)", qPrintable(urCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgReply: failed to encode call1 (%s)", qPrintable(urCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_2, myCall.toStdString()))
|
if (!FT8::Packing::packcall_std(c28_2, myCall.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call2 (%s)", qPrintable(myCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgReply: failed to encode call2 (%s)", qPrintable(myCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packgrid(g15, myLocator.toStdString()))
|
if (myLocator.size() < 4)
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode locator (%s)", qPrintable(myLocator));
|
qDebug("ChirpChatModEncoderFT::encodeMsgReply: locator invalid (%s)", qPrintable(myLocator));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FT8::Packing::packgrid(g15, myLocator.left(4).toUpper().toStdString()))
|
||||||
|
{
|
||||||
|
qDebug("ChirpChatModEncoderFT::encodeMsgReply: failed to encode locator (%s)", qPrintable(myLocator));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,21 +177,21 @@ void ChirpChatModEncoderFT::encodeMsgReport(const QString& myCall, const QString
|
|||||||
{
|
{
|
||||||
int c28_1, c28_2, g15;
|
int c28_1, c28_2, g15;
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_1, urCall.toStdString())) //
|
if (!FT8::Packing::packcall_std(c28_1, urCall.toUpper().toStdString())) //
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call1 (%s)", qPrintable(urCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgReport: failed to encode call1 (%s)", qPrintable(urCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_2, myCall.toStdString()))
|
if (!FT8::Packing::packcall_std(c28_2, myCall.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call2 (%s)", qPrintable(myCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgReport: failed to encode call2 (%s)", qPrintable(myCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packgrid(g15, myReport.toStdString()))
|
if (!FT8::Packing::packgrid(g15, myReport.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode report (%s)", qPrintable(myReport));
|
qDebug("ChirpChatModEncoderFT::encodeMsgReport: failed to encode report (%s)", qPrintable(myReport));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,21 +205,21 @@ void ChirpChatModEncoderFT::encodeMsgFinish(const QString& myCall, const QString
|
|||||||
{
|
{
|
||||||
int c28_1, c28_2, g15;
|
int c28_1, c28_2, g15;
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_1, urCall.toStdString())) //
|
if (!FT8::Packing::packcall_std(c28_1, urCall.toUpper().toStdString())) //
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call1 (%s)", qPrintable(urCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgFinish: failed to encode call1 (%s)", qPrintable(urCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packcall_std(c28_2, myCall.toStdString()))
|
if (!FT8::Packing::packcall_std(c28_2, myCall.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode call2 (%s)", qPrintable(myCall));
|
qDebug("ChirpChatModEncoderFT::encodeMsgFinish: failed to encode call2 (%s)", qPrintable(myCall));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FT8::Packing::packgrid(g15, shorthand.toStdString()))
|
if (!FT8::Packing::packgrid(g15, shorthand.toUpper().toStdString()))
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatModEncoderFT::encodeMsgBeacon: failed to encode shorthand (%s)", qPrintable(shorthand));
|
qDebug("ChirpChatModEncoderFT::encodeMsgFinish: failed to encode shorthand (%s)", qPrintable(shorthand));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user