OpenCPN Partial API docs
Loading...
Searching...
No Matches
conn_params.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2013 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
24#include <string>
25#include <sstream>
26#include <vector>
27#include <unordered_map>
28
29#include <wx/wxprec.h>
30#ifndef WX_PRECOMP
31#include <wx/wx.h>
32#endif
33
34#include <wx/arrstr.h>
35#include <wx/intl.h>
36#include <wx/regex.h>
37#include <wx/string.h>
38#include <wx/tokenzr.h>
39
40#include "model/conn_params.h"
41
42#include "ocpn_plugin.h"
43
44#if !wxUSE_XLOCALE && wxCHECK_VERSION(3, 0, 0)
45#define wxAtoi(arg) atoi(arg)
46#endif
47
48static std::vector<ConnectionParams*> the_connection_params;
49
50std::vector<ConnectionParams*>& TheConnectionParams() {
51 return the_connection_params;
52}
53
54// TODO: Make part of NetworkProtocol interface
55static wxString NetworkProtocolToString(NetworkProtocol NetProtocol) {
56 switch (NetProtocol) {
57 case TCP:
58 return _("TCP");
59 case UDP:
60 return _("UDP");
61 case GPSD:
62 return _("GPSD");
63 case SIGNALK:
64 return _("Signal K");
65 default:
66 return _("Undefined");
67 }
68}
69
70ConnectionParams::ConnectionParams(const wxString& ws) : ConnectionParams() {
71 Deserialize(ws);
72}
73
74ConnectionParams::ConnectionParams()
75 : type(UNKNOWN),
76 net_protocol(TCP),
77 data_protocol(PROTO_NMEA0183),
78 network_port(0),
79 direction(PortDirection::kInput),
80 last_data_protocol(PROTO_NMEA0183),
81 last_net_protocol(TCP),
82 auto_sk_discover(false),
83 checksum_check(true),
84 disable_echo(false),
85 FurunoGP3X(false),
86 GarminUpload(false),
87 is_enabled(true),
88 is_garmin(false),
89 is_server(false),
90 is_setup(false),
91 is_valid(true),
92 no_data_reconnect(false),
93 baudrate(4800),
94 last_network_port(0),
95 input_sentence_list_type(WHITELIST),
96 output_sentence_list_type(WHITELIST),
97 input_sentence_list(WHITELIST),
98 output_sentence_list(WHITELIST),
99 options_panel(nullptr) {}
100
101ConnectionParams::~ConnectionParams() = default;
102
103void ConnectionParams::Deserialize(const wxString& configStr) {
104 is_valid = true;
105 wxArrayString prms = wxStringTokenize(configStr, ";");
106 if (prms.Count() < 18) {
107 is_valid = false;
108 return;
109 }
110
111 type = static_cast<ConnectionType>(wxAtoi(prms[0]));
112 net_protocol = static_cast<NetworkProtocol>(wxAtoi(prms[1]));
113 network_address = prms[2];
114 network_port = static_cast<ConnectionType>(wxAtoi(prms[3]));
115 data_protocol = static_cast<DataProtocol>(wxAtoi(prms[4]));
116 serial_port = prms[5];
117 baudrate = wxAtoi(prms[6]);
118 checksum_check = wxAtoi(prms[7]);
119 int iotval = wxAtoi(prms[8]);
120 direction =
121 iotval <= 2 ? static_cast<PortDirection>(iotval) : PortDirection::kInput;
122 input_sentence_list_type = static_cast<ListType>(wxAtoi(prms[9]));
123 input_sentence_list = wxStringTokenize(prms[10], ",");
124 output_sentence_list_type = static_cast<ListType>(wxAtoi(prms[11]));
125 output_sentence_list = wxStringTokenize(prms[12], ",");
126 is_garmin = !!wxAtoi(prms[14]);
127 GarminUpload = !!wxAtoi(prms[15]);
128 FurunoGP3X = !!wxAtoi(prms[16]);
129
130 is_enabled = true;
131 last_network_port = 0;
132 is_setup = false;
133 if (prms.Count() >= 18) {
134 is_enabled = !!wxAtoi(prms[17]);
135 }
136 if (prms.Count() >= 19) {
137 user_comment = prms[18];
138 }
139 if (prms.Count() >= 20) {
140 auto_sk_discover = !!wxAtoi(prms[19]);
141 }
142 if (prms.Count() >= 21) {
143 socket_can_port = prms[20];
144 }
145 if (prms.Count() >= 22) {
146 no_data_reconnect = wxAtoi(prms[21]);
147 }
148 if (prms.Count() >= 23) {
149 disable_echo = wxAtoi(prms[22]);
150 }
151 if (prms.Count() >= 24) {
152 auth_token = prms[23];
153 }
154}
155
156wxString ConnectionParams::Serialize() const {
157 wxString istcs;
158 for (size_t i = 0; i < input_sentence_list.Count(); i++) {
159 if (i > 0) istcs.Append(",");
160 istcs.Append(input_sentence_list[i]);
161 }
162 wxString ostcs;
163 for (size_t i = 0; i < output_sentence_list.Count(); i++) {
164 if (i > 0) ostcs.Append(",");
165 ostcs.Append(output_sentence_list[i]);
166 }
167 wxString ret = wxString::Format(
168 "%d;%d;%s;%d;%d;%s;%d;%d;%d;%d;%s;%d;%s;%d;%d;%d;%d;%d;%s;%d;%s;%d;%d;%s",
169 type, net_protocol, network_address.c_str(), network_port, data_protocol,
170 serial_port.c_str(), baudrate, checksum_check,
171 static_cast<int>(direction), input_sentence_list_type, istcs.c_str(),
172 output_sentence_list_type, ostcs.c_str(), 0 /* Priority */, is_garmin,
173 GarminUpload, FurunoGP3X, is_enabled, user_comment.c_str(),
174 auto_sk_discover, socket_can_port.c_str(), no_data_reconnect,
175 disable_echo, auth_token.c_str());
176
177 return ret;
178}
179
180std::string ConnectionParams::GetKey() const {
181 std::stringstream ss;
182 ss << type << net_protocol << network_address << network_port << data_protocol
183 << serial_port << baudrate << checksum_check << static_cast<int>(direction)
184 << input_sentence_list_type << output_sentence_list_type << is_garmin
185 << user_comment << auto_sk_discover << socket_can_port << no_data_reconnect
186 << disable_echo << auth_token;
187 for (const auto& sentence : output_sentence_list) ss << sentence;
188 for (const auto& sentence : input_sentence_list) ss << sentence;
189 return ss.str();
190}
191
193 static const std::unordered_map<PortDirection, wxString> StringByDirection = {
194 {PortDirection::kInput, _("Input")},
195 {PortDirection::kOutput, _("Output")},
196 {PortDirection::kInOut, _("InOut")},
197 {PortDirection::kUpload, _("Upload")}};
198 if (static_cast<size_t>(direction) >= StringByDirection.size()) return "???";
199 return StringByDirection.at(direction);
200}
201
203 if (type == SERIAL)
204 return wxString::Format("Serial:%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(),
208 network_port);
209 } else if (type == INTERNAL_BT) {
210 return serial_port; // mac
211 } else
212 return "";
213}
214
216 if (type == SERIAL && serial_port.empty()) return false;
217 if (type == NETWORK && (network_address.empty() || !network_port))
218 return false;
219 if (type == INTERNAL_BT && serial_port.empty()) return false;
220 return true;
221}
222
224 if (type == SERIAL) {
225 wxString t = wxString::Format("Serial:%s", serial_port.c_str());
226 wxString comx = t.AfterFirst(':').BeforeFirst(' ');
227 return comx.ToStdString();
228 }
229 if (type == NETWORK) {
230 wxString proto = NetworkProtocolToString(net_protocol);
231 wxString t = wxString::Format("%s:%s:%d", proto.c_str(),
232 network_address.c_str(), network_port);
233 return t.ToStdString();
234 }
235 if (type == SOCKETCAN) {
236 std::string rv;
237 if (!socket_can_port.ToStdString().empty())
238 rv += "socketCAN-" + socket_can_port.ToStdString();
239 return rv;
240 }
241 if (type == INTERNAL_BT) {
242 return serial_port.ToStdString();
243 }
244 if (type == INTERNAL_GPS) {
245 return serial_port.ToStdString();
246 }
247 return "";
248}
249
251 if (type == SERIAL) {
252 wxString sp = wxString::Format("Serial:%s", serial_port.c_str());
253 return sp.ToStdString();
254 } else {
255 wxString proto = NetworkProtocolToString(last_net_protocol);
256 wxString sp =
257 wxString::Format("%s:%s:%d", proto.c_str(),
258 last_network_address.c_str(), last_network_port);
259 return sp.ToStdString();
260 }
261}
262
263bool ConnectionParams::SentencePassesFilter(const wxString& sentence,
264 FilterDirection direction) const {
265 wxArrayString filter;
266 bool listype = false;
267
268 if (direction == FILTER_INPUT) {
269 filter = input_sentence_list;
270 if (input_sentence_list_type == WHITELIST) listype = true;
271 } else {
272 filter = output_sentence_list;
273 if (output_sentence_list_type == WHITELIST) listype = true;
274 }
275 if (filter.Count() == 0) // Empty list means everything passes
276 return true;
277
278 for (size_t i = 0; i < filter.Count(); i++) {
279 const wxString& fs = filter[i];
280 switch (fs.Length()) {
281 case 2:
282 if (fs == sentence.Mid(1, 2)) return listype;
283 break;
284 case 3:
285 if (fs == sentence.Mid(3, 3)) return listype;
286 break;
287 case 5:
288 if (fs == sentence.Mid(1, 5)) return listype;
289 break;
290 default:
291 // TODO: regex patterns like ".GPZ.." or 6-character patterns
292 // are rejected in the connection settings dialogue currently
293 // experts simply edit .opencpn/opencpn.config
294 wxRegEx re(fs);
295 if (re.Matches(sentence.Mid(0, 8))) {
296 return listype;
297 }
298 break;
299 }
300 }
301 return !listype;
302}
303
305 if (type == NETWORK) {
306 if (net_protocol == SIGNALK)
307 return NavAddr::Bus::Signalk;
308 else if (net_protocol == GPSD)
309 return NavAddr::Bus::N0183;
310 }
311 switch (data_protocol) {
312 case PROTO_NMEA0183:
313 return NavAddr::Bus::N0183;
314 case PROTO_NMEA2000:
315 return NavAddr::Bus::N2000;
316 default:
317 return NavAddr::Bus::Undef;
318 }
319}
320
322 if (type == NETWORK) {
323 if (last_net_protocol == SIGNALK)
324 return NavAddr::Bus::Signalk;
325 else if (last_net_protocol == GPSD)
326 return NavAddr::Bus::N0183;
327 }
328 switch (last_data_protocol) {
329 case PROTO_NMEA0183:
330 return NavAddr::Bus::N0183;
331 case PROTO_NMEA2000:
332 return NavAddr::Bus::N2000;
333 default:
334 return NavAddr::Bus::Undef;
335 }
336}
Connection data container close to a POD struct.
Definition conn_params.h:75
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.
Connection parameters.
PlugIn Object Definition/API.