-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix map #609
Fix map #609
Conversation
modified: src/v2i-hub/MapPlugin/src/MapPlugin.cpp new file: src/v2i-hub/MapPlugin/src/MapPlugin.h
fileContent.erase(remove(fileContent.begin(), fileContent.end(), '\n'), fileContent.end()); | ||
|
||
// Check for and remove MessageFrame | ||
if (fileContent.size() >= 4 && fileContent.substr(0, 4) == "0012") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if there are multiple "38" in the binary payload? The same for 0012?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great findings on these bugs!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dan-du-car The message I used had 6 "38" in it. It only looked for the first instance, so this worked. But I can change it to make sure it only looks for it in the first couple of bytes depending on payload length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave it as is. Find only looks for the first instance of the string.
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this erase() starting from position 0 to one character before position "pos"? Or is this "pos" of a number of characters to be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend to move this file reading and sanitizing steps into a separate function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I'll move it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It removes the number of pos bytes, starting from 0. So in this case removes bytes 0:[pos-1]
return tmx::message::to_tree(static_cast<tmx::message>(m)); | ||
} | ||
|
||
static MapFile from_tree(tmx::message_tree_type tree) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these from_tree and to_tree functions used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like it. They were also included in another the inputs/ISDDataAdaptor.hpp and also not used. I'll remove it and retest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was needed by message.hpp in TmxApi. Left it in
|
||
std_attribute(this->msg, int, Action, -1, ); | ||
std_attribute(this->msg, std::string, FilePath, "", ); | ||
std_attribute(this->msg, std::string, InputType, "", ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this "inputType" used? What does this represent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it was declared but is expected to be empty? I'll find out if we need it or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's needed to find the file extension type for ISD, TXT, XML, JSON, UPER. Kept it in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. What is the difference between UPER and TXT upload? It seems they both upload bytes but TXT has message frame in it? Why do we need these two different uploads that has similar content? I am not familiar with the usage of this plugin, so I am a bit curious about these different extension types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UPER is used to accept the message frame, but it assumes the message is correct and broadcasts it to TMX core.
I made changes to the TXT to accept the message frame, but it strips it and decodes the remaining content to verify the message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think any format we accept should very message content before broadcast. When it is not verified we get exceptions on down stream plugins that attempt to ingest this message. I created the TXT format a while back to avoid dealing with issues with the UPER format logic. These two formats can likely be consolidated since they are both uper hex
MapFile(): tmx::message() {} | ||
virtual ~MapFile() {} | ||
|
||
std_attribute(this->msg, int, Action, -1, ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rest of actions this MAP support? Which default action is this initialized to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default is no action existing. It looks like only action is for finding the file path.
modified: src/v2i-hub/MapPlugin/src/MapPlugin.h
@@ -304,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") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull from MAP PSID constant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved in latest commit
modified: src/v2i-hub/MapPlugin/src/MapPlugin.h
string map_messageID = enum_to_hex_string(); | ||
|
||
// Check for and remove MessageFrame | ||
if (fileContent.size() >= 4 && fileContent.substr(0, 4) == map_messageID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a very robust way to determine whether the message contains the message frame or not. I think it would be more robust if we initially assumed the header was there and tried to decode it, if we run into an exception we log the exception as a warning and log that we are retrying without the header. Having code in our plugin that is couple to the exact format of the MAP message means that we have to rewrite it every-time the exact format changes. Having code that is loosely couple to just the C Struct and data means that the format can change without require logic changes here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do that, but we'd still have to have logic to figure out whether the header has an additional 2 bytes or not. The message frame will always contain the message ID, at the beginning so this is a good way to quickly check for it instead of trying and failing to encode the message. I think both ways would work, but I'd rather run this check instead of attempting a blind encoding.
|
||
bool LoadMapFiles(); | ||
void DebugPrintMapFiles(); | ||
string enum_to_hex_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's to convert the messageID from a decimal enum to a hex string. The only place the message ID is declared in TmxApiMessages
bool LoadMapFiles(); | ||
void DebugPrintMapFiles(); | ||
string enum_to_hex_string(); | ||
string removeMessageFrame(string &fileContent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left an earlier comment about how I think this would be better implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Responded in other comment
@@ -304,6 +207,39 @@ int MapPlugin::Main() { | |||
return (EXIT_SUCCESS); | |||
} | |||
|
|||
string MapPlugin::enum_to_hex_string() | |||
{ | |||
sprintf(mapID_buffer, "%04X", tmx::messages::api::mapData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if this method is called and mapID_buffer is not initialized or garbage initialized?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialized with zeros in header file. Missed the {0}, but just added it.
return map_messageID; | ||
} | ||
|
||
string MapPlugin::removeMessageFrame(string &fileContent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if this method is called and fileContent is not initialized or null initialized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fileContent is passed by reference and the method is only called after fileContent has already been initialized. Let me know if you want to add anything else to it to make sure this method doesn't crash the plugin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I requested some changes here. Please let me know if this story/PR is growing more in scope and needs some kind of story associated with it. I can help implementing the changes as well if needed.
using namespace tmx::messages; | ||
using namespace tmx::utils; | ||
#include "MapPlugin.h" | ||
#include <chrono> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these includes not moved to the header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, moved over to header.
@@ -0,0 +1,111 @@ | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#pragma once
is a way to guard against against headers being included multiple times. This inclusion guard below does the same thing
#ifndef MAPPLUGIN_H_
#define MAPPLUGIN_H_
There is no reason to do both. Just pick one (https://learn.microsoft.com/en-us/cpp/preprocessor/once?view=msvc-170)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kept is as #pragma once, thanks!
modified: src/v2i-hub/MapPlugin/src/MapPlugin.h
return map_messageID; | ||
} | ||
|
||
string MapPlugin::removeMessageFrame(string &fileContent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be const string &filcontent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple more things I would like fixed inside the MAP plugin under this issue as long as this issue is not blocking some other work or stakeholder. I think we should consolidate TXT and UPER formats and avoid any direct byte reading or changing. We should verify any message and possibly log (tmx-event) if we are unable to verify a given message.
If you believe we can do some of this later, if you could create a follow on story for the MAP plugin to consolidate these two formats that would be create. Lastly I just want to confirm that both TXT and UPER have been tested for functionality before merging this.
modified: src/v2i-hub/MapPlugin/src/MapPlugin.h
modified: src/v2i-hub/MapPlugin/src/MapPlugin.h
modified: src/v2i-hub/MapPlugin/src/MapPlugin.h
Quality Gate failedFailed conditions |
PR Details
Description
Changes were made to handle files that could be expected. This includes:
Files with newline characters
Files with only MapData
Files containing a MessageFrame along with MapData
Plugin was also cleaned up with a header file.
Related Issue
#608
Motivation and Context
These changes make the MAP plugin more robust because it's able to handle MAP files that could be expected to be generated by a user.
How Has This Been Tested?
Tested using files with and without newline characters, files with and without MessageFrames, and a combination of the two.
Types of changes
Checklist:
V2XHUB Contributing Guide