27#include <unordered_map>
38#include <wx/tokenzr.h>
44#if !wxUSE_XLOCALE && wxCHECK_VERSION(3, 0, 0)
45#define wxAtoi(arg) atoi(arg)
48static std::vector<ConnectionParams*> the_connection_params;
51 return the_connection_params;
55static wxString NetworkProtocolToString(NetworkProtocol NetProtocol) {
56 switch (NetProtocol) {
66 return _(
"Undefined");
74ConnectionParams::ConnectionParams()
77 data_protocol(PROTO_NMEA0183),
79 direction(PortDirection::kInput),
80 last_data_protocol(PROTO_NMEA0183),
81 last_net_protocol(TCP),
82 auto_sk_discover(false),
92 no_data_reconnect(false),
95 input_sentence_list_type(WHITELIST),
96 output_sentence_list_type(WHITELIST),
97 options_panel(nullptr) {}
99ConnectionParams::~ConnectionParams() =
default;
101void ConnectionParams::Deserialize(
const wxString& configStr) {
103 wxArrayString prms = wxStringTokenize(configStr,
";");
104 if (prms.Count() < 18) {
109 type =
static_cast<ConnectionType
>(wxAtoi(prms[0]));
110 net_protocol =
static_cast<NetworkProtocol
>(wxAtoi(prms[1]));
111 network_address = prms[2];
112 network_port =
static_cast<ConnectionType
>(wxAtoi(prms[3]));
113 data_protocol =
static_cast<DataProtocol
>(wxAtoi(prms[4]));
114 serial_port = prms[5];
115 baudrate = wxAtoi(prms[6]);
116 checksum_check = wxAtoi(prms[7]);
117 int iotval = wxAtoi(prms[8]);
119 iotval <= 2 ? static_cast<PortDirection>(iotval) : PortDirection::kInput;
120 input_sentence_list_type =
static_cast<ListType
>(wxAtoi(prms[9]));
121 input_sentence_list = wxStringTokenize(prms[10],
",");
122 output_sentence_list_type =
static_cast<ListType
>(wxAtoi(prms[11]));
123 output_sentence_list = wxStringTokenize(prms[12],
",");
124 is_garmin = !!wxAtoi(prms[14]);
125 GarminUpload = !!wxAtoi(prms[15]);
126 FurunoGP3X = !!wxAtoi(prms[16]);
129 last_network_port = 0;
131 if (prms.Count() >= 18) {
132 is_enabled = !!wxAtoi(prms[17]);
134 if (prms.Count() >= 19) {
135 user_comment = prms[18];
137 if (prms.Count() >= 20) {
138 auto_sk_discover = !!wxAtoi(prms[19]);
140 if (prms.Count() >= 21) {
141 socket_can_port = prms[20];
143 if (prms.Count() >= 22) {
144 no_data_reconnect = wxAtoi(prms[21]);
146 if (prms.Count() >= 23) {
147 disable_echo = wxAtoi(prms[22]);
149 if (prms.Count() >= 24) {
150 auth_token = prms[23];
154wxString ConnectionParams::Serialize()
const {
156 for (
size_t i = 0; i < input_sentence_list.Count(); i++) {
157 if (i > 0) istcs.Append(
",");
158 istcs.Append(input_sentence_list[i]);
161 for (
size_t i = 0; i < output_sentence_list.Count(); i++) {
162 if (i > 0) ostcs.Append(
",");
163 ostcs.Append(output_sentence_list[i]);
165 wxString ret = wxString::Format(
166 "%d;%d;%s;%d;%d;%s;%d;%d;%d;%d;%s;%d;%s;%d;%d;%d;%d;%d;%s;%d;%s;%d;%d;%s",
167 type, net_protocol, network_address.c_str(), network_port, data_protocol,
168 serial_port.c_str(), baudrate, checksum_check,
169 static_cast<int>(direction), input_sentence_list_type, istcs.c_str(),
170 output_sentence_list_type, ostcs.c_str(), 0 , is_garmin,
171 GarminUpload, FurunoGP3X, is_enabled, user_comment.c_str(),
172 auto_sk_discover, socket_can_port.c_str(), no_data_reconnect,
173 disable_echo, auth_token.c_str());
179 std::stringstream ss;
180 ss << type << net_protocol << network_address << network_port << data_protocol
181 << serial_port << baudrate << checksum_check << static_cast<int>(direction)
182 << input_sentence_list_type << output_sentence_list_type << is_garmin
183 << user_comment << auto_sk_discover << socket_can_port << no_data_reconnect
184 << disable_echo << auth_token;
185 for (
const auto& sentence : output_sentence_list) ss << sentence;
186 for (
const auto& sentence : input_sentence_list) ss << sentence;
191 static const std::unordered_map<PortDirection, wxString> StringByDirection = {
192 {PortDirection::kInput, _(
"Input")},
193 {PortDirection::kOutput, _(
"Output")},
194 {PortDirection::kInOut, _(
"InOut")},
195 {PortDirection::kUpload, _(
"Upload")}};
196 if (
static_cast<size_t>(direction) >= StringByDirection.size())
return "???";
197 return StringByDirection.at(direction);
202 return wxString::Format(
"Serial:%s", serial_port.c_str());
203 else if (type == CANABLE)
204 return wxString::Format(
"CANable:%s", serial_port.c_str());
205 else if (type == NETWORK) {
206 wxString proto = NetworkProtocolToString(net_protocol);
207 return wxString::Format(
"%s:%s:%d", proto.c_str(), network_address.c_str(),
209 }
else if (type == INTERNAL_BT) {
216 if (type == SERIAL && serial_port.empty())
return false;
217 if (type == CANABLE && serial_port.empty())
return false;
218 if (type == NETWORK && (network_address.empty() || !network_port))
220 if (type == INTERNAL_BT && serial_port.empty())
return false;
225 if (type == SERIAL || type == CANABLE) {
226 wxString t = wxString::Format(
"Serial:%s", serial_port.c_str());
227 wxString comx = t.AfterFirst(
':').BeforeFirst(
' ');
228 return comx.ToStdString();
230 if (type == NETWORK) {
231 wxString proto = NetworkProtocolToString(net_protocol);
232 wxString t = wxString::Format(
"%s:%s:%d", proto.c_str(),
233 network_address.c_str(), network_port);
234 return t.ToStdString();
236 if (type == SOCKETCAN) {
238 if (!socket_can_port.ToStdString().empty())
239 rv +=
"socketCAN-" + socket_can_port.ToStdString();
242 if (type == INTERNAL_BT) {
243 return serial_port.ToStdString();
245 if (type == INTERNAL_GPS) {
246 return serial_port.ToStdString();
252 if (type == SERIAL) {
253 wxString sp = wxString::Format(
"Serial:%s", serial_port.c_str());
254 return sp.ToStdString();
256 wxString proto = NetworkProtocolToString(last_net_protocol);
258 wxString::Format(
"%s:%s:%d", proto.c_str(),
259 last_network_address.c_str(), last_network_port);
260 return sp.ToStdString();
265 FilterDirection direction)
const {
266 wxArrayString filter;
267 bool listype =
false;
269 if (direction == FILTER_INPUT) {
270 filter = input_sentence_list;
271 if (input_sentence_list_type == WHITELIST) listype =
true;
273 filter = output_sentence_list;
274 if (output_sentence_list_type == WHITELIST) listype =
true;
276 if (filter.Count() == 0)
279 for (
size_t i = 0; i < filter.Count(); i++) {
280 const wxString& fs = filter[i];
281 switch (fs.Length()) {
283 if (fs == sentence.Mid(1, 2))
return listype;
286 if (fs == sentence.Mid(3, 3))
return listype;
289 if (fs == sentence.Mid(1, 5))
return listype;
296 if (re.Matches(sentence.Mid(0, 8))) {
306 if (type == CANABLE)
return NavAddr::Bus::N2000;
307 if (type == NETWORK) {
308 if (net_protocol == SIGNALK)
309 return NavAddr::Bus::Signalk;
310 else if (net_protocol == GPSD)
311 return NavAddr::Bus::N0183;
313 switch (data_protocol) {
315 return NavAddr::Bus::N0183;
317 return NavAddr::Bus::N2000;
319 return NavAddr::Bus::Undef;
324 if (type == NETWORK) {
325 if (last_net_protocol == SIGNALK)
326 return NavAddr::Bus::Signalk;
327 else if (last_net_protocol == GPSD)
328 return NavAddr::Bus::N0183;
330 switch (last_data_protocol) {
332 return NavAddr::Bus::N0183;
334 return NavAddr::Bus::N2000;
336 return NavAddr::Bus::Undef;
Connection data container close to a POD struct.
bool IsPortValid() const
Return true if port data like com port or network address are sane.
bool SentencePassesFilter(const wxString &sentence, FilterDirection direction) const
Return true if given sentence and direction passes connection filters.
std::string GetStrippedDSPort() const
Return port string with possible windows extra data removed, in some cases empty.
std::string GetKey() const
Return string unique for each instance.
NavAddr::Bus GetLastCommProtocol() const
Return NavAddr::Bus corresponding to last known network address/port or serial parameters.
std::string GetLastDSPort() const
Return Last known network "address:protocol:port" for network connections, else "Serial: <port>".
wxString GetDSPort() const
Return port description including for example serial port or network address/port,...
wxString GetPortDirectionValueStr() const
Return translated name for direction, like _("Input").
NavAddr::Bus GetCommProtocol() const
Return NavAddr::Bus corresponding to network address/port or serial parameters.
std::vector< ConnectionParams * > & TheConnectionParams()
Return global list of connections.
PlugIn Object Definition/API.