14 const auto dataFiledSize =
static_cast<std::uint16_t
>(dataField.size());
38 std::uint8_t versionNumber;
41 std::uint8_t dataFieldHeaderFlag;
42 std::uint16_t sequenceCount;
44 bool segmented{
false};
47 "Config: Missing int field: ccsds_version_number");
49 "Config: Missing bool field: ccsds_type");
51 "Config: Missing bool field: ccsds_data_field_header_flag");
53 "Config: Missing int field: ccsds_APID");
55 "Config: Missing bool field: ccsds_segmented");
63 m_primaryHeader.setVersionNumber(versionNumber);
64 m_primaryHeader.setType(type);
65 m_primaryHeader.setDataFieldHeaderFlag(dataFieldHeaderFlag);
66 m_primaryHeader.setAPID(APID);
74 m_primaryHeader.setSequenceFlags(sequenceFlag);
75 m_primaryHeader.setSequenceCount(sequenceCount);
77 if (cfg.
isKey(
"data_field_size")) {
78 std::uint16_t dataFieldSize;
80 m_dataField.setDataPacketSize(dataFieldSize);
83 if (cfg.
isKey(
"define_secondary_header")) {
84 bool secondaryHeaderFlag{
false};
86 if (secondaryHeaderFlag) {
91 if (cfg.
isKey(
"application_data")) {
92 std::vector<std::uint8_t> applicationData{};
93 ASSIGN_OR_PRINT(applicationData, cfg.
get<std::vector<std::uint8_t>>(
"application_data"));
107 return m_dataField.getDataFieldAvailableBytesSize();
112 return m_primaryHeader.getDataFieldHeaderFlag();
116 std::vector<std::uint8_t> crc(2);
117 const auto crcVar = getCRC();
118 crc[0] = (crcVar >> 8) & 0xFF;
119 crc[1] = crcVar & 0xFF;
130 return m_primaryHeader;
135 return m_primaryHeader.getFullHeader();
140 return m_primaryHeader.serialize();
145 return m_dataField.getDataFieldHeaderBytes();
150 return m_dataField.getApplicationData();
154 return m_dataField.serialize();
158 auto header = getPrimaryHeaderBytes();
159 auto dataField = m_dataField.serialize();
160 const auto crc = getCRCVectorBytes();
162 std::vector<std::uint8_t> packet;
163 packet.reserve(header.size() + dataField.size() + crc.size());
164 packet.insert(packet.end(), header.begin(), header.end());
165 if (!getFullDataFieldBytes().empty()) {
166 packet.insert(packet.end(), dataField.begin(), dataField.end());
168 packet.insert(packet.end(), crc.begin(), crc.end());
175 "Cannot Deserialize Packet, Invalid Data provided data size must be at least 8 bytes");
177 std::vector<std::uint8_t> dataFieldVector;
178 std::copy(data.begin() + 6, data.end(), std::back_inserter(dataFieldVector));
180 FORWARD_RESULT(deserialize({data[0], data[1], data[2], data[3], data[4], data[5]}, dataFieldVector));
187 "Cannot Deserialize Packet, Invalid Data provided data size must be at least 8 bytes");
189 "Cannot Deserialize Packet, BufferHeader is not of defined size");
190 RET_IF_ERR_MSG(!m_dataField.getDataFieldHeaderFactory().typeIsRegistered(headerType),
192 "Cannot Deserialize Packet, Unregistered Secondary header: " + headerType);
193 std::uint16_t headerDataSizeBytes{0};
194 const auto secondaryHeader = m_dataField.getDataFieldHeaderFactory().create(headerType);
195 if (headerType ==
"PusC" && headerSize > 0) {
196 headerDataSizeBytes = headerSize;
198 headerDataSizeBytes = secondaryHeader->getSize();
201 std::vector<std::uint8_t> dataFieldHeaderVector;
202 std::copy_n(data.begin() + 6, headerDataSizeBytes, std::back_inserter(dataFieldHeaderVector));
203 FORWARD_RESULT(secondaryHeader->deserialize(dataFieldHeaderVector ));
204 setDataFieldHeader(secondaryHeader);
206 if (data.size() > (8 + headerDataSizeBytes)) {
207 std::vector<std::uint8_t> dataFieldVector;
209 if (data.size() > (9 + headerDataSizeBytes)) {
210 std::copy(data.begin() + 6 + headerDataSizeBytes, data.end(), std::back_inserter(dataFieldVector));
212 FORWARD_RESULT(deserialize({data[0], data[1], data[2], data[3], data[4], data[5]}, dataFieldVector));
220 "Cannot Serialize Packet, Invalid Data provided");
222 std::vector<std::uint8_t> secondaryHeader;
223 std::vector<std::uint8_t> dataFieldVector;
224 std::copy(data.begin() + 6, data.begin() + 6 + headerDataSizeBytes, std::back_inserter(secondaryHeader));
226 if (data.size() > (7 + headerDataSizeBytes)) {
227 std::copy(data.begin() + 6 + headerDataSizeBytes, data.end(), std::back_inserter(dataFieldVector));
229 FORWARD_RESULT(deserialize({data[0], data[1], data[2], data[3], data[4], data[5]}, dataFieldVector));
235 "Cannot Deserialize Packet, Invalid Header Data provided.");
237 m_sequenceCounter = m_primaryHeader.getSequenceCount();
240 "Cannot Deserialize Packet, Invalid Data provided, at least CRC is required.");
242 std::vector<uint8_t> dataCopy;
243 m_CRC16 = (data[data.size() - 2] << 8) + data.back();
245 if (data.size() == 2)
return true;
247 std::copy(data.begin(), data.end() - 2, std::back_inserter(dataCopy));
255 return 8 + m_dataField.getDataFieldUsedBytesSize();
260 m_sequenceCounter = m_primaryHeader.getSequenceCount();
261 m_updateStatus =
false;
267 m_sequenceCounter = m_primaryHeader.getSequenceCount();
268 m_updateStatus =
false;
273 m_primaryHeader = header;
278 m_sequenceCounter = m_primaryHeader.getSequenceCount();
279 m_updateStatus =
false;
283 m_dataField.setDataFieldHeader(header);
284 m_updateStatus =
false;
288 FORWARD_RESULT(m_dataField.setDataFieldHeader( data, headerType ));
289 m_updateStatus =
false;
294 const std::string &headerType) {
295 FORWARD_RESULT(m_dataField.setDataFieldHeader( pData, sizeData, headerType ));
296 m_updateStatus =
false;
302 m_updateStatus =
false;
308 m_updateStatus =
false;
314 m_updateStatus =
false;
320 m_updateStatus =
false;
325 m_primaryHeader.setSequenceFlags(flags);
326 m_updateStatus =
false;
331 "Unable to set non 0 value for UNSEGMENTED packet");
332 m_sequenceCounter = count;
333 m_updateStatus =
false;
338 m_dataField.setDataPacketSize(size);
342 m_enableUpdatePacket = enable;
343 m_dataField.setDataFieldHeaderAutoUpdateStatus(enable);
#define RET_IF_ERR_MSG(condition, errorCode, message)
Macro to return an error with an error message if a condition is met.
#define ASSIGN_OR_PRINT(var, result)
Macro to assign a result value or print an error message.
#define FORWARD_RESULT(result)
Macro to return a result as-is (for functions returning Result<T>).
uint16_t crc16(const std::vector< std::uint8_t > &data, std::uint16_t polynomial=0x1021, std::uint16_t initialValue=0xFFFF, std::uint16_t finalXorValue=0x0000)
Computes the CRC-16 checksum for a given data vector with configurable parameters.
Represents the data field of a CCSDS packet.
std::vector< std::uint8_t > serialize()
Retrieves the full data field by combining the data field header and application data.
bool getDataFieldHeaderFlag() const
retrieves true if a known secondary header has been set
bool m_updateStatus
When setting data thus value should be set to false.
std::vector< uint8_t > getPrimaryHeaderBytes()
Retrieves the primary header of the packet as a vector of bytes.
void update()
Updates Primary headers data field size.
std::vector< uint8_t > getCRCVectorBytes()
Retrieves the CRC-16 checksum as a vector of bytes.
void setUpdatePacketEnable(bool enable)
needs to be called as soon as possible, probably also from constructor.
ResultBool setSequenceCount(std::uint16_t count)
Sets the sequence count for the packet.
bool getDataFieldHeaderFlag()
@ returns the data field header flag
void setDataFieldHeader(const std::shared_ptr< SecondaryHeaderAbstract > &header)
Sets the data field header using the provided SecondaryHeaderAbstract derived header.
std::uint16_t m_sequenceCounter
Header m_primaryHeader
6 bytes / 48 bits / 12 hex
std::uint64_t getPrimaryHeader64bit()
Retrieves the primary header of the packet.
DataField m_dataField
variable
ResultBool loadFromConfig(const Config &cfg)
Loads a packet from a configuration object, including secondary header if present.
std::uint16_t getCRC()
Computes and retrieves the CRC-16 checksum of the packet.
std::uint16_t getDataFieldMaximumSize() const
returns the maximum data field size
void setSequenceFlags(ESequenceFlag flags)
Sets the sequence flags for the packet's primary header.
std::vector< uint8_t > getFullDataFieldBytes()
Retrieves the full data field data.
std::vector< uint8_t > serialize()
Retrieves the full packet as a vector of bytes.
ResultBool loadFromConfigFile(const std::string &configPath)
Loads a packet from a configuration file, including secondary header if present.
ResultBool setApplicationData(const std::vector< std::uint8_t > &data)
Sets the application data for the packet.
std::uint16_t m_CRC16
Cyclic Redundancy check 16 bits.
std::vector< uint8_t > getDataFieldHeaderBytes()
Retrieves the secondary header data from the data field.
void setPrimaryHeader(PrimaryHeader data)
Sets the primary header using the provided PrimaryHeader object.
ResultBool deserialize(const std::vector< std::uint8_t > &data)
Deserializes a vector of bytes into a CCSDS packet.
std::uint16_t getFullPacketLength()
Retrieves the current size of the CCSDS Packet.
Header & getPrimaryHeader()
returns the CCSDS packet's Primary Header.
std::vector< uint8_t > getApplicationDataBytes()
Retrieves the application data from the data field.
DataField & getDataField()
returns the CCSDS packet's DataField.
bool m_enableUpdatePacket
Enables primary header and secondary header update.
void setDataFieldSize(std::uint16_t size)
Sets the maximum data packet size for the CCSDS DataField.
CRC16Config m_CRC16Config
structure holding configuration of crc calculation.
Encapsulates a result that can hold either a value or an Error.
Parses and stores config values from custom file format.
bool isKey(const std::string &key) const
CCSDS::ResultBool load(const std::string &filename)
Load config file.
CCSDS::Result< T > get(const std::string &key) const
Get value by key and type.
@ INVALID_DATA
Data is invalid.
@ INVALID_HEADER_DATA
Header data is invalid.
@ CONFIG_FILE_ERROR
Configuration file error.
@ INVALID_SECONDARY_HEADER_DATA
Secondary header data is invalid.
ESequenceFlag
Represents the sequence flags used in CCSDS telemetry transfer frames.
@ UNSEGMENTED
11 Complete packet in a single frame.
@ FIRST_SEGMENT
01 First segment of a new packet.
std::uint16_t initialValue
std::uint16_t finalXorValue