OpenCPN Partial API docs
Loading...
Searching...
No Matches
comm_drv_n2k_net.h
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose:
5 * Author: David Register, Alec Leamas
6 *
7 ***************************************************************************
8 * Copyright (C) 2023 by David Register, Alec Leamas *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25
26#ifndef _COMMDRIVERN2KNET_H
27#define _COMMDRIVERN2KNET_H
28
29#include <wx/wxprec.h>
30
31#ifndef WX_PRECOMP
32#include <wx/wx.h>
33#endif // precompiled header
34
35#include "model/comm_can_util.h"
36#include "model/comm_drv_n2k.h"
37#include "model/conn_params.h"
38
39#include <wx/datetime.h>
40
41#ifdef __WXGTK__
42// newer versions of glib define its own GSocket but we unfortunately use this
43// name in our own (semi-)public header and so can't change it -- rename glib
44// one instead
45// #include <gtk/gtk.h>
46#define GSocket GlibGSocket
47#include <wx/socket.h>
48#undef GSocket
49#else
50#include <wx/socket.h>
51#endif
52
53#ifndef __WXMSW__
54#include <sys/socket.h> // needed for (some) Mac builds
55#include <netinet/in.h>
56#endif
57
58#define RX_BUFFER_SIZE_NET 4096
59
60#define ESCAPE 0x10
61#define STARTOFTEXT 0x02
62#define ENDOFTEXT 0x03
63
64#define MsgTypeN2kData 0x93
65#define MsgTypeN2kRequest 0x94
66
67typedef enum {
68 N2KFormat_Undefined = 0,
69 N2KFormat_YD_RAW,
70 N2KFormat_Actisense_RAW_ASCII,
71 N2KFormat_Actisense_N2K_ASCII,
72 N2KFormat_Actisense_N2K,
73 N2KFormat_Actisense_RAW,
74 N2KFormat_Actisense_NGT,
75 N2KFormat_SeaSmart,
76 N2KFormat_MiniPlex
77} N2K_Format;
78
79typedef enum { TX_FORMAT_YDEN = 0, TX_FORMAT_ACTISENSE } GW_TX_FORMAT;
80
81class CommDriverN2KNetEvent; // Internal
82class MrqContainer;
83class FastMessageMap;
84
85class circular_buffer {
86public:
87 circular_buffer(size_t size);
88 void reset();
89 size_t capacity() const;
90 size_t size() const;
91 bool empty() const;
92 bool full() const;
93 void put(unsigned char item);
94 unsigned char get();
95
96private:
97 std::mutex mutex_;
98 std::unique_ptr<unsigned char[]> buf_;
99 size_t head_ = 0;
100 size_t tail_ = 0;
101 const size_t max_size_;
102 bool full_ = 0;
103};
104
105class CommDriverN2KNet : public CommDriverN2K, public wxEvtHandler {
106public:
108 CommDriverN2KNet(const ConnectionParams* params, DriverListener& listener);
109
110 virtual ~CommDriverN2KNet();
111
112 void SetListener(DriverListener& l) override {};
113
114 void Open();
115 void Close();
116 ConnectionParams GetParams() const { return m_params; }
117
118 bool SetOutputSocketOptions(wxSocketBase* tsock);
119 void OnServerSocketEvent(wxSocketEvent& event); // The listener
120 void OnTimerSocket(wxTimerEvent& event) { OnTimerSocket(); }
121 void OnTimerSocket();
122 void OnSocketEvent(wxSocketEvent& event);
123 void OpenNetworkGPSD();
124 void OpenNetworkTCP(unsigned int addr);
125 void OpenNetworkUDP(unsigned int addr);
126 void OnSocketReadWatchdogTimer(wxTimerEvent& event);
127 void HandleResume();
128
129 bool SendMessage(std::shared_ptr<const NavMsg> msg,
130 std::shared_ptr<const NavAddr> addr) override;
131 wxSocketBase* GetSock() const { return m_sock; }
132
133private:
134 ConnectionParams m_params;
135 DriverListener& m_listener;
136
137 void handle_N2K_MSG(CommDriverN2KNetEvent& event);
138 wxString GetNetPort() const { return m_net_port; }
139 wxIPV4address GetAddr() const { return m_addr; }
140 wxTimer* GetSocketThreadWatchdogTimer() {
141 return &m_socketread_watchdog_timer;
142 }
143 wxTimer* GetSocketTimer() { return &m_socket_timer; }
144 void SetSock(wxSocketBase* sock) { m_sock = sock; }
145 void SetTSock(wxSocketBase* sock) { m_tsock = sock; }
146 wxSocketBase* GetTSock() const { return m_tsock; }
147 void SetSockServer(wxSocketServer* sock) { m_socket_server = sock; }
148 wxSocketServer* GetSockServer() const { return m_socket_server; }
149 void SetMulticast(bool multicast) { m_is_multicast = multicast; }
150 bool GetMulticast() const { return m_is_multicast; }
151
152 NetworkProtocol GetProtocol() { return m_net_protocol; }
153 void SetBrxConnectEvent(bool event) { m_brx_connect_event = event; }
154 bool GetBrxConnectEvent() { return m_brx_connect_event; }
155
156 void SetConnectTime(wxDateTime time) { m_connect_time = time; }
157 wxDateTime GetConnectTime() { return m_connect_time; }
158
159 dsPortType GetPortType() const { return m_io_select; }
160 wxString GetPort() const { return m_portstring; }
161
162 std::vector<unsigned char> PushFastMsgFragment(const CanHeader& header,
163 int position);
164 std::vector<unsigned char> PushCompleteMsg(const CanHeader header,
165 int position,
166 const can_frame frame);
167
168 void HandleCanFrameInput(can_frame frame);
169
170 ConnectionType GetConnectionType() const { return m_connection_type; }
171
172 bool ChecksumOK(const std::string& sentence);
173 void SetOk(bool ok) { m_bok = ok; };
174
175 N2K_Format DetectFormat(std::vector<unsigned char> packet);
176 bool ProcessActisense_ASCII_RAW(std::vector<unsigned char> packet);
177 bool ProcessActisense_ASCII_N2K(std::vector<unsigned char> packet);
178 bool ProcessActisense_N2K(std::vector<unsigned char> packet);
179 bool ProcessActisense_RAW(std::vector<unsigned char> packet);
180 bool ProcessActisense_NGT(std::vector<unsigned char> packet);
181 bool ProcessSeaSmart(std::vector<unsigned char> packet);
182 bool ProcessMiniPlex(std::vector<unsigned char> packet);
183
184 bool SendN2KNetwork(std::shared_ptr<const Nmea2000Msg>& msg,
185 std::shared_ptr<const NavAddr2000> dest_addr);
186
187 std::vector<std::vector<unsigned char>> GetTxVector(
188 const std::shared_ptr<const Nmea2000Msg>& msg,
189 std::shared_ptr<const NavAddr2000> dest_addr);
190 bool SendSentenceNetwork(std::vector<std::vector<unsigned char>> payload);
191 bool HandleMgntMsg(uint64_t pgn, std::vector<unsigned char>& payload);
192 bool PrepareForTX();
193
194 wxString m_net_port;
195 NetworkProtocol m_net_protocol;
196 wxIPV4address m_addr;
197 wxSocketBase* m_sock;
198 wxSocketBase* m_tsock;
199 wxSocketServer* m_socket_server;
200 bool m_is_multicast;
201 MrqContainer* m_mrq_container;
202
203 int m_txenter;
204 int m_dog_value;
205 std::string m_sock_buffer;
206 wxString m_portstring;
207 dsPortType m_io_select;
208 wxDateTime m_connect_time;
209 bool m_brx_connect_event;
210 bool m_bchecksumCheck;
211 ConnectionType m_connection_type;
212
213 wxTimer m_socket_timer;
214 wxTimer m_socketread_watchdog_timer;
215
216 bool m_bok;
217 int m_ib;
218 bool m_bInMsg, m_bGotESC, m_bGotSOT;
219
220 circular_buffer* m_circle;
221 unsigned char* rx_buffer;
222 std::string m_sentence;
223
224 FastMessageMap* fast_messages;
225 N2K_Format m_n2k_format;
226 uint8_t m_order;
227 char m_TX_flag;
228
229 ObsListener resume_listener;
230
231 DECLARE_EVENT_TABLE()
232};
233
234#endif // guard
CAN v2.0 29 bit header as used by NMEA 2000.
void SetListener(DriverListener &l) override
Set the entity which will receive incoming data.
void OnSocketEvent(wxSocketEvent &event)
Interface implemented by transport layer and possible other parties like test code which should handl...
Definition comm_driver.h:48
Track fast message fragments eventually forming complete messages.
Define an action to be performed when a KeyProvider is notified.
Definition observable.h:228