OpenCPN Partial API docs
garmin_protocol_mgr.h
1 /******************************************************************************
2  *
3  * Project: OpenCPN
4  * Purpose: NMEA Data Object
5  * Author: David Register
6  *
7  ***************************************************************************
8  * Copyright (C) 2010 by David S. Register *
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  *
27  *
28  *
29  */
30 
31 #ifndef _GARMINPROTOCOLHANDLER_H__
32 #define _GARMINPROTOCOLHANDLER_H__
33 
34 #include <atomic>
35 #include <string>
36 
37 #ifndef __WXMSW__
38 #include <sys/socket.h> // needed for (some) Mac builds
39 #include <netinet/in.h>
40 #else
41 #include <windows.h>
42 #include <dbt.h>
43 #include <initguid.h>
44 #endif
45 
46 
47 #include <wx/wxprec.h>
48 
49 #ifndef WX_PRECOMP
50 #include <wx/wx.h>
51 #endif // precompiled header
52 
53 #include <wx/datetime.h>
54 
55 #ifdef __WXGTK__
56 // newer versions of glib define its own GSocket but we unfortunately use this
57 // name in our own (semi-)public header and so can't change it -- rename glib
58 // one instead
59 //#include <gtk/gtk.h>
60 #define GSocket GlibGSocket
61 #include <wx/socket.h>
62 #undef GSocket
63 #else
64 #include <wx/socket.h>
65 #endif
66 
67 #include "garminusb.h"
68 #include "model/conn_params.h"
69 #include "model/ds_porttype.h"
70 
71 //----------------------------------------------------------------------------
72 // constants
73 //----------------------------------------------------------------------------
74 #ifndef PI
75 #define PI 3.1415926535897931160E0 /* pi */
76 #endif
77 
78 #define TIMER_SOCKET 7006
79 
80 //----------------------------------------------------------------------------
81 // Garmin Device Management
82 // Handle USB and Serial Port Garmin PVT protocol data interface.
83 //----------------------------------------------------------------------------
84 
85 //--------------------------------------------------------
86 // Some Garmin Data Structures and Constants
87 //--------------------------------------------------------
88 #define GARMIN_USB_API_VERSION 1
89 #define GARMIN_USB_MAX_BUFFER_SIZE 4096
90 #define GARMIN_USB_INTERRUPT_DATA_SIZE 64
91 
92 #define IOCTL_GARMIN_USB_API_VERSION \
93  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
94 #define IOCTL_GARMIN_USB_INTERRUPT_IN \
95  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x850, METHOD_BUFFERED, FILE_ANY_ACCESS)
96 #define IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE \
97  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x851, METHOD_BUFFERED, FILE_ANY_ACCESS)
98 
99 #ifdef __WXMSW__
100 // {2C9C45C2-8E7D-4C08-A12D-816BBAE722C0}
101 DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b,
102  0xba, 0xe7, 0x22, 0xc0);
103 #endif
104 
105 /*
106  * New packet types in USB.
107  */
108 #define GUSB_SESSION_START 5 /* We request units attention */
109 #define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */
110 #define GUSB_REQUEST_BULK 2 /* Unit requests we read from bulk pipe */
111 
112 #define GUSB_RESPONSE_PVT 51 /* PVT Data Packet */
113 #define GUSB_RESPONSE_SDR 114 /* Satellite Data Record Packet */
114 
115 typedef struct unit_info_type_ {
116  unsigned long serial_number;
117  unsigned long unit_id;
118  unsigned long unit_version;
119  char *os_identifier; /* In case the OS has another name for it. */
120  char *product_identifier; /* From the hardware itself. */
122 
123 /* push current alignment to stack, set alignment to 1 byte boundary */
124 #pragma pack(push, 1)
125 
126 typedef struct {
127  float alt;
128  float epe;
129  float eph;
130  float epv;
131  short fix;
132  double tow;
133  double lat;
134  double lon;
135  float east;
136  float north;
137  float up;
138  float msl_hght;
139  short leap_scnds;
140  long wn_days;
142 
143 #pragma pack(pop) /* restore original alignment from stack */
144 
145 typedef struct {
146  float alt;
147  float epe;
148  float eph;
149  float epv;
150  short fix;
151  double tow;
152  double lat;
153  double lon;
154  float east;
155  float north;
156  float up;
157  float msl_hght;
158  short leap_scnds;
159  long wn_days;
161 
162 /* Packet structure for Pkt_ID = 114 (Satellite Data Record) */
163 typedef struct {
164  unsigned char svid; // space vehicle identification (1-32 and 33-64 for WAAS)
165  short snr; // signal-to-noise ratio
166  unsigned char elev; // satellite elevation in degrees
167  short azmth; // satellite azimuth in degrees
168  unsigned char status; // status bit-field
169 } cpo_sat_data;
170 
171 /*
172  * The status bit field represents a set of booleans described below:
173  * Bit Meaning when bit is one (1)
174  * 0 The unit has ephemeris data for the specified
175  * satellite. 1 The unit has a differential correction for the specified
176  * satellite. 2 The unit is using this satellite in the solution.
177  */
178 
179 enum { rs_fromintr, rs_frombulk };
180 
181 #define TIMER_GARMIN1 7005
182 
184 class GARMIN_USB_Thread;
185 
186 class GarminProtocolHandler : public wxEvtHandler {
187 public:
188  GarminProtocolHandler(wxString port, wxEvtHandler *MessageTarget,
189  bool bsel_usb);
191 
192  void Close(void);
193 
194  void StopIOThread(bool b_pause);
195  void RestartIOThread(void);
196 
197  void StopSerialThread(void);
198 
199  void OnTimerGarmin1(wxTimerEvent &event);
200 
201  bool FindGarminDeviceInterface();
202 
203  wxEvtHandler *m_pMainEventHandler;
204  void *m_pparent;
205 
206  int m_max_tx_size;
207  int m_receive_state;
208  cpo_sat_data m_sat_data[12];
209  unit_info_type grmin_unit_info[2];
210  int m_nSats;
211  wxTimer TimerGarmin1;
212 
213  std::atomic_int m_Thread_run_flag;
214  GARMIN_Serial_Thread *m_garmin_serial_thread;
215  GARMIN_USB_Thread *m_garmin_usb_thread;
216  bool m_bneed_int_reset;
217  int m_ndelay;
218  bool m_bOK;
219  bool m_busb;
220  wxString m_port;
221 
222 #ifdef __WXMSW__
223  HANDLE garmin_usb_start();
224  bool ResetGarminUSBDriver();
225  static bool IsGarminPlugged();
226  bool gusb_syncup(void);
227 
228  int gusb_win_get(garmin_usb_packet *ibuf, size_t sz);
229  int gusb_win_get_bulk(garmin_usb_packet *ibuf, size_t sz);
230  int gusb_win_send(const garmin_usb_packet *opkt, size_t sz);
231 
232  int gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz);
233  int gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz);
234 
235  HANDLE m_usb_handle;
236 
237  WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
238 #endif
239 
240  DECLARE_EVENT_TABLE()
241 };
242 
243 //-------------------------------------------------------------------------------------------------------------
244 //
245 // Garmin Serial Port Worker Thread
246 //
247 // This thread manages reading the positioning data stream from the declared
248 // Garmin GRMN Mode serial device
249 //
250 //-------------------------------------------------------------------------------------------------------------
251 class GARMIN_Serial_Thread : public wxThread {
252 public:
254  wxEvtHandler *MessageTarget, wxString port);
255  ~GARMIN_Serial_Thread(void);
256  void *Entry();
257  void string(wxCharBuffer mb_str);
258 
259 private:
260  wxEvtHandler *m_pMessageTarget;
261  GarminProtocolHandler *m_parent;
262 
263  wxString m_port;
264  bool m_bconnected;
265  bool m_bdetected;
266 };
267 
268 //-------------------------------------------------------------------------------------------------------------
269 //
270 // Garmin USB Worker Thread
271 //
272 // This thread manages reading the positioning data stream from the declared
273 // Garmin USB device
274 //
275 //-------------------------------------------------------------------------------------------------------------
276 class GARMIN_USB_Thread : public wxThread {
277 public:
279  wxEvtHandler *MessageTarget, unsigned int device_handle,
280  size_t max_tx_size);
281  ~GARMIN_USB_Thread(void);
282  void *Entry();
283 
284 private:
285  int gusb_win_get(garmin_usb_packet *ibuf, size_t sz);
286  int gusb_win_get_bulk(garmin_usb_packet *ibuf, size_t sz);
287  int gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz);
288 
289  wxEvtHandler *m_pMessageTarget;
290  GarminProtocolHandler *m_parent;
291 
292  int m_receive_state;
293  cpo_sat_data m_sat_data[12];
294  unit_info_type grmin_unit_info[2];
295  int m_nSats;
296  int m_max_tx_size;
297 #ifdef __WXMSW__
298  HANDLE m_usb_handle;
299 #endif
300 };
301 
302 #endif // __GARMINPROTOCOLHANDLER_H__