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 input_sentence_list(WHITELIST),
98 output_sentence_list(WHITELIST),
99 options_panel(nullptr) {}
101ConnectionParams::~ConnectionParams() =
default;
103void ConnectionParams::Deserialize(
const wxString& configStr) {
105 wxArrayString prms = wxStringTokenize(configStr,
";");
106 if (prms.Count() < 18) {
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]);
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]);
131 last_network_port = 0;
133 if (prms.Count() >= 18) {
134 is_enabled = !!wxAtoi(prms[17]);
136 if (prms.Count() >= 19) {
137 user_comment = prms[18];
139 if (prms.Count() >= 20) {
140 auto_sk_discover = !!wxAtoi(prms[19]);
142 if (prms.Count() >= 21) {
143 socket_can_port = prms[20];
145 if (prms.Count() >= 22) {
146 no_data_reconnect = wxAtoi(prms[21]);
148 if (prms.Count() >= 23) {
149 disable_echo = wxAtoi(prms[22]);
151 if (prms.Count() >= 24) {
152 auth_token = prms[23];
156wxString ConnectionParams::Serialize()
const {
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]);
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]);
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 , 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());
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;
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);
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(),
209 }
else if (type == INTERNAL_BT) {
216 if (type == SERIAL && serial_port.empty())
return false;
217 if (type == NETWORK && (network_address.empty() || !network_port))
219 if (type == INTERNAL_BT && serial_port.empty())
return false;
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();
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();
235 if (type == SOCKETCAN) {
237 if (!socket_can_port.ToStdString().empty())
238 rv +=
"socketCAN-" + socket_can_port.ToStdString();
241 if (type == INTERNAL_BT) {
242 return serial_port.ToStdString();
244 if (type == INTERNAL_GPS) {
245 return serial_port.ToStdString();
251 if (type == SERIAL) {
252 wxString sp = wxString::Format(
"Serial:%s", serial_port.c_str());
253 return sp.ToStdString();
255 wxString proto = NetworkProtocolToString(last_net_protocol);
257 wxString::Format(
"%s:%s:%d", proto.c_str(),
258 last_network_address.c_str(), last_network_port);
259 return sp.ToStdString();
264 FilterDirection direction)
const {
265 wxArrayString filter;
266 bool listype =
false;
268 if (direction == FILTER_INPUT) {
269 filter = input_sentence_list;
270 if (input_sentence_list_type == WHITELIST) listype =
true;
272 filter = output_sentence_list;
273 if (output_sentence_list_type == WHITELIST) listype =
true;
275 if (filter.Count() == 0)
278 for (
size_t i = 0; i < filter.Count(); i++) {
279 const wxString& fs = filter[i];
280 switch (fs.Length()) {
282 if (fs == sentence.Mid(1, 2))
return listype;
285 if (fs == sentence.Mid(3, 3))
return listype;
288 if (fs == sentence.Mid(1, 5))
return listype;
295 if (re.Matches(sentence.Mid(0, 8))) {
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;
311 switch (data_protocol) {
313 return NavAddr::Bus::N0183;
315 return NavAddr::Bus::N2000;
317 return NavAddr::Bus::Undef;
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;
328 switch (last_data_protocol) {
330 return NavAddr::Bus::N0183;
332 return NavAddr::Bus::N2000;
334 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.