9#include <unordered_map>
18#include "../test/inc/TestManager.h"
24 std::cout << std::endl <<
25 "▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌\n"
26 "▐ ██████╗ ██████╗███████╗██████╗ ███████╗ ▌\n"
27 "▐ ██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ▌\n"
28 "▐ ██║ ██║ ███████╗██║ ██║███████╗ ▌\n"
29 "▐ ██║ ██║ ╚════██║██║ ██║╚════██║ █▀█░█▀█░█▀▀░█░█░ ▌\n"
30 "▐ ╚██████╗╚██████╗███████║██████╔╝███████║ █▀▀░█▀█░█░░░█▀▄░ ▌\n"
31 "▐ ╚═════╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝ ▀░░░▀░▀░▀▀▀░▀░▀░ ▌\n"
32 "▐ ██╗ ██╗ █████╗ ██╗ ██╗██████╗ █████╗ ████████╗ ██████╗ ██████╗ ▌\n"
33 "▐ ██║ ██║██╔══██╗██║ ██║██╔══██╗██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ▌\n"
34 "▐ ██║ ██║███████║██║ ██║██║ ██║███████║ ██║ ██║ ██║██████╔╝ ▌\n"
35 "▐ ╚██╗ ██╔╝██╔══██║██║ ██║██║ ██║██╔══██║ ██║ ██║ ██║██╔══██╗ ▌\n"
36 "▐ ╚████╔╝ ██║ ██║███████╗██║██████╔╝██║ ██║ ██║ ╚██████╔╝██║ ██║ ▌\n"
37 "▐ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ▌\n"
38 "▐▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▌\n"
40 std::cout <<
"Usage: ccsds_validator [OPTIONS] - take a binary file holding CCSDS packets and validates it." << std::endl;
41 std::cout <<
"Mandatory parameters:" << std::endl;
42 std::cout <<
" -i or --input <filename> : input file to be encoded" << std::endl;;
43 std::cout << std::endl;
44 std::cout <<
"Optionals:" << std::endl;
45 std::cout <<
" -c or --config <filename> : Configuration file" << std::endl;
46 std::cout <<
" -h or --help : Show this help and message" << std::endl;
47 std::cout <<
" -v or --verbose : Show packet specific report" << std::endl;
48 std::cout <<
" -p or --print-packets : Show generated packets information" << std::endl;
49 std::cout << std::endl;
50 std::cout <<
"Note : If config file is provided, the loaded packets are validated against the the template packet." << std::endl;
51 std::cout << std::endl;
52 std::cout <<
"For further information please visit: https://github.com/ExoSpaceLabs/CCSDSPack" << std::endl;
69std::string
printReport(
const std::vector<bool>& report,
bool& result,
const bool validateAgainstTemplate) {
71 std::string packetReport =
" [REPORT] Data Field Length and Primary Header : ";
72 packetReport += (report[0]) ? GREEN +
"Passed\n" + RESET : RED +
"failed\n" + RESET;
73 packetReport +=
" [REPORT] CRC15 value coherence : " ;
74 packetReport += (report[1]) ? GREEN +
"Passed\n" + RESET : RED +
"failed\n" + RESET;
75 packetReport +=
" [REPORT] Sequence Control flags and count coherence : " ;
76 packetReport += (report[2]) ? GREEN +
"Passed\n" + RESET : RED +
"failed\n" + RESET;
77 packetReport +=
" [REPORT] Sequence Control count coherence : " ;
78 packetReport += (report[3]) ? GREEN +
"Passed\n" + RESET : RED +
"failed\n" + RESET;
80 result = report[0] && report[1] && report[2] && report[3];
81 if (validateAgainstTemplate){
82 packetReport +=
" [REPORT] Identification and Version : " ;
83 packetReport += (report[4]) ? GREEN +
"Passed\n" + RESET : RED +
"failed\n" + RESET;
84 packetReport +=
" [REPORT] Template Sequence Control : " ;
85 packetReport += (report[5]) ? GREEN +
"Passed\n" + RESET : RED +
"failed\n" + RESET;
86 result = result && report[4] && report[5];
93 output.reserve(input.size());
95 for (
size_t i = 0; i < input.size(); ) {
96 if (input[i] ==
'\033' && i + 1 < input.size() && input[i + 1] ==
'[') {
99 while (i < input.size() && (input[i] <
'@' || input[i] >
'~')) {
102 if (i < input.size()) ++i;
104 output += input[i++];
108 input = std::move(output);
111int main(
const int argc,
char* argv[]) {
112 std::string appName =
"ccsds_validator";
114 std::unordered_map<std::string, std::string> allowed;
115 allowed.insert({
"h",
"help"});
116 allowed.insert({
"v",
"verbose"});
117 allowed.insert({
"i",
"input"});
118 allowed.insert({
"c",
"config"});
119 allowed.insert({
"p",
"print-packets"});
121 const std::set<std::string> booleanArgs{
"verbose",
"help",
"print-packets"};
123 std::unordered_map<std::string, std::string> args;
124 args.insert({
"verbose",
"false"});
125 args.insert({
"print",
"false"});
126 args.insert({
"print-packets",
"false"});
128 const auto start = std::chrono::high_resolution_clock::now();
130 std::cerr <<
"[ Error " << res.error().code() <<
" ]: "<< res.error().message() << std::endl ;
131 return res.error().code();
137 if (args[
"help"] ==
"true") {
141 bool verbose{args[
"verbose"] ==
"true"};
143 if (args.find(
"input") == args.end()) {
144 std::cerr <<
"[ Error " <<
ARG_PARSE_ERROR <<
" ]: " <<
"Input file must be specified" << std::endl;
150 std::cerr <<
"[ Error " <<
ARG_PARSE_ERROR <<
" ]: " <<
"Input \"" << args[
"input"] <<
"\" does not exist" << std::endl;
153 const std::string input{args[
"input"]};
157 std::vector<uint8_t> inputBytes;
158 bool isConfigProvided{
false};
165 std::cerr <<
"[ Error " << res.error().code() <<
" ]: "<< res.error().message() << std::endl ;
166 return res.error().code();
168 inputBytes = res.value();
171 customConsole(appName,
"deserializing CCSDS packets from file");
172 if (
const auto res = manager.
load(inputBytes); !res.has_value()) {
173 std::cerr <<
"[ Error " << res.error().code() <<
" ]: "<< res.error().message() << std::endl ;
174 return res.error().code();
178 if (args.find(
"config") != args.end()) {
179 isConfigProvided =
true;
181 std::cerr <<
"[ Error " <<
ARG_PARSE_ERROR <<
" ]: " <<
"Config \"" << args[
"config"] <<
"\" does not exist" << std::endl;
184 const std::string configFile{args[
"config"]};
187 customConsole(appName,
"reading CCSDS configuration file: " + configFile);
191 if (
auto res = cfg.
load(configFile); !res.has_value()) {
192 std::cerr <<
"[ Error " << res.error().code() <<
" ]: "<< res.error().message() << std::endl ;
193 return res.error().code();
204 if (verbose)
customConsole(appName,
"printing data to screen:");
206 std::vector<std::vector<bool>> reports;
207 std::string reportsStream;
208 bool overallResult{
true};
209 std::int32_t packetIndex{1};
210 std::vector<int> failedPackets;
211 const bool printPackets{args[
"print-packets"] ==
"true"};
214 if (verbose) std::cout <<
"[ CCSDS VALIDATOR ] Printing Packet [ " << packetIndex <<
" ]: " << std::endl;
215 reportsStream +=
"[ CCSDS VALIDATOR ] Packet report for id: [ " + std::to_string(packetIndex) +
" ]\n";
219 reports.emplace_back(report);
220 bool currentResult{
false};
221 std::string appendReport =
printReport(report,currentResult, isConfigProvided);
222 overallResult = overallResult && currentResult;
223 reportsStream += appendReport;
224 if (verbose) std::cout << appendReport << std::endl;
225 if (verbose) std::cout <<
"[ CCSDS VALIDATOR ] Packet Result [ ";
226 if (verbose && currentResult) std::cout << GREEN;
230 if (verbose && currentResult) std::cout <<
"PASSED" ;
232 std::cout <<
"FAILED";
234 if (verbose) std::cout << RESET <<
" ]" << std::endl;
235 if (!currentResult) failedPackets.push_back(packetIndex);
239 if (!failedPackets.empty() && verbose) {
240 std::string failedPacketsStream;
241 failedPacketsStream =
"[ CCSDS VALIDATOR ] Packets failed validation: [ ";
242 for (
const auto& packetID : failedPackets) {
243 failedPacketsStream += std::to_string(packetID) +
" ";
245 failedPacketsStream +=
"]\n" ;
246 std::cout << failedPacketsStream << std::endl;
247 reportsStream += failedPacketsStream;
249 std::string resultString = (overallResult) ? GREEN +
"PASSED" + RESET : RED +
"FAILED" + RESET;
250 reportsStream +=
"[ CCSDS VALIDATOR ] Packets validation [" + resultString +
"]";
251 customConsole(appName,
"Packets validation [" + resultString +
"]");
254 const auto end = std::chrono::high_resolution_clock::now();
255 const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
256 customConsole(appName,
"execution time: " + std::to_string(duration.count()) +
" [us]");
257 if (!overallResult) {
bool fileExists(const std::string &fileName)
filesystem check fore file existence prepared for both windows and linux.
void printPacket(CCSDS::Packet &packet)
Prints to console a CCSDS Packets, breaking it down to Primary header and Data field.
CCSDS::ResultBuffer readBinaryFile(const std::string &filename)
Read a specified binary file and return its contents as a buffer.
void printPackets(CCSDS::Manager &manager)
Prints to console a series of CCSDS Packets contained in the manager.
Manages CCSDS packets and their templates.
std::vector< Packet > getPackets()
Retrieves all stored packets.
ResultBool load(const std::vector< Packet > &packets)
Load a vector of packets.
void setAutoUpdateEnable(bool enable)
Enables or disables automatic updates for packets.
void setDataFieldSize(std::uint16_t size)
Sets the size of the data field.
void setAutoValidateEnable(bool enable)
Enables or disables automatic validation of packets.
Represents a CCSDS (Consultative Committee for Space Data Systems) packet.
ResultBool loadFromConfig(const Config &cfg)
Loads a packet from a configuration object, including secondary header if present.
bool has_value() const
Checks if the result contains a valid value.
Handles validation of CCSDS packets.
std::vector< bool > getReport() const
Returns a report of performed validation checks.
void configure(bool validatePacketCoherence, bool validateSequenceCount, bool validateAgainstTemplate)
Configures validation options.
void setTemplatePacket(const Packet &templatePacket)
Sets the template packet for validation.
bool validate(const Packet &packet)
Validates a given packet.
Parses and stores config values from custom file format.
CCSDS::ResultBool load(const std::string &filename)
Load config file.
void customConsole(const std::string &appName, const std::string &message, const std::string &logLevel="INFO")
Prints log to console adding various information about.
CCSDS::ResultBool parseArguments(int argc, char *argv[], std::unordered_map< std::string, std::string > &allowedMap, std::unordered_map< std::string, std::string > &outArgs, const std::set< std::string > &booleanArgs)
Parses the input arguments with defined values returns an unordered map with given keys and input val...
@ PACKET_VALIDATION_FAILED
@ ARG_PARSE_ERROR
Error Parsing argument.
void printHelp()
This is the source file that holds the execution logic of ccsds_encoder binary file.
std::string printReport(const std::vector< bool > &report, bool &result, const bool validateAgainstTemplate)
Returns a report of performed validation checks in a string format.
int main(const int argc, char *argv[])
void stripAnsiCodes(std::string &input)