28#include <wx/msw/winundef.h>
37#if defined(HAVE_READLINK) && !defined(HAVE_LIBGEN_H)
38#error Using readlink(3) requires libgen.h which cannot be found.
43#include "multiplexer.h"
45#include "config_vars.h"
46#include "conn_params.h"
47#include "comm_drv_registry.h"
48#include "comm_drv_n0183_serial.h"
49#include "comm_drv_n0183_net.h"
50#include "comm_navmsg_bus.h"
53#include "udev_rule_mgr.h"
56extern bool g_b_legacy_input_filter_behaviour;
62static std::string do_readlink(
const char *link) {
64 const char *colon = strchr(link,
':');
65 const char *path = colon ? colon + 1 : link;
67 char target[PATH_MAX + 1] = {0};
68 int r = readlink(path, target,
sizeof(target));
69 if (r == -1 && (errno == EINVAL || errno == ENOENT)) {
74 wxLogDebug(
"Error reading device link %s: %s", path, strerror(errno));
80 char buff[PATH_MAX + 1];
81 memcpy(buff, path, std::min(strlen(path) + 1, (
size_t)PATH_MAX));
82 return std::string(dirname(buff)) +
"/" + target;
85static bool is_same_device(
const char *port1,
const char *port2) {
86 std::string dev1 = do_readlink(port1);
87 std::string dev2 = do_readlink(port2);
93static bool inline is_same_device(
const char *port1,
const char *port2) {
94 return strcmp(port1, port2) == 0;
100 auto &msgbus = NavMsgBus::GetInstance();
105 auto ptr = ev.GetSharedPtr();
106 auto n0183_msg = std::static_pointer_cast<const Nmea0183Msg>(ptr);
107 HandleN0183(n0183_msg);
110 if (g_GPS_Ident.IsEmpty()) g_GPS_Ident = wxT(
"Generic");
113Multiplexer::~Multiplexer() {}
115void Multiplexer::LogOutputMessageColor(
const wxString &msg,
116 const wxString &stream_name,
117 const wxString &color) {
118 if (m_log_callbacks.log_is_active()) {
119 wxDateTime now = wxDateTime::Now();
122 ss = now.FormatISOTime();
124 ss.Prepend(_T(
"--> "));
126 ss.Append(stream_name);
131 m_log_callbacks.log_message(ss.ToStdString());
135void Multiplexer::LogOutputMessage(
const wxString &msg, wxString stream_name,
138 LogOutputMessageColor(msg, stream_name, _T(
"<CORAL>"));
140 LogOutputMessageColor(msg, stream_name, _T(
"<BLUE>"));
143void Multiplexer::LogInputMessage(
const wxString &msg,
144 const wxString &stream_name,
bool b_filter,
146 if (m_log_callbacks.log_is_active()) {
147 wxDateTime now = wxDateTime::Now();
150 ss = now.FormatISOTime();
153 ss.Append(stream_name);
157 ss.Prepend(_T(
"<RED>"));
160 if (g_b_legacy_input_filter_behaviour)
161 ss.Prepend(_T(
"<CORAL>"));
163 ss.Prepend(_T(
"<MAROON>"));
165 ss.Prepend(_T(
"<GREEN>"));
167 m_log_callbacks.log_message(ss.ToStdString());
171void Multiplexer::HandleN0183(std::shared_ptr<const Nmea0183Msg> n0183_msg) {
174 const auto& drivers = CommDriverRegistry::GetInstance().
GetDrivers();
175 auto source_driver = FindDriver(drivers, n0183_msg->source->iface);
178 bool bpass_input_filter =
true;
183 if (m_log_callbacks.log_is_active()) {
184 std::string str = n0183_msg->payload;
189 std::dynamic_pointer_cast<CommDriverN0183Serial>(source_driver);
191 params = drv_serial->GetParams();
193 auto drv_net = std::dynamic_pointer_cast<CommDriverN0183Net>(source_driver);
195 params = drv_net->GetParams();
200 bpass_input_filter = params.SentencePassesFilter(n0183_msg->payload.c_str(),
203 bool b_error =
false;
204 for (std::string::iterator it = str.begin(); it != str.end(); ++it) {
209 bin_print.Printf(_T(
"<0x%02X>"), *it);
211 if ((*it != 0x0a) && (*it != 0x0d)) b_error =
true;
224 wxString port(n0183_msg->source->iface);
225 LogInputMessage(fmsg, port, !bpass_input_filter, b_error);
230 std::string source_iface;
232 source_iface = source_driver->iface;
236 for (
auto& driver : drivers) {
238 if (driver->bus == NavAddr::Bus::N0183) {
241 std::dynamic_pointer_cast<CommDriverN0183Serial>(driver);
243 params = drv_serial->GetParams();
245 auto drv_net = std::dynamic_pointer_cast<CommDriverN0183Net>(driver);
247 params = drv_net->GetParams();
251 if ((g_b_legacy_input_filter_behaviour && !bpass_input_filter) ||
252 bpass_input_filter) {
257 if (params.Type == SERIAL || driver->iface != source_iface) {
258 if (params.IOSelect == DS_TYPE_INPUT_OUTPUT ||
259 params.IOSelect == DS_TYPE_OUTPUT)
261 bool bout_filter =
true;
262 bool bxmit_ok =
true;
263 if (params.SentencePassesFilter(n0183_msg->payload.c_str(),
265 bxmit_ok = driver->SendMessage(n0183_msg,
266 std::make_shared<NavAddr0183>(driver->iface));
273 LogOutputMessageColor(fmsg, driver->iface, _T(
"<BLUE>"));
275 LogOutputMessageColor(fmsg, driver->iface, _T(
"<RED>"));
277 LogOutputMessageColor(fmsg, driver->iface, _T(
"<CORAL>"));
const std::vector< DriverPtr > & GetDrivers()
static std::string MessageKey(const char *type="ALL")
Return key which should be used to listen to given message type.
Adds a std::shared<void> element to wxCommandEvent.