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
23
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 options_panel(nullptr) {}
98
99ConnectionParams::~ConnectionParams() = default;
100
101void ConnectionParams::Deserialize(const wxString& configStr) {
102 is_valid = true;
103 wxArrayString prms = wxStringTokenize(configStr, ";");
104 if (prms.Count() < 18) {
105 is_valid = false;
106 return;
107 }
108
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]);
118 direction =
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]);
127
128 is_enabled = true;
129 last_network_port = 0;
130 is_setup = false;
131 if (prms.Count() >= 18) {
132 is_enabled = !!wxAtoi(prms[17]);
133 }
134 if (prms.Count() >= 19) {
135 user_comment = prms[18];
136 }
137 if (prms.Count() >= 20) {
138 auto_sk_discover = !!wxAtoi(prms[19]);
139 }
140 if (prms.Count() >= 21) {
141 socket_can_port = prms[20];
142 }
143 if (prms.Count() >= 22) {
144 no_data_reconnect = wxAtoi(prms[21]);
145 }
146 if (prms.Count() >= 23) {
147 disable_echo = wxAtoi(prms[22]);
148 }
149 if (prms.Count() >= 24) {
150 auth_token = prms[23];
151 }
152}
153
154wxString ConnectionParams::Serialize() const {
155 wxString istcs;
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]);
159 }
160 wxString ostcs;
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]);
164 }
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 /* Priority */, 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());
174
175 return ret;
176}
177
178std::string ConnectionParams::GetKey() const {
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;
187 return ss.str();
188}
189
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);
198}
199
201 if (type == SERIAL)
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(),
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 == CANABLE && serial_port.empty()) return false;
218 if (type == NETWORK && (network_address.empty() || !network_port))
219 return false;
220 if (type == INTERNAL_BT && serial_port.empty()) return false;
221 return true;
222}
223
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();
229 }
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();
235 }
236 if (type == SOCKETCAN) {
237 std::string rv;
238 if (!socket_can_port.ToStdString().empty())
239 rv += "socketCAN-" + socket_can_port.ToStdString();
240 return rv;
241 }
242 if (type == INTERNAL_BT) {
243 return serial_port.ToStdString();
244 }
245 if (type == INTERNAL_GPS) {
246 return serial_port.ToStdString();
247 }
248 return "";
249}
250
252 if (type == SERIAL) {
253 wxString sp = wxString::Format("Serial:%s", serial_port.c_str());
254 return sp.ToStdString();
255 } else {
256 wxString proto = NetworkProtocolToString(last_net_protocol);
257 wxString sp =
258 wxString::Format("%s:%s:%d", proto.c_str(),
259 last_network_address.c_str(), last_network_port);
260 return sp.ToStdString();
261 }
262}
263
264bool ConnectionParams::SentencePassesFilter(const wxString& sentence,
265 FilterDirection direction) const {
266 wxArrayString filter;
267 bool listype = false;
268
269 if (direction == FILTER_INPUT) {
270 filter = input_sentence_list;
271 if (input_sentence_list_type == WHITELIST) listype = true;
272 } else {
273 filter = output_sentence_list;
274 if (output_sentence_list_type == WHITELIST) listype = true;
275 }
276 if (filter.Count() == 0) // Empty list means everything passes
277 return true;
278
279 for (size_t i = 0; i < filter.Count(); i++) {
280 const wxString& fs = filter[i];
281 switch (fs.Length()) {
282 case 2:
283 if (fs == sentence.Mid(1, 2)) return listype;
284 break;
285 case 3:
286 if (fs == sentence.Mid(3, 3)) return listype;
287 break;
288 case 5:
289 if (fs == sentence.Mid(1, 5)) return listype;
290 break;
291 default:
292 // TODO: regex patterns like ".GPZ.." or 6-character patterns
293 // are rejected in the connection settings dialogue currently
294 // experts simply edit .opencpn/opencpn.config
295 wxRegEx re(fs);
296 if (re.Matches(sentence.Mid(0, 8))) {
297 return listype;
298 }
299 break;
300 }
301 }
302 return !listype;
303}
304
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;
312 }
313 switch (data_protocol) {
314 case PROTO_NMEA0183:
315 return NavAddr::Bus::N0183;
316 case PROTO_NMEA2000:
317 return NavAddr::Bus::N2000;
318 default:
319 return NavAddr::Bus::Undef;
320 }
321}
322
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;
329 }
330 switch (last_data_protocol) {
331 case PROTO_NMEA0183:
332 return NavAddr::Bus::N0183;
333 case PROTO_NMEA2000:
334 return NavAddr::Bus::N2000;
335 default:
336 return NavAddr::Bus::Undef;
337 }
338}
Connection data container close to a POD struct.
Definition conn_params.h:76
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.