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