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