28#include "model/base_platform.h"
31#include "wx/jsonreader.h"
32#include "wx/jsonwriter.h"
35#include "std_filesystem.h"
37using Direction = NavmsgStatus::Direction;
38using State = NavmsgStatus::State;
39using Accepted = NavmsgStatus::Accepted;
41static const std::unordered_map<Accepted, std::string> StringByAccepted = {
42 {Accepted::kOk,
"Ok"},
43 {Accepted::kFilteredNoOutput,
"FilteredNoOutput"},
44 {Accepted::kFilteredDropped,
"FilteredDropped"},
45 {Accepted::kNone,
"None"}};
49 return StringByAccepted.at(a);
50 }
catch (std::out_of_range& e) {
51 std::cout <<
"Error: " << e.what() <<
" :" <<
static_cast<int>(a) <<
"\n";
52 assert(
false &&
"Bad Accepted state");
58 for (
auto& kv : StringByAccepted)
59 if (kv.second == s)
return kv.first;
60 return Accepted::kNone;
64static const std::unordered_map<const char*, Direction> dir_map = {
65 {
"input", Direction::kInput},
66 {
"handled", Direction::kHandled},
67 {
"output", Direction::kOutput},
68 {
"internal", Direction::kInternal},
69 {
"none", NavmsgStatus::Direction::kNone}};
71static const std::unordered_map<const char*, State> statemap = {
73 {
"checksum-err", State::kChecksumError},
74 {
"malformed", State::kMalformed},
75 {
"tx-error", State::kTxError}};
77static const std::unordered_map<const char*, Accepted> acceptmap = {
78 {
"Ok", Accepted::kOk},
79 {
"FilteredDropped", Accepted::kFilteredDropped},
80 {
"FilteredNoOutput", Accepted::kFilteredNoOutput},
81 {
"None", Accepted::kNone}};
83static NavmsgStatus::Direction StringToDirection(
const std::string s) {
86 if (s ==
"received")
return NavmsgStatus::Direction::kHandled;
88 for (
auto kv : dir_map)
89 if (kv.first == s) return kv.second;
90 return NavmsgStatus::Direction::kNone;
93static std::string DirectionToString(Direction direction) {
94 for (
auto kv : dir_map)
95 if (kv.second == direction) return kv.first;
96 assert(
false &&
"Illegal direction enumeration type (!)");
100static Accepted StringToAccepted(
const std::string s) {
101 for (
auto kv : acceptmap)
102 if (kv.first == s) return kv.second;
103 return Accepted::kNone;
106static std::string AcceptedToString(Accepted accept) {
107 for (
auto kv : acceptmap)
108 if (kv.second == accept) return kv.first;
109 assert(
false &&
"Illegal direction enumeration type (!)");
113static State StringToState(
const std::string s) {
114 for (
auto kv : statemap)
115 if (kv.first == s) return kv.second;
119static std::string StateToString(State state) {
120 for (
auto kv : statemap)
121 if (kv.second == state) return kv.first;
122 assert(
false &&
"Illegal direction enumeration type (!)");
127 for (
int i = 0; i < json_val.
Size(); i++) {
128 auto str = json_val[i].
AsString().ToStdString();
129 filter.buses.insert(NavAddr::StringToBus(str));
134 for (
int i = 0; i < json_val.
Size(); i++) {
135 auto str = json_val[i].
AsString().ToStdString();
136 filter.directions.insert(StringToDirection(str));
141 for (
int i = 0; i < json_val.
Size(); i++) {
142 auto str = json_val[i].
AsString().ToStdString();
143 filter.accepted.insert(StringToAccepted(str));
148 for (
int i = 0; i < json_val.
Size(); i++) {
149 auto str = json_val[i].
AsString().ToStdString();
150 filter.status.insert(StringToState(str));
156 auto val = json_val[
"blockedMsg"];
157 for (
int i = 0; i < val.Size(); i++)
158 filter.exclude_msg.insert(val[i].AsString().ToStdString());
159 }
else if (json_val.
HasMember(
"allowedMsg")) {
160 auto val = json_val[
"allowedMsg"];
161 for (
int i = 0; i < val.Size(); i++)
162 filter.include_msg.insert(val[i].AsString().ToStdString());
167 for (
int i = 0; i < json_val.
Size(); i++)
168 filter.interfaces.insert(json_val[i].AsString().ToStdString());
173 for (
int i = 0; i < json_val.
Size(); i++)
174 filter.pgns.insert(std::stoi(json_val[i].AsString().ToStdString()));
182 for (
int i = 0; i < json_val.
Size(); i++) {
183 filter.src_pgns.insert(std::stoi(json_val[i].AsString().ToStdString()));
191 std::vector<NavmsgFilter> filters;
193 for (
auto& entry : fs::directory_iterator(dir)) {
195 if (filter.m_is_valid)
196 filters.push_back(filter);
198 wxLogWarning(
"Illegal system filter: %s",
199 entry.path().string().c_str());
202 wxLogWarning(
"Bad system filter path: %s", dir.string().c_str());
208 fs::path dirpath(g_BasePlatform->GetSharedDataDir().ToStdString());
212std::vector<NavmsgFilter> GetUserFilters() {
219 std::vector user_filters = GetUserFilters();
220 filters.insert(filters.end(), user_filters.begin(), user_filters.end());
225 const std::shared_ptr<const NavMsg>& msg) {
226 if (directions.size() > 0) {
227 if (directions.find(msg_status.direction) == directions.end())
return false;
229 if (status.size() > 0) {
230 if (status.find(msg_status.status) == status.end())
return false;
232 if (buses.size() > 0) {
233 if (buses.find(msg->bus) == buses.end())
return false;
235 if (include_msg.size() > 0) {
236 if (include_msg.find(msg->key()) == include_msg.end())
return false;
238 if (exclude_msg.size() > 0) {
239 if (exclude_msg.find(msg->key()) != exclude_msg.end())
return false;
241 if (interfaces.size() > 0) {
242 if (interfaces.find(msg->source->iface) == interfaces.end())
return false;
244 if (accepted.size() > 0) {
245 if (accepted.find(msg_status.accepted) == accepted.end())
return false;
247 auto n2k_msg = std::dynamic_pointer_cast<const Nmea2000Msg>(msg);
249 if (pgns.size() > 0) {
250 if (pgns.find(n2k_msg->PGN) == pgns.end())
return false;
252 if (src_pgns.size() > 0) {
253 auto src = std::static_pointer_cast<const NavAddr2000>(msg->source);
254 if (src && src_pgns.find(src->name) == src_pgns.end())
return false;
261 std::ifstream stream(path);
263 std::stringstream ss;
264 ss << stream.rdbuf();
271 int err_count = reader.
Parse(
string, &root);
273 wxLogWarning(
"Error parsing filter XML");
275 wxLogWarning(
"Parse error: %s", e.c_str());
279 filter.m_name = root[
"filter"][
"name"].
AsString();
280 filter.m_description = root[
"filter"][
"description"].
AsString();
281 if (root[
"filter"].HasMember(
"buses"))
282 ParseBuses(filter, root[
"filter"][
"buses"]);
283 if (root[
"filter"].HasMember(
"accepted"))
284 ParseAccepted(filter, root[
"filter"][
"accepted"]);
285 if (root[
"filter"].HasMember(
"status"))
286 ParseStatus(filter, root[
"filter"][
"status"]);
287 if (root[
"filter"].HasMember(
"directions"))
288 ParseDirections(filter, root[
"filter"][
"directions"]);
289 if (root[
"filter"].HasMember(
"msgFilter"))
290 ParseMsgFilter(filter, root[
"filter"][
"msgFilter"]);
291 if (root[
"filter"].HasMember(
"interfaces"))
292 ParseInterfaces(filter, root[
"filter"][
"interfaces"]);
293 if (root[
"filter"].HasMember(
"pgns"))
294 ParsePgn(filter, root[
"filter"][
"pgns"]);
295 if (root[
"filter"].HasMember(
"src_pgns"))
296 ParseSource(filter, root[
"filter"][
"src_pgns"]);
302 root[
"filter"][
"name"] = m_name;
303 root[
"filter"][
"description"] = m_description;
306 if (!buses.empty()) {
307 for (
auto b : buses) filter[
"buses"].Append(NavAddr::BusToString(b));
309 if (!directions.empty()) {
310 for (
auto d : directions) filter[
"directions"].Append(DirectionToString(d));
312 if (!accepted.empty()) {
313 for (
auto a : accepted) filter[
"accepted"].Append(AcceptedToString(a));
315 if (!status.empty()) {
316 for (
auto s : status) filter[
"status"].Append(StateToString(s));
318 if (!include_msg.empty()) {
319 for (
auto m : include_msg) filter[
"msgFilter"][
"allowedMsg"].Append(m);
320 }
else if (!exclude_msg.empty()) {
321 for (
auto m : exclude_msg) filter[
"msgFilter"][
"blockedMsg"].Append(m);
323 if (!interfaces.empty()) {
324 for (
auto i : interfaces) filter[
"interfaces"].Append(i);
327 for (
auto p : pgns) filter[
"pgns"].Append(p.to_string());
329 if (!src_pgns.empty()) {
330 for (
auto p : src_pgns) filter[
"src_pgns"].Append(p.to_string());
334 writer.
Write(root, ws);
335 return ws.ToStdString();
bool Pass(NavmsgStatus status, const std::shared_ptr< const NavMsg > &msg)
Return true if message is not matched by filter.
static std::vector< NavmsgFilter > GetFilters(const fs::path &path)
Return list of pre-defined filters shipped with app, test hook.
static std::vector< NavmsgFilter > GetAllFilters()
Return list of all filters, system + user defined.
std::string to_string() const
Output parsable JSON string representation.
static NavmsgFilter Parse(const std::string &s)
Parse text as created by to_string().
static std::vector< NavmsgFilter > GetSystemFilters()
Return list of pre-defined filters shipped with application.
Representation of message status as determined by the multiplexer.
static Accepted StringToAccepted(const std::string &s)
Return Accepted value corresponding to argument s.
static std::string AcceptedToString(Accepted)
Return string representation of argument.
const wxArrayString & GetErrors() const
Return a reference to the error message's array.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
int Size() const
Return the size of the array or map stored in this value.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
The JSON document writer.
void Write(const wxJSONValue &value, wxString &str)
Write the JSONvalue object to a JSON text.
Data monitor filter definitions.