satdump/plugins/goes_support/goes/grb/data/payload_assembler.cpp

111 lines
4.1 KiB
C++
Raw Permalink Normal View History

2021-11-14 21:11:43 +01:00
#include "payload_assembler.h"
#include "logger.h"
namespace goes
{
namespace grb
{
2022-07-26 03:03:30 +02:00
GRBFilePayloadAssembler::GRBFilePayloadAssembler()
2021-11-14 21:11:43 +01:00
{
}
void GRBFilePayloadAssembler::work(ccsds::CCSDSPacket &pkt)
{
// If lengths do not match, discard
2021-11-16 20:42:57 +01:00
if (pkt.header.packet_length + 1 != (int)pkt.payload.size())
2021-11-14 21:11:43 +01:00
return;
2022-06-19 11:13:39 +02:00
if (current_payloads.count(pkt.header.apid) == 0)
current_payloads.insert({pkt.header.apid, GRBFilePayload()});
GRBFilePayload &current_payload = current_payloads[pkt.header.apid];
2021-11-14 21:11:43 +01:00
if (pkt.header.sequence_flag == 1 || pkt.header.sequence_flag == 3)
{
2022-06-19 11:13:39 +02:00
if (current_payload.in_progress)
2021-11-14 21:11:43 +01:00
{
// Process
if (current_payload.valid)
2022-07-26 03:03:30 +02:00
processor->processPayload(current_payload);
2021-11-14 21:11:43 +01:00
}
// Reset
current_payload = GRBFilePayload();
// Check CRC. We need to recompose the packet for that
bool crc_ok = crc_valid(pkt);
if (!crc_ok && !ignore_crc)
2021-11-14 21:11:43 +01:00
{
logger->error("Invalid CRC. Discarding payload.");
return;
}
// Parse secondary header
current_payload.apid = pkt.header.apid;
current_payload.sec_header = GRBSecondaryHeader(&pkt.payload.data()[0]);
// Fill in payload, discarding CRC and header
current_payload.payload.insert(current_payload.payload.end(), &pkt.payload.data()[8], &pkt.payload.data()[pkt.payload.size() - 4]);
2022-06-19 11:13:39 +02:00
current_payload.in_progress = true;
2021-11-14 21:11:43 +01:00
}
else if (pkt.header.sequence_flag == 0 || pkt.header.sequence_flag == 2)
{
bool crc_ok = crc_valid(pkt);
if (!crc_ok && !ignore_crc)
2021-11-14 21:11:43 +01:00
{
2022-06-19 11:13:39 +02:00
current_payload.in_progress = false;
2021-11-14 21:11:43 +01:00
current_payload.valid = false;
logger->error("Invalid CRC. Discarding payload.");
return;
}
2022-06-19 11:13:39 +02:00
if (current_payload.in_progress && // Make sure a file is in progress
2021-11-14 21:11:43 +01:00
current_payload.apid == pkt.header.apid // ....and that the APID matches
)
{
current_payload.payload.insert(current_payload.payload.end(), &pkt.payload.data()[8], &pkt.payload.data()[pkt.payload.size() - 4]);
}
2022-06-19 11:13:39 +02:00
if (pkt.header.sequence_flag == 2 && current_payload.in_progress) // We're done with this payload
2021-11-14 21:11:43 +01:00
{
// Process
if (current_payload.valid)
2022-07-26 03:03:30 +02:00
processor->processPayload(current_payload);
2022-06-19 11:13:39 +02:00
current_payload.in_progress = false;
2021-11-14 21:11:43 +01:00
}
}
}
bool GRBFilePayloadAssembler::crc_valid(ccsds::CCSDSPacket &pkt)
{
// Extract CRC
uint32_t sent_checksum = 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];
// We need to re-compose the packet
std::vector<uint8_t> fullPkt;
try
{
fullPkt.insert(fullPkt.end(), &pkt.header.raw[0], &pkt.header.raw[6]);
fullPkt.insert(fullPkt.end(), &pkt.payload[0], &pkt.payload[pkt.payload.size() - 4]);
}
catch (std::exception&)
2021-11-14 21:11:43 +01:00
{
return false;
}
// Compute out own
uint32_t checksum = crc.compute(fullPkt.data(), fullPkt.size());
fullPkt.clear(); // Free memory
// if (checksum != sent_checksum)
2023-05-08 23:08:34 +02:00
// logger->critical("CRC CHECK %d %d", sent_checksum, checksum);
2021-11-14 21:11:43 +01:00
return checksum == sent_checksum;
}
}
}