satdump/src-core/common/ccsds/ccsds.cpp

151 lines
4.5 KiB
C++
Raw Permalink Normal View History

2021-07-02 01:03:35 +02:00
#include "ccsds.h"
#include <cmath>
#include <cstdint>
2021-07-02 01:03:35 +02:00
#include <cstring>
#include <cstdio>
2021-07-02 01:03:35 +02:00
namespace ccsds
{
CCSDSHeader::CCSDSHeader() {}
2021-07-02 01:03:35 +02:00
CCSDSHeader::CCSDSHeader(uint8_t *rawi)
{
std::memcpy(raw, rawi, 6);
2023-03-20 16:46:57 +01:00
version = rawi[0] >> 5;
type = (rawi[0] >> 4) % 2;
secondary_header_flag = (rawi[0] >> 3) % 2;
apid = (rawi[0] % (int)pow(2, 3)) << 8 | rawi[1];
sequence_flag = rawi[2] >> 6;
packet_sequence_count = (rawi[2] % (int)pow(2, 6)) << 8 | rawi[3];
packet_length = rawi[4] << 8 | rawi[5];
}
void CCSDSHeader::encodeHDR()
{
2023-05-08 23:59:31 +02:00
raw[0] = (version & 0b111) << 5 | (type & 0b1) << 4 | (secondary_header_flag & 0b1) << 3 | ((apid >> 8) & 0b111);
2023-03-20 16:46:57 +01:00
raw[1] = apid & 0xFF;
2023-05-08 23:59:31 +02:00
raw[2] = (sequence_flag & 0b11) << 6 | ((packet_sequence_count >> 8) & 0b111111);
2023-03-20 16:46:57 +01:00
raw[3] = packet_sequence_count & 0xFF;
raw[4] = packet_length >> 8;
raw[5] = packet_length & 0xFF;
}
void CCSDSPacket::encodeHDR()
{
header.packet_length = payload.size() - 1;
header.encodeHDR();
2021-07-02 01:03:35 +02:00
}
// Parse CCSDS header
CCSDSHeader parseCCSDSHeader(uint8_t *header) { return CCSDSHeader(header); }
2023-04-16 00:30:39 +02:00
CCSDSHeader::CCSDSHeader(const CCSDSHeader &v) noexcept
{
memcpy(raw, v.raw, 6);
version = v.version;
type = v.type;
secondary_header_flag = v.secondary_header_flag;
apid = v.apid;
sequence_flag = v.sequence_flag;
packet_sequence_count = v.packet_sequence_count;
packet_length = v.packet_length;
}
CCSDSHeader &CCSDSHeader::operator=(const CCSDSHeader &v) noexcept
{
if (this != &v)
{
memcpy(raw, v.raw, 6);
version = v.version;
type = v.type;
secondary_header_flag = v.secondary_header_flag;
apid = v.apid;
sequence_flag = v.sequence_flag;
packet_sequence_count = v.packet_sequence_count;
packet_length = v.packet_length;
}
return *this;
};
CCSDSPacket::CCSDSPacket(const CCSDSPacket &v) noexcept
{
header = v.header;
payload = v.payload;
}
CCSDSPacket &CCSDSPacket::operator=(const CCSDSPacket &v) noexcept
{
if (this != &v)
{
header = v.header;
payload = v.payload;
}
return *this;
};
bool crcCheckCCITT(CCSDSPacket &pkt)
{
uint16_t crc2 = pkt.payload[pkt.payload.size() - 2] << 8 | pkt.payload[pkt.payload.size() - 1];
uint16_t crc = 0xFFFF;
const int CCITT_CRC_GEN = 0x1021;
2025-02-03 07:48:52 +01:00
for (int j = 0; j < (int)pkt.payload.size() + 6 - 2; j++)
{
uint8_t val = j < 6 ? pkt.header.raw[j] : pkt.payload[j - 6];
unsigned short dataByte = static_cast<unsigned short>(val) << 8;
for (int i = 8; i > 0; i--)
{
if ((dataByte ^ crc) & 0x8000)
crc = (crc << 1) ^ CCITT_CRC_GEN;
else
crc <<= 1;
dataByte <<= 1;
}
}
return crc == crc2;
}
bool crcCheckHLDC32(CCSDSPacket &pkt)
{
uint32_t crc2 = pkt.payload[pkt.payload.size() - 4] << 24 | pkt.payload[pkt.payload.size() - 3] << 16 | pkt.payload[pkt.payload.size() - 2] << 8 | pkt.payload[pkt.payload.size() - 1];
uint32_t crc = 0xFFFFFFFF;
const int HDLC_CRC_GEN = 0xEDB88320;
for (int j = 0; j < (int)pkt.payload.size() + 6 - 4; j++)
{
uint8_t val = j < 6 ? pkt.header.raw[j] : pkt.payload[j - 6];
unsigned short dataByte = static_cast<unsigned short>(val) << 8;
for (int i = 8; i > 0; i--)
{
if ((dataByte ^ crc) & 0x80000000)
crc = (crc << 1) ^ HDLC_CRC_GEN;
else
crc <<= 1;
dataByte <<= 1;
}
}
return crc ^ 0xFFFFFFFF == crc2;
}
bool crcCheckVerticalParity(CCSDSPacket &pkt)
{
uint16_t crc2 = pkt.payload[pkt.payload.size() - 2] << 8 | pkt.payload[pkt.payload.size() - 1];
uint16_t checksum = 0;
2025-02-03 07:48:52 +01:00
for (int j = 0; j < (int)(pkt.payload.size() + 6 - 2) / 2; j++)
{
int j1 = j * 2 + 0;
int j2 = j * 2 + 1;
uint8_t val1 = j1 < 6 ? pkt.header.raw[j1] : pkt.payload[j1 - 6];
uint8_t val2 = j2 < 6 ? pkt.header.raw[j2] : pkt.payload[j2 - 6];
checksum ^= val1 << 8 | val2;
}
return crc2 == checksum;
}
} // namespace ccsds