CCSDSPack
C++ Library for CCSDS Space Packet manipulation. i.e. generation, extraction, analisys and more
Loading...
Searching...
No Matches
CCSDSPacket.cpp
Go to the documentation of this file.
1#include "CCSDSPacket.h"
2#include "CCSDSDataField.h"
3#include "CCSDSUtils.h"
4#include <algorithm>
5
8 const auto dataField = m_dataField.getFullDataFieldBytes();
9 const auto dataFiledSize = static_cast<uint16_t>(dataField.size());
10 const auto dataFieldHeaderFlag(m_dataField.getDataFieldHeaderFlag());
11 m_primaryHeader.setDataLength(dataFiledSize);
12 m_primaryHeader.setDataFieldHeaderFlag(dataFieldHeaderFlag);
13 // todo this part needs to be moved out of conditional updating
16 } else {
18 }
20 m_updateStatus = true;
21 }
22}
23
25 update();
26 return m_CRC16;
27}
28
30 return m_dataField.getDataFieldAvailableBytesSize();
31}
32
34 update();
35 return m_primaryHeader.getDataFieldHeaderFlag();
36}
37
38std::vector<uint8_t> CCSDS::Packet::getCRCVectorBytes() {
39 std::vector<uint8_t> crc(2);
40 const auto crcVar = getCRC();
41 crc[0] = (crcVar >> 8) & 0xFF; // MSB (Most Significant Byte)
42 crc[1] = crcVar & 0xFF; // LSB (Least Significant Byte)
43 return crc;
44}
45
47 update();
48 return m_dataField;
49}
50
52 update();
53 return m_primaryHeader;
54}
55
57 update();
58 return m_primaryHeader.getFullHeader();
59};
60
62 update();
63 return m_primaryHeader.serialize();
64}
65
67 update();
68 return m_dataField.getDataFieldHeaderBytes();
69}
70
72 update();
73 return m_dataField.getApplicationData();
74}
75
77 return m_dataField.getFullDataFieldBytes();
78}
79
80std::vector<uint8_t> CCSDS::Packet::serialize() {
81 auto header = getPrimaryHeaderBytes();
82 auto dataField = m_dataField.getFullDataFieldBytes();
83 const auto crc = getCRCVectorBytes();
84
85 std::vector<uint8_t> packet;
86 packet.reserve(header.size() + dataField.size() + crc.size());
87 packet.insert(packet.end(), header.begin(), header.end());
88 if (!getFullDataFieldBytes().empty()) {
89 packet.insert(packet.end(), dataField.begin(), dataField.end());
90 }
91 packet.insert(packet.end(), crc.begin(), crc.end());
92
93 return packet;
94}
95
96CCSDS::ResultBool CCSDS::Packet::deserialize(const std::vector<uint8_t> &data) {
98 "Cannot Deserialize Packet, Invalid Data provided data size must be at least 8 bytes");
99
100 std::vector<uint8_t> dataFieldVector;
101 std::copy(data.begin() + 6, data.end(), std::back_inserter(dataFieldVector));
102
103 FORWARD_RESULT(deserialize({data[0], data[1], data[2], data[3], data[4], data[5]}, dataFieldVector));
104
105 return true;
106}
107
108CCSDS::ResultBool CCSDS::Packet::deserialize(const std::vector<uint8_t> &data, const std::string &headerType) {
109 RET_IF_ERR_MSG(data.size() <= 8, ErrorCode::INVALID_DATA,
110 "Cannot Deserialize Packet, Invalid Data provided data size must be at least 8 bytes");
111 RET_IF_ERR_MSG(headerType == "BufferHeader", ErrorCode::INVALID_SECONDARY_HEADER_DATA,
112 "Cannot Deserialize Packet, BufferHeader is not of defined size");
113 RET_IF_ERR_MSG(!m_dataField.getDataFieldHeaderFactory().typeIsRegistered(headerType), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
114 "Cannot Deserialize Packet, Unregistered Secondary header: " + headerType);
115
116 const auto secondaryHeader = m_dataField.getDataFieldHeaderFactory().create(headerType);
117 const auto headerDataSizeBytes = secondaryHeader->getSize();
118
119 std::vector<uint8_t> dataFieldHeaderVector;
120 std::copy_n(data.begin() + 6, headerDataSizeBytes , std::back_inserter(dataFieldHeaderVector));
121 FORWARD_RESULT( secondaryHeader->deserialize(dataFieldHeaderVector ));
122 setDataFieldHeader(secondaryHeader);
123
124 if (data.size() > (8 + headerDataSizeBytes)) {
125 std::vector<uint8_t> dataFieldVector;
126
127 if (data.size() > (9 + headerDataSizeBytes)) {
128 std::copy(data.begin() + 6 + headerDataSizeBytes, data.end(), std::back_inserter(dataFieldVector));
129 }
130 FORWARD_RESULT(deserialize({data[0], data[1], data[2], data[3], data[4], data[5]}, dataFieldVector));
131 }
132
133 return true;
134}
135
136CCSDS::ResultBool CCSDS::Packet::deserialize(const std::vector<uint8_t> &data, const uint16_t headerDataSizeBytes) {
137 RET_IF_ERR_MSG(data.size() <= (8 + headerDataSizeBytes), ErrorCode::INVALID_DATA,
138 "Cannot Serialize Packet, Invalid Data provided");
139
140 std::vector<uint8_t> secondaryHeader;
141 std::vector<uint8_t> dataFieldVector;
142 std::copy(data.begin() + 6, data.begin() + 6 + headerDataSizeBytes, std::back_inserter(secondaryHeader));
143 FORWARD_RESULT(m_dataField.setDataFieldHeader(secondaryHeader));
144 if (data.size() > (7 + headerDataSizeBytes)) {
145 std::copy(data.begin() + 6 + headerDataSizeBytes, data.end(), std::back_inserter(dataFieldVector));
146 }
147 FORWARD_RESULT(deserialize({data[0], data[1], data[2], data[3], data[4], data[5]}, dataFieldVector));
148 return true;
149}
150
151CCSDS::ResultBool CCSDS::Packet::deserialize(const std::vector<uint8_t> &headerData, const std::vector<uint8_t> &data) {
152 RET_IF_ERR_MSG(headerData.size() != 6, ErrorCode::INVALID_HEADER_DATA,
153 "Cannot Deserialize Packet, Invalid Header Data provided.");
154 FORWARD_RESULT(m_primaryHeader.deserialize( headerData ));
155 m_sequenceCounter = m_primaryHeader.getSequenceCount();
156
158 "Cannot Deserialize Packet, Invalid Data provided, at least CRC is required.");
159
160 std::vector<uint8_t> dataCopy;
161 m_CRC16 = (data[data.size() - 2] << 8) + data.back();
162
163 if (data.size() == 2) return true; // returns since no application data is to be written.
164
165 std::copy(data.begin(), data.end() - 2, std::back_inserter(dataCopy));
166 FORWARD_RESULT(m_dataField.setApplicationData(dataCopy));
167
168 return true;;
169}
170
172 // where 8 is derived from 6 bytes for Primary header and 2 bytes for CRC16.
173 return 8 + m_dataField.getDataFieldUsedBytesSize();
174}
175
177 FORWARD_RESULT(m_primaryHeader.setData( data ));
178 m_sequenceCounter = m_primaryHeader.getSequenceCount();
179 m_updateStatus = false;
180 return true;
181}
182
183CCSDS::ResultBool CCSDS::Packet::setPrimaryHeader(const std::vector<uint8_t> &data) {
184 FORWARD_RESULT(m_primaryHeader.deserialize( data ));
185 m_sequenceCounter = m_primaryHeader.getSequenceCount();
186 m_updateStatus = false;
187 return true;
188}
189
191 m_primaryHeader = header;
192}
193
195 m_primaryHeader.setData(data);
196 m_sequenceCounter = m_primaryHeader.getSequenceCount();
197 m_updateStatus = false;
198}
199
200void CCSDS::Packet::setDataFieldHeader(const std::shared_ptr<SecondaryHeaderAbstract> &header) {
201 m_dataField.setDataFieldHeader(header);
202 m_updateStatus = false;
203}
204
205CCSDS::ResultBool CCSDS::Packet::setDataFieldHeader(const std::vector<uint8_t> &data, const std::string &headerType) {
206 FORWARD_RESULT(m_dataField.setDataFieldHeader( data, headerType ));
207 m_updateStatus = false;
208 return true;
209}
210
211CCSDS::ResultBool CCSDS::Packet::setDataFieldHeader(const uint8_t *pData, const size_t sizeData,
212 const std::string &headerType) {
213 FORWARD_RESULT(m_dataField.setDataFieldHeader( pData, sizeData, headerType ));
214 m_updateStatus = false;
215 return true;
216}
217
218CCSDS::ResultBool CCSDS::Packet::setDataFieldHeader(const std::vector<uint8_t> &data) {
219 FORWARD_RESULT(m_dataField.setDataFieldHeader( data ));
220 m_updateStatus = false;
221 return true;
222}
223
224CCSDS::ResultBool CCSDS::Packet::setDataFieldHeader(const uint8_t *pData, const size_t sizeData) {
225 FORWARD_RESULT(m_dataField.setDataFieldHeader( pData,sizeData ));
226 m_updateStatus = false;
227 return true;;
228}
229
230CCSDS::ResultBool CCSDS::Packet::setApplicationData(const std::vector<uint8_t> &data) {
231 FORWARD_RESULT(m_dataField.setApplicationData( data ));
232 m_updateStatus = false;
233 return true;
234}
235
236CCSDS::ResultBool CCSDS::Packet::setApplicationData(const uint8_t *pData, const size_t sizeData) {
237 FORWARD_RESULT(m_dataField.setApplicationData( pData,sizeData ));
238 m_updateStatus = false;
239 return true;
240}
241
243 m_primaryHeader.setSequenceFlags(flags);
244 m_updateStatus = false;
245}
246
248 RET_IF_ERR_MSG(m_primaryHeader.getSequenceFlags() == UNSEGMENTED && count != 0, ErrorCode::INVALID_DATA,
249 "Unable to set non 0 value for UNSEGMENTED packet");
250 m_sequenceCounter = count;
251 m_updateStatus = false;
252 return true;
253}
254
255void CCSDS::Packet::setDataFieldSize(const uint16_t size) {
256 m_dataField.setDataPacketSize(size);
257}
258
260 m_enableUpdatePacket = enable;
261 m_dataField.setDataFieldHeaderAutoUpdateStatus(enable);
262}
#define RET_IF_ERR_MSG(condition, errorCode, message)
Macro to return an error with an error message if a condition is met.
#define FORWARD_RESULT(result)
Macro to return a result as-is (for functions returning Result<T>).
uint16_t crc16(const std::vector< uint8_t > &data, uint16_t polynomial=0x1021, uint16_t initialValue=0xFFFF, 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.
bool getDataFieldHeaderFlag() const
retrieves true if a known secondary header has been set
std::vector< uint8_t > getFullDataFieldBytes()
Retrieves the full data field by combining the data field header and application data.
Manages the decomposition and manipulation of CCSDS primary headers.
Definition CCSDSHeader.h:80
void setDataLength(const uint16_t &value)
16 bits
void setSequenceCount(const uint16_t &value)
14 bits
uint8_t getSequenceFlags() const
2 bits
Definition CCSDSHeader.h:88
ResultBool setData(const uint64_t &data)
Sets the header data from a 64-bit integer representation.
void setDataFieldHeaderFlag(const uint8_t &value)
1 bits
uint16_t m_CRC16
Cyclic Redundancy check 16 bits.
ResultBool setSequenceCount(uint16_t count)
Sets the sequence count for the packet.
std::vector< uint8_t > serialize()
Retrieves the full packet as a vector of bytes.
bool m_updateStatus
When setting data thus value should be set to false.
ResultBool deserialize(const std::vector< uint8_t > &data)
Deserializes a vector of bytes into a CCSDS packet.
void update()
Updates Primary headers data field size.
ResultBool setApplicationData(const std::vector< uint8_t > &data)
Sets the application data for the packet.
void setUpdatePacketEnable(bool enable)
needs to be called as soon as possible, probably also from constructor.
void setDataFieldSize(uint16_t size)
Sets the maximum data packet size for the CCSDS DataField.
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.
Header m_primaryHeader
6 bytes / 48 bits / 12 hex
uint64_t getPrimaryHeader64bit()
Retrieves the primary header of the packet.
DataField m_dataField
variable
uint16_t getCRC()
Computes and retrieves the CRC-16 checksum of the packet.
void setSequenceFlags(ESequenceFlag flags)
Sets the sequence flags for the packet's primary header.
std::vector< uint8_t > getApplicationDataBytes()
Retrieves the application data from the data field.
std::vector< uint8_t > getFullDataFieldBytes()
Retrieves the full data field data.
void setPrimaryHeader(PrimaryHeader data)
Sets the primary header using the provided PrimaryHeader object.
std::vector< uint8_t > getCRCVectorBytes()
Retrieves the CRC-16 checksum as a vector of bytes.
uint16_t m_sequenceCounter
uint16_t getFullPacketLength()
Retrieves the current size of the CCSDS Packet.
CCSDS::Header & getPrimaryHeader()
returns the CCSDS packet's Primary Header.
uint16_t getDataFieldMaximumSize()
returns the maximum data field size
CCSDS::DataField & getDataField()
returns the CCSDS packet's DataField.
bool m_enableUpdatePacket
Enables primary header and secondary header update.
std::vector< uint8_t > getDataFieldHeaderBytes()
Retrieves the secondary header data from the data field.
std::vector< uint8_t > getPrimaryHeaderBytes()
Retrieves the primary header of the packet as a vector of bytes.
CRC16Config m_CRC16Config
structure holding configuration of crc calculation.
Encapsulates a result that can hold either a value or an Error.
Definition CCSDSResult.h:81
ESequenceFlag
Represents the sequence flags used in CCSDS telemetry transfer frames.
Definition CCSDSHeader.h:19
@ UNSEGMENTED
11 Complete packet in a single frame.
Definition CCSDSHeader.h:23
@ INVALID_DATA
Data is invalid.
Definition CCSDSResult.h:23
@ INVALID_HEADER_DATA
Header data is invalid.
Definition CCSDSResult.h:24
@ INVALID_SECONDARY_HEADER_DATA
Secondary header data is invalid.
Definition CCSDSResult.h:25
uint16_t finalXorValue
Definition CCSDSPacket.h:39
uint16_t initialValue
Definition CCSDSPacket.h:38
Represents the primary header of a CCSDS packet.
Definition CCSDSHeader.h:41