CCSDSPack
C++ Library for CCSDS Space Packet manipulation. i.e. generation, extraction, analisys and more
Loading...
Searching...
No Matches
Functions
exec_decoder.cpp File Reference
#include <unordered_map>
#include <string>
#include <vector>
#include <iostream>
#include <chrono>
#include <sstream>
#include "CCSDSPack.h"
#include "exec_utils.h"
Include dependency graph for exec_decoder.cpp:

Go to the source code of this file.

Functions

void printHelpDecoder ()
 This is the source file that holds the execution logic of ccsds_encoder binary file.
 
int main (const int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( const int  argc,
char *  argv[] 
)

Definition at line 52 of file exec_decoder.cpp.

52 {
53 std::string appName = "ccsds_decoder";
54
55 std::unordered_map<std::string, std::string> allowed;
56 allowed.insert({"h", "help"});
57 allowed.insert({"v", "verbose"});
58 allowed.insert({"i", "input"});
59 allowed.insert({"o", "output"});
60 allowed.insert({"c", "config"});
61
62 const std::set<std::string> booleanArgs{"verbose", "help"};
63
64 std::unordered_map<std::string, std::string> args;
65 args.insert({"verbose", "false"});
66 args.insert({"help", "false"});
67
68 const auto start = std::chrono::high_resolution_clock::now();
69 if (const auto res = parseArguments(argc, argv, allowed, args, booleanArgs); !res.has_value()) {
70 std::cerr << "[ Error " << res.error().code() << " ]: "<< res.error().message() << std::endl ;
71 return res.error().code();
72 }
73 // std::cout << "Parsed args:\n";
74 //for (const auto& [k, v] : args) {
75 // std::cout << " " << k << ": " << v << '\n';
76 //}
77 if (args["help"] == "true") {
79 return 0;
80 }
81 bool verbose{args["verbose"] == "true"};
82
83 if (args.find("input") == args.end()) {
84 std::cerr << "[ Error " << ARG_PARSE_ERROR << " ]: " << "Input file must be specified" << std::endl;
86 return ARG_PARSE_ERROR;
87 }
88
89 if (!fileExists(args["input"])) {
90 std::cerr << "[ Error " << ARG_PARSE_ERROR << " ]: " << "Input \"" << args["input"] << "\" does not exist" << std::endl;
91 return ARG_PARSE_ERROR;
92 }
93 const std::string input{args["input"]};
94 const std::string output{args["output"]};
95
96 if (output.empty()) {
97 std::cerr << "[ Error " << ARG_PARSE_ERROR << " ]: " << "Output file must be specified" << std::endl;
99 return ARG_PARSE_ERROR;
100 }
101
102 if (args.find("config") == args.end()) {
103 std::cerr << "[ Error " << ARG_PARSE_ERROR << " ]: " << "Config file must be specified" << std::endl;
105 return ARG_PARSE_ERROR;
106 }
107
108 if (!fileExists(args["config"])) {
109 std::cerr << "[ Error " << ARG_PARSE_ERROR << " ]: " << "Config \"" << args["config"] << "\" does not exist" << std::endl;
110 return ARG_PARSE_ERROR;
111 }
112 const std::string configFile{args["config"]};
113
114 // prepare template packet
115 customConsole(appName,"reading CCSDS configuration file: " + configFile);
116 Config cfg;
117 {
118 if (auto res = cfg.load(configFile); !res.has_value()) {
119 std::cerr << "[ Error " << res.error().code() << " ]: "<< res.error().message() << std::endl ;
120 return res.error().code();
121 }
122 }
123
124 CCSDS::Manager manager;
125
126 if (cfg.isKey("data_field_size")) {
127 std::uint16_t dataFieldSize;
128 ASSIGN_OR_PRINT(dataFieldSize, cfg.get<int>("data_field_size"));
129 manager.setDataFieldSize(dataFieldSize);
130
131 }
132
133 if (cfg.isKey("sync_pattern_enable")) {
134 bool syncPatternEnable;
135 ASSIGN_OR_PRINT(syncPatternEnable, cfg.get<bool>("sync_pattern_enable"));
136 manager.setSyncPatternEnable(syncPatternEnable);
137 if (syncPatternEnable && cfg.isKey("sync_pattern")) {
138 std::uint32_t syncPattern;
139 ASSIGN_OR_PRINT(syncPattern, cfg.get<int>("sync_pattern"));
140 manager.setSyncPattern(syncPattern);
141 }
142 }
143
144 bool validationEnable;
145 if (!cfg.isKey("validation_enable")) {
146 std::cerr << "[ Error " << CONFIG_MISSING_PARAMETER << " ]: " << "Config: Missing bool field: validation_enable" << std::endl;
148 }
149 ASSIGN_OR_PRINT(validationEnable, cfg.get<bool>("validation_enable"));
150 customConsole(appName,"creating CCSDS template packet");
151
152 if (const auto res = manager.loadTemplateConfig(cfg);!res.has_value()) {
153 std::cerr << "[ Error " << res.error().code() << " ]: "<< res.error().message() << std::endl ;
154 return res.error().code();
155 }
156
157 std::vector<std::uint8_t> inputBytes;
158 customConsole(appName,"reading data from " + input);
159
160 if (const auto res = readBinaryFile(input); !res.has_value()) {
161 std::cerr << "[ Error " << res.error().code() << " ]: "<< res.error().message() << std::endl ;
162 return res.error().code();
163 }else {
164 inputBytes = res.value();
165 if (manager.getTemplate().getPrimaryHeader().getSequenceFlags() == CCSDS::UNSEGMENTED && inputBytes.size() > manager.getDataFieldSize()){
166 std::cerr << "[ Error " << INVALID_INPUT_DATA << " ]: "<< "Input data is too big for unsegmented packets, data "
167 << inputBytes.size() << " must be less than defined data packet length of " << manager.getDataFieldSize() << std::endl ;
168 return INVALID_INPUT_DATA;
169 }
170 }
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();
175 }
176 if (verbose) customConsole(appName,"printing loaded packets data to screen:");
177 if (verbose) printPackets(manager);
178
179 customConsole(appName,"retrieving Application data from CCSDS packets");
180 manager.setAutoValidateEnable(validationEnable);
181 std::vector<std::uint8_t> outputData;
182 if (const auto res = manager.getApplicationDataBuffer(); !res.has_value()) {
183 std::cerr << "[ Error " << res.error().code() << " ]: "<< res.error().message() << std::endl ;
184 return res.error().code();
185 }else {
186 outputData = res.value();
187 }
188
189 customConsole(appName,"writing data to " + output);
190 if (const auto res = writeBinaryFile(outputData, output); !res.has_value()) {
191 std::cerr << "[ Error " << res.error().code() << " ]: "<< res.error().message() << std::endl ;
192 return res.error().code();
193 }
194
195 const auto end = std::chrono::high_resolution_clock::now();
196 const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
197 customConsole(appName,"execution time: " + std::to_string(duration.count()) + " [us]");
198 customConsole(appName,"[ Exit code 0 ]");
199 return 0;
200}
#define ASSIGN_OR_PRINT(var, result)
Macro to assign a result value or print an error message.
bool fileExists(const std::string &fileName)
filesystem check fore file existence prepared for both windows and linux.
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.
void printPackets(CCSDS::Manager &manager)
Prints to console a series of CCSDS Packets contained in the manager.
std::uint8_t getSequenceFlags() const
2 bits
Definition CCSDSHeader.h:88
Manages CCSDS packets and their templates.
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)
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.
Packet getTemplate()
Retrieves the packet template.
ResultBuffer getApplicationDataBuffer()
Retrieves the application data from the packets.
ResultBool loadTemplateConfig(const Config &cfg)
Loads a template packet from a configuration object.
void setDataFieldSize(std::uint16_t size)
Sets the size of the data field.
void setAutoValidateEnable(bool enable)
Enables or disables automatic validation of packets.
Header & getPrimaryHeader()
returns the CCSDS packet's Primary Header.
bool has_value() const
Checks if the result contains a valid value.
Parses and stores config values from custom file format.
Definition CCSDSConfig.h:11
bool isKey(const std::string &key) const
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 CCSDSConfig.h:20
void printHelpDecoder()
This is the source file that holds the execution logic of ccsds_encoder binary 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...
@ CONFIG_MISSING_PARAMETER
Definition exec_utils.h:13
@ ARG_PARSE_ERROR
Error Parsing argument.
Definition exec_utils.h:12
@ INVALID_INPUT_DATA
Definition exec_utils.h:14
@ UNSEGMENTED
11 Complete packet in a single frame.
Definition CCSDSHeader.h:23
Here is the call graph for this function:

◆ printHelpDecoder()

void printHelpDecoder ( )

This is the source file that holds the execution logic of ccsds_encoder binary file.

Definition at line 16 of file exec_decoder.cpp.

16 {
17 // ascii art generated on https://www.asciiart.eu/text-to-ascii-art
18 // with ANSI SHADOW Font, with 80 and Block frame
19
20 std::cout << std::endl <<
21 "▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌\n"
22 "▐ ██████╗ ██████╗███████╗██████╗ ███████╗ ▌\n"
23 "▐ ██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ▌\n"
24 "▐ ██║ ██║ ███████╗██║ ██║███████╗ ▌\n"
25 "▐ ██║ ██║ ╚════██║██║ ██║╚════██║ █▀█░█▀█░█▀▀░█░█░ ▌\n"
26 "▐ ╚██████╗╚██████╗███████║██████╔╝███████║ █▀▀░█▀█░█░░░█▀▄░ ▌\n"
27 "▐ ╚═════╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝ ▀░░░▀░▀░▀▀▀░▀░▀░ ▌\n"
28 "▐ ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ ▌\n"
29 "▐ ██╔══██╗██╔════╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗ ▌\n"
30 "▐ ██║ ██║█████╗ ██║ ██║ ██║██║ ██║█████╗ ██████╔╝ ▌\n"
31 "▐ ██║ ██║██╔══╝ ██║ ██║ ██║██║ ██║██╔══╝ ██╔══██╗ ▌\n"
32 "▐ ██████╔╝███████╗ ╚██████╗╚██████╔╝██████╔╝███████╗██║ ██║ ▌\n"
33 "▐ ╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ▌\n"
34 "▐▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▌\n"
35 << std::endl;
36 std::cout << "Usage: ccsds_decoder [OPTIONS] - decode a ccsds binary file and generate a file from application data." << std::endl;
37 std::cout << "Mandatory parameters:" << std::endl;
38 std::cout << " -i or --input <filename> : input file to be encoded" << std::endl;;
39 std::cout << " -o or --output <filename> : Generated output file" << std::endl;;
40 std::cout << " -c or --config <filename> : Configuration file" << std::endl;
41 std::cout << std::endl;
42 std::cout << "Optionals:" << std::endl;
43 std::cout << " -h or --help : Show this help and message" << std::endl;
44 std::cout << " -v or --verbose : Show generated packets information" << std::endl;
45 std::cout << std::endl;
46 std::cout << "Note : the template CCSDS packet is defined in the configuration file" << std::endl;
47 std::cout << " This should follow the guide lines provided in the link below." << std::endl;
48 std::cout << std::endl;
49 std::cout << "For further information please visit: https://github.com/ExoSpaceLabs/CCSDSPack" << std::endl;
50}
Here is the caller graph for this function: