From 87bb8539b30a82c9487b6d97a3a6c748a6024302 Mon Sep 17 00:00:00 2001 From: Dominik Kuhn Date: Fri, 7 Oct 2022 15:57:14 +0100 Subject: [PATCH] create a CmdlineHelper class and move the overloaded validation functions --- CMakeLists.txt | 2 +- POCmdlineHelperClasses.cpp | 23 +++++++ POCmdlineHelperClasses.hpp | 17 +++++ POHelperClasses.cpp | 135 ++++++++++++++++++++++++++++++++++++- POHelperClasses.hpp | 8 ++- main.cpp | 126 ---------------------------------- 6 files changed, 181 insertions(+), 130 deletions(-) create mode 100644 POCmdlineHelperClasses.cpp create mode 100644 POCmdlineHelperClasses.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a66b91d..9373277 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) add_compile_options(-Wall -Wextra -pedantic -lstdc++) add_definitions(-DCFG_DEBUG -DCFG_eu868 -DCFG_sx1276_radio -DDEBUG_LMIC -DDEBUG_HAL -DDEBUG_RADIO) -add_executable(mqtt2LoRaWAN main.cpp MQTTDataStreamer.cpp POHelperClasses.cpp ./lmic/lmic.c ./lmic/aes.c ./lmic/radio.c ./lmic/oslmic.c ./lora_gps_hat/debug.c ./lora_gps_hat/gpio.c ./lora_gps_hat/hal.c ) +add_executable(mqtt2LoRaWAN main.cpp MQTTDataStreamer.cpp POHelperClasses.cpp POCmdlineHelperClasses.cpp ./lmic/lmic.c ./lmic/aes.c ./lmic/radio.c ./lmic/oslmic.c ./lora_gps_hat/debug.c ./lora_gps_hat/gpio.c ./lora_gps_hat/hal.c ) target_include_directories (mqtt2LoRaWAN PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" diff --git a/POCmdlineHelperClasses.cpp b/POCmdlineHelperClasses.cpp new file mode 100644 index 0000000..81dff74 --- /dev/null +++ b/POCmdlineHelperClasses.cpp @@ -0,0 +1,23 @@ + +#include + +#include "POHelperClasses.hpp" +#include "POCmdlineHelperClasses.hpp" + + +namespace po = boost::program_options; + + +void po_cmdline_helper::init(boost::program_options::options_description cmdline_desc){ + + cmdline_desc.add_options() ("help", "produce help message") + ("version,v", "print the version number") + ("hostname,h", po::value()->default_value("localhost"), "Hostname") + ("port,p", po::value()->default_value(1883), "Port") + ("config,c", po::value(), "configuration file") + ("magic,m", po::value(), "magic value (in NNN-NNN format)") + ("appeui", po::value(), "APPEUI") + ("deveui", po::value(), "DEVEUI") + ("devkey", po::value(), "DEVKEY"); + +} diff --git a/POCmdlineHelperClasses.hpp b/POCmdlineHelperClasses.hpp new file mode 100644 index 0000000..1257692 --- /dev/null +++ b/POCmdlineHelperClasses.hpp @@ -0,0 +1,17 @@ +#ifndef ProgramOptions_CmdLine_HelperClasses_HPP +#define ProgramOptions_CmdLine_HelperClasses_HPP + + +#include + + +class po_cmdline_helper { + +public: + void init(boost::program_options::options_description cmdline_desc); + +}; + + +#endif + diff --git a/POHelperClasses.cpp b/POHelperClasses.cpp index 662a415..428f031 100644 --- a/POHelperClasses.cpp +++ b/POHelperClasses.cpp @@ -1,9 +1,13 @@ +#include #include #include "POHelperClasses.hpp" +#include +#include + appeui::appeui(std::string appeui_hexstring){ std::copy(appeui_hexstring.begin(), appeui_hexstring.end(), application_eui64.e8); @@ -17,8 +21,135 @@ deveui::deveui(std::string deveui_hexstring){ } - - devkey::devkey(std::string devkey_hexstring){ std::copy(devkey_hexstring.begin(), devkey_hexstring.end(), device_key); } + + +/* Overload the 'validate' function for the user-defined class. + It makes sure that value is of form XXX-XXX + where X are digits and converts the second group to an integer. + This has no practical meaning, meant only to show how + regex can be used to validate values. +*/ +void validate(boost::any& v, + const std::vector& values, + magic_number*, int) +{ + static boost::regex r("\\d\\d\\d-(\\d\\d\\d)"); + + using namespace boost::program_options; + + // Make sure no previous assignment to 'a' was made. + validators::check_first_occurrence(v); + // Extract the first string from 'values'. If there is more than + // one string, it's an error, and exception will be thrown. + const std::string& s = validators::get_single_string(values); + + // Do regex match and convert the interesting part to + // int. + boost::smatch match; + if (regex_match(s, match, r)) { + v = boost::any(magic_number(boost::lexical_cast(match[1]))); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} + + +void validate(boost::any& v, + const std::vector& values, + appeui*, int) +{ + static boost::regex r("^([[:xdigit:]]{2}[:.-]?){7}[[:xdigit:]]{2}$"); + + boost::regex re("[:.-]"); + + using namespace boost::program_options; + + // Make sure no previous assignment to 'a' was made. + validators::check_first_occurrence(v); + + // Extract the first string from 'values'. If there is more than + // one string, it's an error, and exception will be thrown. + const std::string& s = validators::get_single_string(values); + + // Do regex match and convert the interesting part to + // int. + boost::smatch match; + if (regex_match(s, match, r)) { + std::string unfilterd_string = match[0]; + std::string filterd_string = boost::regex_replace( unfilterd_string, re, "" ); + std::cout << "regex funktioniert .... " << filterd_string << std::endl; + std::cout << "boost algorithm ... " << boost::algorithm::unhex(filterd_string) << std::endl; + + v = boost::any( appeui( boost::algorithm::unhex(filterd_string) ) ); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} + + +void validate(boost::any& v, + const std::vector& values, + deveui*, int) +{ + static boost::regex r("^([[:xdigit:]]{2}[:.-]?){7}[[:xdigit:]]{2}$"); + + boost::regex re("[:.-]"); + + using namespace boost::program_options; + + // Make sure no previous assignment to 'a' was made. + validators::check_first_occurrence(v); + + // Extract the first string from 'values'. If there is more than + // one string, it's an error, and exception will be thrown. + const std::string& s = validators::get_single_string(values); + + // Do regex match and convert the interesting part to + // int. + boost::smatch match; + if (regex_match(s, match, r)) { + std::string unfilterd_string = match[0]; + std::string filterd_string = boost::regex_replace( unfilterd_string, re, "" ); + std::cout << "regex funktioniert .... " << filterd_string << std::endl; + std::cout << "boost algorithm ... " << boost::algorithm::unhex(filterd_string) << std::endl; + + v = boost::any( deveui( boost::algorithm::unhex(filterd_string) ) ); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} + +void validate(boost::any& v, + const std::vector& values, + devkey*, int) +{ + static boost::regex r("^([[:xdigit:]]{2}[:.-]?){15}[[:xdigit:]]{2}$"); + + boost::regex re("[:.-]"); + + using namespace boost::program_options; + + // Make sure no previous assignment to 'a' was made. + validators::check_first_occurrence(v); + + // Extract the first string from 'values'. If there is more than + // one string, it's an error, and exception will be thrown. + const std::string& s = validators::get_single_string(values); + + // Do regex match and convert the interesting part to + // int. + boost::smatch match; + if (regex_match(s, match, r)) { + std::string unfilterd_string = match[0]; + std::string filterd_string = boost::regex_replace( unfilterd_string, re, "" ); + std::cout << "regex funktioniert .... " << filterd_string << std::endl; + std::cout << "boost algorithm ... " << boost::algorithm::unhex(filterd_string) << std::endl; + + v = boost::any( devkey( boost::algorithm::unhex(filterd_string) ) ); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} diff --git a/POHelperClasses.hpp b/POHelperClasses.hpp index 2ef2a40..99a9455 100644 --- a/POHelperClasses.hpp +++ b/POHelperClasses.hpp @@ -4,6 +4,7 @@ #include #include +#include typedef union { uint8_t e8[8]; /* lower 64-bit address */ @@ -31,7 +32,6 @@ public: }; - class deveui { public: @@ -40,6 +40,7 @@ public: }; + class devkey { public: @@ -48,5 +49,10 @@ public: }; +void validate(boost::any& v, const std::vector& values, magic_number*, int); +void validate(boost::any& v, const std::vector& values, appeui*, int); +void validate(boost::any& v, const std::vector& values, deveui*, int); +void validate(boost::any& v, const std::vector& values, devkey*, int); + #endif diff --git a/main.cpp b/main.cpp index c91dff1..65942c5 100644 --- a/main.cpp +++ b/main.cpp @@ -148,132 +148,6 @@ public: }; -/* Overload the 'validate' function for the user-defined class. - It makes sure that value is of form XXX-XXX - where X are digits and converts the second group to an integer. - This has no practical meaning, meant only to show how - regex can be used to validate values. -*/ -void validate(boost::any& v, - const std::vector& values, - magic_number*, int) -{ - static boost::regex r("\\d\\d\\d-(\\d\\d\\d)"); - - using namespace boost::program_options; - - // Make sure no previous assignment to 'a' was made. - validators::check_first_occurrence(v); - // Extract the first string from 'values'. If there is more than - // one string, it's an error, and exception will be thrown. - const std::string& s = validators::get_single_string(values); - - // Do regex match and convert the interesting part to - // int. - boost::smatch match; - if (regex_match(s, match, r)) { - v = boost::any(magic_number(boost::lexical_cast(match[1]))); - } else { - throw validation_error(validation_error::invalid_option_value); - } -} - -void validate(boost::any& v, - const std::vector& values, - appeui*, int) -{ - static boost::regex r("^([[:xdigit:]]{2}[:.-]?){7}[[:xdigit:]]{2}$"); - - boost::regex re("[:.-]"); - - using namespace boost::program_options; - - // Make sure no previous assignment to 'a' was made. - validators::check_first_occurrence(v); - - // Extract the first string from 'values'. If there is more than - // one string, it's an error, and exception will be thrown. - const std::string& s = validators::get_single_string(values); - - // Do regex match and convert the interesting part to - // int. - boost::smatch match; - if (regex_match(s, match, r)) { - std::string unfilterd_string = match[0]; - std::string filterd_string = boost::regex_replace( unfilterd_string, re, "" ); - std::cout << "regex funktioniert .... " << filterd_string << std::endl; - std::cout << "boost algorithm ... " << boost::algorithm::unhex(filterd_string) << std::endl; - - v = boost::any( appeui( boost::algorithm::unhex(filterd_string) ) ); - } else { - throw validation_error(validation_error::invalid_option_value); - } -} - - -void validate(boost::any& v, - const std::vector& values, - deveui*, int) -{ - static boost::regex r("^([[:xdigit:]]{2}[:.-]?){7}[[:xdigit:]]{2}$"); - - boost::regex re("[:.-]"); - - using namespace boost::program_options; - - // Make sure no previous assignment to 'a' was made. - validators::check_first_occurrence(v); - - // Extract the first string from 'values'. If there is more than - // one string, it's an error, and exception will be thrown. - const std::string& s = validators::get_single_string(values); - - // Do regex match and convert the interesting part to - // int. - boost::smatch match; - if (regex_match(s, match, r)) { - std::string unfilterd_string = match[0]; - std::string filterd_string = boost::regex_replace( unfilterd_string, re, "" ); - std::cout << "regex funktioniert .... " << filterd_string << std::endl; - std::cout << "boost algorithm ... " << boost::algorithm::unhex(filterd_string) << std::endl; - - v = boost::any( deveui( boost::algorithm::unhex(filterd_string) ) ); - } else { - throw validation_error(validation_error::invalid_option_value); - } -} - -void validate(boost::any& v, - const std::vector& values, - devkey*, int) -{ - static boost::regex r("^([[:xdigit:]]{2}[:.-]?){15}[[:xdigit:]]{2}$"); - - boost::regex re("[:.-]"); - - using namespace boost::program_options; - - // Make sure no previous assignment to 'a' was made. - validators::check_first_occurrence(v); - - // Extract the first string from 'values'. If there is more than - // one string, it's an error, and exception will be thrown. - const std::string& s = validators::get_single_string(values); - - // Do regex match and convert the interesting part to - // int. - boost::smatch match; - if (regex_match(s, match, r)) { - std::string unfilterd_string = match[0]; - std::string filterd_string = boost::regex_replace( unfilterd_string, re, "" ); - std::cout << "regex funktioniert .... " << filterd_string << std::endl; - std::cout << "boost algorithm ... " << boost::algorithm::unhex(filterd_string) << std::endl; - - v = boost::any( devkey( boost::algorithm::unhex(filterd_string) ) ); - } else { - throw validation_error(validation_error::invalid_option_value); - } -} std::string mapper(std::string env_var)