Skip to content

Commit

Permalink
modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp
Browse files Browse the repository at this point in the history
	modified:   src/v2i-hub/MapPlugin/src/MapPlugin.h
  • Loading branch information
jwillmartin committed Jun 12, 2024
1 parent fce0eda commit fa843d0
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 92 deletions.
133 changes: 55 additions & 78 deletions src/v2i-hub/MapPlugin/src/MapPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -156,7 +154,7 @@ int MapPlugin::Main() {
if (temp != activeAction)
{
lock_guard<mutex> lock(data_lock);
string byteStr = _mapFiles[temp].get_Bytes();
std::string byteStr = _mapFiles[temp].get_Bytes();
if (!byteStr.empty())
{
msg.reset(dynamic_cast<MapDataEncodedMessage *>(factory.NewMessage(api::MSGSUBTYPE_MAPDATA_STRING)));
Expand All @@ -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);
Expand Down Expand Up @@ -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<char>(in)), std::istreambuf_iterator<char>());
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()
Expand All @@ -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";
Expand All @@ -274,69 +290,30 @@ bool MapPlugin::LoadMapFiles()
}
else if (inType == "TXT")
{
byte_stream bytes;
std::ifstream in(fn, std::ios::binary);
if (!in)
{
PLOG(logERROR) << "Failed to open file: " << fn;
}
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<codec::uper<MapDataMessage>>(bytes);

if (mapMsg)
{
string fileContent((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
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<codec::uper<MapDataMessage>>(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<char>(in)), std::istreambuf_iterator<char>());
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")
Expand Down
37 changes: 23 additions & 14 deletions src/v2i-hub/MapPlugin/src/MapPlugin.h
Original file line number Diff line number Diff line change
@@ -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 <atomic>
#include <iostream>
#include <map>
Expand All @@ -20,6 +27,8 @@

#include <tmx/tmx.h>
#include <tmx/IvpPlugin.h>
#include <tmx/j2735_messages/MapDataMessage.hpp>
#include <MapData.h>
#include <tmx/messages/IvpBattelleDsrc.h>
#include <tmx/messages/IvpSignalControllerStatus.h>
#include <tmx/messages/IvpJ2735.h>
Expand All @@ -38,7 +47,6 @@

#include <MapSupport.h>

using namespace std;
using namespace tmx;
using namespace tmx::messages;
using namespace tmx::utils;
Expand All @@ -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<tmx::message>(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;
Expand All @@ -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<int> _mapAction {-1};
Expand All @@ -97,12 +105,13 @@ class MapPlugin: public PluginClientClockAware {
int sendFrequency = 1000;
FrequencyThrottle<int> errThrottle;

char mapID_buffer[5] = {0};
std::array<char, 5> 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);

};

Expand Down

0 comments on commit fa843d0

Please sign in to comment.