mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
APRS: Fix forwarding of binary data to APRS-IS for #2028. Support UTF-8.
PacketDemod: Support UTF-8.
This commit is contained in:
parent
d1bfdbaa63
commit
68b833ad97
@ -390,7 +390,7 @@ bool M17DemodProcessor::decode_packet(modemm17::M17FrameDecoder::packet_buffer_t
|
|||||||
<< " Via: " << ax25.m_via
|
<< " Via: " << ax25.m_via
|
||||||
<< " Type: " << ax25.m_type
|
<< " Type: " << ax25.m_type
|
||||||
<< " PID: " << ax25.m_pid
|
<< " PID: " << ax25.m_pid
|
||||||
<< " Data: " << ax25.m_dataASCII;
|
<< " Data: " << QString::fromUtf8(ax25.m_data);
|
||||||
|
|
||||||
if (m_demodInputMessageQueue)
|
if (m_demodInputMessageQueue)
|
||||||
{
|
{
|
||||||
@ -402,7 +402,7 @@ bool M17DemodProcessor::decode_packet(modemm17::M17FrameDecoder::packet_buffer_t
|
|||||||
ax25.m_via,
|
ax25.m_via,
|
||||||
ax25.m_type,
|
ax25.m_type,
|
||||||
ax25.m_pid,
|
ax25.m_pid,
|
||||||
ax25.m_dataASCII
|
ax25.m_data
|
||||||
);
|
);
|
||||||
msg->getPacket() = packet;
|
msg->getPacket() = packet;
|
||||||
m_demodInputMessageQueue->push(msg);
|
m_demodInputMessageQueue->push(msg);
|
||||||
|
@ -216,7 +216,7 @@ bool PacketDemod::handleMessage(const Message& cmd)
|
|||||||
<< "\"" << ax25.m_via << "\","
|
<< "\"" << ax25.m_via << "\","
|
||||||
<< ax25.m_type << ","
|
<< ax25.m_type << ","
|
||||||
<< ax25.m_pid << ","
|
<< ax25.m_pid << ","
|
||||||
<< "\"" << ax25.m_dataASCII << "\","
|
<< "\"" << QString::fromUtf8(ax25.m_data) << "\","
|
||||||
<< "\"" << ax25.m_dataHex << "\"\n";
|
<< "\"" << ax25.m_dataHex << "\"\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -348,7 +348,7 @@ void PacketDemod::applySettings(const PacketDemodSettings& settings, bool force)
|
|||||||
if (newFile)
|
if (newFile)
|
||||||
{
|
{
|
||||||
// Write header
|
// Write header
|
||||||
m_logStream << "Date,Time,Data,From,To,Via,Type,PID,Data ASCII,Data Hex\n";
|
m_logStream << "Date,Time,Data,From,To,Via,Type,PID,Data UTF-8,Data Hex\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -59,7 +59,7 @@ void PacketDemodGUI::resizeTable()
|
|||||||
ui->packets->setItem(row, PACKET_COL_VIA, new QTableWidgetItem("123456-15-"));
|
ui->packets->setItem(row, PACKET_COL_VIA, new QTableWidgetItem("123456-15-"));
|
||||||
ui->packets->setItem(row, PACKET_COL_TYPE, new QTableWidgetItem("Type-"));
|
ui->packets->setItem(row, PACKET_COL_TYPE, new QTableWidgetItem("Type-"));
|
||||||
ui->packets->setItem(row, PACKET_COL_PID, new QTableWidgetItem("PID-"));
|
ui->packets->setItem(row, PACKET_COL_PID, new QTableWidgetItem("PID-"));
|
||||||
ui->packets->setItem(row, PACKET_COL_DATA_ASCII, new QTableWidgetItem("ABCEDGHIJKLMNOPQRSTUVWXYZ"));
|
ui->packets->setItem(row, PACKET_COL_DATA_STRING, new QTableWidgetItem("ABCEDGHIJKLMNOPQRSTUVWXYZ"));
|
||||||
ui->packets->setItem(row, PACKET_COL_DATA_HEX, new QTableWidgetItem("ABCEDGHIJKLMNOPQRSTUVWXYZ"));
|
ui->packets->setItem(row, PACKET_COL_DATA_HEX, new QTableWidgetItem("ABCEDGHIJKLMNOPQRSTUVWXYZ"));
|
||||||
ui->packets->resizeColumnsToContents();
|
ui->packets->resizeColumnsToContents();
|
||||||
ui->packets->removeRow(row);
|
ui->packets->removeRow(row);
|
||||||
@ -168,7 +168,7 @@ void PacketDemodGUI::packetReceived(const QByteArray& packet, QDateTime dateTime
|
|||||||
QTableWidgetItem *viaItem = new QTableWidgetItem();
|
QTableWidgetItem *viaItem = new QTableWidgetItem();
|
||||||
QTableWidgetItem *typeItem = new QTableWidgetItem();
|
QTableWidgetItem *typeItem = new QTableWidgetItem();
|
||||||
QTableWidgetItem *pidItem = new QTableWidgetItem();
|
QTableWidgetItem *pidItem = new QTableWidgetItem();
|
||||||
QTableWidgetItem *dataASCIIItem = new QTableWidgetItem();
|
QTableWidgetItem *dataStringItem = new QTableWidgetItem();
|
||||||
QTableWidgetItem *dataHexItem = new QTableWidgetItem();
|
QTableWidgetItem *dataHexItem = new QTableWidgetItem();
|
||||||
ui->packets->setItem(row, PACKET_COL_DATE, dateItem);
|
ui->packets->setItem(row, PACKET_COL_DATE, dateItem);
|
||||||
ui->packets->setItem(row, PACKET_COL_TIME, timeItem);
|
ui->packets->setItem(row, PACKET_COL_TIME, timeItem);
|
||||||
@ -177,7 +177,7 @@ void PacketDemodGUI::packetReceived(const QByteArray& packet, QDateTime dateTime
|
|||||||
ui->packets->setItem(row, PACKET_COL_VIA, viaItem);
|
ui->packets->setItem(row, PACKET_COL_VIA, viaItem);
|
||||||
ui->packets->setItem(row, PACKET_COL_TYPE, typeItem);
|
ui->packets->setItem(row, PACKET_COL_TYPE, typeItem);
|
||||||
ui->packets->setItem(row, PACKET_COL_PID, pidItem);
|
ui->packets->setItem(row, PACKET_COL_PID, pidItem);
|
||||||
ui->packets->setItem(row, PACKET_COL_DATA_ASCII, dataASCIIItem);
|
ui->packets->setItem(row, PACKET_COL_DATA_STRING, dataStringItem);
|
||||||
ui->packets->setItem(row, PACKET_COL_DATA_HEX, dataHexItem);
|
ui->packets->setItem(row, PACKET_COL_DATA_HEX, dataHexItem);
|
||||||
dateItem->setText(dateTime.date().toString());
|
dateItem->setText(dateTime.date().toString());
|
||||||
timeItem->setText(dateTime.time().toString());
|
timeItem->setText(dateTime.time().toString());
|
||||||
@ -186,7 +186,7 @@ void PacketDemodGUI::packetReceived(const QByteArray& packet, QDateTime dateTime
|
|||||||
viaItem->setText(ax25.m_via);
|
viaItem->setText(ax25.m_via);
|
||||||
typeItem->setText(ax25.m_type);
|
typeItem->setText(ax25.m_type);
|
||||||
pidItem->setText(ax25.m_pid);
|
pidItem->setText(ax25.m_pid);
|
||||||
dataASCIIItem->setText(ax25.m_dataASCII);
|
dataStringItem->setText(QString::fromUtf8(ax25.m_data)); // Should possibly support different encodings here. PacketMod uses UTF8.
|
||||||
dataHexItem->setText(ax25.m_dataHex);
|
dataHexItem->setText(ax25.m_dataHex);
|
||||||
filterRow(row);
|
filterRow(row);
|
||||||
ui->packets->setSortingEnabled(true);
|
ui->packets->setSortingEnabled(true);
|
||||||
|
@ -116,7 +116,7 @@ private:
|
|||||||
PACKET_COL_VIA,
|
PACKET_COL_VIA,
|
||||||
PACKET_COL_TYPE,
|
PACKET_COL_TYPE,
|
||||||
PACKET_COL_PID,
|
PACKET_COL_PID,
|
||||||
PACKET_COL_DATA_ASCII,
|
PACKET_COL_DATA_STRING,
|
||||||
PACKET_COL_DATA_HEX
|
PACKET_COL_DATA_HEX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -736,10 +736,10 @@
|
|||||||
</column>
|
</column>
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Data (ASCII)</string>
|
<string>Data</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Packet data as ASCII</string>
|
<string>Packet data as UTF-8 character string</string>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
<column>
|
<column>
|
||||||
@ -757,9 +757,10 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ButtonSwitch</class>
|
<class>RollupContents</class>
|
||||||
<extends>QToolButton</extends>
|
<extends>QWidget</extends>
|
||||||
<header>gui/buttonswitch.h</header>
|
<header>gui/rollupcontents.h</header>
|
||||||
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ValueDialZ</class>
|
<class>ValueDialZ</class>
|
||||||
@ -768,10 +769,9 @@
|
|||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>RollupContents</class>
|
<class>ButtonSwitch</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QToolButton</extends>
|
||||||
<header>gui/rollupcontents.h</header>
|
<header>gui/buttonswitch.h</header>
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>LevelMeterSignalDB</class>
|
<class>LevelMeterSignalDB</class>
|
||||||
|
@ -92,5 +92,5 @@ The received packets table displays the contents of the packets that have been r
|
|||||||
* Via - List of addresses of repeaters the packet has passed through or directed via.
|
* Via - List of addresses of repeaters the packet has passed through or directed via.
|
||||||
* Type - The AX.25 frame type.
|
* Type - The AX.25 frame type.
|
||||||
* PID - Protocol Identifier.
|
* PID - Protocol Identifier.
|
||||||
* Data (ASCII) - The AX.25 information field displayed as ASCII.
|
* Data - The AX.25 information field displayed as UTF-8 character string.
|
||||||
* Data (Hex) - The AX.25 information field displayed as hexadecimal.
|
* Data (Hex) - The AX.25 information field displayed as hexadecimal.
|
||||||
|
@ -408,7 +408,7 @@ bool APRSGUI::handleMessage(const Message& message)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << "APRSGUI::handleMessage: Failed to decode as APRS";
|
qDebug() << "APRSGUI::handleMessage: Failed to decode as APRS";
|
||||||
qDebug() << ax25.m_from << " " << ax25.m_to << " " << ax25.m_via << " " << ax25.m_type << " " << ax25.m_pid << " "<< ax25.m_dataASCII;
|
qDebug() << "From:" << ax25.m_from << "To:" << ax25.m_to << "Via:" << ax25.m_via << "Type:" << ax25.m_type << "PID:" << ax25.m_pid << "Data:" << QString::fromLatin1(ax25.m_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -102,23 +102,25 @@ bool APRSWorker::handleMessage(const Message& cmd)
|
|||||||
{
|
{
|
||||||
MainCore::MsgPacket& report = (MainCore::MsgPacket&) cmd;
|
MainCore::MsgPacket& report = (MainCore::MsgPacket&) cmd;
|
||||||
AX25Packet ax25;
|
AX25Packet ax25;
|
||||||
APRSPacket *aprs = new APRSPacket();
|
|
||||||
if (ax25.decode(report.getPacket()))
|
if (ax25.decode(report.getPacket()))
|
||||||
{
|
{
|
||||||
// #2029 - Forward data even if we can't decode it fully
|
APRSPacket aprs;
|
||||||
aprs->decode(ax25);
|
|
||||||
|
|
||||||
if (!aprs->m_data.isEmpty())
|
// #2029 - Forward data even if we can't decode it fully
|
||||||
|
aprs.decode(ax25);
|
||||||
|
|
||||||
|
if (!aprs.m_data.isEmpty())
|
||||||
{
|
{
|
||||||
// See: http://www.aprs-is.net/IGateDetails.aspx for gating rules
|
// See: http://www.aprs-is.net/IGateDetails.aspx for gating rules
|
||||||
if (!aprs->m_via.contains("TCPIP")
|
if (!aprs.m_via.contains("TCPIP")
|
||||||
&& !aprs->m_via.contains("TCPXX")
|
&& !aprs.m_via.contains("TCPXX")
|
||||||
&& !aprs->m_via.contains("NOGATE")
|
&& !aprs.m_via.contains("NOGATE")
|
||||||
&& !aprs->m_via.contains("RFONLY"))
|
&& !aprs.m_via.contains("RFONLY"))
|
||||||
{
|
{
|
||||||
aprs->m_dateTime = report.getDateTime();
|
aprs.m_dateTime = report.getDateTime();
|
||||||
QString igateMsg = aprs->toTNC2(m_settings.m_igateCallsign);
|
QByteArray igateMsg = aprs.toTNC2(m_settings.m_igateCallsign);
|
||||||
send(igateMsg.toUtf8(), igateMsg.length());
|
send(igateMsg.data(), igateMsg.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +212,7 @@ void APRSWorker::recv()
|
|||||||
if (!m_loggedIn)
|
if (!m_loggedIn)
|
||||||
{
|
{
|
||||||
// Log in with callsign and passcode
|
// Log in with callsign and passcode
|
||||||
QString login = QString("user %1 pass %2 vers SDRangel 6.4.0%3\r\n").arg(m_settings.m_igateCallsign).arg(m_settings.m_igatePasscode).arg(m_settings.m_igateFilter.isEmpty() ? "" : QString(" filter %1").arg(m_settings.m_igateFilter));
|
QString login = QString("user %1 pass %2 vers SDRangel 7.19.2%3\r\n").arg(m_settings.m_igateCallsign).arg(m_settings.m_igatePasscode).arg(m_settings.m_igateFilter.isEmpty() ? "" : QString(" filter %1").arg(m_settings.m_igateFilter));
|
||||||
send(login.toLatin1(), login.length());
|
send(login.toLatin1(), login.length());
|
||||||
m_loggedIn = true;
|
m_loggedIn = true;
|
||||||
if (m_msgQueueToFeature)
|
if (m_msgQueueToFeature)
|
||||||
|
@ -44,7 +44,7 @@ inline int charToIntAscii(QString&s, int idx)
|
|||||||
bool APRSPacket::decode(AX25Packet packet)
|
bool APRSPacket::decode(AX25Packet packet)
|
||||||
{
|
{
|
||||||
// Check type, PID and length of packet
|
// Check type, PID and length of packet
|
||||||
if ((packet.m_type == "UI") && (packet.m_pid == "f0") && (packet.m_dataASCII.length() >= 1))
|
if ((packet.m_type == "UI") && (packet.m_pid == "f0") && (packet.m_data.length() >= 1))
|
||||||
{
|
{
|
||||||
// Check destination address
|
// Check destination address
|
||||||
QRegularExpression re("^(AIR.*|ALL.*|AP.*|BEACON|CQ.*|GPS.*|DF.*|DGPS.*|DRILL.*|DX.*|ID.*|JAVA.*|MAIL.*|MICE.*|QST.*|QTH.*|RTCM.*|SKY.*|SPACE.*|SPC.*|SYM.*|TEL.*|TEST.*|TLM.*|WX.*|ZIP.*)");
|
QRegularExpression re("^(AIR.*|ALL.*|AP.*|BEACON|CQ.*|GPS.*|DF.*|DGPS.*|DRILL.*|DX.*|ID.*|JAVA.*|MAIL.*|MICE.*|QST.*|QTH.*|RTCM.*|SKY.*|SPACE.*|SPC.*|SYM.*|TEL.*|TEST.*|TLM.*|WX.*|ZIP.*)");
|
||||||
@ -54,7 +54,10 @@ bool APRSPacket::decode(AX25Packet packet)
|
|||||||
m_from = packet.m_from;
|
m_from = packet.m_from;
|
||||||
m_to = packet.m_to;
|
m_to = packet.m_to;
|
||||||
m_via = packet.m_via;
|
m_via = packet.m_via;
|
||||||
m_data = packet.m_dataASCII;
|
m_data = packet.m_data;
|
||||||
|
|
||||||
|
// UTF-8 is supported: http://aprs.org/aprs12/utf-8.txt
|
||||||
|
QString data = QString::fromUtf8(packet.m_data);
|
||||||
|
|
||||||
if (packet.m_to.startsWith("GPS") || packet.m_to.startsWith("SPC") || packet.m_to.startsWith("SYM"))
|
if (packet.m_to.startsWith("GPS") || packet.m_to.startsWith("SPC") || packet.m_to.startsWith("SYM"))
|
||||||
{
|
{
|
||||||
@ -64,20 +67,20 @@ bool APRSPacket::decode(AX25Packet packet)
|
|||||||
// Source address SSID can be used to specify a symbol
|
// Source address SSID can be used to specify a symbol
|
||||||
|
|
||||||
// First byte of information field is data type ID
|
// First byte of information field is data type ID
|
||||||
char dataType = packet.m_dataASCII[0].toLatin1();
|
char dataType = data[0].toLatin1();
|
||||||
int idx = 1;
|
int idx = 1;
|
||||||
switch (dataType)
|
switch (dataType)
|
||||||
{
|
{
|
||||||
case '!': // Position without timestamp or Ultimeter 2000 WX Station
|
case '!': // Position without timestamp or Ultimeter 2000 WX Station
|
||||||
parsePosition(packet.m_dataASCII, idx);
|
parsePosition(data, idx);
|
||||||
if (m_symbolCode == '_')
|
if (m_symbolCode == '_')
|
||||||
parseWeather(packet.m_dataASCII, idx, false);
|
parseWeather(data, idx, false);
|
||||||
else if (m_symbolCode == '@')
|
else if (m_symbolCode == '@')
|
||||||
parseStorm(packet.m_dataASCII, idx);
|
parseStorm(data, idx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parseDataExension(packet.m_dataASCII, idx);
|
parseDataExension(data, idx);
|
||||||
parseComment(packet.m_dataASCII, idx);
|
parseComment(data, idx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '#': // Peet Bros U-II Weather Station
|
case '#': // Peet Bros U-II Weather Station
|
||||||
@ -85,85 +88,85 @@ bool APRSPacket::decode(AX25Packet packet)
|
|||||||
case '%': // Agrelo DFJr / MicroFinder
|
case '%': // Agrelo DFJr / MicroFinder
|
||||||
break;
|
break;
|
||||||
case ')': // Item
|
case ')': // Item
|
||||||
parseItem(packet.m_dataASCII, idx);
|
parseItem(data, idx);
|
||||||
parsePosition(packet.m_dataASCII, idx);
|
parsePosition(data, idx);
|
||||||
parseDataExension(packet.m_dataASCII, idx);
|
parseDataExension(data, idx);
|
||||||
parseComment(packet.m_dataASCII, idx);
|
parseComment(data, idx);
|
||||||
break;
|
break;
|
||||||
case '*': // Peet Bros U-II Weather Station
|
case '*': // Peet Bros U-II Weather Station
|
||||||
break;
|
break;
|
||||||
case '/': // Position with timestamp (no APRS messaging)
|
case '/': // Position with timestamp (no APRS messaging)
|
||||||
parseTime(packet.m_dataASCII, idx);
|
parseTime(data, idx);
|
||||||
parsePosition(packet.m_dataASCII, idx);
|
parsePosition(data, idx);
|
||||||
if (m_symbolCode == '_')
|
if (m_symbolCode == '_')
|
||||||
parseWeather(packet.m_dataASCII, idx, false);
|
parseWeather(data, idx, false);
|
||||||
else if (m_symbolCode == '@')
|
else if (m_symbolCode == '@')
|
||||||
parseStorm(packet.m_dataASCII, idx);
|
parseStorm(data, idx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parseDataExension(packet.m_dataASCII, idx);
|
parseDataExension(data, idx);
|
||||||
parseComment(packet.m_dataASCII, idx);
|
parseComment(data, idx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ':': // Message
|
case ':': // Message
|
||||||
parseMessage(packet.m_dataASCII, idx);
|
parseMessage(data, idx);
|
||||||
break;
|
break;
|
||||||
case ';': // Object
|
case ';': // Object
|
||||||
parseObject(packet.m_dataASCII, idx);
|
parseObject(data, idx);
|
||||||
parseTime(packet.m_dataASCII, idx);
|
parseTime(data, idx);
|
||||||
parsePosition(packet.m_dataASCII, idx);
|
parsePosition(data, idx);
|
||||||
if (m_symbolCode == '_')
|
if (m_symbolCode == '_')
|
||||||
parseWeather(packet.m_dataASCII, idx, false);
|
parseWeather(data, idx, false);
|
||||||
else if (m_symbolCode == '@')
|
else if (m_symbolCode == '@')
|
||||||
parseStorm(packet.m_dataASCII, idx);
|
parseStorm(data, idx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parseDataExension(packet.m_dataASCII, idx);
|
parseDataExension(data, idx);
|
||||||
parseComment(packet.m_dataASCII, idx);
|
parseComment(data, idx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '<': // Station Capabilities
|
case '<': // Station Capabilities
|
||||||
break;
|
break;
|
||||||
case '=': // Position without timestamp (with APRS messaging)
|
case '=': // Position without timestamp (with APRS messaging)
|
||||||
parsePosition(packet.m_dataASCII, idx);
|
parsePosition(data, idx);
|
||||||
if (m_symbolCode == '_')
|
if (m_symbolCode == '_')
|
||||||
parseWeather(packet.m_dataASCII, idx, false);
|
parseWeather(data, idx, false);
|
||||||
else if (m_symbolCode == '@')
|
else if (m_symbolCode == '@')
|
||||||
parseStorm(packet.m_dataASCII, idx);
|
parseStorm(data, idx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parseDataExension(packet.m_dataASCII, idx);
|
parseDataExension(data, idx);
|
||||||
parseComment(packet.m_dataASCII, idx);
|
parseComment(data, idx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '>': // Status
|
case '>': // Status
|
||||||
parseStatus(packet.m_dataASCII, idx);
|
parseStatus(data, idx);
|
||||||
break;
|
break;
|
||||||
case '?': // Query
|
case '?': // Query
|
||||||
break;
|
break;
|
||||||
case '@': // Position with timestamp (with APRS messaging)
|
case '@': // Position with timestamp (with APRS messaging)
|
||||||
parseTime(packet.m_dataASCII, idx);
|
parseTime(data, idx);
|
||||||
parsePosition(packet.m_dataASCII, idx);
|
parsePosition(data, idx);
|
||||||
if (m_symbolCode == '_')
|
if (m_symbolCode == '_')
|
||||||
parseWeather(packet.m_dataASCII, idx, false);
|
parseWeather(data, idx, false);
|
||||||
else if (m_symbolCode == '@')
|
else if (m_symbolCode == '@')
|
||||||
parseStorm(packet.m_dataASCII, idx);
|
parseStorm(data, idx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parseDataExension(packet.m_dataASCII, idx);
|
parseDataExension(data, idx);
|
||||||
parseComment(packet.m_dataASCII, idx);
|
parseComment(data, idx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'T': // Telemetry data
|
case 'T': // Telemetry data
|
||||||
parseTelemetry(packet.m_dataASCII, idx);
|
parseTelemetry(data, idx);
|
||||||
break;
|
break;
|
||||||
case '_': // Weather report (without position)
|
case '_': // Weather report (without position)
|
||||||
parseTimeMDHM(packet.m_dataASCII, idx);
|
parseTimeMDHM(data, idx);
|
||||||
parseWeather(packet.m_dataASCII, idx, true);
|
parseWeather(data, idx, true);
|
||||||
break;
|
break;
|
||||||
case '`': // Mic-E Information Field Data (current)
|
case '`': // Mic-E Information Field Data (current)
|
||||||
case '\'': // Mic-E Information Field Data (old)
|
case '\'': // Mic-E Information Field Data (old)
|
||||||
parseMicE(packet.m_dataASCII, idx, m_to);
|
parseMicE(data, idx, m_to);
|
||||||
break;
|
break;
|
||||||
case '{': // User-defined APRS packet format
|
case '{': // User-defined APRS packet format
|
||||||
break;
|
break;
|
||||||
@ -182,10 +185,9 @@ bool APRSPacket::decode(AX25Packet packet)
|
|||||||
qDebug() << "APRSPacket::decode: AX.25 Destination did not match known regexp " << m_to;
|
qDebug() << "APRSPacket::decode: AX.25 Destination did not match known regexp " << m_to;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "APRSPacket::decode: Invalid value in type=" << packet.m_type << " pid=" << packet.m_pid << " length of " << packet.m_dataASCII;
|
qDebug() << "APRSPacket::decode: Not ARPS: type=" << packet.m_type << " pid=" << packet.m_pid << " length=" << packet.m_data.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ struct SDRBASE_API APRSPacket {
|
|||||||
QString m_from;
|
QString m_from;
|
||||||
QString m_to;
|
QString m_to;
|
||||||
QString m_via;
|
QString m_via;
|
||||||
QString m_data; // Original ASCII data
|
QByteArray m_data; // Original binary data
|
||||||
|
|
||||||
QDateTime m_dateTime; // Date/time of reception / decoding
|
QDateTime m_dateTime; // Date/time of reception / decoding
|
||||||
|
|
||||||
@ -244,9 +244,36 @@ struct SDRBASE_API APRSPacket {
|
|||||||
return QString("%1,%2").arg(m_latitude).arg(m_longitude);
|
return QString("%1,%2").arg(m_latitude).arg(m_longitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString toTNC2(QString igateCallsign)
|
QByteArray toTNC2(QString igateCallsign)
|
||||||
{
|
{
|
||||||
return m_from + ">" + m_to + (m_via.isEmpty() ? "" : ("," + m_via)) + ",qAR," + igateCallsign + ":" + m_data + "\r\n";
|
QByteArray data;
|
||||||
|
|
||||||
|
data.append(m_from.toLatin1());
|
||||||
|
data.append('>');
|
||||||
|
data.append(m_to.toLatin1());
|
||||||
|
if (!m_via.isEmpty())
|
||||||
|
{
|
||||||
|
data.append(',');
|
||||||
|
data.append(m_via.toLatin1());
|
||||||
|
}
|
||||||
|
data.append(",qAR,");
|
||||||
|
data.append(igateCallsign.toLatin1());
|
||||||
|
data.append(':');
|
||||||
|
|
||||||
|
// #2028 - Protect against APRS-IS server command injection, by only sending up to first CR/LF
|
||||||
|
int idx = m_data.indexOf("\r\n");
|
||||||
|
if (idx >= 0)
|
||||||
|
{
|
||||||
|
data.append(m_data.left(idx + 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.append(m_data);
|
||||||
|
data.append('\r');
|
||||||
|
data.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a TNC2 formatted packet (as sent by APRS-IS Igates) to an AX25 byte array
|
// Convert a TNC2 formatted packet (as sent by APRS-IS Igates) to an AX25 byte array
|
||||||
|
@ -132,7 +132,7 @@ bool AX25Packet::decode(QByteArray packet)
|
|||||||
infoStart = i;
|
infoStart = i;
|
||||||
infoEnd = packet.size()-2-i;
|
infoEnd = packet.size()-2-i;
|
||||||
QByteArray info(packet.mid(infoStart, infoEnd));
|
QByteArray info(packet.mid(infoStart, infoEnd));
|
||||||
m_dataASCII = QString::fromLatin1(info);
|
m_data = info;
|
||||||
m_dataHex = QString(info.toHex());
|
m_dataHex = QString(info.toHex());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -32,7 +32,7 @@ struct SDRBASE_API AX25Packet {
|
|||||||
QString m_via;
|
QString m_via;
|
||||||
QString m_type;
|
QString m_type;
|
||||||
QString m_pid;
|
QString m_pid;
|
||||||
QString m_dataASCII;
|
QByteArray m_data;
|
||||||
QString m_dataHex;
|
QString m_dataHex;
|
||||||
|
|
||||||
bool decode(QByteArray packet);
|
bool decode(QByteArray packet);
|
||||||
|
Loading…
Reference in New Issue
Block a user