mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-15 23:10:11 -07:00
252 lines
4.1 KiB
C++
252 lines
4.1 KiB
C++
/*
|
|
* AISPacket.cpp
|
|
*
|
|
* Created on: Dec 6, 2015
|
|
* Author: peter
|
|
*/
|
|
|
|
#include <cassert>
|
|
#include <diag/Trace.h>
|
|
#include <cstring>
|
|
|
|
#include "RXPacket.hpp"
|
|
|
|
|
|
RXPacket::RXPacket ()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
RXPacket::~RXPacket ()
|
|
{
|
|
}
|
|
|
|
void RXPacket::setChannel(VHFChannel channel)
|
|
{
|
|
mChannel = channel;
|
|
}
|
|
|
|
VHFChannel RXPacket::channel() const
|
|
{
|
|
return mChannel;
|
|
}
|
|
|
|
RXPacket::RXPacket(const RXPacket ©)
|
|
{
|
|
memcpy(mPacket, copy.mPacket, sizeof mPacket);
|
|
mSize = copy.mSize;
|
|
mCRC = copy.mCRC;
|
|
mRSSI = copy.mRSSI;
|
|
mType = copy.mType;
|
|
mRI = copy.mRI;
|
|
mMMSI = copy.mMMSI;
|
|
mSlot = copy.mSlot;
|
|
mChannel = copy.mChannel;
|
|
}
|
|
|
|
RXPacket &RXPacket::operator =(const RXPacket ©)
|
|
{
|
|
memcpy(mPacket, copy.mPacket, sizeof mPacket);
|
|
mSize = copy.mSize;
|
|
mCRC = copy.mCRC;
|
|
mType = copy.mType;
|
|
mRSSI = copy.mRSSI;
|
|
mRI = copy.mRI;
|
|
mMMSI = copy.mMMSI;
|
|
mChannel = copy.mChannel;
|
|
mSlot = copy.mSlot;
|
|
return *this;
|
|
}
|
|
|
|
void RXPacket::reset()
|
|
{
|
|
mType = 0;
|
|
mRI = 0;
|
|
mMMSI = 0;
|
|
mSize = 0;
|
|
mCRC = 0xffff;
|
|
mSlot = 0xffffffff;
|
|
mRSSI = 0;
|
|
memset(mPacket, 0, sizeof mPacket);
|
|
}
|
|
|
|
void RXPacket::setSlot(uint32_t slot)
|
|
{
|
|
mSlot = slot;
|
|
}
|
|
|
|
uint32_t RXPacket::slot() const
|
|
{
|
|
return mSlot;
|
|
}
|
|
|
|
|
|
void RXPacket::setRSSI(uint8_t rssi)
|
|
{
|
|
mRSSI = rssi;
|
|
}
|
|
|
|
uint8_t RXPacket::rssi() const
|
|
{
|
|
return mRSSI;
|
|
}
|
|
|
|
|
|
void RXPacket::addBit(uint8_t bit)
|
|
{
|
|
ASSERT(mSize < MAX_AIS_RX_PACKET_SIZE);
|
|
|
|
uint16_t index = mSize / 8;
|
|
uint8_t offset = mSize % 8;
|
|
|
|
if ( bit )
|
|
mPacket[index] |= ( 1 << offset );
|
|
else
|
|
mPacket[index] &= ~( 1 << offset );
|
|
|
|
++mSize;
|
|
}
|
|
|
|
uint8_t RXPacket::bit(uint16_t pos) const
|
|
{
|
|
if ( pos < mSize ) {
|
|
uint16_t index = pos / 8;
|
|
uint8_t offset = pos % 8;
|
|
|
|
return (mPacket[index] & (1 << offset)) != 0;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
uint32_t RXPacket::bits(uint16_t pos, uint8_t count) const
|
|
{
|
|
ASSERT(count <= 32);
|
|
uint32_t result = 0;
|
|
|
|
for ( uint16_t i = pos; i < pos+count; ++i ) {
|
|
result <<= 1;
|
|
result |= bit(i);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void RXPacket::addBitCRC(uint8_t data)
|
|
{
|
|
if ( (data ^ mCRC) & 0x0001 )
|
|
mCRC = (mCRC >> 1) ^ 0x8408;
|
|
else
|
|
mCRC >>= 1;
|
|
}
|
|
|
|
void RXPacket::addByte(uint8_t byte)
|
|
{
|
|
// The payload is LSB (inverted MSB bytes). This brings it back into MSB format
|
|
|
|
addBit(byte & 0x01);
|
|
addBit(byte & 0x02);
|
|
addBit(byte & 0x04);
|
|
addBit(byte & 0x08);
|
|
addBit(byte & 0x10);
|
|
addBit(byte & 0x20);
|
|
addBit(byte & 0x40);
|
|
addBit(byte & 0x80);
|
|
|
|
// Now we can update our CRC in MSB order which is how it was calculated during encoding by the sender ...
|
|
addBitCRC((byte & 0x80) >> 7);
|
|
addBitCRC((byte & 0x40) >> 6);
|
|
addBitCRC((byte & 0x20) >> 5);
|
|
addBitCRC((byte & 0x10) >> 4);
|
|
addBitCRC((byte & 0x08) >> 3);
|
|
addBitCRC((byte & 0x04) >> 2);
|
|
addBitCRC((byte & 0x02) >> 1);
|
|
addBitCRC(byte & 0x01);
|
|
|
|
}
|
|
|
|
|
|
uint16_t RXPacket::size() const
|
|
{
|
|
return mSize;
|
|
}
|
|
|
|
|
|
bool RXPacket::isBad() const
|
|
{
|
|
/*
|
|
* We don't anticipate anything less than 168 + 16 = 184 bits
|
|
*/
|
|
|
|
//return mSize < 184;
|
|
return mSize < 64;
|
|
}
|
|
|
|
uint16_t RXPacket::crc() const
|
|
{
|
|
return mCRC;
|
|
}
|
|
|
|
void RXPacket::discardCRC()
|
|
{
|
|
if ( mCRC == 0xffff )
|
|
return;
|
|
mSize -= 16;
|
|
mCRC = 0xffff;
|
|
}
|
|
|
|
void RXPacket::addFillBits(uint8_t numBits)
|
|
{
|
|
for ( uint8_t i = 0; i < numBits; ++i )
|
|
addBit(0);
|
|
}
|
|
|
|
|
|
|
|
bool RXPacket::checkCRC() const
|
|
{
|
|
//uint16_t rcrc = ((mCRC & 0xff00) >> 8) | ((mCRC & 0x00ff) << 8);
|
|
//trace_printf("%.4x %.4x %.4x\n", mCRC, ~(mCRC), ~(rcrc));
|
|
return mCRC == 0xf0b8;
|
|
|
|
}
|
|
|
|
uint8_t RXPacket::messageType() const
|
|
{
|
|
if ( mType )
|
|
return mType;
|
|
|
|
for ( int i = 0; i < 6; ++i ) {
|
|
mType <<= 1;
|
|
mType |= bit(i);
|
|
}
|
|
|
|
return mType;
|
|
}
|
|
|
|
uint8_t RXPacket::repeatIndicator() const
|
|
{
|
|
if ( mRI )
|
|
return mRI;
|
|
|
|
mRI = bit(6) << 1 | bit(7);
|
|
return mRI;
|
|
}
|
|
|
|
uint32_t RXPacket::mmsi() const
|
|
{
|
|
if ( mMMSI )
|
|
return mMMSI;
|
|
|
|
for ( int i = 8; i < 38; ++i ) {
|
|
mMMSI <<= 1;
|
|
mMMSI |= bit(i);
|
|
}
|
|
|
|
return mMMSI;
|
|
}
|
|
|
|
|
|
|
|
|