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/jsonval.h>
32#include <wx/jsonreader.h>
33
34#include "model/base_platform.h"
35#include "model/comm_appmsg.h"
38#include "model/comm_drv_n2k.h"
41
42#include "ocpn_plugin.h"
43using namespace std;
44
45vector<uint8_t> GetN2000Payload(NMEA2000Id id, ObservedEvt ev) {
46 auto msg = UnpackEvtPointer<Nmea2000Msg>(ev);
47 return msg->payload;
48}
49
51 auto msg = UnpackEvtPointer<Nmea2000Msg>(ev);
52 return msg->source->to_string();
53}
54
56 auto msg = UnpackEvtPointer<Nmea0183Msg>(ev);
57 return msg->payload;
58}
59
61 auto msg = UnpackEvtPointer<PluginMsg>(ev);
62 return msg->message;
63}
64
65std::shared_ptr<void> GetSignalkPayload(ObservedEvt ev) {
66 auto msg = UnpackEvtPointer<SignalkMsg>(ev);
67 wxJSONReader reader;
68 wxJSONValue data;
69 reader.Parse(wxString(msg->raw_message), &data);
70
71 wxJSONValue root(wxJSONTYPE_OBJECT);
72 root["Data"] = data;
73 root["ErrorCount"] = reader.GetErrorCount();
74 root["WarningCount"] = reader.GetWarningCount();
75
76 root["Errors"] = wxJSONValue(wxJSONTYPE_ARRAY);
77 for (size_t i = 0; i < reader.GetErrors().GetCount(); i++)
78 root["Errors"].Append(reader.GetErrors().Item(i));
79
80 root["Warnings"] = wxJSONValue(wxJSONTYPE_ARRAY);
81 for (size_t i = 0; i < reader.GetWarnings().GetCount(); i++)
82 root["Warnings"].Append(reader.GetWarnings().Item(i));
83
84 root["Context"] = msg->context;
85 root["ContextSelf"] = msg->context_self;
86
87 return static_pointer_cast<void>(std::make_shared<wxJSONValue>(root));
88}
89
90shared_ptr<ObservableListener> GetListener(NMEA2000Id id, wxEventType et,
91 wxEvtHandler* eh) {
92 return make_shared<ObservableListener>(Nmea2000Msg(id.id), eh, et);
93}
94
95std::shared_ptr<ObservableListener> GetListener(NMEA0183Id id, wxEventType et,
96 wxEvtHandler* eh) {
97 return make_shared<ObservableListener>(Nmea0183Msg(id.id), eh, et);
98}
99
100shared_ptr<ObservableListener> GetListener(SignalkId id, wxEventType et,
101 wxEvtHandler* eh) {
102 return make_shared<ObservableListener>(SignalkMsg(), eh, et);
103}
104
105shared_ptr<ObservableListener> GetListener(NavDataId id, wxEventType et,
106 wxEvtHandler* eh) {
107 return make_shared<ObservableListener>(BasicNavDataMsg(), eh, et);
108}
109
110std::shared_ptr<ObservableListener> GetListener(PluginMsgId id, wxEventType et,
111 wxEvtHandler* eh) {
112 return make_shared<ObservableListener>(PluginMsg(id.id, ""), eh, et);
113}
114
116 auto msg = UnpackEvtPointer<BasicNavDataMsg>(ev);
117 PluginNavdata data;
118
119 data.lat = msg->pos.lat;
120 data.lon = msg->pos.lon;
121 data.sog = msg->sog;
122 data.cog = msg->cog;
123 data.var = msg->var;
124 data.hdt = msg->hdt;
125 data.time = msg->time;
126 return data;
127}
128
131std::vector<DriverHandle> GetActiveDrivers() {
132 std::vector<DriverHandle> result;
133
134 auto& registry = CommDriverRegistry::GetInstance();
135 const std::vector<DriverPtr>& drivers = registry.GetDrivers();
136
137 for (auto& driver : drivers) result.push_back(driver->Key());
138
139 return result;
140}
141
142const std::unordered_map<std::string, std::string> GetAttributes(
143 DriverHandle handle) {
144 auto& registry = CommDriverRegistry::GetInstance();
145 auto& drivers = registry.GetDrivers();
146 auto func = [handle](const DriverPtr d) { return d->Key() == handle; };
147 AbstractCommDriver* found = nullptr;
148 for (auto& d : drivers)
149 if (d->Key() == handle) found = d.get();
150 if (found)
151 return found->GetAttributes();
152 else
153 return {};
154}
155
157 DriverHandle handle, const std::shared_ptr<std::vector<uint8_t>>& payload) {
158 // Find the driver from the handle
159 auto& registry = CommDriverRegistry::GetInstance();
160 auto& drivers = registry.GetDrivers();
161 AbstractCommDriver* found = nullptr;
162 for (auto& d : drivers)
163 if (d->Key() == handle) found = d.get();
164 if (!found) {
165 return RESULT_COMM_INVALID_HANDLE;
166 }
167
168 // Determine protocol
169 std::unordered_map<std::string, std::string> attributes =
170 GetAttributes(handle);
171 auto protocol_it = attributes.find("protocol");
172 if (protocol_it == attributes.end()) return RESULT_COMM_INVALID_PARMS;
173 std::string protocol = protocol_it->second;
174
175 if (protocol == "nmea0183") {
176 auto d0183 = dynamic_cast<CommDriverN0183*>(found);
177
178 std::string msg(payload->begin(), payload->end());
179 std::string id = msg.substr(1, 5);
180 auto address = std::make_shared<NavAddr>();
181 auto msg_out = std::make_shared<Nmea0183Msg>(id, msg, address);
182 bool xmit_ok = d0183->SendMessage(msg_out, address);
183 return xmit_ok ? RESULT_COMM_NO_ERROR : RESULT_COMM_TX_ERROR;
184 } else if (protocol == "internal") {
185 std::string msg(payload->begin(), payload->end());
186 size_t space_pos = msg.find(" ");
187 if (space_pos == std::string::npos) return RESULT_COMM_INVALID_PARMS;
188 auto plugin_msg = std::make_shared<PluginMsg>(msg.substr(0, space_pos),
189 msg.substr(space_pos + 1));
190 NavMsgBus::GetInstance().Notify(static_pointer_cast<NavMsg>(plugin_msg));
191 return RESULT_COMM_NO_ERROR;
192 } else {
193 return RESULT_COMM_INVALID_PARMS;
194 }
195}
196
198 DriverHandle handle, int PGN, int destinationCANAddress, int priority,
199 const std::shared_ptr<std::vector<uint8_t>>& payload) {
200 uint64_t _PGN;
201 _PGN = PGN;
202
203 // Find the driver from the handle
204 auto& registry = CommDriverRegistry::GetInstance();
205 auto& drivers = registry.GetDrivers();
206
207 AbstractCommDriver* found(nullptr);
208 for (auto& d : drivers)
209 if (d->Key() == handle) found = d.get();
210 if (!found) {
211 return RESULT_COMM_INVALID_HANDLE;
212 }
213 auto dest_addr =
214 std::make_shared<const NavAddr2000>(found->iface, destinationCANAddress);
215 auto msg =
216 std::make_shared<const Nmea2000Msg>(_PGN, *payload, dest_addr, priority);
217 bool result = found->SendMessage(msg, dest_addr);
218
219 return RESULT_COMM_NO_ERROR;
220}
221
223 std::vector<int>& pgn_list) {
224 if (!pgn_list.size()) return RESULT_COMM_INVALID_PARMS;
225
226 // Find the driver from the handle
227 auto& registry = CommDriverRegistry::GetInstance();
228 auto& drivers = registry.GetDrivers();
229 AbstractCommDriver* found(nullptr);
230 for (auto& d : drivers)
231 if (d->Key() == handle) found = d.get();
232
233 if (!found) {
234 return RESULT_COMM_INVALID_HANDLE;
235 }
236 auto dn2k = dynamic_cast<CommDriverN2K*>(found);
237
238 int nloop = 0;
239 for (size_t i = 0; i < pgn_list.size(); i++) {
240 int nTry = 5;
241 int iresult = -1;
242 nloop = 0;
243 while (nTry && iresult < 0) {
244 iresult = dn2k->SetTXPGN(pgn_list[i]);
245 nTry--;
246 nloop++;
247 }
248 if (iresult < 0) {
249 return RESULT_COMM_REGISTER_PGN_ERROR;
250 }
251 }
252 return RESULT_COMM_NO_ERROR;
253}
254
255wxString* GetpPrivateApplicationDataLocation(void) {
256 return g_BasePlatform->GetPrivateDataDirPtr();
257}
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.
Adds a std::shared<void> element to wxCommandEvent.
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.
PlugIn Object Definition/API.
CommDriverResult
Error return values
std::string DriverHandle
Plugin API supporting direct access to comm drivers for output purposes.
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.
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.
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.
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...
Facade for NavAddr0183.
Facade for NavAddr2000.
Facade for BasicNavDataMsg.
Facade for NavAddrPluginMsg.
Available decoded data for plugins.
Facade for NavAddrSignalK.