From 0ff8c7a07e5d7753872823a486427ead6fb07787 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Wed, 17 Apr 2024 18:35:41 -0400 Subject: [PATCH 01/12] modified: src/v2i-hub/MapPlugin/manifest.json modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp new file: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/manifest.json | 2 +- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 166 ++++++------------------ src/v2i-hub/MapPlugin/src/MapPlugin.h | 104 +++++++++++++++ 3 files changed, 146 insertions(+), 126 deletions(-) create mode 100644 src/v2i-hub/MapPlugin/src/MapPlugin.h diff --git a/src/v2i-hub/MapPlugin/manifest.json b/src/v2i-hub/MapPlugin/manifest.json index c63f1c718..8cd561b34 100644 --- a/src/v2i-hub/MapPlugin/manifest.json +++ b/src/v2i-hub/MapPlugin/manifest.json @@ -31,7 +31,7 @@ { "key":"MAP_Files", "default":"{ \"MapFiles\": [ {\"Action\":0, \"FilePath\":\"/var/www/plugins/MAP/MAP_9709_UPER.txt\"}] }", - "description":"JSON data defining a list of map files. One map file for each action set specified by the TSC." + "description":"JSON data defining a list of map files. One map file for each action set specified by the TSC." } ] } diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 2317e7800..79ffbdb09 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -1,114 +1,17 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "XmlMapParser.h" -#include "ConvertToJ2735r41.h" -#include "inputs/isd/ISDToJ2735r41.h" - -#define USE_STD_CHRONO -#include -#include - -#include "utils/common.h" -#include "utils/map.h" - -#include -using namespace std; -using namespace tmx; -using namespace tmx::messages; -using namespace tmx::utils; +#include "MapPlugin.h" +#include +#include +#include namespace MapPlugin { -#if SAEJ2735_SPEC < 63 -UPERframe _uperFrameMessage; -#endif - -class MapFile: public tmx::message { -public: - MapFile(): tmx::message() {} - virtual ~MapFile() {} - - std_attribute(this->msg, int, Action, -1, ); - std_attribute(this->msg, std::string, FilePath, "", ); - std_attribute(this->msg, std::string, InputType, "", ); - std_attribute(this->msg, std::string, Bytes, "", ); -public: - static tmx::message_tree_type to_tree(MapFile m) { - return tmx::message::to_tree(static_cast(m)); - } - - static MapFile from_tree(tmx::message_tree_type tree) { - MapFile m; - m.set_contents(tree); - return m; - } -}; - -//int _mapAction = -1; -//bool _isMapFilesNew = false; -//bool _isMapLoaded = false; - -volatile int gMessageCount = 0; - -class MapPlugin: public PluginClientClockAware { -public: - MapPlugin(string name); - virtual ~MapPlugin(); - - virtual int Main(); -protected: - void UpdateConfigSettings(); - - // Virtual method overrides. - void OnConfigChanged(const char *key, const char *value); - void OnMessageReceived(IvpMessage *msg); - void OnStateChange(IvpPluginState state); - -private: - std::atomic _mapAction {-1}; - std::atomic _isMapFileNew {false}; - std::atomic _cohdaR63 {false}; - - std::map _mapFiles; - std::mutex data_lock; - - J2735MessageFactory factory; - - int sendFrequency = 1000; - FrequencyThrottle errThrottle; - - bool LoadMapFiles(); - void DebugPrintMapFiles(); -}; - -MapPlugin::MapPlugin(string name) : - PluginClientClockAware(name) { - AddMessageFilter(IVPMSG_TYPE_SIGCONT, "ACT", IvpMsgFlags_None); - SubscribeToMessages(); - errThrottle.set_Frequency(std::chrono::minutes(30)); +MapPlugin::MapPlugin(string name) : PluginClientClockAware(name) { + AddMessageFilter(IVPMSG_TYPE_SIGCONT, "ACT", IvpMsgFlags_None); + SubscribeToMessages(); + errThrottle.set_Frequency(std::chrono::minutes(30)); } -MapPlugin::~MapPlugin() { - -} +MapPlugin::~MapPlugin() {} void MapPlugin::UpdateConfigSettings() { GetConfigValue("Frequency", sendFrequency); @@ -337,30 +240,42 @@ bool MapPlugin::LoadMapFiles() ISDToJ2735r41 converter(fn); mapFile.set_Bytes(converter.to_encoded_message().get_payload_str()); - PLOG(logINFO) << fn << " ISD file encoded as " << mapFile.get_Bytes(); + PLOG(logINFO) << fn << "ISD file encoded as " << mapFile.get_Bytes(); } else if (inType == "TXT") { - byte_stream bytes; - ifstream in(fn); - in >> bytes; + std::ifstream in; + try { + in.open(fn, std::ios::in | std::ios::binary ); + if (in.is_open()) { + std::string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); + PLOG(logINFO) << fn << " MAP encoded bytes: " << fileContent; - PLOG(logINFO) << fn << " MAP encoded bytes are " << bytes; + byte_stream bytes(fileContent.begin(), fileContent.end()); + MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); - MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message >(bytes); - if (mapMsg) { - PLOG(logDEBUG) << "Map is " << *mapMsg; + if (mapMsg) { + PLOG(logDEBUG) << "Map is: " << *mapMsg; - MapDataEncodedMessage mapEnc; - mapEnc.encode_j2735_message(*mapMsg); - mapFile.set_Bytes(mapEnc.get_payload_str()); + MapDataEncodedMessage mapEnc; + mapEnc.encode_j2735_message(*mapMsg); + mapFile.set_Bytes(mapEnc.get_payload_str()); - PLOG(logINFO) << fn << " J2735 message bytes encoded as " << mapFile.get_Bytes(); + PLOG(logINFO) << fn << " J2735 message bytes encoded as: " << mapFile.get_Bytes(); + } + } + else { + PLOG(logERROR) << "Failed to open file: " << fn; + } + } + catch( const ios_base::failure &e) { + PLOG(logERROR) << "Exception Encountered : \n" << e.what(); } } else if (inType == "UPER") { - PLOG(logDEBUG) << "Reading MAP file as UPER encoded hex bytes including MessageFrame." << std::endl; + PLOG(logDEBUG) << "Reading MAP file as UPER encoded hex bytes including MessageFrame."; std::ifstream in; try { in.open(fn, std::ios::in | std::ios::binary ); @@ -368,17 +283,18 @@ bool MapPlugin::LoadMapFiles() in.seekg(0, std::ios::end); int fileSize = in.tellg(); in.seekg(0, std::ios::beg); - PLOG(logDEBUG) << "File size is " << fileSize <(in)), std::istreambuf_iterator()); - PLOG(logDEBUG) << "File contents : " << bytes_string << std::endl; + bytes_string.erase(remove(bytes_string.begin(), bytes_string.end(), '\n'), bytes_string.end()); + PLOG(logDEBUG) << "File contents: " << bytes_string; mapFile.set_Bytes(bytes_string); } else { - PLOG(logERROR) << "Failed to open file " << fn << "." << std::endl; + PLOG(logERROR) << "Failed to open file: " << fn << "."; } } catch( const ios_base::failure &e) { - PLOG(logERROR) << "Exception Encountered : \n" << e.what(); + PLOG(logERROR) << "Exception Encountered: \n" << e.what(); } } else if (inType == "XML") @@ -396,7 +312,7 @@ bool MapPlugin::LoadMapFiles() mapEnc.encode_j2735_message(mapMsg); mapFile.set_Bytes(mapEnc.get_payload_str()); - PLOG(logINFO) << fn << " XML file encoded as " << mapFile.get_Bytes(); + PLOG(logINFO) << fn << " XML file encoded as: " << mapFile.get_Bytes(); } else { @@ -421,7 +337,7 @@ bool MapPlugin::LoadMapFiles() mapFile.set_Bytes(mapEnc->get_payload_str()); - PLOG(logINFO) << fn << " input file encoded as " << mapEnc->get_payload_str(); + PLOG(logINFO) << fn << " input file encoded as: " << mapEnc->get_payload_str(); } else { diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h new file mode 100644 index 000000000..f7419f417 --- /dev/null +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -0,0 +1,104 @@ +#pragma once + +#ifndef MAPPLUGIN_H_ +#define MAPPLUGIN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "XmlMapParser.h" +#include "ConvertToJ2735r41.h" +#include "inputs/isd/ISDToJ2735r41.h" + +#define USE_STD_CHRONO +#include +#include + +#include "utils/common.h" +#include "utils/map.h" + +#include + +using namespace std; +using namespace tmx; +using namespace tmx::messages; +using namespace tmx::utils; + +namespace MapPlugin { + +#if SAEJ2735_SPEC < 63 +UPERframe _uperFrameMessage; +#endif + +class MapFile: public tmx::message { +public: + MapFile(): tmx::message() {} + virtual ~MapFile() {} + + std_attribute(this->msg, int, Action, -1, ); + std_attribute(this->msg, std::string, FilePath, "", ); + std_attribute(this->msg, std::string, InputType, "", ); + std_attribute(this->msg, std::string, Bytes, "", ); + + static tmx::message_tree_type to_tree(MapFile m) { + return tmx::message::to_tree(static_cast(m)); + } + + static MapFile from_tree(tmx::message_tree_type tree) { + MapFile m; + m.set_contents(tree); + return m; + } +}; + +class MapPlugin: public PluginClientClockAware { +public: + MapPlugin(string name); + virtual ~MapPlugin(); + virtual int Main(); + +protected: + void UpdateConfigSettings(); + + // Virtual method overrides. + void OnConfigChanged(const char *key, const char *value); + void OnMessageReceived(IvpMessage *msg); + void OnStateChange(IvpPluginState state); + +private: + std::atomic _mapAction {-1}; + std::atomic _isMapFileNew {false}; + std::atomic _cohdaR63 {false}; + + std::map _mapFiles; + std::mutex data_lock; + + J2735MessageFactory factory; + + int sendFrequency = 1000; + FrequencyThrottle errThrottle; + + bool LoadMapFiles(); + void DebugPrintMapFiles(); +}; + +} // namespace MapPlugin + +#endif /* MAPPLUGIN_H_ */ From f2f5d45a79bf160d089d37a0d332fae4524252cf Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 18 Apr 2024 11:07:54 -0400 Subject: [PATCH 02/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 79ffbdb09..94886eb58 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -251,19 +251,20 @@ bool MapPlugin::LoadMapFiles() std::string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); PLOG(logINFO) << fn << " MAP encoded bytes: " << fileContent; + mapFile.set_Bytes(fileContent); - byte_stream bytes(fileContent.begin(), fileContent.end()); - MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); + // byte_stream bytes(fileContent.begin(), fileContent.end()); + // MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); - if (mapMsg) { - PLOG(logDEBUG) << "Map is: " << *mapMsg; + // if (mapMsg) { + // PLOG(logDEBUG) << "Map is: " << *mapMsg; - MapDataEncodedMessage mapEnc; - mapEnc.encode_j2735_message(*mapMsg); - mapFile.set_Bytes(mapEnc.get_payload_str()); + // MapDataEncodedMessage mapEnc; + // mapEnc.encode_j2735_message(*mapMsg); + // mapFile.set_Bytes(mapEnc.get_payload_str()); - PLOG(logINFO) << fn << " J2735 message bytes encoded as: " << mapFile.get_Bytes(); - } + // PLOG(logINFO) << fn << " J2735 message bytes encoded as: " << mapFile.get_Bytes(); + // } } else { PLOG(logERROR) << "Failed to open file: " << fn; @@ -349,7 +350,7 @@ bool MapPlugin::LoadMapFiles() } catch (exception &ex) { - PLOG(logERROR) << "Unable to convert " << mapFile.get_FilePath() << ": " << ex.what(); + PLOG(logERROR) << "Unable to convert " << mapFile.get_FilePath() << " : " << ex.what(); return false; } } From 2a9ff27c2af01fbe25090316debce97bbfc2613f Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 18 Apr 2024 16:17:18 -0400 Subject: [PATCH 03/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 41 ++++++++++++------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 94886eb58..59e31b4ad 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -244,35 +244,32 @@ bool MapPlugin::LoadMapFiles() } else if (inType == "TXT") { - std::ifstream in; - try { - in.open(fn, std::ios::in | std::ios::binary ); - if (in.is_open()) { + byte_stream bytes; + std::ifstream in(fn, std::ios::binary); + if (!in) { + PLOG(logERROR) << "Failed to open file: " << fn; + } else { + try { std::string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + in.close(); fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); - PLOG(logINFO) << fn << " MAP encoded bytes: " << fileContent; - mapFile.set_Bytes(fileContent); - // byte_stream bytes(fileContent.begin(), fileContent.end()); - // MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); + std::istringstream streamableContent(fileContent); + streamableContent >> bytes; + MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); + if (mapMsg) { + PLOG(logDEBUG) << "Map is " << *mapMsg; - // if (mapMsg) { - // PLOG(logDEBUG) << "Map is: " << *mapMsg; + MapDataEncodedMessage mapEnc; + mapEnc.encode_j2735_message(*mapMsg); + mapFile.set_Bytes(mapEnc.get_payload_str()); - // MapDataEncodedMessage mapEnc; - // mapEnc.encode_j2735_message(*mapMsg); - // mapFile.set_Bytes(mapEnc.get_payload_str()); - - // PLOG(logINFO) << fn << " J2735 message bytes encoded as: " << mapFile.get_Bytes(); - // } - } - else { - PLOG(logERROR) << "Failed to open file: " << fn; + PLOG(logINFO) << fn << " J2735 message bytes encoded as " << mapFile.get_Bytes(); + } + } catch (const std::ios_base::failure& e) { + PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); } } - catch( const ios_base::failure &e) { - PLOG(logERROR) << "Exception Encountered : \n" << e.what(); - } } else if (inType == "UPER") { From 64a451cd7d4b3c085549f142b1bf0ac3cf5cc548 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 18 Apr 2024 17:06:04 -0400 Subject: [PATCH 04/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 59e31b4ad..71f9b597f 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -252,8 +252,17 @@ bool MapPlugin::LoadMapFiles() try { std::string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); in.close(); + // Remove any newline characters fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); + // Check for and remove MessageFrame + if (fileContent.size() >= 4 && fileContent.substr(0, 4) == "0012") { + size_t pos = fileContent.find("38"); + PLOG(logDEBUG) << "Beginning of MapData found at: " << pos; + fileContent.erase(0, pos); + PLOG(logDEBUG) << "Payload without MessageFrame: " << fileContent; + } + std::istringstream streamableContent(fileContent); streamableContent >> bytes; MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); From d298723958658897f5f12ee9c6f8dc6aae8e77f4 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 18 Apr 2024 17:13:15 -0400 Subject: [PATCH 05/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 71f9b597f..9fd815db7 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -240,7 +240,7 @@ bool MapPlugin::LoadMapFiles() ISDToJ2735r41 converter(fn); mapFile.set_Bytes(converter.to_encoded_message().get_payload_str()); - PLOG(logINFO) << fn << "ISD file encoded as " << mapFile.get_Bytes(); + PLOG(logINFO) << fn << " ISD file encoded as " << mapFile.get_Bytes(); } else if (inType == "TXT") { @@ -264,7 +264,8 @@ bool MapPlugin::LoadMapFiles() } std::istringstream streamableContent(fileContent); - streamableContent >> bytes; + streamableContent >> bytes; + PLOG(logINFO) << fn << " MAP encoded bytes are " << bytes; MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); if (mapMsg) { PLOG(logDEBUG) << "Map is " << *mapMsg; @@ -356,7 +357,7 @@ bool MapPlugin::LoadMapFiles() } catch (exception &ex) { - PLOG(logERROR) << "Unable to convert " << mapFile.get_FilePath() << " : " << ex.what(); + PLOG(logERROR) << "Unable to convert " << mapFile.get_FilePath() << ": " << ex.what(); return false; } } From cfc8b43dec7318919ca716a4014ee9525fbbea11 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Mon, 29 Apr 2024 16:34:34 -0400 Subject: [PATCH 06/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 19 ++++++++++++------- src/v2i-hub/MapPlugin/src/MapPlugin.h | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 9fd815db7..ebd378a6b 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -207,6 +207,17 @@ int MapPlugin::Main() { return (EXIT_SUCCESS); } +string MapPlugin::removeMessageFrame(string &fileContent) { + // Check for and remove MessageFrame + if (fileContent.size() >= 4 && fileContent.substr(0, 4) == "0012") { + size_t pos = fileContent.find("38"); + PLOG(logDEBUG) << "Beginning of MapData found at: " << pos; + fileContent.erase(0, pos); + PLOG(logDEBUG) << "Payload without MessageFrame: " << fileContent; + } + return fileContent; +} + bool MapPlugin::LoadMapFiles() { if (_mapFiles.empty()) @@ -255,13 +266,7 @@ bool MapPlugin::LoadMapFiles() // Remove any newline characters fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); - // Check for and remove MessageFrame - if (fileContent.size() >= 4 && fileContent.substr(0, 4) == "0012") { - size_t pos = fileContent.find("38"); - PLOG(logDEBUG) << "Beginning of MapData found at: " << pos; - fileContent.erase(0, pos); - PLOG(logDEBUG) << "Payload without MessageFrame: " << fileContent; - } + fileContent = removeMessageFrame(fileContent); std::istringstream streamableContent(fileContent); streamableContent >> bytes; diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index f7419f417..ef129e276 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -97,6 +97,8 @@ class MapPlugin: public PluginClientClockAware { bool LoadMapFiles(); void DebugPrintMapFiles(); + string removeMessageFrame(string &fileContent); + }; } // namespace MapPlugin From 65a9e423680845dfd9ee71c9f868131952b2909d Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Fri, 24 May 2024 12:47:27 -0400 Subject: [PATCH 07/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 74 ++++++++++++++++++------- src/v2i-hub/MapPlugin/src/MapPlugin.h | 5 ++ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index ebd378a6b..18a9ab3d3 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -177,7 +177,7 @@ int MapPlugin::Main() { msg->set_payload(byteStr); msg->set_encoding(enc); msg->set_flags(IvpMsgFlags_RouteDSRC); - msg->addDsrcMetadata(0x8002); + msg->addDsrcMetadata(tmx::messages::api::mapData_PSID); activeAction = temp; PLOG(logINFO) << "Map for action " << activeAction << " will be sent"; @@ -207,15 +207,37 @@ int MapPlugin::Main() { return (EXIT_SUCCESS); } -string MapPlugin::removeMessageFrame(string &fileContent) { +string MapPlugin::enum_to_hex_string() +{ + sprintf(mapID_buffer, "%04X", tmx::messages::api::mapData); + string map_messageID = mapID_buffer; + return map_messageID; +} + +string MapPlugin::removeMessageFrame(string &fileContent) +{ + string map_messageID = enum_to_hex_string(); + // Check for and remove MessageFrame - if (fileContent.size() >= 4 && fileContent.substr(0, 4) == "0012") { - size_t pos = fileContent.find("38"); - PLOG(logDEBUG) << "Beginning of MapData found at: " << pos; - fileContent.erase(0, pos); - PLOG(logDEBUG) << "Payload without MessageFrame: " << fileContent; + if (fileContent.size() >= 4 && fileContent.substr(0, 4) == map_messageID) + { + // Check if message is hex size > 255, remove appropriate header + string tempFrame = fileContent; + tempFrame.erase(0, 6); + PLOG(logDEBUG4) << "Checking size of: " << tempFrame; + if (tempFrame.size() > 510) + { + fileContent.erase(0, 8); + + } + else + { + fileContent.erase(0, 6); + } + + PLOG(logDEBUG4) << "Payload without MessageFrame: " << fileContent; } - return fileContent; + return fileContent; } bool MapPlugin::LoadMapFiles() @@ -257,22 +279,28 @@ bool MapPlugin::LoadMapFiles() { byte_stream bytes; std::ifstream in(fn, std::ios::binary); - if (!in) { + if (!in) + { PLOG(logERROR) << "Failed to open file: " << fn; - } else { - try { - std::string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + } + else + { + try + { + string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); in.close(); // Remove any newline characters fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); - + PLOG(logDEBUG4) << "Map without newline " << fileContent; fileContent = removeMessageFrame(fileContent); std::istringstream streamableContent(fileContent); streamableContent >> bytes; PLOG(logINFO) << fn << " MAP encoded bytes are " << bytes; MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); - if (mapMsg) { + + if (mapMsg) + { PLOG(logDEBUG) << "Map is " << *mapMsg; MapDataEncodedMessage mapEnc; @@ -281,7 +309,8 @@ bool MapPlugin::LoadMapFiles() PLOG(logINFO) << fn << " J2735 message bytes encoded as " << mapFile.get_Bytes(); } - } catch (const std::ios_base::failure& e) { + } catch (const std::ios_base::failure& e) + { PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); } } @@ -289,24 +318,27 @@ bool MapPlugin::LoadMapFiles() else if (inType == "UPER") { PLOG(logDEBUG) << "Reading MAP file as UPER encoded hex bytes including MessageFrame."; - std::ifstream in; + std::ifstream in; try { in.open(fn, std::ios::in | std::ios::binary ); - if (in.is_open()) { + if (in.is_open()) + { in.seekg(0, std::ios::end); int fileSize = in.tellg(); in.seekg(0, std::ios::beg); PLOG(logDEBUG) << "File size is: " << fileSize; - std::string bytes_string((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + string bytes_string((std::istreambuf_iterator(in)), std::istreambuf_iterator()); bytes_string.erase(remove(bytes_string.begin(), bytes_string.end(), '\n'), bytes_string.end()); PLOG(logDEBUG) << "File contents: " << bytes_string; - mapFile.set_Bytes(bytes_string); + mapFile.set_Bytes(bytes_string); } - else { + else + { PLOG(logERROR) << "Failed to open file: " << fn << "."; } } - catch( const ios_base::failure &e) { + catch( const ios_base::failure &e) + { PLOG(logERROR) << "Exception Encountered: \n" << e.what(); } } diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index ef129e276..accdf0f8c 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include "XmlMapParser.h" #include "ConvertToJ2735r41.h" #include "inputs/isd/ISDToJ2735r41.h" @@ -95,8 +97,11 @@ class MapPlugin: public PluginClientClockAware { int sendFrequency = 1000; FrequencyThrottle errThrottle; + char mapID_buffer[5]; + bool LoadMapFiles(); void DebugPrintMapFiles(); + string enum_to_hex_string(); string removeMessageFrame(string &fileContent); }; From 32dc37bd3c74bb7593e01b80f0a2480ac727f603 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Wed, 29 May 2024 18:32:35 -0400 Subject: [PATCH 08/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 3 --- src/v2i-hub/MapPlugin/src/MapPlugin.h | 10 ++++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 18a9ab3d3..f0850e544 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -1,7 +1,4 @@ #include "MapPlugin.h" -#include -#include -#include namespace MapPlugin { diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index accdf0f8c..c2f34da8a 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -1,8 +1,5 @@ #pragma once -#ifndef MAPPLUGIN_H_ -#define MAPPLUGIN_H_ - #include #include #include @@ -17,6 +14,9 @@ #include #include #include +#include +#include +#include #include #include @@ -97,7 +97,7 @@ class MapPlugin: public PluginClientClockAware { int sendFrequency = 1000; FrequencyThrottle errThrottle; - char mapID_buffer[5]; + char mapID_buffer[5] = {0}; bool LoadMapFiles(); void DebugPrintMapFiles(); @@ -107,5 +107,3 @@ class MapPlugin: public PluginClientClockAware { }; } // namespace MapPlugin - -#endif /* MAPPLUGIN_H_ */ From fa843d04ef0e5e76c3139f8d9ac2f20dbd065662 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Wed, 12 Jun 2024 17:51:40 -0400 Subject: [PATCH 09/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 133 ++++++++++-------------- src/v2i-hub/MapPlugin/src/MapPlugin.h | 37 ++++--- 2 files changed, 78 insertions(+), 92 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index f0850e544..2cfe88cc3 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -2,14 +2,12 @@ namespace MapPlugin { -MapPlugin::MapPlugin(string name) : PluginClientClockAware(name) { +MapPlugin::MapPlugin(const std::string &name) : PluginClientClockAware(name) { AddMessageFilter(IVPMSG_TYPE_SIGCONT, "ACT", IvpMsgFlags_None); SubscribeToMessages(); errThrottle.set_Frequency(std::chrono::minutes(30)); } -MapPlugin::~MapPlugin() {} - void MapPlugin::UpdateConfigSettings() { GetConfigValue("Frequency", sendFrequency); @@ -69,7 +67,7 @@ void MapPlugin::OnConfigChanged(const char *key, const char *value) { // Check for special case Cohda R63 messages if (strcmp("Cohda R63", key)) { - string strValue(value); + std::string strValue(value); if (boost::iequals(strValue, "1") || boost::iequals(strValue, "true") @@ -156,7 +154,7 @@ int MapPlugin::Main() { if (temp != activeAction) { lock_guard lock(data_lock); - string byteStr = _mapFiles[temp].get_Bytes(); + std::string byteStr = _mapFiles[temp].get_Bytes(); if (!byteStr.empty()) { msg.reset(dynamic_cast(factory.NewMessage(api::MSGSUBTYPE_MAPDATA_STRING))); @@ -169,7 +167,7 @@ int MapPlugin::Main() { continue; } - string enc = msg->get_encoding(); + std::string enc = msg->get_encoding(); msg->refresh_timestamp(); msg->set_payload(byteStr); msg->set_encoding(enc); @@ -204,37 +202,55 @@ int MapPlugin::Main() { return (EXIT_SUCCESS); } -string MapPlugin::enum_to_hex_string() +std::string MapPlugin::enum_to_hex_string() { - sprintf(mapID_buffer, "%04X", tmx::messages::api::mapData); - string map_messageID = mapID_buffer; - return map_messageID; + std::snprintf(mapID_buffer.data(), mapID_buffer.size(), "%04X", tmx::messages::api::mapData); + std::string map_messageID(mapID_buffer.data()); + + return map_messageID; } -string MapPlugin::removeMessageFrame(string &fileContent) +std::string MapPlugin::removeMessageFrame(const std::string &fileContent) { - string map_messageID = enum_to_hex_string(); + std::string map_messageID = enum_to_hex_string(); // Check for and remove MessageFrame if (fileContent.size() >= 4 && fileContent.substr(0, 4) == map_messageID) { // Check if message is hex size > 255, remove appropriate header - string tempFrame = fileContent; + std::string tempFrame = fileContent; + std::string newFrame = fileContent; tempFrame.erase(0, 6); PLOG(logDEBUG4) << "Checking size of: " << tempFrame; - if (tempFrame.size() > 510) - { - fileContent.erase(0, 8); - - } - else - { - fileContent.erase(0, 6); - } + auto headerSize = (tempFrame.size() > 510) ? 8 : 6; + newFrame.erase(0, headerSize); - PLOG(logDEBUG4) << "Payload without MessageFrame: " << fileContent; + PLOG(logDEBUG4) << "Payload without MessageFrame: " << newFrame; + return newFrame; } - return fileContent; + else + { + return fileContent; + } +} + +std::string MapPlugin::checkMapContent(std::ifstream &in, const std::string &fileName) +{ + try + { + std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + in.close(); + // Remove any newline characters + content.erase(remove(content.begin(), content.end(), '\n'), content.end()); + PLOG(logDEBUG4) << "Map without newline " << content; + std::string payload = removeMessageFrame(content); + + return payload; + } + catch (const std::ios_base::failure& e) + { + PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); + } } bool MapPlugin::LoadMapFiles() @@ -249,12 +265,12 @@ bool MapPlugin::LoadMapFiles() if (mapFile.get_Bytes() == "") { // Fill in the bytes for each map file - string inType = mapFile.get_InputType(); + std::string inType = mapFile.get_InputType(); if (inType.empty()) { try { - string fn = mapFile.get_FilePath(); + std::string fn = mapFile.get_FilePath(); if (fn.substr(fn.size() - 5) == ".json") inType = "ISD"; @@ -274,7 +290,6 @@ bool MapPlugin::LoadMapFiles() } else if (inType == "TXT") { - byte_stream bytes; std::ifstream in(fn, std::ios::binary); if (!in) { @@ -282,61 +297,23 @@ bool MapPlugin::LoadMapFiles() } else { - try + std::string payload = checkMapContent(in, fn); + byte_stream bytes; + std::istringstream streamableContent(payload); + streamableContent >> bytes; + PLOG(logINFO) << "MAP encoded bytes are " << bytes; + MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); + + if (mapMsg) { - string fileContent((std::istreambuf_iterator(in)), std::istreambuf_iterator()); - in.close(); - // Remove any newline characters - fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); - PLOG(logDEBUG4) << "Map without newline " << fileContent; - fileContent = removeMessageFrame(fileContent); - - std::istringstream streamableContent(fileContent); - streamableContent >> bytes; - PLOG(logINFO) << fn << " MAP encoded bytes are " << bytes; - MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); - - if (mapMsg) - { - PLOG(logDEBUG) << "Map is " << *mapMsg; + PLOG(logDEBUG) << "Map is " << *mapMsg; - MapDataEncodedMessage mapEnc; - mapEnc.encode_j2735_message(*mapMsg); - mapFile.set_Bytes(mapEnc.get_payload_str()); + MapDataEncodedMessage mapEnc; + mapEnc.encode_j2735_message(*mapMsg); + mapFile.set_Bytes(mapEnc.get_payload_str()); - PLOG(logINFO) << fn << " J2735 message bytes encoded as " << mapFile.get_Bytes(); - } - } catch (const std::ios_base::failure& e) - { - PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); - } - } - } - else if (inType == "UPER") - { - PLOG(logDEBUG) << "Reading MAP file as UPER encoded hex bytes including MessageFrame."; - std::ifstream in; - try { - in.open(fn, std::ios::in | std::ios::binary ); - if (in.is_open()) - { - in.seekg(0, std::ios::end); - int fileSize = in.tellg(); - in.seekg(0, std::ios::beg); - PLOG(logDEBUG) << "File size is: " << fileSize; - string bytes_string((std::istreambuf_iterator(in)), std::istreambuf_iterator()); - bytes_string.erase(remove(bytes_string.begin(), bytes_string.end(), '\n'), bytes_string.end()); - PLOG(logDEBUG) << "File contents: " << bytes_string; - mapFile.set_Bytes(bytes_string); + PLOG(logINFO) << "J2735 message bytes encoded as " << mapFile.get_Bytes(); } - else - { - PLOG(logERROR) << "Failed to open file: " << fn << "."; - } - } - catch( const ios_base::failure &e) - { - PLOG(logERROR) << "Exception Encountered: \n" << e.what(); } } else if (inType == "XML") diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index c2f34da8a..d0974ed66 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -1,5 +1,12 @@ -#pragma once +//============================================================================ +// Name : MapPlugin.cpp +// Author : FHWA Saxton Transportation Operations Laboratory +// Version : 7.6.0 +// Copyright : Copyright (c) 2024 FHWA Saxton Transportation Operations Laboratory. All rights reserved. +// Description : MAP Plugin +//============================================================================ +#pragma once #include #include #include @@ -20,6 +27,8 @@ #include #include +#include +#include #include #include #include @@ -38,7 +47,6 @@ #include -using namespace std; using namespace tmx; using namespace tmx::messages; using namespace tmx::utils; @@ -52,18 +60,18 @@ UPERframe _uperFrameMessage; class MapFile: public tmx::message { public: MapFile(): tmx::message() {} - virtual ~MapFile() {} + virtual ~MapFile() = default; std_attribute(this->msg, int, Action, -1, ); std_attribute(this->msg, std::string, FilePath, "", ); std_attribute(this->msg, std::string, InputType, "", ); std_attribute(this->msg, std::string, Bytes, "", ); - static tmx::message_tree_type to_tree(MapFile m) { + static tmx::message_tree_type to_tree(MapFile& m) { return tmx::message::to_tree(static_cast(m)); } - static MapFile from_tree(tmx::message_tree_type tree) { + static MapFile from_tree(const tmx::message_tree_type &tree) { MapFile m; m.set_contents(tree); return m; @@ -72,17 +80,17 @@ class MapFile: public tmx::message { class MapPlugin: public PluginClientClockAware { public: - MapPlugin(string name); - virtual ~MapPlugin(); - virtual int Main(); + explicit MapPlugin(const std::string &name); + virtual ~MapPlugin() = default; + int Main() override; protected: void UpdateConfigSettings(); // Virtual method overrides. - void OnConfigChanged(const char *key, const char *value); - void OnMessageReceived(IvpMessage *msg); - void OnStateChange(IvpPluginState state); + void OnConfigChanged(const char *key, const char *value) override; + void OnMessageReceived(IvpMessage *msg) override; + void OnStateChange(IvpPluginState state) override; private: std::atomic _mapAction {-1}; @@ -97,12 +105,13 @@ class MapPlugin: public PluginClientClockAware { int sendFrequency = 1000; FrequencyThrottle errThrottle; - char mapID_buffer[5] = {0}; + std::array mapID_buffer; bool LoadMapFiles(); void DebugPrintMapFiles(); - string enum_to_hex_string(); - string removeMessageFrame(string &fileContent); + std::string enum_to_hex_string(); + std::string removeMessageFrame(const std::string &fileContent); + std::string checkMapContent(std::ifstream &in, const std::string &fileName); }; From aef5746b43ec151d0688733ce3aeda3d690c63c7 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 13 Jun 2024 14:03:22 -0400 Subject: [PATCH 10/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 573 ++++++++++++------------ src/v2i-hub/MapPlugin/src/MapPlugin.h | 22 +- 2 files changed, 294 insertions(+), 301 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 2cfe88cc3..12d783a12 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -1,392 +1,395 @@ #include "MapPlugin.h" +using namespace tmx::utils; + namespace MapPlugin { -MapPlugin::MapPlugin(const std::string &name) : PluginClientClockAware(name) { - AddMessageFilter(IVPMSG_TYPE_SIGCONT, "ACT", IvpMsgFlags_None); - SubscribeToMessages(); - errThrottle.set_Frequency(std::chrono::minutes(30)); -} + MapPlugin::MapPlugin(const std::string &name) : PluginClientClockAware(name) { + AddMessageFilter(IVPMSG_TYPE_SIGCONT, "ACT", IvpMsgFlags_None); + SubscribeToMessages(); + errThrottle.set_Frequency(std::chrono::minutes(30)); + } -void MapPlugin::UpdateConfigSettings() { - GetConfigValue("Frequency", sendFrequency); + void MapPlugin::UpdateConfigSettings() { + GetConfigValue("Frequency", sendFrequency); - message_tree_type rawMapFiles; - GetConfigValue("MAP_Files", rawMapFiles); + message_tree_type rawMapFiles; + GetConfigValue("MAP_Files", rawMapFiles); - if (!rawMapFiles.empty()) { - try - { - lock_guard lock(data_lock); - _mapFiles.clear(); + if (!rawMapFiles.empty()) { + try + { + lock_guard lock(data_lock); + _mapFiles.clear(); - tmx::message mapFiles; - mapFiles.set_contents(rawMapFiles); + tmx::message mapFiles; + mapFiles.set_contents(rawMapFiles); - PLOG(logDEBUG) << "Got MAP_Files: " << mapFiles; + PLOG(logDEBUG) << "Got MAP_Files: " << mapFiles; - for (auto mapFile : mapFiles.template get_array("MapFiles")) - { - if (mapFile.get_Action() < 0) - continue; + for (auto mapFile : mapFiles.template get_array("MapFiles")) + { + if (mapFile.get_Action() < 0) + continue; - _mapFiles[mapFile.get_Action()] = mapFile; - _isMapFileNew = true; - } + _mapFiles[mapFile.get_Action()] = mapFile; + _isMapFileNew = true; + } - // Check to see if the active map was lost - if (!_mapFiles.count(_mapAction)) - { - if (_mapAction > 0) + // Check to see if the active map was lost + if (!_mapFiles.count(_mapAction)) { - PLOG(logINFO) << "New configuration does not contain a map for active action " << - _mapAction << ". Using default action."; + if (_mapAction > 0) + { + PLOG(logINFO) << "New configuration does not contain a map for active action " << + _mapAction << ". Using default action."; + } + _mapAction = -1; } - _mapAction = -1; - } - if (_mapFiles.size() > 0 && _mapAction < 0) - _mapAction = _mapFiles.begin()->first; + if (_mapFiles.size() > 0 && _mapAction < 0) + _mapAction = _mapFiles.begin()->first; - } - catch (exception &ex) - { - PLOG(logERROR) << "Unable to parse map file input: " << ex.what(); + } + catch (exception &ex) + { + PLOG(logERROR) << "Unable to parse map file input: " << ex.what(); + } + + DebugPrintMapFiles(); } - DebugPrintMapFiles(); } -} - -void MapPlugin::OnConfigChanged(const char *key, const char *value) { - PluginClient::OnConfigChanged(key, value); + void MapPlugin::OnConfigChanged(const char *key, const char *value) { + PluginClient::OnConfigChanged(key, value); - if (_plugin->state == IvpPluginState_registered) - { - // Check for special case Cohda R63 messages - if (strcmp("Cohda R63", key)) + if (_plugin->state == IvpPluginState_registered) { - std::string strValue(value); - - if (boost::iequals(strValue, "1") - || boost::iequals(strValue, "true") - || boost::iequals(strValue, "t") - || boost::iequals(strValue, "on")) + // Check for special case Cohda R63 messages + if (strcmp("Cohda R63", key)) { - _cohdaR63 = true; + std::string strValue(value); + + if (boost::iequals(strValue, "1") + || boost::iequals(strValue, "true") + || boost::iequals(strValue, "t") + || boost::iequals(strValue, "on")) + { + _cohdaR63 = true; + } + else + { + _cohdaR63 = false; + } } else { - _cohdaR63 = false; + UpdateConfigSettings(); } } - else - { - UpdateConfigSettings(); - } } -} -void MapPlugin::OnStateChange(IvpPluginState state) { - PluginClientClockAware::OnStateChange(state); + void MapPlugin::OnStateChange(IvpPluginState state) { + PluginClientClockAware::OnStateChange(state); - if (state == IvpPluginState_registered) { - UpdateConfigSettings(); + if (state == IvpPluginState_registered) { + UpdateConfigSettings(); + } } -} -void MapPlugin::OnMessageReceived(IvpMessage *msg) { - PluginClient::OnMessageReceived(msg); + void MapPlugin::OnMessageReceived(IvpMessage *msg) { + PluginClient::OnMessageReceived(msg); - if ((strcmp(msg->type, IVPMSG_TYPE_SIGCONT) == 0) - && (strcmp(msg->subtype, "ACT") == 0) - && (msg->payload->type == cJSON_String)) { - int action = ivpSigCont_getIvpSignalControllerAction(msg); + if ((strcmp(msg->type, IVPMSG_TYPE_SIGCONT) == 0) + && (strcmp(msg->subtype, "ACT") == 0) + && (msg->payload->type == cJSON_String)) { + int action = ivpSigCont_getIvpSignalControllerAction(msg); - if (action != _mapAction) - { - // Ignore if there is no map for this action - lock_guard lock(data_lock); - if (_mapFiles.count(action) <= 0) + if (action != _mapAction) { - if (errThrottle.Monitor(action)) + // Ignore if there is no map for this action + lock_guard lock(data_lock); + if (_mapFiles.count(action) <= 0) { - PLOG(logERROR) << "Missing map for Action " << action; + if (errThrottle.Monitor(action)) + { + PLOG(logERROR) << "Missing map for Action " << action; + } + return; } - return; - } - _isMapFileNew = _mapAction.exchange(action) != action; + _isMapFileNew = _mapAction.exchange(action) != action; + } } } -} -int MapPlugin::Main() { - PLOG(logINFO) << "Starting plugin."; + int MapPlugin::Main() { + PLOG(logINFO) << "Starting plugin."; - bool mapFilesOk = false; + bool mapFilesOk = false; - std::unique_ptr msg; - int activeAction = -1; - - // wait for the clock to be initialized - getClock()->wait_for_initialization(); + std::unique_ptr msg; + int activeAction = -1; + + // wait for the clock to be initialized + getClock()->wait_for_initialization(); - while (_plugin->state != IvpPluginState_error) { - if (_isMapFileNew) { - msg.reset(); - activeAction = -1; + while (_plugin->state != IvpPluginState_error) { + if (_isMapFileNew) { + msg.reset(); + activeAction = -1; - mapFilesOk = LoadMapFiles(); - _isMapFileNew = false; - } + mapFilesOk = LoadMapFiles(); + _isMapFileNew = false; + } - int temp = _mapAction; - if (temp < 0) - { - // No action set yet, so just wait - sleep(1); - continue; - } + int temp = _mapAction; + if (temp < 0) + { + // No action set yet, so just wait + sleep(1); + continue; + } - // Action has changed, so retrieve the correct map - if (temp != activeAction) - { - lock_guard lock(data_lock); - std::string byteStr = _mapFiles[temp].get_Bytes(); - if (!byteStr.empty()) + // Action has changed, so retrieve the correct map + if (temp != activeAction) { - msg.reset(dynamic_cast(factory.NewMessage(api::MSGSUBTYPE_MAPDATA_STRING))); - if (!msg) - { if (errThrottle.Monitor(temp)) - { - PLOG(logERROR) << "Unable to create map from bytes " << byteStr << ": " << factory.get_event(); + lock_guard lock(data_lock); + std::string byteStr = _mapFiles[temp].get_Bytes(); + if (!byteStr.empty()) + { + msg.reset(dynamic_cast(factory.NewMessage(tmx::messages::api::MSGSUBTYPE_MAPDATA_STRING))); + if (!msg) + { if (errThrottle.Monitor(temp)) + { + PLOG(logERROR) << "Unable to create map from bytes " << byteStr << ": " << factory.get_event(); + } + sleep(1); + continue; } - sleep(1); - continue; - } - std::string enc = msg->get_encoding(); - msg->refresh_timestamp(); - msg->set_payload(byteStr); - msg->set_encoding(enc); - msg->set_flags(IvpMsgFlags_RouteDSRC); - msg->addDsrcMetadata(tmx::messages::api::mapData_PSID); + std::string enc = msg->get_encoding(); + msg->refresh_timestamp(); + msg->set_payload(byteStr); + msg->set_encoding(enc); + msg->set_flags(IvpMsgFlags_RouteDSRC); + msg->addDsrcMetadata(tmx::messages::api::mapData_PSID); - activeAction = temp; - PLOG(logINFO) << "Map for action " << activeAction << " will be sent"; + activeAction = temp; + PLOG(logINFO) << "Map for action " << activeAction << " will be sent"; + } } - } - if (mapFilesOk) - { - // Time to send a new message - routeable_message *rMsg = dynamic_cast(msg.get()); - if (_cohdaR63) + if (mapFilesOk) { - auto bytes = rMsg->get_payload_bytes(); - rMsg->set_payload_bytes(bytes); // TODO: Translate to R63 bytes - } + // Time to send a new message + routeable_message *rMsg = dynamic_cast(msg.get()); + if (_cohdaR63) + { + auto bytes = rMsg->get_payload_bytes(); + rMsg->set_payload_bytes(bytes); // TODO: Translate to R63 bytes + } - if (rMsg) { - rMsg->refresh_timestamp(); - BroadcastMessage(*rMsg); + if (rMsg) { + rMsg->refresh_timestamp(); + BroadcastMessage(*rMsg); + } } + + auto sleepUntil = getClock()->nowInMilliseconds() + sendFrequency; + getClock()->sleep_until(sleepUntil); } - auto sleepUntil = getClock()->nowInMilliseconds() + sendFrequency; - getClock()->sleep_until(sleepUntil); + return (EXIT_SUCCESS); } - return (EXIT_SUCCESS); -} - -std::string MapPlugin::enum_to_hex_string() -{ - std::snprintf(mapID_buffer.data(), mapID_buffer.size(), "%04X", tmx::messages::api::mapData); - std::string map_messageID(mapID_buffer.data()); - - return map_messageID; -} - -std::string MapPlugin::removeMessageFrame(const std::string &fileContent) -{ - std::string map_messageID = enum_to_hex_string(); - - // Check for and remove MessageFrame - if (fileContent.size() >= 4 && fileContent.substr(0, 4) == map_messageID) - { - // Check if message is hex size > 255, remove appropriate header - std::string tempFrame = fileContent; - std::string newFrame = fileContent; - tempFrame.erase(0, 6); - PLOG(logDEBUG4) << "Checking size of: " << tempFrame; - auto headerSize = (tempFrame.size() > 510) ? 8 : 6; - newFrame.erase(0, headerSize); - - PLOG(logDEBUG4) << "Payload without MessageFrame: " << newFrame; - return newFrame; - } - else + std::string MapPlugin::enum_to_hex_string() { - return fileContent; + std::snprintf(mapID_buffer.data(), mapID_buffer.size(), "%04X", tmx::messages::api::mapData); + std::string map_messageID(mapID_buffer.data()); + + return map_messageID; } -} -std::string MapPlugin::checkMapContent(std::ifstream &in, const std::string &fileName) -{ - try + std::string MapPlugin::removeMessageFrame(const std::string &fileContent) { - std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); - in.close(); - // Remove any newline characters - content.erase(remove(content.begin(), content.end(), '\n'), content.end()); - PLOG(logDEBUG4) << "Map without newline " << content; - std::string payload = removeMessageFrame(content); - - return payload; + std::string map_messageID = enum_to_hex_string(); + + // Check for and remove MessageFrame + if (fileContent.size() >= 4 && fileContent.substr(0, 4) == map_messageID) + { + // Check if message is hex size > 255, remove appropriate header + std::string tempFrame = fileContent; + std::string newFrame = fileContent; + tempFrame.erase(0, 6); + PLOG(logDEBUG4) << "Checking size of: " << tempFrame; + auto headerSize = (tempFrame.size() > 510) ? 8 : 6; + newFrame.erase(0, headerSize); + + PLOG(logDEBUG4) << "Payload without MessageFrame: " << newFrame; + return newFrame; + } + else + { + return fileContent; + } } - catch (const std::ios_base::failure& e) + + std::string MapPlugin::checkMapContent(std::ifstream &in) { - PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); + try + { + std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + in.close(); + // Remove any newline characters + content.erase(remove(content.begin(), content.end(), '\n'), content.end()); + PLOG(logDEBUG4) << "Map without newline " << content; + std::string payload = removeMessageFrame(content); + + return payload; + } + catch (const std::ios_base::failure& e) + { + PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); + return ""; + } } -} -bool MapPlugin::LoadMapFiles() -{ - if (_mapFiles.empty()) - return false; - - lock_guard lock(data_lock); - for (auto &mapPair : _mapFiles) + bool MapPlugin::LoadMapFiles() { - MapFile &mapFile = mapPair.second; - if (mapFile.get_Bytes() == "") + if (_mapFiles.empty()) + return false; + + lock_guard lock(data_lock); + for (auto &mapPair : _mapFiles) { - // Fill in the bytes for each map file - std::string inType = mapFile.get_InputType(); - if (inType.empty()) + MapFile &mapFile = mapPair.second; + if (mapFile.get_Bytes() == "") { - try + // Fill in the bytes for each map file + std::string inType = mapFile.get_InputType(); + if (inType.empty()) { - std::string fn = mapFile.get_FilePath(); - - if (fn.substr(fn.size() - 5) == ".json") - inType = "ISD"; - else if (fn.substr(fn.size() - 4) == ".txt") - inType = "TXT"; - else if (fn.substr(fn.size()- 5) == ".uper") - inType ="UPER"; - else - inType = "XML"; - - if (inType == "ISD") + try { - ISDToJ2735r41 converter(fn); - mapFile.set_Bytes(converter.to_encoded_message().get_payload_str()); + std::string fn = mapFile.get_FilePath(); + + if (fn.substr(fn.size() - 5) == ".json") + inType = "ISD"; + else if (fn.substr(fn.size() - 4) == ".txt") + inType = "TXT"; + else if (fn.substr(fn.size()- 5) == ".uper") + inType ="UPER"; + else + inType = "XML"; - PLOG(logINFO) << fn << " ISD file encoded as " << mapFile.get_Bytes(); - } - else if (inType == "TXT") - { - std::ifstream in(fn, std::ios::binary); - if (!in) + if (inType == "ISD") { - PLOG(logERROR) << "Failed to open file: " << fn; + ISDToJ2735r41 converter(fn); + mapFile.set_Bytes(converter.to_encoded_message().get_payload_str()); + + PLOG(logINFO) << fn << " ISD file encoded as " << mapFile.get_Bytes(); } - else + else if (inType == "TXT") { - std::string payload = checkMapContent(in, fn); - byte_stream bytes; - std::istringstream streamableContent(payload); - streamableContent >> bytes; - PLOG(logINFO) << "MAP encoded bytes are " << bytes; - MapDataMessage *mapMsg = MapDataEncodedMessage::decode_j2735_message>(bytes); - - if (mapMsg) + std::ifstream in(fn, std::ios::binary); + if (!in) { - PLOG(logDEBUG) << "Map is " << *mapMsg; + PLOG(logERROR) << "Failed to open file: " << fn; + } + else + { + std::string payload = checkMapContent(in); + byte_stream bytes; + std::istringstream streamableContent(payload); + streamableContent >> bytes; + PLOG(logINFO) << "MAP encoded bytes are " << bytes; + tmx::messages::MapDataMessage *mapMsg = tmx::messages::MapDataEncodedMessage::decode_j2735_message>(bytes); + + if (mapMsg) + { + PLOG(logDEBUG) << "Map is " << *mapMsg; - MapDataEncodedMessage mapEnc; - mapEnc.encode_j2735_message(*mapMsg); - mapFile.set_Bytes(mapEnc.get_payload_str()); + tmx::messages::MapDataEncodedMessage mapEnc; + mapEnc.encode_j2735_message(*mapMsg); + mapFile.set_Bytes(mapEnc.get_payload_str()); - PLOG(logINFO) << "J2735 message bytes encoded as " << mapFile.get_Bytes(); + PLOG(logINFO) << "J2735 message bytes encoded as " << mapFile.get_Bytes(); + } } } - } - else if (inType == "XML") - { - tmx::message_container_type container; - container.load(fn); - - if (container.get_storage().get_tree().begin()->first == "MapData") + else if (inType == "XML") { - MapDataMessage mapMsg; - mapMsg.set_contents(container.get_storage().get_tree()); + tmx::message_container_type container; + container.load(fn); - PLOG(logDEBUG) << "Encoding " << mapMsg; - MapDataEncodedMessage mapEnc; - mapEnc.encode_j2735_message(mapMsg); - mapFile.set_Bytes(mapEnc.get_payload_str()); + if (container.get_storage().get_tree().begin()->first == "MapData") + { + tmx::messages::MapDataMessage mapMsg; + mapMsg.set_contents(container.get_storage().get_tree()); - PLOG(logINFO) << fn << " XML file encoded as: " << mapFile.get_Bytes(); - } - else - { - ConvertToJ2735r41 mapConverter; - XmlMapParser mapParser; - map theMap; + PLOG(logDEBUG) << "Encoding " << mapMsg; + tmx::messages::MapDataEncodedMessage mapEnc; + mapEnc.encode_j2735_message(mapMsg); + mapFile.set_Bytes(mapEnc.get_payload_str()); - if (mapParser.ReadGidFile(fn, &theMap)) + PLOG(logINFO) << fn << " XML file encoded as: " << mapFile.get_Bytes(); + } + else { - mapConverter.convertMap(&theMap); - - PLOG(logDEBUG) << "Encoded Bytes:" << mapConverter.encodedByteCount; + ConvertToJ2735r41 mapConverter; + XmlMapParser mapParser; + map theMap; - if (mapConverter.encodedByteCount > 0) + if (mapParser.ReadGidFile(fn, &theMap)) { - byte_stream bytes(mapConverter.encodedByteCount); - memcpy(bytes.data(), mapConverter.encoded, mapConverter.encodedByteCount); + mapConverter.convertMap(&theMap); - auto *mapEnc = factory.NewMessage(bytes); - if (!mapEnc) - return false; + PLOG(logDEBUG) << "Encoded Bytes:" << mapConverter.encodedByteCount; - mapFile.set_Bytes(mapEnc->get_payload_str()); + if (mapConverter.encodedByteCount > 0) + { + byte_stream bytes(mapConverter.encodedByteCount); + memcpy(bytes.data(), mapConverter.encoded, mapConverter.encodedByteCount); - PLOG(logINFO) << fn << " input file encoded as: " << mapEnc->get_payload_str(); - } - else - { - return false; + auto *mapEnc = factory.NewMessage(bytes); + if (!mapEnc) + return false; + + mapFile.set_Bytes(mapEnc->get_payload_str()); + + PLOG(logINFO) << fn << " input file encoded as: " << mapEnc->get_payload_str(); + } + else + { + return false; + } } } } } - } - catch (exception &ex) - { - PLOG(logERROR) << "Unable to convert " << mapFile.get_FilePath() << ": " << ex.what(); - return false; + catch (exception &ex) + { + PLOG(logERROR) << "Unable to convert " << mapFile.get_FilePath() << ": " << ex.what(); + return false; + } } } } - } - return true; -} + return true; + } -void MapPlugin::DebugPrintMapFiles() { - PLOG(logDEBUG) << _mapFiles.size() - << " map files specified by configuration settings:"; + void MapPlugin::DebugPrintMapFiles() { + PLOG(logDEBUG) << _mapFiles.size() + << " map files specified by configuration settings:"; - for (auto iter = _mapFiles.begin(); iter != _mapFiles.end(); iter++) { - int key = iter->first; - PLOG(logDEBUG) << "-- Action " << key << " file is " << iter->second.get_FilePath(); + for (auto iter = _mapFiles.begin(); iter != _mapFiles.end(); iter++) { + int key = iter->first; + PLOG(logDEBUG) << "-- Action " << key << " file is " << iter->second.get_FilePath(); + } } -} } /* End namespace MapPlugin */ diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index d0974ed66..bf41b1680 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -25,15 +25,11 @@ #include #include -#include #include -#include -#include #include #include #include #include -#include #include "XmlMapParser.h" #include "ConvertToJ2735r41.h" #include "inputs/isd/ISDToJ2735r41.h" @@ -47,10 +43,6 @@ #include -using namespace tmx; -using namespace tmx::messages; -using namespace tmx::utils; - namespace MapPlugin { #if SAEJ2735_SPEC < 63 @@ -59,15 +51,14 @@ UPERframe _uperFrameMessage; class MapFile: public tmx::message { public: - MapFile(): tmx::message() {} - virtual ~MapFile() = default; + using tmx::message::message; std_attribute(this->msg, int, Action, -1, ); std_attribute(this->msg, std::string, FilePath, "", ); std_attribute(this->msg, std::string, InputType, "", ); std_attribute(this->msg, std::string, Bytes, "", ); - static tmx::message_tree_type to_tree(MapFile& m) { + static tmx::message_tree_type to_tree(const MapFile& m) { return tmx::message::to_tree(static_cast(m)); } @@ -78,10 +69,9 @@ class MapFile: public tmx::message { } }; -class MapPlugin: public PluginClientClockAware { +class MapPlugin: public tmx::utils::PluginClientClockAware { public: explicit MapPlugin(const std::string &name); - virtual ~MapPlugin() = default; int Main() override; protected: @@ -100,10 +90,10 @@ class MapPlugin: public PluginClientClockAware { std::map _mapFiles; std::mutex data_lock; - J2735MessageFactory factory; + tmx::messages::J2735MessageFactory factory; int sendFrequency = 1000; - FrequencyThrottle errThrottle; + tmx::utils::FrequencyThrottle errThrottle; std::array mapID_buffer; @@ -111,7 +101,7 @@ class MapPlugin: public PluginClientClockAware { void DebugPrintMapFiles(); std::string enum_to_hex_string(); std::string removeMessageFrame(const std::string &fileContent); - std::string checkMapContent(std::ifstream &in, const std::string &fileName); + std::string checkMapContent(std::ifstream &in); }; From 7bbf82362ee50bda987dd451aeadd49909a91632 Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 13 Jun 2024 14:52:21 -0400 Subject: [PATCH 11/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index bf41b1680..5ede90e3e 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -52,6 +52,13 @@ UPERframe _uperFrameMessage; class MapFile: public tmx::message { public: using tmx::message::message; + ~MapFile() override = default; + + MapFile(MapFile&&) noexcept = default; + MapFile& operator=(MapFile&&) noexcept = default; + + MapFile(const MapFile&) = default; + MapFile& operator=(const MapFile&) = default; std_attribute(this->msg, int, Action, -1, ); std_attribute(this->msg, std::string, FilePath, "", ); @@ -59,7 +66,7 @@ class MapFile: public tmx::message { std_attribute(this->msg, std::string, Bytes, "", ); static tmx::message_tree_type to_tree(const MapFile& m) { - return tmx::message::to_tree(static_cast(m)); + return tmx::message::to_tree(static_cast(m)); } static MapFile from_tree(const tmx::message_tree_type &tree) { From 7de6bbd78fe18416fd8316d9a313108c9ca753fa Mon Sep 17 00:00:00 2001 From: jwillmartin Date: Thu, 27 Jun 2024 14:45:36 -0400 Subject: [PATCH 12/12] modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp modified: src/v2i-hub/MapPlugin/src/MapPlugin.h --- src/v2i-hub/MapPlugin/src/MapPlugin.cpp | 70 +++++++++++++------------ src/v2i-hub/MapPlugin/src/MapPlugin.h | 25 +++++---- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index 12d783a12..7ee8d4ae7 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -236,23 +236,33 @@ namespace MapPlugin { } } - std::string MapPlugin::checkMapContent(std::ifstream &in) + std::string MapPlugin::checkMapContent(const std::string &fn) { + PLOG(logDEBUG4) << "In MapPlugin :: checkMapContent"; try { - std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); - in.close(); - // Remove any newline characters - content.erase(remove(content.begin(), content.end(), '\n'), content.end()); - PLOG(logDEBUG4) << "Map without newline " << content; - std::string payload = removeMessageFrame(content); - - return payload; + std::ifstream in(fn.c_str(), std::ios::binary); + if (!in) + { + PLOG(logERROR) << "Failed to open file: " << fn.c_str(); + throw std::ios_base::failure("Failed to open file: " + fn); + } + else + { + std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + in.close(); + // Remove any newline characters + content.erase(remove(content.begin(), content.end(), '\n'), content.end()); + PLOG(logDEBUG4) << "Map without newline " << content; + std::string payload = removeMessageFrame(content); + + return payload; + } } catch (const std::ios_base::failure& e) { PLOG(logERROR) << "Exception encountered while reading file: " << e.what(); - return ""; + throw; } } @@ -279,10 +289,10 @@ namespace MapPlugin { inType = "ISD"; else if (fn.substr(fn.size() - 4) == ".txt") inType = "TXT"; - else if (fn.substr(fn.size()- 5) == ".uper") - inType ="UPER"; - else + else if (fn.substr(fn.size() - 4) == ".xml") inType = "XML"; + else + PLOG(logWARNING) << "Incorrect MapFile extension entered!"; if (inType == "ISD") { @@ -293,30 +303,22 @@ namespace MapPlugin { } else if (inType == "TXT") { - std::ifstream in(fn, std::ios::binary); - if (!in) - { - PLOG(logERROR) << "Failed to open file: " << fn; - } - else + std::string payload = checkMapContent(fn); + byte_stream bytes; + std::istringstream streamableContent(payload); + streamableContent >> bytes; + PLOG(logINFO) << "MAP encoded bytes are " << bytes; + tmx::messages::MapDataMessage *mapMsg = tmx::messages::MapDataEncodedMessage::decode_j2735_message>(bytes); + + if (mapMsg) { - std::string payload = checkMapContent(in); - byte_stream bytes; - std::istringstream streamableContent(payload); - streamableContent >> bytes; - PLOG(logINFO) << "MAP encoded bytes are " << bytes; - tmx::messages::MapDataMessage *mapMsg = tmx::messages::MapDataEncodedMessage::decode_j2735_message>(bytes); - - if (mapMsg) - { - PLOG(logDEBUG) << "Map is " << *mapMsg; + PLOG(logDEBUG) << "Map is " << *mapMsg; - tmx::messages::MapDataEncodedMessage mapEnc; - mapEnc.encode_j2735_message(*mapMsg); - mapFile.set_Bytes(mapEnc.get_payload_str()); + tmx::messages::MapDataEncodedMessage mapEnc; + mapEnc.encode_j2735_message(*mapMsg); + mapFile.set_Bytes(mapEnc.get_payload_str()); - PLOG(logINFO) << "J2735 message bytes encoded as " << mapFile.get_Bytes(); - } + PLOG(logINFO) << "J2735 message bytes encoded as " << mapFile.get_Bytes(); } } else if (inType == "XML") diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.h b/src/v2i-hub/MapPlugin/src/MapPlugin.h index 5ede90e3e..f0da14270 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.h +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.h @@ -65,7 +65,7 @@ class MapFile: public tmx::message { std_attribute(this->msg, std::string, InputType, "", ); std_attribute(this->msg, std::string, Bytes, "", ); - static tmx::message_tree_type to_tree(const MapFile& m) { + static tmx::message_tree_type to_tree(const MapFile &m) { return tmx::message::to_tree(static_cast(m)); } @@ -89,27 +89,26 @@ class MapPlugin: public tmx::utils::PluginClientClockAware { void OnMessageReceived(IvpMessage *msg) override; void OnStateChange(IvpPluginState state) override; + bool LoadMapFiles(); + void DebugPrintMapFiles(); + + std::string enum_to_hex_string(); + std::string removeMessageFrame(const std::string &fileContent); + std::string checkMapContent(const std::string &fn); + private: + tmx::messages::J2735MessageFactory factory; + tmx::utils::FrequencyThrottle errThrottle; + std::atomic _mapAction {-1}; std::atomic _isMapFileNew {false}; std::atomic _cohdaR63 {false}; - std::map _mapFiles; std::mutex data_lock; - - tmx::messages::J2735MessageFactory factory; - + std::map _mapFiles; int sendFrequency = 1000; - tmx::utils::FrequencyThrottle errThrottle; std::array mapID_buffer; - - bool LoadMapFiles(); - void DebugPrintMapFiles(); - std::string enum_to_hex_string(); - std::string removeMessageFrame(const std::string &fileContent); - std::string checkMapContent(std::ifstream &in); - }; } // namespace MapPlugin