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 "conn_params.h"
44
45#include "ocpn_frame.h"
46#include "ocpn_plugin.h"
47#include "options.h"
48
49#if !wxUSE_XLOCALE && wxCHECK_VERSION(3, 0, 0)
50#define wxAtoi(arg) atoi(arg)
51#endif
52
53static wxArrayOfConnPrm* the_connection_params = 0;
54
55wxArrayOfConnPrm* TheConnectionParams() {
56 if (the_connection_params == 0)
57 the_connection_params = new wxArrayOfConnPrm();
58 return the_connection_params;
59}
60
61ConnectionParams::ConnectionParams(const wxString &configStr) {
62 m_optionsPanel = NULL;
63 Deserialize(configStr);
64}
65
66void ConnectionParams::Deserialize(const wxString &configStr) {
67 Valid = true;
68 wxArrayString prms = wxStringTokenize(configStr, _T(";"));
69 if (prms.Count() < 18) {
70 Valid = false;
71 return;
72 }
73
74 Type = (ConnectionType)wxAtoi(prms[0]);
75 NetProtocol = (NetworkProtocol)wxAtoi(prms[1]);
76 NetworkAddress = prms[2];
77 NetworkPort = (ConnectionType)wxAtoi(prms[3]);
78 Protocol = (DataProtocol)wxAtoi(prms[4]);
79 Port = prms[5];
80 Baudrate = wxAtoi(prms[6]);
81 ChecksumCheck = wxAtoi(prms[7]);
82 int iotval = wxAtoi(prms[8]);
83 IOSelect = ((iotval <= 2) ? static_cast<dsPortType>(iotval) : DS_TYPE_INPUT);
84 InputSentenceListType = (ListType)wxAtoi(prms[9]);
85 InputSentenceList = wxStringTokenize(prms[10], _T(","));
86 OutputSentenceListType = (ListType)wxAtoi(prms[11]);
87 OutputSentenceList = wxStringTokenize(prms[12], _T(","));
88 Priority = wxAtoi(prms[13]);
89 Garmin = !!wxAtoi(prms[14]);
90 GarminUpload = !!wxAtoi(prms[15]);
91 FurunoGP3X = !!wxAtoi(prms[16]);
92
93 bEnabled = true;
94 LastNetworkPort = 0;
95 b_IsSetup = false;
96 if (prms.Count() >= 18) {
97 bEnabled = !!wxAtoi(prms[17]);
98 }
99 if (prms.Count() >= 19) {
100 UserComment = prms[18];
101 }
102 if (prms.Count() >= 20) {
103 AutoSKDiscover = !!wxAtoi(prms[19]);
104 }
105 if (prms.Count() >= 21) {
106 socketCAN_port = prms[20];
107 }
108}
109
110wxString ConnectionParams::Serialize() const {
111 wxString istcs;
112 for (size_t i = 0; i < InputSentenceList.Count(); i++) {
113 if (i > 0) istcs.Append(_T(","));
114 istcs.Append(InputSentenceList[i]);
115 }
116 wxString ostcs;
117 for (size_t i = 0; i < OutputSentenceList.Count(); i++) {
118 if (i > 0) ostcs.Append(_T(","));
119 ostcs.Append(OutputSentenceList[i]);
120 }
121 wxString ret = wxString::Format(
122 _T("%d;%d;%s;%d;%d;%s;%d;%d;%d;%d;%s;%d;%s;%d;%d;%d;%d;%d;%s;%d;%s"), Type,
123 NetProtocol, NetworkAddress.c_str(), NetworkPort, Protocol, Port.c_str(),
124 Baudrate, ChecksumCheck, IOSelect, InputSentenceListType, istcs.c_str(),
125 OutputSentenceListType, ostcs.c_str(), Priority, Garmin, GarminUpload,
126 FurunoGP3X, bEnabled, UserComment.c_str(), AutoSKDiscover, socketCAN_port.c_str());
127
128 return ret;
129}
130
131ConnectionParams::ConnectionParams() {
132 Type = UNKNOWN;
133 NetProtocol = TCP;
134 NetworkAddress = wxEmptyString;
135 NetworkPort = 0;
136 Protocol = PROTO_NMEA0183;
137 Port = wxEmptyString;
138 Baudrate = 4800;
139 ChecksumCheck = true;
140 Garmin = false;
141 FurunoGP3X = false;
142 IOSelect = DS_TYPE_INPUT;
143 InputSentenceListType = WHITELIST;
144 OutputSentenceListType = WHITELIST;
145 Priority = 0;
146 Valid = true;
147 bEnabled = true;
148 b_IsSetup = false;
149 m_optionsPanel = NULL;
150 AutoSKDiscover = false;
151}
152
153ConnectionParams::~ConnectionParams() {
154 // delete m_optionsPanel;
155}
156
157wxString ConnectionParams::GetSourceTypeStr() const {
158 switch (Type) {
159 case SERIAL:
160 return _("Serial");
161 case NETWORK:
162 return _("Network");
163 case INTERNAL_GPS:
164 return _("GPS");
165 case INTERNAL_BT:
166 return _("BT");
167 default:
168 return _T("");
169 }
170}
171
172wxString ConnectionParams::GetAddressStr() const {
173 if (Type == SERIAL)
174 return wxString::Format(_T("%s"), Port.c_str());
175 else if (Type == NETWORK)
176 return wxString::Format(_T("%s:%d"), NetworkAddress.c_str(), NetworkPort);
177 else if (Type == INTERNAL_GPS)
178 return _("Internal");
179 else if (Type == INTERNAL_BT)
180 return NetworkAddress;
181 else
182 return _T("");
183}
184
185// TODO: Make part of NetworkProtocol interface
186static wxString NetworkProtocolToString(NetworkProtocol NetProtocol) {
187 switch (NetProtocol) {
188 case TCP:
189 return _("TCP");
190 case UDP:
191 return _("UDP");
192 case GPSD:
193 return _("GPSD");
194 case SIGNALK:
195 return _("Signal K");
196 default:
197 return _("Undefined");
198 }
199}
200
201wxString ConnectionParams::GetParametersStr() const {
202 switch (Type) {
203 case SERIAL:
204 return wxString::Format(_T("%d"), Baudrate);
205 case NETWORK:
206 return NetworkProtocolToString(NetProtocol);
207 case INTERNAL_GPS:
208 return _T("GPS");
209 case INTERNAL_BT:
210 return Port;
211 default:
212 return _T("");
213 }
214}
215
216wxString ConnectionParams::GetIOTypeValueStr() const {
217 if (IOSelect == DS_TYPE_INPUT)
218 return _("Input");
219 else if (IOSelect == DS_TYPE_OUTPUT)
220 return _("Output");
221 else
222 return _("In/Out");
223}
224
225wxString ConnectionParams::FilterTypeToStr(ListType type,
226 FilterDirection dir) const {
227 if (dir == FILTER_INPUT) {
228 if (type == BLACKLIST)
229 return _("Reject");
230 else
231 return _("Accept");
232 } else {
233 if (type == BLACKLIST)
234 return _("Drop");
235 else
236 return _("Send");
237 }
238}
239
240wxString ConnectionParams::GetFiltersStr() const {
241 wxString istcs;
242 for (size_t i = 0; i < InputSentenceList.Count(); i++) {
243 if (i > 0) istcs.Append(_T(","));
244 istcs.Append(InputSentenceList[i]);
245 }
246 wxString ostcs;
247 for (size_t i = 0; i < OutputSentenceList.Count(); i++) {
248 if (i > 0) ostcs.Append(_T(","));
249 ostcs.Append(OutputSentenceList[i]);
250 }
251 wxString ret = wxEmptyString;
252 if (istcs.Len() > 0) {
253 ret.Append(_("In"));
254 ret.Append(wxString::Format(
255 _T(": %s %s"),
256 FilterTypeToStr(InputSentenceListType, FILTER_INPUT).c_str(),
257 istcs.c_str()));
258 } else
259 ret.Append(_("In: None"));
260
261 if (ostcs.Len() > 0) {
262 ret.Append(_T(", "));
263 ret.Append(_("Out"));
264 ret.Append(wxString::Format(
265 _T(": %s %s"),
266 FilterTypeToStr(OutputSentenceListType, FILTER_OUTPUT).c_str(),
267 ostcs.c_str()));
268 } else
269 ret.Append(_(", Out: None"));
270 return ret;
271}
272
273wxString ConnectionParams::GetDSPort() const {
274 if (Type == SERIAL)
275 return wxString::Format(_T("Serial:%s"), Port.c_str());
276 else if (Type == NETWORK) {
277 wxString proto = NetworkProtocolToString(NetProtocol);
278 return wxString::Format(_T("%s:%s:%d"), proto.c_str(),
279 NetworkAddress.c_str(), NetworkPort);
280 } else if (Type == INTERNAL_BT) {
281 return Port; // mac
282 } else
283 return _T("");
284}
285
286std::string ConnectionParams::GetStrippedDSPort() {
287 if (Type == SERIAL){
288 wxString t = wxString::Format(_T("Serial:%s"), Port.c_str());
289 wxString comx = t.AfterFirst(':').BeforeFirst(' ');
290 return comx.ToStdString();
291 }
292 else if (Type == NETWORK) {
293 wxString proto = NetworkProtocolToString(NetProtocol);
294 wxString t = wxString::Format(_T("%s:%s:%d"), proto.c_str(),
295 NetworkAddress.c_str(), NetworkPort);
296 return t.ToStdString();
297
298 } else if (Type == SOCKETCAN) {
299 return "socketCAN";
300 //FIXME (dave)
301 //wxString proto = NetworkProtocolToString(NetProtocol);
302 //wxString t = wxString::Format(_T("%s:%s:%d"), proto.c_str(),
303 // NetworkAddress.c_str(), NetworkPort);
304 //return t.ToStdString();
305
306 } else if (Type == INTERNAL_BT) {
307 return Port.ToStdString();
308 } else
309 return "";
310}
311
312std::string ConnectionParams::GetLastDSPort() const {
313 if (Type == SERIAL){
314 wxString sp = wxString::Format(_T("Serial:%s"), Port.c_str());
315 return sp.ToStdString();
316 }
317 else {
318 wxString proto = NetworkProtocolToString(LastNetProtocol);
319 wxString sp = wxString::Format(_T("%s:%s:%d"), proto.c_str(),
320 LastNetworkAddress.c_str(), LastNetworkPort);
321 return sp.ToStdString();
322 }
323}
324
325bool ConnectionParams::SentencePassesFilter(const wxString& sentence, FilterDirection direction)
326{
327 wxArrayString filter;
328 bool listype = false;
329
330 if (direction == FILTER_INPUT)
331 {
332 filter = InputSentenceList;
333 if (InputSentenceListType == WHITELIST)
334 listype = true;
335 }
336 else
337 {
338 filter = OutputSentenceList;
339 if (OutputSentenceListType == WHITELIST)
340 listype = true;
341 }
342 if (filter.Count() == 0) //Empty list means everything passes
343 return true;
344
345 wxString fs;
346 for (size_t i = 0; i < filter.Count(); i++)
347 {
348 fs = filter[i];
349 switch (fs.Length())
350 {
351 case 2:
352 if (fs == sentence.Mid(1, 2))
353 return listype;
354 break;
355 case 3:
356 if (fs == sentence.Mid(3, 3))
357 return listype;
358 break;
359 case 5:
360 if (fs == sentence.Mid(1, 5))
361 return listype;
362 break;
363 default:
364 // TODO: regex patterns like ".GPZ.." or 6-character patterns
365 // are rejected in the connection settings dialogue currently
366 // experts simply edit .opencpn/opncpn.config
367 wxRegEx re(fs);
368 if (re.Matches(sentence.Mid(0, 8)))
369 {
370 return listype;
371 }
372 break;
373 }
374 }
375 return !listype;
376}
377
378NavAddr::Bus ConnectionParams::GetCommProtocol(){
379 if (Type == NETWORK){
380 if (NetProtocol == SIGNALK)
381 return NavAddr::Bus::Signalk;
382 else if (NetProtocol == UDP)
383 return NavAddr::Bus::N0183;
384 else if (NetProtocol == TCP)
385 return NavAddr::Bus::N0183;
386 else if (NetProtocol == GPSD)
387 return NavAddr::Bus::N0183;
388 }
389
390 switch (Protocol){
391 case PROTO_NMEA0183:
392 return NavAddr::Bus::N0183;
393 case PROTO_NMEA2000:
394 return NavAddr::Bus::N2000;
395 default:
396 return NavAddr::Bus::Undef;
397 }
398}
399
400NavAddr::Bus ConnectionParams::GetLastCommProtocol(){
401 if (Type == NETWORK){
402 if (LastNetProtocol == SIGNALK)
403 return NavAddr::Bus::Signalk;
404 else if (LastNetProtocol == UDP)
405 return NavAddr::Bus::N0183;
406 else if (LastNetProtocol == TCP)
407 return NavAddr::Bus::N0183;
408 else if (LastNetProtocol == GPSD)
409 return NavAddr::Bus::N0183;
410 }
411
412 switch (LastDataProtocol){
413 case PROTO_NMEA0183:
414 return NavAddr::Bus::N0183;
415 case PROTO_NMEA2000:
416 return NavAddr::Bus::N2000;
417 default:
418 return NavAddr::Bus::Undef;
419 }
420}
421
422