1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 09:48:45 -05:00

Merge pull request #895 from srcejon/fix_858

Fix decoding of AIS class B messages for #858
This commit is contained in:
Edouard Griffiths 2021-05-11 11:36:34 +02:00 committed by GitHub
commit 71d5597a68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 14 deletions

View File

@ -462,6 +462,7 @@ AISDemodGUI::AISDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
setTitleColor(m_channelMarker.getColor()); setTitleColor(m_channelMarker.getColor());
m_settings.setChannelMarker(&m_channelMarker); m_settings.setChannelMarker(&m_channelMarker);
m_settings.setScopeGUI(ui->scopeGUI);
m_deviceUISet->addChannelMarker(&m_channelMarker); m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this); m_deviceUISet->addRollupWidget(this);

View File

@ -24,7 +24,8 @@
#include "aisdemodsettings.h" #include "aisdemodsettings.h"
AISDemodSettings::AISDemodSettings() : AISDemodSettings::AISDemodSettings() :
m_channelMarker(0) m_channelMarker(0),
m_scopeGUI(0)
{ {
resetToDefaults(); resetToDefaults();
} }
@ -85,6 +86,7 @@ QByteArray AISDemodSettings::serialize() const
s.writeU32(18, m_reverseAPIPort); s.writeU32(18, m_reverseAPIPort);
s.writeU32(19, m_reverseAPIDeviceIndex); s.writeU32(19, m_reverseAPIDeviceIndex);
s.writeU32(20, m_reverseAPIChannelIndex); s.writeU32(20, m_reverseAPIChannelIndex);
s.writeBlob(21, m_scopeGUI->serialize());
for (int i = 0; i < AISDEMOD_MESSAGE_COLUMNS; i++) for (int i = 0; i < AISDEMOD_MESSAGE_COLUMNS; i++)
s.writeS32(100 + i, m_messageColumnIndexes[i]); s.writeS32(100 + i, m_messageColumnIndexes[i]);
@ -146,6 +148,12 @@ bool AISDemodSettings::deserialize(const QByteArray& data)
d.readU32(20, &utmp, 0); d.readU32(20, &utmp, 0);
m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
if (m_scopeGUI)
{
d.readBlob(21, &bytetmp);
m_scopeGUI->deserialize(bytetmp);
}
for (int i = 0; i < AISDEMOD_MESSAGE_COLUMNS; i++) for (int i = 0; i < AISDEMOD_MESSAGE_COLUMNS; i++)
d.readS32(100 + i, &m_messageColumnIndexes[i], i); d.readS32(100 + i, &m_messageColumnIndexes[i], i);
for (int i = 0; i < AISDEMOD_MESSAGE_COLUMNS; i++) for (int i = 0; i < AISDEMOD_MESSAGE_COLUMNS; i++)

View File

@ -56,6 +56,7 @@ struct AISDemodSettings
uint16_t m_reverseAPIPort; uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex; uint16_t m_reverseAPIDeviceIndex;
uint16_t m_reverseAPIChannelIndex; uint16_t m_reverseAPIChannelIndex;
Serializable *m_scopeGUI;
int m_messageColumnIndexes[AISDEMOD_MESSAGE_COLUMNS];//!< How the columns are ordered in the table int m_messageColumnIndexes[AISDEMOD_MESSAGE_COLUMNS];//!< How the columns are ordered in the table
int m_messageColumnSizes[AISDEMOD_MESSAGE_COLUMNS]; //!< Size of the columns in the table int m_messageColumnSizes[AISDEMOD_MESSAGE_COLUMNS]; //!< Size of the columns in the table
@ -63,6 +64,7 @@ struct AISDemodSettings
AISDemodSettings(); AISDemodSettings();
void resetToDefaults(); void resetToDefaults();
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
void setScopeGUI(Serializable *scopeGUI) { m_scopeGUI = scopeGUI; }
QByteArray serialize() const; QByteArray serialize() const;
bool deserialize(const QByteArray& data); bool deserialize(const QByteArray& data);
}; };

View File

@ -186,21 +186,21 @@ void AISDemodSink::processOneSample(Complex &ci)
for (int i = 0; i < sampleCnt; i++) { for (int i = 0; i < sampleCnt; i++) {
sampleSum += m_rxBuf[(x + sampleOffset + i) % m_rxBufLength] - dcOffset; sampleSum += m_rxBuf[(x + sampleOffset + i) % m_rxBufLength] - dcOffset;
} }
int sample = sampleSum >= 0.0f ? 1 : 0; int symbol = sampleSum >= 0.0f ? 1 : 0;
// Move to next sample // Move to next symbol
x = (x + m_samplesPerSymbol) % m_rxBufLength; x = (x + m_samplesPerSymbol) % m_rxBufLength;
// HDLC deframing // HDLC deframing
// NRZI decoding // NRZI decoding
int bit; int bit;
if (sample != symbolPrev) { if (symbol != symbolPrev) {
bit = 0; bit = 0;
} else { } else {
bit = 1; bit = 1;
} }
symbolPrev = sample; symbolPrev = symbol;
// Store in shift reg // Store in shift reg
bits |= bit << bitCount; bits |= bit << bitCount;

View File

@ -450,6 +450,13 @@ void AISGUI::updateVessels(AISMessage *ais)
statusItem->setText(AISPositionReport::getStatusString(lrpr->m_status)); statusItem->setText(AISPositionReport::getStatusString(lrpr->m_status));
} }
} }
if (ais->m_id == 19)
{
AISExtendedClassBPositionReport *ext = dynamic_cast<AISExtendedClassBPositionReport*>(ais);
if (ext) {
shipTypeItem->setText(AISMessage::typeToString(ext->m_type));
}
}
if (ais->m_id == 24) if (ais->m_id == 24)
{ {
AISStaticDataReport *dr = dynamic_cast<AISStaticDataReport*>(ais); AISStaticDataReport *dr = dynamic_cast<AISStaticDataReport*>(ais);

View File

@ -531,7 +531,7 @@ AISStandardClassBPositionReport::AISStandardClassBPositionReport(QByteArray ba)
m_longitudeAvailable = longitude != 0x6791ac0; m_longitudeAvailable = longitude != 0x6791ac0;
m_longitude = longitude / 60.0f / 10000.0f; m_longitude = longitude / 60.0f / 10000.0f;
int32_t latitude = ((ba[10] & 0x3) << 24) | ((ba[11] & 0xff) << 16) | ((ba[12] & 0xff) << 8) | (ba[13] & 0xff); int32_t latitude = ((ba[10] & 0x7) << 24) | ((ba[11] & 0xff) << 16) | ((ba[12] & 0xff) << 8) | (ba[13] & 0xff);
latitude = (latitude << 5) >> 5; latitude = (latitude << 5) >> 5;
m_latitudeAvailable = latitude != 0x3412140; m_latitudeAvailable = latitude != 0x3412140;
m_latitude = latitude / 60.0f / 10000.0f; m_latitude = latitude / 60.0f / 10000.0f;
@ -540,10 +540,10 @@ AISStandardClassBPositionReport::AISStandardClassBPositionReport(QByteArray ba)
m_courseAvailable = cog != 3600; m_courseAvailable = cog != 3600;
m_course = cog * 0.1f; m_course = cog * 0.1f;
m_heading = ((ba[15] & 0xf) << 5) | ((ba[17] >> 3) & 0x1f); m_heading = ((ba[15] & 0xf) << 5) | ((ba[16] >> 3) & 0x1f);
m_headingAvailable = m_heading != 511; m_headingAvailable = m_heading != 511;
m_timeStamp = ((ba[17] & 0x7) << 3) | ((ba[18] >> 5) & 0x7); m_timeStamp = ((ba[16] & 0x7) << 3) | ((ba[17] >> 5) & 0x7);
} }
QString AISStandardClassBPositionReport::toString() QString AISStandardClassBPositionReport::toString()
@ -571,7 +571,7 @@ AISExtendedClassBPositionReport::AISExtendedClassBPositionReport(QByteArray ba)
m_longitudeAvailable = longitude != 0x6791ac0; m_longitudeAvailable = longitude != 0x6791ac0;
m_longitude = longitude / 60.0f / 10000.0f; m_longitude = longitude / 60.0f / 10000.0f;
int32_t latitude = ((ba[10] & 0x3) << 24) | ((ba[11] & 0xff) << 16) | ((ba[12] & 0xff) << 8) | (ba[13] & 0xff); int32_t latitude = ((ba[10] & 0x7) << 24) | ((ba[11] & 0xff) << 16) | ((ba[12] & 0xff) << 8) | (ba[13] & 0xff);
latitude = (latitude << 5) >> 5; latitude = (latitude << 5) >> 5;
m_latitudeAvailable = latitude != 0x3412140; m_latitudeAvailable = latitude != 0x3412140;
m_latitude = latitude / 60.0f / 10000.0f; m_latitude = latitude / 60.0f / 10000.0f;
@ -580,23 +580,26 @@ AISExtendedClassBPositionReport::AISExtendedClassBPositionReport(QByteArray ba)
m_courseAvailable = cog != 3600; m_courseAvailable = cog != 3600;
m_course = cog * 0.1f; m_course = cog * 0.1f;
m_heading = ((ba[15] & 0xf) << 5) | ((ba[17] >> 3) & 0x1f); m_heading = ((ba[15] & 0xf) << 5) | ((ba[16] >> 3) & 0x1f);
m_headingAvailable = m_heading != 511; m_headingAvailable = m_heading != 511;
m_timeStamp = ((ba[17] & 0x7) << 3) | ((ba[18] >> 5) & 0x7); m_timeStamp = ((ba[16] & 0x7) << 3) | ((ba[17] >> 5) & 0x7);
m_name = AISMessage::getString(ba, 18, 1, 20); m_name = AISMessage::getString(ba, 17, 1, 20);
m_type = ((ba[32] & 1) << 7) | ((ba[33] >> 1) & 0x3f);
} }
QString AISExtendedClassBPositionReport::toString() QString AISExtendedClassBPositionReport::toString()
{ {
return QString("Lat: %1%5 Lon: %2%5 Speed: %3 knts Course: %4%5 Name: %6") return QString("Lat: %1%5 Lon: %2%5 Speed: %3 knts Course: %4%5 Name: %6 Type: %7")
.arg(m_latitude) .arg(m_latitude)
.arg(m_longitude) .arg(m_longitude)
.arg(m_speedOverGround) .arg(m_speedOverGround)
.arg(m_course) .arg(m_course)
.arg(QChar(0xb0)) .arg(QChar(0xb0))
.arg(m_name); .arg(m_name)
.arg(typeToString(m_type));
} }
AISDatalinkManagement::AISDatalinkManagement(QByteArray ba) : AISDatalinkManagement::AISDatalinkManagement(QByteArray ba) :

View File

@ -276,6 +276,7 @@ public:
int m_heading; // Degrees int m_heading; // Degrees
int m_timeStamp; int m_timeStamp;
QString m_name; QString m_name;
quint8 m_type;
AISExtendedClassBPositionReport(const QByteArray ba); AISExtendedClassBPositionReport(const QByteArray ba);
virtual QString getType() override { return "Extended Class B equipment position report"; } virtual QString getType() override { return "Extended Class B equipment position report"; }