OpenCPN Partial API docs
Loading...
Searching...
No Matches
conn_params.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 *
5 ***************************************************************************
6 * Copyright (C) 2013 by David S. Register *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22 **************************************************************************/
23
24// For compilers that support precompilation, includes "wx.h".
25#include <wx/wxprec.h>
26
27#ifndef WX_PRECOMP
28#include <wx/wx.h>
29#endif // precompiled headers
30
31#ifdef __MINGW32__
32#undef IPV6STRICT // mingw FTBFS fix: missing struct ip_mreq
33#include <windows.h>
34#endif
35
36#include <wx/checklst.h>
37#include <wx/combobox.h>
38#include <wx/intl.h>
39#include <wx/regex.h>
40#include <wx/statline.h>
41#include <wx/tokenzr.h>
42
43#include "model/conn_params.h"
44
45#include "ocpn_plugin.h"
46
47#if !wxUSE_XLOCALE && wxCHECK_VERSION(3, 0, 0)
48#define wxAtoi(arg) atoi(arg)
49#endif
50
51static std::vector<ConnectionParams*> the_connection_params;
52
53std::vector<ConnectionParams*>& TheConnectionParams() {
54 return the_connection_params;
55}
56
57ConnectionParams::ConnectionParams(const wxString& configStr) {
58 m_optionsPanel = NULL;
59 Deserialize(configStr);
60}
61
62void ConnectionParams::Deserialize(const wxString& configStr) {
63 Valid = true;
64 wxArrayString prms = wxStringTokenize(configStr, _T(";"));
65 if (prms.Count() < 18) {
66 Valid = false;
67 return;
68 }
69
70 Type = (ConnectionType)wxAtoi(prms[0]);
71 NetProtocol = (NetworkProtocol)wxAtoi(prms[1]);
72 NetworkAddress = prms[2];
73 NetworkPort = (ConnectionType)wxAtoi(prms[3]);
74 Protocol = (DataProtocol)wxAtoi(prms[4]);
75 Port = prms[5];
76 Baudrate = wxAtoi(prms[6]);
77 ChecksumCheck = wxAtoi(prms[7]);
78 int iotval = wxAtoi(prms[8]);
79 IOSelect = ((iotval <= 2) ? static_cast<dsPortType>(iotval) : DS_TYPE_INPUT);
80 InputSentenceListType = (ListType)wxAtoi(prms[9]);
81 InputSentenceList = wxStringTokenize(prms[10], _T(","));
82 OutputSentenceListType = (ListType)wxAtoi(prms[11]);
83 OutputSentenceList = wxStringTokenize(prms[12], _T(","));
84 Garmin = !!wxAtoi(prms[14]);
85 GarminUpload = !!wxAtoi(prms[15]);
86 FurunoGP3X = !!wxAtoi(prms[16]);
87
88 bEnabled = true;
89 LastNetworkPort = 0;
90 b_IsSetup = false;
91 if (prms.Count() >= 18) {
92 bEnabled = !!wxAtoi(prms[17]);
93 }
94 if (prms.Count() >= 19) {
95 UserComment = prms[18];
96 }
97 if (prms.Count() >= 20) {
98 AutoSKDiscover = !!wxAtoi(prms[19]);
99 }
100 if (prms.Count() >= 21) {
101 socketCAN_port = prms[20];
102 }
103 if (prms.Count() >= 22) {
104 NoDataReconnect = wxAtoi(prms[21]);
105 }
106 if (prms.Count() >= 23) {
107 DisableEcho = wxAtoi(prms[22]);
108 }
109 if (prms.Count() >= 24) {
110 AuthToken = prms[23];
111 }
112}
113
114wxString ConnectionParams::Serialize() const {
115 wxString istcs;
116 for (size_t i = 0; i < InputSentenceList.Count(); i++) {
117 if (i > 0) istcs.Append(_T(","));
118 istcs.Append(InputSentenceList[i]);
119 }
120 wxString ostcs;
121 for (size_t i = 0; i < OutputSentenceList.Count(); i++) {
122 if (i > 0) ostcs.Append(_T(","));
123 ostcs.Append(OutputSentenceList[i]);
124 }
125 wxString ret = wxString::Format(
126 "%d;%d;%s;%d;%d;%s;%d;%d;%d;%d;%s;%d;%s;%d;%d;%d;%d;%d;%s;%d;%s;%d;%d;%s",
127 Type, NetProtocol, NetworkAddress.c_str(), NetworkPort, Protocol,
128 Port.c_str(), Baudrate, ChecksumCheck, IOSelect, InputSentenceListType,
129 istcs.c_str(), OutputSentenceListType, ostcs.c_str(), 0 /* Priority */,
130 Garmin, GarminUpload, FurunoGP3X, bEnabled, UserComment.c_str(),
131 AutoSKDiscover, socketCAN_port.c_str(), NoDataReconnect, DisableEcho,
132 AuthToken.c_str());
133
134 return ret;
135}
136
137std::string ConnectionParams::GetKey() const {
138 std::stringstream ss;
139 ss << Type << NetProtocol << NetworkAddress << NetworkPort << Protocol << Port
140 << Baudrate << ChecksumCheck << IOSelect << InputSentenceListType
141 << OutputSentenceListType << Garmin << GarminUpload << FurunoGP3X
142 << UserComment << AutoSKDiscover << socketCAN_port << NoDataReconnect
143 << DisableEcho << AuthToken;
144 for (const auto& sentence : OutputSentenceList) ss << sentence;
145 for (const auto& sentence : InputSentenceList) ss << sentence;
146 return ss.str();
147}
148
149ConnectionParams::ConnectionParams() {
150 Type = UNKNOWN;
151 NetProtocol = TCP;
152 NetworkAddress = wxEmptyString;
153 NetworkPort = 0;
154 Protocol = PROTO_NMEA0183;
155 Port = wxEmptyString;
156 Baudrate = 4800;
157 ChecksumCheck = true;
158 Garmin = false;
159 FurunoGP3X = false;
160 IOSelect = DS_TYPE_INPUT;
161 InputSentenceListType = WHITELIST;
162 OutputSentenceListType = WHITELIST;
163 Valid = true;
164 bEnabled = true;
165 b_IsSetup = false;
166 m_optionsPanel = NULL;
167 AutoSKDiscover = false;
168 NoDataReconnect = false;
169 DisableEcho = false;
170 AuthToken = wxEmptyString;
171}
172
173ConnectionParams::~ConnectionParams() {
174 // delete m_optionsPanel;
175}
176
177wxString ConnectionParams::GetSourceTypeStr() const {
178 switch (Type) {
179 case SERIAL:
180 return _("Serial");
181 case NETWORK:
182 return _("Network");
183 case INTERNAL_GPS:
184 return _("GPS");
185 case INTERNAL_BT:
186 return _("BT");
187 default:
188 return _T("");
189 }
190}
191
192wxString ConnectionParams::GetAddressStr() const {
193 if (Type == SERIAL)
194 return wxString::Format(_T("%s"), Port.c_str());
195 else if (Type == NETWORK)
196 return wxString::Format(_T("%s:%d"), NetworkAddress.c_str(), NetworkPort);
197 else if (Type == INTERNAL_GPS)
198 return _("Internal");
199 else if (Type == INTERNAL_BT)
200 return NetworkAddress;
201 else
202 return _T("");
203}
204
205// TODO: Make part of NetworkProtocol interface
206static wxString NetworkProtocolToString(NetworkProtocol NetProtocol) {
207 switch (NetProtocol) {
208 case TCP:
209 return _("TCP");
210 case UDP:
211 return _("UDP");
212 case GPSD:
213 return _("GPSD");
214 case SIGNALK:
215 return _("Signal K");
216 default:
217 return _("Undefined");
218 }
219}
220
221wxString ConnectionParams::GetParametersStr() const {
222 switch (Type) {
223 case SERIAL:
224 return wxString::Format(_T("%d"), Baudrate);
225 case NETWORK:
226 return NetworkProtocolToString(NetProtocol);
227 case INTERNAL_GPS:
228 return _T("GPS");
229 case INTERNAL_BT:
230 return Port;
231 default:
232 return _T("");
233 }
234}
235
236wxString ConnectionParams::GetIOTypeValueStr() const {
237 if (IOSelect == DS_TYPE_INPUT)
238 return _("Input");
239 else if (IOSelect == DS_TYPE_OUTPUT)
240 return _("Output");
241 else
242 return _("In/Out");
243}
244
245wxString ConnectionParams::FilterTypeToStr(ListType type,
246 FilterDirection dir) const {
247 if (dir == FILTER_INPUT) {
248 if (type == BLACKLIST)
249 return _("Reject");
250 else
251 return _("Accept");
252 } else {
253 if (type == BLACKLIST)
254 return _("Drop");
255 else
256 return _("Send");
257 }
258}
259
260wxString ConnectionParams::GetFiltersStr() const {
261 wxString istcs;
262 for (size_t i = 0; i < InputSentenceList.Count(); i++) {
263 if (i > 0) istcs.Append(_T(","));
264 istcs.Append(InputSentenceList[i]);
265 }
266 wxString ostcs;
267 for (size_t i = 0; i < OutputSentenceList.Count(); i++) {
268 if (i > 0) ostcs.Append(_T(","));
269 ostcs.Append(OutputSentenceList[i]);
270 }
271 wxString ret = wxEmptyString;
272 if (istcs.Len() > 0) {
273 ret.Append(_("In"));
274 ret.Append(wxString::Format(
275 _T(": %s %s"),
276 FilterTypeToStr(InputSentenceListType, FILTER_INPUT).c_str(),
277 istcs.c_str()));
278 } else
279 ret.Append(_("In: None"));
280
281 if (ostcs.Len() > 0) {
282 ret.Append(_T(", "));
283 ret.Append(_("Out"));
284 ret.Append(wxString::Format(
285 _T(": %s %s"),
286 FilterTypeToStr(OutputSentenceListType, FILTER_OUTPUT).c_str(),
287 ostcs.c_str()));
288 } else
289 ret.Append(_(", Out: None"));
290 return ret;
291}
292
293wxString ConnectionParams::GetDSPort() const {
294 if (Type == SERIAL)
295 return wxString::Format(_T("Serial:%s"), Port.c_str());
296 else if (Type == NETWORK) {
297 wxString proto = NetworkProtocolToString(NetProtocol);
298 return wxString::Format(_T("%s:%s:%d"), proto.c_str(),
299 NetworkAddress.c_str(), NetworkPort);
300 } else if (Type == INTERNAL_BT) {
301 return Port; // mac
302 } else
303 return _T("");
304}
305
306bool ConnectionParams::GetValidPort() const {
307 if (Type == SERIAL && Port == "")
308 return false;
309 else if (Type == NETWORK && (NetworkAddress == "" || !NetworkPort))
310 return false;
311 else if (Type == INTERNAL_BT && Port == "")
312 return false;
313 else
314 return true;
315}
316
317std::string ConnectionParams::GetStrippedDSPort() const {
318 if (Type == SERIAL) {
319 wxString t = wxString::Format(_T("Serial:%s"), Port.c_str());
320 wxString comx = t.AfterFirst(':').BeforeFirst(' ');
321 return comx.ToStdString();
322 } else if (Type == NETWORK) {
323 wxString proto = NetworkProtocolToString(NetProtocol);
324 wxString t = wxString::Format(_T("%s:%s:%d"), proto.c_str(),
325 NetworkAddress.c_str(), NetworkPort);
326 return t.ToStdString();
327
328 } else if (Type == SOCKETCAN) {
329 std::string rv = "socketCAN-";
330 rv += socketCAN_port.ToStdString();
331 return rv;
332 } else if (Type == INTERNAL_BT) {
333 return Port.ToStdString();
334 } else
335 return "";
336}
337
338std::string ConnectionParams::GetLastDSPort() const {
339 if (Type == SERIAL) {
340 wxString sp = wxString::Format(_T("Serial:%s"), Port.c_str());
341 return sp.ToStdString();
342 } else {
343 wxString proto = NetworkProtocolToString(LastNetProtocol);
344 wxString sp = wxString::Format(_T("%s:%s:%d"), proto.c_str(),
345 LastNetworkAddress.c_str(), LastNetworkPort);
346 return sp.ToStdString();
347 }
348}
349
350bool ConnectionParams::SentencePassesFilter(const wxString& sentence,
351 FilterDirection direction) const {
352 wxArrayString filter;
353 bool listype = false;
354
355 if (direction == FILTER_INPUT) {
356 filter = InputSentenceList;
357 if (InputSentenceListType == WHITELIST) listype = true;
358 } else {
359 filter = OutputSentenceList;
360 if (OutputSentenceListType == WHITELIST) listype = true;
361 }
362 if (filter.Count() == 0) // Empty list means everything passes
363 return true;
364
365 wxString fs;
366 for (size_t i = 0; i < filter.Count(); i++) {
367 fs = filter[i];
368 switch (fs.Length()) {
369 case 2:
370 if (fs == sentence.Mid(1, 2)) return listype;
371 break;
372 case 3:
373 if (fs == sentence.Mid(3, 3)) return listype;
374 break;
375 case 5:
376 if (fs == sentence.Mid(1, 5)) return listype;
377 break;
378 default:
379 // TODO: regex patterns like ".GPZ.." or 6-character patterns
380 // are rejected in the connection settings dialogue currently
381 // experts simply edit .opencpn/opncpn.config
382 wxRegEx re(fs);
383 if (re.Matches(sentence.Mid(0, 8))) {
384 return listype;
385 }
386 break;
387 }
388 }
389 return !listype;
390}
391
392NavAddr::Bus ConnectionParams::GetCommProtocol() const {
393 if (Type == NETWORK) {
394 if (NetProtocol == SIGNALK)
395 return NavAddr::Bus::Signalk;
396 else if (NetProtocol == GPSD)
397 return NavAddr::Bus::N0183;
398 }
399
400 switch (Protocol) {
401 case PROTO_NMEA0183:
402 return NavAddr::Bus::N0183;
403 case PROTO_NMEA2000:
404 return NavAddr::Bus::N2000;
405 default:
406 return NavAddr::Bus::Undef;
407 }
408}
409
410NavAddr::Bus ConnectionParams::GetLastCommProtocol() {
411 if (Type == NETWORK) {
412 if (LastNetProtocol == SIGNALK)
413 return NavAddr::Bus::Signalk;
414 else if (LastNetProtocol == GPSD)
415 return NavAddr::Bus::N0183;
416 }
417
418 switch (LastDataProtocol) {
419 case PROTO_NMEA0183:
420 return NavAddr::Bus::N0183;
421 case PROTO_NMEA2000:
422 return NavAddr::Bus::N2000;
423 default:
424 return NavAddr::Bus::Undef;
425 }
426}
std::string GetKey() const
Return string unique for each instance.
PlugIn Object Definition/API.