OpenCPN Partial API docs
Loading...
Searching...
No Matches
plugin_api.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2022 by David Register *
3 * Copyright (C) 2022 Alec Leamas *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 **************************************************************************/
20
26#include <memory>
27#include <sstream>
28#include <vector>
29
30#include <wx/event.h>
31#include <wx/fileconf.h>
32#include <wx/jsonval.h>
33#include <wx/jsonreader.h>
34#include <wx/tokenzr.h>
35
36#include "model/base_platform.h"
37#include "model/comm_appmsg.h"
40#include "model/comm_drv_n2k.h"
44#include "ocpn_plugin.h"
45#include "model/comm_drv_factory.h"
46using namespace std;
47
48vector<uint8_t> GetN2000Payload(NMEA2000Id id, ObservedEvt ev) {
49 auto msg = UnpackEvtPointer<Nmea2000Msg>(ev);
50 return msg->payload;
51}
52
54 auto msg = UnpackEvtPointer<Nmea2000Msg>(ev);
55 return msg->source->to_string();
56}
57
59 auto msg = UnpackEvtPointer<Nmea0183Msg>(ev);
60 return msg->payload;
61}
62
64 auto msg = UnpackEvtPointer<PluginMsg>(ev);
65 return msg->message;
66}
67
68std::shared_ptr<void> GetSignalkPayload(ObservedEvt ev) {
69 auto msg = UnpackEvtPointer<SignalkMsg>(ev);
70 wxJSONReader reader;
71 wxJSONValue data;
72 reader.Parse(wxString(msg->raw_message), &data);
73
74 wxJSONValue root(wxJSONTYPE_OBJECT);
75 root["Data"] = data;
76 root["ErrorCount"] = reader.GetErrorCount();
77 root["WarningCount"] = reader.GetWarningCount();
78
79 root["Errors"] = wxJSONValue(wxJSONTYPE_ARRAY);
80 for (size_t i = 0; i < reader.GetErrors().GetCount(); i++)
81 root["Errors"].Append(reader.GetErrors().Item(i));
82
83 root["Warnings"] = wxJSONValue(wxJSONTYPE_ARRAY);
84 for (size_t i = 0; i < reader.GetWarnings().GetCount(); i++)
85 root["Warnings"].Append(reader.GetWarnings().Item(i));
86
87 root["Context"] = msg->context;
88 root["ContextSelf"] = msg->context_self;
89
90 return static_pointer_cast<void>(std::make_shared<wxJSONValue>(root));
91}
92
93std::shared_ptr<PI_Notification> GetNotificationMsgPayload(NotificationMsgId id,
94 ObservedEvt ev) {
95 auto msg = UnpackEvtPointer<NotificationMsg>(ev);
96 auto note = msg->notification;
97 auto rv = std::make_shared<PI_Notification>(
98 (PI_NotificationSeverity)note->GetSeverity(), note->GetMessage(),
99 note->GetTimeoutStart(), note->GetTimeoutLeft(), note->GetGuid());
100 rv->action_verb = msg->action_verb;
101 return rv;
102}
103
104shared_ptr<ObservableListener> GetListener(NMEA2000Id id, wxEventType et,
105 wxEvtHandler* eh) {
106 return make_shared<ObservableListener>(Nmea2000Msg(id.id), eh, et);
107}
108
109std::shared_ptr<ObservableListener> GetListener(NMEA0183Id id, wxEventType et,
110 wxEvtHandler* eh) {
111 return make_shared<ObservableListener>(Nmea0183Msg(id.id), eh, et);
112}
113
114shared_ptr<ObservableListener> GetListener(SignalkId id, wxEventType et,
115 wxEvtHandler* eh) {
116 return make_shared<ObservableListener>(SignalkMsg(), eh, et);
117}
118
119shared_ptr<ObservableListener> GetListener(NavDataId id, wxEventType et,
120 wxEvtHandler* eh) {
121 return make_shared<ObservableListener>(BasicNavDataMsg(), eh, et);
122}
123
124std::shared_ptr<ObservableListener> GetListener(PluginMsgId id, wxEventType et,
125 wxEvtHandler* eh) {
126 return make_shared<ObservableListener>(PluginMsg(id.id, ""), eh, et);
127}
128
129std::shared_ptr<ObservableListener> GetListener(NotificationMsgId id,
130 wxEventType et,
131 wxEvtHandler* eh) {
132 return make_shared<ObservableListener>(NotificationMsg(), eh, et);
133}
134
136 auto msg = UnpackEvtPointer<BasicNavDataMsg>(ev);
137 PluginNavdata data;
138
139 data.lat = msg->pos.lat;
140 data.lon = msg->pos.lon;
141 data.sog = msg->sog;
142 data.cog = msg->cog;
143 data.var = msg->var;
144 data.hdt = msg->hdt;
145 data.time = msg->time;
146 return data;
147}
148
151std::vector<DriverHandle> GetActiveDrivers() {
152 std::vector<DriverHandle> result;
153
154 auto& registry = CommDriverRegistry::GetInstance();
155 const std::vector<DriverPtr>& drivers = registry.GetDrivers();
156
157 for (auto& driver : drivers) result.push_back(driver->Key());
158
159 return result;
160}
161
162const std::unordered_map<std::string, std::string> GetAttributes(
163 DriverHandle handle) {
164 auto& registry = CommDriverRegistry::GetInstance();
165 auto& drivers = registry.GetDrivers();
166 auto func = [handle](const DriverPtr d) { return d->Key() == handle; };
167 AbstractCommDriver* found = nullptr;
168 for (auto& d : drivers)
169 if (d->Key() == handle) found = d.get();
170 if (found)
171 return found->GetAttributes();
172 else
173 return {};
174}
175
177 DriverHandle handle, const std::shared_ptr<std::vector<uint8_t>>& payload) {
178 // Find the driver from the handle
179 auto& registry = CommDriverRegistry::GetInstance();
180 auto& drivers = registry.GetDrivers();
181 AbstractCommDriver* found = nullptr;
182 for (auto& d : drivers)
183 if (d->Key() == handle) found = d.get();
184 if (!found) {
186 }
187
188 // Determine protocol
189 std::unordered_map<std::string, std::string> attributes =
190 GetAttributes(handle);
191 auto protocol_it = attributes.find("protocol");
192 if (protocol_it == attributes.end()) return RESULT_COMM_INVALID_PARMS;
193 std::string protocol = protocol_it->second;
194
195 if (protocol == "nmea0183") {
196 auto d0183 = dynamic_cast<CommDriverN0183*>(found);
197
198 std::string msg(payload->begin(), payload->end());
199 std::string id = msg.substr(1, 5);
200 auto address = std::make_shared<NavAddr>();
201 auto msg_out = std::make_shared<Nmea0183Msg>(id, msg, address);
202 bool xmit_ok = d0183->SendMessage(msg_out, address);
204 } else if (protocol == "internal") {
205 std::string msg(payload->begin(), payload->end());
206 size_t space_pos = msg.find(" ");
207 if (space_pos == std::string::npos) return RESULT_COMM_INVALID_PARMS;
208 auto plugin_msg = std::make_shared<PluginMsg>(msg.substr(0, space_pos),
209 msg.substr(space_pos + 1));
210 NavMsgBus::GetInstance().Notify(static_pointer_cast<NavMsg>(plugin_msg));
212 } else {
214 }
215}
216
218 DriverHandle handle, int PGN, int destinationCANAddress, int priority,
219 const std::shared_ptr<std::vector<uint8_t>>& payload) {
220 uint64_t _PGN;
221 _PGN = PGN;
222
223 // Find the driver from the handle
224 auto& registry = CommDriverRegistry::GetInstance();
225 auto& drivers = registry.GetDrivers();
226
227 AbstractCommDriver* found(nullptr);
228 for (auto& d : drivers)
229 if (d->Key() == handle) found = d.get();
230 if (!found) {
232 }
233 auto dest_addr =
234 std::make_shared<const NavAddr2000>(found->iface, destinationCANAddress);
235 auto msg =
236 std::make_shared<const Nmea2000Msg>(_PGN, *payload, dest_addr, priority);
237 bool result = found->SendMessage(msg, dest_addr);
238
240}
241
243 std::vector<int>& pgn_list) {
244 if (!pgn_list.size()) return RESULT_COMM_INVALID_PARMS;
245
246 // Find the driver from the handle
247 auto& registry = CommDriverRegistry::GetInstance();
248 auto& drivers = registry.GetDrivers();
249 AbstractCommDriver* found(nullptr);
250 for (auto& d : drivers)
251 if (d->Key() == handle) found = d.get();
252
253 if (!found) {
255 }
256 auto dn2k = dynamic_cast<CommDriverN2K*>(found);
257
258 int nloop = 0;
259 for (size_t i = 0; i < pgn_list.size(); i++) {
260 int nTry = 5;
261 int iresult = -1;
262 nloop = 0;
263 while (nTry && iresult < 0) {
264 iresult = dn2k->SetTXPGN(pgn_list[i]);
265 nTry--;
266 nloop++;
267 }
268 if (iresult < 0) {
270 }
271 }
273}
274
276 return g_BasePlatform->GetPrivateDataDirPtr();
277}
278
279void ReloadConfigConnections() {
280 // Close and delete all active comm drivers
281 auto& registry = CommDriverRegistry::GetInstance();
282 registry.CloseAllDrivers();
283
284 // Reload config file connections parameters.
285 wxFileConfig* pConf = GetOCPNConfigObject();
286 if (pConf) {
287 pConf->SetPath(_T ( "/Settings/NMEADataSource" ));
288
289 wxString connectionconfigs;
290 pConf->Read(_T( "DataConnections" ), &connectionconfigs);
291 if (!connectionconfigs.IsEmpty()) {
292 wxArrayString confs = wxStringTokenize(connectionconfigs, _T("|"));
293 TheConnectionParams().clear();
294 for (size_t i = 0; i < confs.Count(); i++) {
295 ConnectionParams* prm = new ConnectionParams(confs[i]);
296 if (!prm->Valid) continue;
297 TheConnectionParams().push_back(prm);
298 }
299 }
300 }
301
302 // Reconnect enabled connections
303 for (auto* cp : TheConnectionParams()) {
304 if (cp->bEnabled) {
305 MakeCommDriver(cp);
306 cp->b_IsSetup = TRUE;
307 }
308 }
309}
310
316 const std::string& _message,
317 int _timeout_start, int _timeout_left,
318 std::string _guid) {
319 severity = _severity;
320 message = _message;
321 auto_timeout_start = _timeout_start;
322 auto_timeout_left = _timeout_left;
323 guid = _guid;
324}
325
326int GetActiveNotificationCount() {
327 auto& noteman = NotificationManager::GetInstance();
328 return noteman.GetNotificationCount();
329}
330
331PI_NotificationSeverity GetMaxActiveNotificationLevel() {
332 auto& noteman = NotificationManager::GetInstance();
333 return (PI_NotificationSeverity)noteman.GetMaxSeverity();
334}
335
336std::string RaiseNotification(const PI_NotificationSeverity _severity,
337 const std::string& _message, int timeout_secs) {
338 auto& noteman = NotificationManager::GetInstance();
339 auto notification = std::make_shared<Notification>(
340 (NotificationSeverity)_severity, _message, timeout_secs);
341 return noteman.AddNotification(notification);
342}
343
344bool AcknowledgeNotification(const std::string& guid) {
345 auto& noteman = NotificationManager::GetInstance();
346 return noteman.AcknowledgeNotification(guid);
347}
348
349std::vector<std::shared_ptr<PI_Notification>> GetActiveNotifications() {
350 auto& noteman = NotificationManager::GetInstance();
351 std::vector<std::shared_ptr<PI_Notification>> pi_notes;
352 for (auto note : noteman.GetNotifications()) {
353 auto pi_note = std::make_shared<PI_Notification>(
354 (PI_NotificationSeverity)note->GetSeverity(), note->GetMessage(),
355 note->GetTimeoutStart(), note->GetTimeoutLeft(), note->GetGuid());
356 pi_notes.push_back(pi_note);
357 }
358
359 return pi_notes;
360}
Common interface for all drivers.
Definition comm_driver.h:58
const std::string iface
Physical device for 0183, else a unique string.
Definition comm_driver.h:88
wxString * GetPrivateDataDirPtr()
Legacy compatibility syntactic sugar for GetPrivateDataDir().
NMEA0183 drivers common part.
void Notify(std::shared_ptr< const NavMsg > message)
Accept message received by driver, make it available for upper layers.
A regular Nmea0183 message.
See: https://github.com/OpenCPN/OpenCPN/issues/2729#issuecomment-1179506343.
Custom event class for OpenCPN's notification system.
PI_Notification(PI_NotificationSeverity _severity, const std::string &_message, int _timeout_start, int _timeout_left, std::string _guid)
Plugin Notification Framework support.
A plugin to plugin json message over the REST interface.
A parsed SignalK message over ipv4.
The JSON parser.
Definition jsonreader.h:50
const wxArrayString & GetWarnings() const
Return a reference to the warning message's array.
const wxArrayString & GetErrors() const
Return a reference to the error message's array.
int GetErrorCount() const
Return the size of the error message's array.
int GetWarningCount() const
Return the size of the warning message's array.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
Definition jsonval.h:84
NMEA0183 over IP driver.
NMEA0183 serial driver.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
Class NotificationManager.
PlugIn Object Definition/API.
CommDriverResult
Error return values
@ RESULT_COMM_INVALID_PARMS
Invalid parameters provided to operation.
@ RESULT_COMM_TX_ERROR
Error occurred during transmission.
@ RESULT_COMM_REGISTER_PGN_ERROR
Failed to register PGN parameters.
@ RESULT_COMM_NO_ERROR
Operation completed successfully.
@ RESULT_COMM_INVALID_HANDLE
Invalid or unknown driver handle specified.
PI_NotificationSeverity
Plugin Notification Framework support.
std::string DriverHandle
Plugin API supporting direct access to comm drivers for output purposes.
wxFileConfig * GetOCPNConfigObject(void)
Gets OpenCPN's configuration object.
std::string GetPluginMsgPayload(PluginMsgId id, ObservedEvt ev)
Retrieve the string in a plugin message, internal or received on the REST insterface.
std::string GetN0183Payload(NMEA0183Id id, ObservedEvt ev)
Return payload in a received n0183 message of type id in ev.
PluginNavdata GetEventNavdata(ObservedEvt ev)
Return BasicNavDataMsg decoded data available in ev.
std::shared_ptr< PI_Notification > GetNotificationMsgPayload(NotificationMsgId id, ObservedEvt ev)
Retrieve the Notification Event in a Notification message.
CommDriverResult WriteCommDriverN2K(DriverHandle handle, int PGN, int destinationCANAddress, int priority, const std::shared_ptr< std::vector< uint8_t > > &payload)
Send a PGN message to an NMEA2000 address.
shared_ptr< ObservableListener > GetListener(NMEA2000Id id, wxEventType et, wxEvtHandler *eh)
Gets listener for NMEA 2000 messages.
std::vector< DriverHandle > GetActiveDrivers()
Comm port plugin TX support methods
const std::unordered_map< std::string, std::string > GetAttributes(DriverHandle handle)
Query a specific driver for attributes.
std::string GetN2000Source(NMEA2000Id id, ObservedEvt ev)
Return source identifier (iface) of a received n2000 message of type id in ev.
vector< uint8_t > GetN2000Payload(NMEA2000Id id, ObservedEvt ev)
Return N2K payload for a received n2000 message of type id in ev.
std::shared_ptr< void > GetSignalkPayload(ObservedEvt ev)
Get SignalK status payload after receiving a message.
wxString * GetpPrivateApplicationDataLocation(void)
Gets private application data directory.
CommDriverResult WriteCommDriver(DriverHandle handle, const std::shared_ptr< std::vector< uint8_t > > &payload)
Send a non-NMEA2000 message.
CommDriverResult RegisterTXPGNs(DriverHandle handle, std::vector< int > &pgn_list)
Register PGNs that this application intends to transmit for some NMEA 2000 adapters like Actisense NG...
Identifier for NMEA 0183 sentence types.
Identifier for NMEA 2000 message types.
Navigation data message identifier.
Facade for NotificationMsg.
Facade for NavAddrPluginMsg.
Basic navigation data structure.
double lat
Latitude in decimal degrees.
Identifier for Signal K paths.