CCSDSPack
C++ Library for CCSDS Space Packet manipulation. i.e. generation, extraction, analisys and more
Loading...
Searching...
No Matches
CCSDSManager.cpp
Go to the documentation of this file.
1#include <random>
2#include <utility>
3#include <algorithm>
4#include "CCSDSManager.h"
5#include "CCSDSUtils.h"
6
7void CCSDS::Manager::setSyncPattern(std::uint32_t syncPattern) { m_syncPattern = syncPattern; }
8
9uint32_t CCSDS::Manager::getSyncPattern() const { return m_syncPattern; }
10
11void CCSDS::Manager::setSyncPatternEnable(const bool enable) { m_syncPattEnable = enable; }
12
13bool CCSDS::Manager::getSyncPatternEnable() const { return m_syncPattEnable; }
14
16 RET_IF_ERR_MSG(m_templateIsSet, ErrorCode::TEMPLATE_SET_FAILURE, "Cannot set Template as it is already set, please clear Manager first");
17 m_templatePacket.setUpdatePacketEnable(false);
18 m_templatePacket = std::move(packet);
19 m_validator.setTemplatePacket(m_templatePacket);
20 m_validator.configure(true, true, true);
21 m_validateEnable = true;
22 m_templateIsSet = true;
23 return true;
24}
25
27
28 Packet templatePacket;
29 FORWARD_RESULT(templatePacket.loadFromConfigFile(configPath));
30 m_templatePacket = std::move(templatePacket);
31 m_templateIsSet = true;
32 return true;;
33}
34#ifndef CCSDS_MCU
36
37 Packet templatePacket;
38 FORWARD_RESULT(templatePacket.loadFromConfig(cfg));
39 m_templatePacket = std::move(templatePacket);
40 m_templateIsSet = true;
41 return true;;
42}
43#endif
44void CCSDS::Manager::setDataFieldSize(const std::uint16_t size) {
45 m_templatePacket.setDataFieldSize(size);
46}
47
49 return m_templatePacket.getDataFieldMaximumSize();
50}
51
52CCSDS::ResultBool CCSDS::Manager::setApplicationData(const std::vector<std::uint8_t> &data) {
53 RET_IF_ERR_MSG(data.empty(), ErrorCode::NO_DATA, "Cannot set Application data, Provided data is empty");
54 RET_IF_ERR_MSG(!m_templateIsSet, ErrorCode::INVALID_HEADER_DATA, "Cannot set Application data, No template has been set");
55
56 const auto maxBytesPerPacket = m_templatePacket.getDataFieldMaximumSize();
57 const auto dataBytesSize = data.size();
58
59 if (!m_packets.empty()) {
60 m_packets.clear();
61 }
62
63 std::uint32_t i = 0;
64 auto remainderBytes = static_cast<std::int32_t>(dataBytesSize);
65 auto sequenceFlag = UNSEGMENTED;
66 while (i < dataBytesSize) {
67 Packet newPacket = m_templatePacket;
68 std::vector<std::uint8_t> tmp;
69 if (remainderBytes > maxBytesPerPacket) {
70 tmp.insert(tmp.end(), data.begin() + i, data.begin() + i + maxBytesPerPacket);
71 remainderBytes -= maxBytesPerPacket;
72 if (i == 0) {
73 sequenceFlag = FIRST_SEGMENT;
74 m_sequenceCount++;
75 } else {
76 sequenceFlag = CONTINUING_SEGMENT;
77 }
78 i += maxBytesPerPacket;
79 FORWARD_RESULT(newPacket.setApplicationData(tmp));
80 newPacket.setSequenceFlags(sequenceFlag);
81 FORWARD_RESULT(newPacket.setSequenceCount(m_sequenceCount));
82 } else {
83 tmp.insert(tmp.end(), data.begin() + i, data.begin() + i + remainderBytes);
84 i += remainderBytes;
85 if (sequenceFlag != UNSEGMENTED) {
87 FORWARD_RESULT(newPacket.setSequenceCount(m_sequenceCount));
88 }
89 FORWARD_RESULT(newPacket.setApplicationData(tmp));
90 }
91 newPacket.setUpdatePacketEnable(m_updateEnable);
92 m_packets.push_back(std::move(newPacket));
93 m_sequenceCount++;
94 }
95 return true;
96}
97
98void CCSDS::Manager::setAutoUpdateEnable(const bool enable) {
99 m_updateEnable = enable;
100 for (auto &packet: m_packets) {
101 packet.setUpdatePacketEnable(enable);
102 }
103}
104
106 m_validateEnable = enable;
107}
108
110 auto data = m_templatePacket.serialize();
111 RET_IF_ERR_MSG(data.empty(), ErrorCode::NO_DATA, "Cannot get Packet template data, data is empty (impossible)"); // possibly redundant.
112 return data;
113}
114
116 RET_IF_ERR_MSG(index < 0 || index >= m_packets.size(), ErrorCode::INVALID_DATA,
117 "Cannot get packet, index is out of bounds");
118 if (m_validateEnable) {
119 m_packets[index].update();
120 const std::string errorMessage = "Validation failure for packet at index " + std::to_string(index);
121 RET_IF_ERR_MSG(!m_validator.validate(m_packets[index]), ErrorCode::VALIDATION_FAILURE,
122 errorMessage);
123 }
124 return m_packets[index].serialize();
125}
126
127std::vector<std::uint8_t> CCSDS::Manager::getPacketsBuffer() const {
128 std::vector<std::uint8_t> buffer;
129 for (auto packet : m_packets) {
130 if (m_syncPattEnable) {
131 buffer.push_back(m_syncPattern >> 24 & 0xff);
132 buffer.push_back(m_syncPattern >> 16 & 0xff);
133 buffer.push_back(m_syncPattern >> 8 & 0xff);
134 buffer.push_back(m_syncPattern & 0xff);
135 }
136 std::vector<std::uint8_t> packetBuffer = packet.serialize();
137 buffer.insert(buffer.end(), packetBuffer.begin(), packetBuffer.end());
138 }
139 return buffer;
140}
141
143 RET_IF_ERR_MSG(m_packets.empty(), ErrorCode::NO_DATA, "Cannot get Application data, no packets have been set.");
144 std::vector<std::uint8_t> data;
145
146 for (std::uint32_t index = 0; index < m_packets.size(); index++) {
147 if (m_validateEnable) {
148 const std::string errorMessage = "Validation failure for packet at index" + std::to_string(index);
149 RET_IF_ERR_MSG(!m_validator.validate(m_packets[index]), ErrorCode::VALIDATION_FAILURE,
150 errorMessage);
151 }
152 auto applicationData = m_packets[index].getApplicationDataBytes();
153 data.insert(data.end(), applicationData.begin(), applicationData.end());
154 }
155 return data;
156}
157
159 RET_IF_ERR_MSG(index < 0 || index >= m_packets.size(), ErrorCode::INVALID_DATA,
160 "Cannot get Application data, index is out of bounds");
161 return m_packets[index].getApplicationDataBytes();
162}
163
165 return m_packets.size();
166}
167
168std::vector<CCSDS::Packet> CCSDS::Manager::getPackets() {
169 return m_packets;
170}
171
173
174 if (m_validateEnable && !m_updateEnable) {
175 if (!m_templateIsSet) {
176 m_validator.configure(true, true, false);
177 }
178 RET_IF_ERR_MSG(m_validator.validate(packet), ErrorCode::VALIDATION_FAILURE, "packet is not valid");
179 }
180 packet.setUpdatePacketEnable(m_updateEnable);
181 m_packets.push_back(std::move(packet));
182 return true;
183}
184
185CCSDS::ResultBool CCSDS::Manager::addPacketFromBuffer(const std::vector<std::uint8_t>& packetBuffer) {
186 Packet packet;
187 FORWARD_RESULT(packet.deserialize(packetBuffer));
188 FORWARD_RESULT(addPacket(packet));
189 return true;
190}
191
192
193[[nodiscard]] CCSDS::ResultBool CCSDS::Manager::load(const std::vector<Packet>& packets) {
194
195 for (const auto& packet: packets) {
196 FORWARD_RESULT(addPacket(packet));
197 }
198 return true;
199}
200
201[[nodiscard]] CCSDS::ResultBool CCSDS::Manager::load(const std::vector<std::uint8_t>& packetsBuffer) {
202 RET_IF_ERR_MSG(packetsBuffer.size() < 8, ErrorCode::INVALID_DATA, "invalid packet buffer size");
203 std::uint32_t offset{0};
204 while (offset < packetsBuffer.size()) {
205 std::vector<std::uint8_t> headerData;
206 if (m_syncPattEnable) {
207 const std::uint32_t value = (static_cast<std::uint32_t>(packetsBuffer[offset]) << 24) |
208 (static_cast<std::uint32_t>(packetsBuffer[offset+1]) << 16) |
209 (static_cast<std::uint32_t>(packetsBuffer[offset+2]) << 8) |
210 (static_cast<std::uint32_t>(packetsBuffer[offset+3]));
211 RET_IF_ERR_MSG(value != m_syncPattern, ErrorCode::INVALID_DATA, "Sync Pattern mismatch.");
212 offset += 4;
213 }
214 headerData.clear();
215 copy_n(packetsBuffer.begin() + offset, 6, std::back_inserter(headerData));
216 Header header;
217 FORWARD_RESULT( header.deserialize(headerData));
218
219 const std::uint16_t packetSize = header.getDataLength() + 8;
220 std::vector<std::uint8_t>packetData;
221 packetData.clear();
222 copy_n(packetsBuffer.begin() + offset, packetSize, std::back_inserter(packetData));
223 FORWARD_RESULT(addPacketFromBuffer(packetData));
224 offset += packetSize;
225 }
226 return true;
227}
228
229CCSDS::ResultBool CCSDS::Manager::read(const std::string &binaryFile) {
230 std::vector<std::uint8_t> buffer;
231 ASSIGN_CP(buffer, readBinaryFile(binaryFile));
232 FORWARD_RESULT(load(buffer));
233 return true;
234}
235
236CCSDS::ResultBool CCSDS::Manager::write(const std::string& binaryFile) const {
237 FORWARD_RESULT(writeBinaryFile(getPacketsBuffer(),binaryFile));
238 return true;
239}
240
241
243 Packet templatePacket;
244 templatePacket.setUpdatePacketEnable(false);
245 if (stringEndsWith(filename, ".bin")) {
246 std::vector<std::uint8_t> buffer;
247 ASSIGN_CP(buffer, readBinaryFile(filename));
248 FORWARD_RESULT(templatePacket.deserialize(buffer));
249 }else if (stringEndsWith(filename, ".cfg")) {
250 FORWARD_RESULT(templatePacket.loadFromConfigFile(filename));
251 } else {
252 return Error{INVALID_DATA,"Cannot load template, invalid file provided [supported extensions [.bin, .cfg]]"};
253 }
254 FORWARD_RESULT(setPacketTemplate(templatePacket));
255 return true;
256}
257
259 clearPackets();
260 m_templateIsSet = false;
261 m_templatePacket= {};
262}
263
265 m_packets.clear();
266 m_sequenceCount = 0;
267 m_validator.clear();
268}
#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>).
#define ASSIGN_CP(var, result)
Macro to assign a result value to a variable or return an error by copy.
bool stringEndsWith(const std::string &str, const std::string &suffix)
Tests if str ends with suffix.
CCSDS::ResultBuffer readBinaryFile(const std::string &filename)
Read a specified binary file and return its contents as a buffer.
CCSDS::ResultBool writeBinaryFile(const std::vector< std::uint8_t > &data, const std::string &filename)
This function takes in a buffer of data and a file name.
Represents an error with both an error code and a message.
Definition CCSDSResult.h:44
Manages the decomposition and manipulation of CCSDS primary headers.
Definition CCSDSHeader.h:80
ResultBool deserialize(const std::vector< std::uint8_t > &data)
Sets the header data from a 64-bit integer representation.
std::uint16_t getDataLength() const
16 bits
Definition CCSDSHeader.h:90
ResultBool loadTemplateConfigFile(const std::string &configPath)
Loads a template packet from a configuration file.
ResultBool setPacketTemplate(Packet packet)
Sets a new packet template.
std::vector< Packet > getPackets()
Retrieves all stored packets.
ResultBuffer getPacketTemplate()
Retrieves the packet template in serialized form.
void setSyncPatternEnable(bool enable)
enable sync pattern utilization both in serialization, deserialization, read and write.
std::uint16_t getDataFieldSize() const
retrieves the set data field size (this includes the secondary header if present)
ResultBool readTemplate(const std::string &filename)
Load a template packet from a binary or configuration file.
void setSyncPattern(std::uint32_t syncPattern)
set sync pattern that should indicate the start of a CCSDS packet.
ResultBool load(const std::vector< Packet > &packets)
Load a vector of packets.
ResultBool addPacket(Packet packet)
Adds a new packet to the list.
std::uint32_t getSyncPattern() const
returns the currently set sync pattern.
std::uint16_t getTotalPackets() const
Retrieves the total number of packets managed.
ResultBuffer getApplicationDataBuffer()
Retrieves the application data from the packets.
std::uint32_t m_syncPattern
ResultBool loadTemplateConfig(const Config &cfg)
Loads a template packet from a configuration object.
ResultBool read(const std::string &binaryFile)
Load a packet or a series of packets from a binary file.
void clearPackets()
Clears the packets and sets the counter to 0.
std::vector< std::uint8_t > getPacketsBuffer() const
Retrieves a buffer containing all the stored packets sequentially.
ResultBool addPacketFromBuffer(const std::vector< std::uint8_t > &packetBuffer)
Adds a new packet to the list.
void setAutoUpdateEnable(bool enable)
Enables or disables automatic updates for packets.
void setDataFieldSize(std::uint16_t size)
Sets the size of the data field.
bool getSyncPatternEnable() const
returns the current settings of the sync pattern enable
ResultBool setApplicationData(const std::vector< std::uint8_t > &data)
Sets the application data for the packet.
void clear()
Clears the manager, removes all packets and template.
void setAutoValidateEnable(bool enable)
Enables or disables automatic validation of packets.
ResultBuffer getApplicationDataBufferAtIndex(std::uint16_t index)
Retrieves the application data from a packet at the given index.
ResultBool write(const std::string &binaryFile) const
Write a packet or a series of packets to a binary file.
ResultBuffer getPacketBufferAtIndex(std::uint16_t index)
Retrieves a packet at the specified index.
Represents a CCSDS (Consultative Committee for Space Data Systems) packet.
Definition CCSDSPacket.h:59
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.
ResultBool loadFromConfig(const Config &cfg)
Loads a packet from a configuration object, including secondary header if present.
void setSequenceFlags(ESequenceFlag flags)
Sets the sequence flags for the packet's primary header.
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.
ResultBool deserialize(const std::vector< std::uint8_t > &data)
Deserializes a vector of bytes into a CCSDS packet.
Encapsulates a result that can hold either a value or an Error.
Definition CCSDSResult.h:82
Parses and stores config values from custom file format.
Definition CCSDSConfig.h:11
@ NO_DATA
No data available.
Definition CCSDSResult.h:23
@ INVALID_DATA
Data is invalid.
Definition CCSDSResult.h:24
@ INVALID_HEADER_DATA
Header data is invalid.
Definition CCSDSResult.h:25
@ TEMPLATE_SET_FAILURE
Failed to set Template Packet.
Definition CCSDSResult.h:31
@ VALIDATION_FAILURE
Validation Failure.
Definition CCSDSResult.h:30
@ LAST_SEGMENT
10 Last segment of a multi-frame packet.
Definition CCSDSHeader.h:22
@ UNSEGMENTED
11 Complete packet in a single frame.
Definition CCSDSHeader.h:23
@ CONTINUING_SEGMENT
00 Intermediate segment of a packet.
Definition CCSDSHeader.h:20
@ FIRST_SEGMENT
01 First segment of a new packet.
Definition CCSDSHeader.h:21