From e149188ae477fee974cdff2d11e8ae36b505543f Mon Sep 17 00:00:00 2001 From: Dominik Kuhn Date: Tue, 13 Sep 2022 20:45:36 +0100 Subject: [PATCH] adding some regex program options to handle eui64 addresses --- CMakeLists.txt | 2 +- POHelperClasses.cpp | 3 ++ POHelperClasses.hpp | 30 ++++++++++++++++ default.conf | 1 + main.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 POHelperClasses.cpp create mode 100644 POHelperClasses.hpp create mode 100644 default.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cf94e..a66b91d 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 ./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 ./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/POHelperClasses.cpp b/POHelperClasses.cpp new file mode 100644 index 0000000..6f850c7 --- /dev/null +++ b/POHelperClasses.cpp @@ -0,0 +1,3 @@ +#include "POHelperClasses.hpp" + + diff --git a/POHelperClasses.hpp b/POHelperClasses.hpp new file mode 100644 index 0000000..45006ca --- /dev/null +++ b/POHelperClasses.hpp @@ -0,0 +1,30 @@ +#ifndef ProgramOptions_HELPERCLASSES_HPP +#define ProgramOptions_HELPERCLASSES_HPP + +#include + + +typedef union { + uint8_t e8[8]; /* lower 64-bit address */ + uint8_t e32[2]; +} eui64_t; + + +/* Define a completely non-sensical class. */ +class magic_number { + +public: + magic_number(int n) : n(n) {} + int n; +}; + +class appeui { + +public: + appeui(eui64_t application_eui64) : application_eui64{application_eui64} {} + eui64_t application_eui64; +}; + + + +#endif diff --git a/default.conf b/default.conf new file mode 100644 index 0000000..4d5c407 --- /dev/null +++ b/default.conf @@ -0,0 +1 @@ +APPEUI = 70B3D57ED005538D \ No newline at end of file diff --git a/main.cpp b/main.cpp index 50db35f..c37814c 100644 --- a/main.cpp +++ b/main.cpp @@ -3,9 +3,11 @@ #include #include +#include "POHelperClasses.hpp" #include "MQTTDataStreamer.hpp" #include +#include namespace po = boost::program_options; extern "C" @@ -144,6 +146,69 @@ 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::cout << "regex funktioniert .... " << boost::regex_replace(unfilterd_string, re, "" ) << std::endl; + // v = boost::any(appeui( boost::lexical_cast(match[1]) )); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} + + + + ////////////////////////////////////////////////// // MAIN - INITIALIZATION AND STARTUP ////////////////////////////////////////////////// @@ -167,9 +232,12 @@ int main(int argc, char *argv[]) // set options allowed by the command line po::options_description command_line_options("Allowed options"); command_line_options.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()->default_value("default.conf"), "configuration file"); + ("config,c", po::value()->default_value("default.conf"), "configuration file") + ("magic,m", po::value(), "magic value (in NNN-NNN format)") + ("eui", po::value(), "APPEU"); // set options allowed in config file po::options_description config_file_options; @@ -200,6 +268,24 @@ int main(int argc, char *argv[]) return 0; } + if (variable_map.count("version")) { + cout << "Version 1.\n"; + return 0; + } + + if (variable_map.count("magic")) { + cout << "The magic is \"" << variable_map["magic"].as().n << "\"\n"; + return 0; + } + + + if (variable_map.count("eui")) + { + // std::cout << "APPEUI: " << variable_map["eui"].as().application_eui64.e32 << std::endl; + return 0; + } + + if (variable_map.count("APPEUI")) { std::cout << "APPEUI: " << variable_map["APPEUI"].as() << std::endl;