OpenCPN Partial API docs
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 
67 
68 typedef enum
69 {
70  N2KFormat_Undefined = 0,
71  N2KFormat_YD_RAW,
72  N2KFormat_Actisense_RAW_ASCII,
73  N2KFormat_Actisense_N2K_ASCII,
74  N2KFormat_Actisense_N2K,
75  N2KFormat_Actisense_RAW,
76  N2KFormat_Actisense_NGT,
77  N2KFormat_SeaSmart,
78  N2KFormat_MiniPlex
79 } N2K_Format;
80 
81 typedef enum
82 {
83  TX_FORMAT_YDEN = 0,
84  TX_FORMAT_ACTISENSE
85 } GW_TX_FORMAT;
86 
87 class CommDriverN2KNetEvent; // Internal
88 class MrqContainer;
89 class FastMessageMap;
90 
91 
92 class circular_buffer {
93 public:
94  circular_buffer(size_t size);
95  void reset();
96  size_t capacity() const;
97  size_t size() const;
98  bool empty() const;
99  bool full() const;
100  void put(unsigned char item);
101  unsigned char get();
102 
103 private:
104  std::mutex mutex_;
105  std::unique_ptr<unsigned char[]> buf_;
106  size_t head_ = 0;
107  size_t tail_ = 0;
108  const size_t max_size_;
109  bool full_ = 0;
110 };
111 
112 class CommDriverN2KNet : public CommDriverN2K, public wxEvtHandler {
113 public:
115  CommDriverN2KNet(const ConnectionParams* params, DriverListener& listener);
116 
117  virtual ~CommDriverN2KNet();
118 
120  void Activate() override;
121  void SetListener(DriverListener& l) override{};
122 
123  void Open();
124  void Close();
125  ConnectionParams GetParams() const { return m_params; }
126 
127  bool SetOutputSocketOptions(wxSocketBase* tsock);
128  void OnServerSocketEvent(wxSocketEvent& event); // The listener
129  void OnTimerSocket(wxTimerEvent& event) { OnTimerSocket(); }
130  void OnTimerSocket();
131  void OnSocketEvent(wxSocketEvent& event);
132  void OpenNetworkGPSD();
133  void OpenNetworkTCP(unsigned int addr);
134  void OpenNetworkUDP(unsigned int addr);
135  void OnSocketReadWatchdogTimer(wxTimerEvent& event);
136  void HandleResume();
137 
138  bool SendMessage(std::shared_ptr<const NavMsg> msg,
139  std::shared_ptr<const NavAddr> addr) override;
140  wxSocketBase* GetSock() const { return m_sock; }
141 
142 private:
143  ConnectionParams m_params;
144  DriverListener& m_listener;
145 
146  void handle_N2K_MSG(CommDriverN2KNetEvent& event);
147  wxString GetNetPort() const { return m_net_port; }
148  wxIPV4address GetAddr() const { return m_addr; }
149  wxTimer* GetSocketThreadWatchdogTimer() {
150  return &m_socketread_watchdog_timer;
151  }
152  wxTimer* GetSocketTimer() { return &m_socket_timer; }
153  void SetSock(wxSocketBase* sock) { m_sock = sock; }
154  void SetTSock(wxSocketBase* sock) { m_tsock = sock; }
155  wxSocketBase* GetTSock() const { return m_tsock; }
156  void SetSockServer(wxSocketServer* sock) { m_socket_server = sock; }
157  wxSocketServer* GetSockServer() const { return m_socket_server; }
158  void SetMulticast(bool multicast) { m_is_multicast = multicast; }
159  bool GetMulticast() const { return m_is_multicast; }
160 
161  NetworkProtocol GetProtocol() { return m_net_protocol; }
162  void SetBrxConnectEvent(bool event) { m_brx_connect_event = event; }
163  bool GetBrxConnectEvent() { return m_brx_connect_event; }
164 
165  void SetConnectTime(wxDateTime time) { m_connect_time = time; }
166  wxDateTime GetConnectTime() { return m_connect_time; }
167 
168  dsPortType GetPortType() const { return m_io_select; }
169  wxString GetPort() const { return m_portstring; }
170 
171  std::vector<unsigned char> PushFastMsgFragment(const CanHeader& header,
172  int position);
173  std::vector<unsigned char> PushCompleteMsg(const CanHeader header,
174  int position,
175  const can_frame frame);
176 
177  void HandleCanFrameInput(can_frame frame);
178 
179  ConnectionType GetConnectionType() const { return m_connection_type; }
180 
181  bool ChecksumOK(const std::string& sentence);
182  void SetOk(bool ok) { m_bok = ok; };
183 
184  N2K_Format DetectFormat(std::vector<unsigned char> packet);
185  bool ProcessActisense_ASCII_RAW(std::vector<unsigned char> packet);
186  bool ProcessActisense_ASCII_N2K(std::vector<unsigned char> packet);
187  bool ProcessActisense_N2K(std::vector<unsigned char> packet);
188  bool ProcessActisense_RAW(std::vector<unsigned char> packet);
189  bool ProcessActisense_NGT(std::vector<unsigned char> packet);
190  bool ProcessSeaSmart(std::vector<unsigned char> packet);
191  bool ProcessMiniPlex(std::vector<unsigned char> packet);
192 
193 
194  bool SendN2KNetwork(std::shared_ptr<const Nmea2000Msg> &msg,
195  std::shared_ptr<const NavAddr2000> dest_addr);
196 
197  std::vector<std::vector<unsigned char>>
198  GetTxVector(const std::shared_ptr<const Nmea2000Msg> &msg,
199  std::shared_ptr<const NavAddr2000> dest_addr);
200  bool SendSentenceNetwork(std::vector<std::vector<unsigned char>> payload);
201  bool HandleMgntMsg(uint64_t pgn, std::vector<unsigned char> &payload);
202  bool PrepareForTX();
203 
204  wxString m_net_port;
205  NetworkProtocol m_net_protocol;
206  wxIPV4address m_addr;
207  wxSocketBase* m_sock;
208  wxSocketBase* m_tsock;
209  wxSocketServer* m_socket_server;
210  bool m_is_multicast;
211  MrqContainer *m_mrq_container;
212 
213  int m_txenter;
214  int m_dog_value;
215  std::string m_sock_buffer;
216  wxString m_portstring;
217  dsPortType m_io_select;
218  wxDateTime m_connect_time;
219  bool m_brx_connect_event;
220  bool m_bchecksumCheck;
221  ConnectionType m_connection_type;
222 
223  wxTimer m_socket_timer;
224  wxTimer m_socketread_watchdog_timer;
225 
226  bool m_bok;
227  int m_ib;
228  bool m_bInMsg, m_bGotESC, m_bGotSOT;
229 
230  circular_buffer *m_circle;
231  unsigned char *rx_buffer;
232  std::string m_sentence;
233 
234  FastMessageMap *fast_messages;
235  N2K_Format m_n2k_format;
236  uint8_t m_order;
237  char m_TX_flag;
238 
239  ObsListener resume_listener;
240 
241  DECLARE_EVENT_TABLE()
242 };
243 
244 #endif // guard
245 
CAN v2.0 29 bit header as used by NMEA 2000.
Definition: comm_can_util.h:64
void SetListener(DriverListener &l) override
Set the entity which will receive incoming data.
void OnSocketEvent(wxSocketEvent &event)
void Activate() override
Register driver and possibly do other post-ctor steps.
Interface implemented by transport layer and possible other parties like test code which should handl...
Definition: comm_driver.h:47
Track fast message fragments eventually forming complete messages.
Definition: comm_can_util.h:80
Define an action to be performed when a KeyProvider is notified.
Definition: observable.h:210