CCSDSPack
C++ Library for CCSDS Space Packet manipulation. i.e. generation, extraction, analisys and more
Loading...
Searching...
No Matches
CCSDSDataField.cpp
Go to the documentation of this file.
1// Copyright 2025-2026 ExoSpaceLabs
2// SPDX-License-Identifier: Apache-2.0
3
4#include "CCSDSDataField.h"
6
7#include <utility>
8
9std::vector<std::uint8_t> CCSDS::DataField::serialize() {
10 update();
11 const auto &dataFieldHeader = getDataFieldHeaderBytes();
12 std::vector<std::uint8_t> fullData{};
13 if (!dataFieldHeader.empty()) {
14 fullData.insert(fullData.end(), dataFieldHeader.begin(), dataFieldHeader.end());
15 }
16 fullData.insert(fullData.end(), m_applicationData.begin(), m_applicationData.end());
17 return fullData;
18}
19
20std::vector<std::uint8_t> CCSDS::DataField::getApplicationData() {
21 return m_applicationData;
22}
23
25 return m_dataPacketSize - getDataFieldUsedBytesSize();
26}
27
29 return m_dataPacketSize;
30}
31
33 return m_applicationData.size();
34}
35
36
38 if (!getDataFieldHeaderFlag()) {
39 return m_applicationData.size();
40 }
41 if (m_secondaryHeader != nullptr) {
42 return m_applicationData.size() + m_secondaryHeader->getSize();
43 }
44 return 0;
45}
46
47std::shared_ptr<CCSDS::SecondaryHeaderAbstract> CCSDS::DataField::getSecondaryHeader() {
48 update();
49 return m_secondaryHeader;
50}
51
53 if (!m_dataFieldHeaderUpdated && m_enableDataFieldUpdate) {
54 if (m_secondaryHeaderFactory.typeIsRegistered(m_dataFieldHeaderType)) {
55 m_secondaryHeader->update(this);
56 }
57 m_dataFieldHeaderUpdated = true;
58 }
59}
60
61CCSDS::ResultBool CCSDS::DataField::setApplicationData(const std::uint8_t *pData, const size_t &sizeData) {
62 RET_IF_ERR_MSG(!pData, ErrorCode::NULL_POINTER, "Application data is nullptr");
63 RET_IF_ERR_MSG(sizeData < 1, ErrorCode::INVALID_APPLICATION_DATA, "Application data size cannot be < 1");
64 RET_IF_ERR_MSG(sizeData > getDataFieldAvailableBytesSize(), ErrorCode::INVALID_APPLICATION_DATA,
65 "Application data field exceeds available size");
66
67 if (!m_applicationData.empty()) {
68 printf( "[ CCSDS Data ] Warning: Data field is not empty, it has been overwritten.");
69 }
70 m_applicationData.assign(pData, pData + sizeData);
71 m_dataFieldHeaderUpdated = false;
72 return true;
73}
74
75CCSDS::ResultBool CCSDS::DataField::setApplicationData(const std::vector<std::uint8_t> &applicationData) {
76 RET_IF_ERR_MSG(applicationData.size() > getDataFieldAvailableBytesSize(), ErrorCode::INVALID_APPLICATION_DATA,
77 "Application data field exceeds available size.");
78 m_applicationData = applicationData;
79 m_dataFieldHeaderUpdated = false;
80 return true;
81}
82
83CCSDS::ResultBool CCSDS::DataField::setDataFieldHeader(const std::uint8_t *pData, const size_t &sizeData) {
84 RET_IF_ERR_MSG(!pData, ErrorCode::NULL_POINTER, "Secondary header data is nullptr");
85 RET_IF_ERR_MSG(sizeData < 1, ErrorCode::INVALID_SECONDARY_HEADER_DATA, "Secondary header data size cannot be < 1");
86 RET_IF_ERR_MSG(sizeData > getDataFieldAvailableBytesSize(), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
87 "Secondary header data exceeds available size.");
88
89 std::vector<std::uint8_t> data;
90 data.assign(pData, pData + sizeData);
91 FORWARD_RESULT( setDataFieldHeader(data) );
92 return true;
93}
94
95CCSDS::ResultBool CCSDS::DataField::setDataFieldHeader(const std::uint8_t *pData, const size_t &sizeData,
96 const std::string &pType) {
97 RET_IF_ERR_MSG(!pData, ErrorCode::NULL_POINTER, "Secondary header data is nullptr");
98
99 RET_IF_ERR_MSG(!m_secondaryHeaderFactory.typeIsRegistered(pType), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
100 "Secondary header type is not registered: " + pType);
101
102 if (m_secondaryHeaderFactory.typeIsRegistered(pType)) {
103 std::vector<std::uint8_t> data;
104 data.assign(pData, pData + sizeData);
105 FORWARD_RESULT(setDataFieldHeader(data,pType));
106 } else {
107 FORWARD_RESULT(setDataFieldHeader(pData, sizeData));
108 m_dataFieldHeaderType = pType;
109 }
110 m_dataFieldHeaderUpdated = false;
111 return true;
112}
113
114CCSDS::ResultBool CCSDS::DataField::setDataFieldHeader(const std::vector<std::uint8_t> &data,
115 const std::string &pType) {
116 RET_IF_ERR_MSG(data.size() > getDataFieldAvailableBytesSize(), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
117 "Secondary header data exceeds available size");
118 RET_IF_ERR_MSG(!m_secondaryHeaderFactory.typeIsRegistered(pType), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
119 "Secondary header type is not registered: " + pType);
120
121 auto header = m_secondaryHeaderFactory.create(pType);
122
123 if (!header->variableLength) {
124 RET_IF_ERR_MSG(data.size() != header->getSize(), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
125 "Secondary header data size mismatch for type: " + pType);
126 }
127
128 m_secondaryHeader = std::move(header);
129 FORWARD_RESULT(m_secondaryHeader->deserialize(data));
130
131 m_dataFieldHeaderType = pType;
132
133 m_dataFieldHeaderUpdated = false;
134 return true;
135}
136
137CCSDS::ResultBool CCSDS::DataField::setDataFieldHeader(const std::vector<std::uint8_t> &dataFieldHeader) {
138 RET_IF_ERR_MSG(dataFieldHeader.size() > getDataFieldAvailableBytesSize(), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
139 "Secondary header data exceeds available size");
140
141 BufferHeader header;
142 m_secondaryHeader = std::make_shared<BufferHeader>(dataFieldHeader);
143 FORWARD_RESULT( m_secondaryHeader->deserialize(dataFieldHeader) );
144
145 m_dataFieldHeaderType = m_secondaryHeader->getType(); ;
146 m_dataFieldHeaderUpdated = false;
147 return true;
148}
149
150#ifndef CCSDS_MCU
152 RET_IF_ERR_MSG(!cfg.isKey("secondary_header_type"), ErrorCode::CONFIG_FILE_ERROR,
153 "Config: Missing string field: secondary_header_type");
154 std::string type{};
155 ASSIGN_OR_PRINT(type, cfg.get<std::string>("secondary_header_type"));
156 RET_IF_ERR_MSG(!m_secondaryHeaderFactory.typeIsRegistered(type), ErrorCode::INVALID_SECONDARY_HEADER_DATA,
157 "Secondary header type is not registered: " + type);
158
159 m_secondaryHeader = m_secondaryHeaderFactory.create(type);
161 "Failed to create secondary header of type: " + type);
162 m_secondaryHeader->loadFromConfig(cfg);
163 m_dataFieldHeaderType = m_secondaryHeader->getType();
164 return true;
165}
166#endif
167
168void CCSDS::DataField::setDataFieldHeader(std::shared_ptr<SecondaryHeaderAbstract> header) {
169 m_secondaryHeader = std::move(header);
170 m_dataFieldHeaderType = m_secondaryHeader->getType();
171 m_dataFieldHeaderUpdated = false;
172}
173
174void CCSDS::DataField::setDataPacketSize(const std::uint16_t &value) { m_dataPacketSize = value; }
175
176std::vector<std::uint8_t> CCSDS::DataField::getDataFieldHeaderBytes() {
177 update();
178 if (m_secondaryHeader) {
179 return m_secondaryHeader->serialize();
180 }
181 return {};
182}
183
184
#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>).
Represents a fixed secondary header used as a data buffer.
std::vector< std::uint8_t > serialize()
Retrieves the full data field by combining the data field header and application data.
std::shared_ptr< SecondaryHeaderAbstract > getSecondaryHeader()
retrieves the known PUS type
std::uint16_t getDataFieldUsedBytesSize() const
Retrieves the used size of the data field in bytes.
void setDataPacketSize(const std::uint16_t &value)
Sets the maximum data packet size for the CCSDS DataField.
ResultBool setDataFieldHeader(const std::uint8_t *pData, const size_t &sizeData)
Sets the secondary header data for the data field.
std::uint16_t getDataFieldAbsoluteBytesSize() const
Retrieves the absolute size of the data field in bytes.
void update()
Updates the data field header based on the current application data size.
std::vector< std::uint8_t > getDataFieldHeaderBytes()
Retrieves the secondary header data as a vector of bytes.
std::uint16_t getApplicationDataBytesSize() const
Retrieves the size of the application data stored in the data field.
std::vector< std::uint8_t > getApplicationData()
Retrieves the application data from the data field.
std::vector< std::uint8_t > m_applicationData
Application data buffer.
ResultBool setApplicationData(const std::vector< std::uint8_t > &applicationData)
Sets the application data using a vector of bytes.
std::uint16_t getDataFieldAvailableBytesSize() const
Retrieves the available size of the data field in bytes.
Encapsulates a result that can hold either a value or an Error.
Definition CCSDSResult.h:85
Parses and stores config values from custom file format.
Definition CCSDSConfig.h:14
bool isKey(const std::string &key) const
CCSDS::Result< T > get(const std::string &key) const
Get value by key and type.
Definition CCSDSConfig.h:23
@ INVALID_APPLICATION_DATA
Application data is invalid.
Definition CCSDSResult.h:30
@ CONFIG_FILE_ERROR
Configuration file error.
Definition CCSDSResult.h:37
@ INVALID_SECONDARY_HEADER_DATA
Secondary header data is invalid.
Definition CCSDSResult.h:29
@ NULL_POINTER
Null pointer encountered.
Definition CCSDSResult.h:31