41#include <netinet/tcp.h>
50#include <wx/datetime.h>
54#include <wx/tokenzr.h>
65#include "garmin_wrapper.h"
66#include "garmin_protocol_mgr.h"
70#include "androidUTIL.h"
75static const long long lNaN = 0xfff8000000000000;
76#define NAN (*(double *)&lNaN)
79extern bool g_benableUDPNullHeader;
81#define N_DOG_TIMEOUT 5
85DEFINE_GUID(GARMIN_GUID1, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b,
86 0xba, 0xe7, 0x22, 0xc0);
106 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
107 PSID AdministratorsGroup;
108 b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
109 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
110 &AdministratorsGroup);
112 if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) {
115 FreeSid(AdministratorsGroup);
121void le_write16(
void *addr,
const unsigned value) {
122 unsigned char *p = (
unsigned char *)addr;
127void le_write32(
void *addr,
const unsigned value) {
128 unsigned char *p = (
unsigned char *)addr;
135signed int le_read16(
const void *addr) {
136 const unsigned char *p = (
const unsigned char *)addr;
137 return p[0] | (p[1] << 8);
140signed int le_read32(
const void *addr) {
141 const unsigned char *p = (
const unsigned char *)addr;
142 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
148EVT_TIMER(TIMER_GARMIN1, GarminProtocolHandler::OnTimerGarmin1)
152 wxEvtHandler *MessageTarget,
155 m_pMainEventHandler = MessageTarget;
156 m_garmin_serial_thread = NULL;
157 m_garmin_usb_thread = NULL;
164 char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
166 char pvt_off[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0};
170 m_usb_handle = INVALID_HANDLE_VALUE;
172 m_bneed_int_reset =
true;
173 m_receive_state = rs_fromintr;
176 wxLogMessage(_T(
"Searching for Garmin DeviceInterface and Device..."));
178 if (!FindGarminDeviceInterface()) {
179 wxLogMessage(_T(
" Find:Is the Garmin USB driver installed?"));
181 if (!ResetGarminUSBDriver())
182 wxLogMessage(_T(
" Reset:Is the Garmin USB Device plugged in?"));
202 TimerGarmin1.SetOwner(
this, TIMER_GARMIN1);
203 TimerGarmin1.Start(100);
206GarminProtocolHandler::~GarminProtocolHandler() {}
208void GarminProtocolHandler::Close(
void) {
215void GarminProtocolHandler::StopSerialThread(
void) {
216 if (m_garmin_serial_thread) {
217 wxLogMessage(_T(
"Stopping Garmin Serial thread"));
218 m_Thread_run_flag = 0;
221 while ((m_Thread_run_flag >= 0) && (tsec--)) {
226 if (m_Thread_run_flag < 0)
227 msg.Printf(_T(
"Stopped in %d sec."), 5 - tsec);
229 msg.Printf(_T(
"Not Stopped after 5 sec."));
233 m_garmin_serial_thread = NULL;
236void GarminProtocolHandler::StopIOThread(
bool b_pause) {
237 if (b_pause) TimerGarmin1.Stop();
239 if (m_garmin_usb_thread) {
240 wxLogMessage(_T(
"Stopping Garmin USB thread"));
241 m_Thread_run_flag = 0;
244 while ((m_Thread_run_flag >= 0) && (tsec--)) {
249 if (m_Thread_run_flag < 0)
250 msg.Printf(_T(
"Stopped in %d sec."), 5 - tsec);
252 msg.Printf(_T(
"Not Stopped after 5 sec."));
256 m_garmin_usb_thread = NULL;
259 if (m_busb && (m_usb_handle != INVALID_HANDLE_VALUE))
260 CloseHandle(m_usb_handle);
261 m_usb_handle = INVALID_HANDLE_VALUE;
267void GarminProtocolHandler::RestartIOThread(
void) {
268 wxLogMessage(_T(
"Restarting Garmin I/O thread"));
269 TimerGarmin1.Start(1000);
272void GarminProtocolHandler::OnTimerGarmin1(wxTimerEvent &event) {
273 char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
280 if (INVALID_HANDLE_VALUE == m_usb_handle) {
281 if (INVALID_HANDLE_VALUE != garmin_usb_start()) {
283 m_receive_state = rs_fromintr;
291 m_Thread_run_flag = 1;
292 m_garmin_usb_thread->Run();
298 TimerGarmin1.Start(1000);
302bool GarminProtocolHandler::ResetGarminUSBDriver() {
303 OSVERSIONINFO version_info;
304 version_info.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
306 if (GetVersionEx(&version_info)) {
307 if (version_info.dwMajorVersion > 5) {
308 if (!IsUserAdmin()) {
310 _T(
" GarminUSBDriver Reset skipped, requires elevated ")
311 _T(
"privileges on Vista and later...."));
318 SP_DEVINFO_DATA devInfo;
319 SP_PROPCHANGE_PARAMS pchange;
321 devs = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
322 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
323 if (devs == INVALID_HANDLE_VALUE)
return false;
325 devInfo.cbSize =
sizeof(devInfo);
326 if (!SetupDiEnumDeviceInfo(devs, 0, &devInfo)) {
327 wxLogMessage(_T(
" GarminUSBDriver Reset0 failed..."));
331 pchange.ClassInstallHeader.cbSize =
sizeof(SP_CLASSINSTALL_HEADER);
332 pchange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
333 pchange.StateChange = DICS_PROPCHANGE;
334 pchange.Scope = DICS_FLAG_CONFIGSPECIFIC;
335 pchange.HwProfile = 0;
337 if (!SetupDiSetClassInstallParams(devs, &devInfo, &pchange.ClassInstallHeader,
339 wxLogMessage(_T(
" GarminUSBDriver Reset1 failed..."));
343 if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devs, &devInfo)) {
344 wxLogMessage(_T(
" GarminUSBDriver Reset2 failed..."));
348 wxLogMessage(_T(
"GarminUSBDriver Reset succeeded."));
353bool GarminProtocolHandler::
354 FindGarminDeviceInterface() {
358 SP_DEVINFO_DATA devInfo;
360 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
361 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
363 if (hdevinfo != INVALID_HANDLE_VALUE) {
364 devInfo.cbSize =
sizeof(devInfo);
365 if (!SetupDiEnumDeviceInfo(hdevinfo, 0, &devInfo)) {
373bool GarminProtocolHandler::IsGarminPlugged() {
377 SP_DEVICE_INTERFACE_DATA infodata;
380 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
381 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
383 if (hdevinfo == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
385 infodata.cbSize =
sizeof(infodata);
387 bool bgarmin_unit_found =
388 (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
391 if (!bgarmin_unit_found)
return false;
393 PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
394 SP_DEVINFO_DATA devinfo;
396 SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
398 pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
399 pdd->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
401 devinfo.cbSize =
sizeof(SP_DEVINFO_DATA);
402 if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
413HANDLE GarminProtocolHandler::garmin_usb_start() {
417 SP_DEVICE_INTERFACE_DATA infodata;
420 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
421 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
423 if (hdevinfo == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
425 infodata.cbSize =
sizeof(infodata);
427 bool bgarmin_unit_found =
428 (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
431 if (!bgarmin_unit_found)
return INVALID_HANDLE_VALUE;
433 wxLogMessage(_T(
"Garmin USB Device Found"));
435 if ((m_usb_handle == INVALID_HANDLE_VALUE) || (m_usb_handle == 0)) {
436 PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
437 SP_DEVINFO_DATA devinfo;
439 SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
441 pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
442 pdd->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
444 devinfo.cbSize =
sizeof(SP_DEVINFO_DATA);
445 if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
448 _T(
" SetupDiGetDeviceInterfaceDetail failed for Garmin Device..."));
450 return INVALID_HANDLE_VALUE;
458 if (m_bneed_int_reset) {
459 ResetGarminUSBDriver();
460 m_bneed_int_reset =
false;
463 m_usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ | GENERIC_WRITE, 0,
464 NULL, OPEN_EXISTING, 0, NULL);
466 if (m_usb_handle == INVALID_HANDLE_VALUE) {
468 msg.Printf(_T(
" (usb) CreateFile on '%s' failed"), pdd->DevicePath);
490 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE,
491 NULL, 0, &m_max_tx_size, GARMIN_USB_INTERRUPT_DATA_SIZE,
493 wxLogMessage(_T(
" Couldn't get Garmin USB packet size."));
494 CloseHandle(m_usb_handle);
495 m_usb_handle = INVALID_HANDLE_VALUE;
496 return INVALID_HANDLE_VALUE;
499 if (!gusb_syncup()) {
500 CloseHandle(m_usb_handle);
501 m_usb_handle = INVALID_HANDLE_VALUE;
507bool GarminProtocolHandler::gusb_syncup(
void) {
508 static int unit_number;
509 static const char oinit[12] = {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0,
518 m_receive_state = rs_fromintr;
520 for (i = 0; i < 25; i++) {
521 le_write16(&iresp.gusb_pkt.pkt_id[0], 0);
522 le_write32(&iresp.gusb_pkt.datasz[0], 0);
523 le_write32(&iresp.gusb_pkt.databuf[0], 0);
526 gusb_cmd_get(&iresp,
sizeof(iresp));
528 if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) &&
529 (le_read32(iresp.gusb_pkt.datasz) == 4)) {
538 wxLogMessage(_T(
"Successful Garmin USB syncup."));
544 wxLogMessage(_T(
" Unable to establish Garmin USB syncup."));
552 unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
554 rv = gusb_win_send(opkt, sz);
564 if (sz && !(sz % m_max_tx_size)) {
565 wxLogMessage(_T(
"win_send_call1"));
566 gusb_win_send(opkt, 0);
567 wxLogMessage(_T(
"win_send_ret1"));
575 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
576 int orig_receive_state;
578 orig_receive_state = m_receive_state;
579 switch (m_receive_state) {
581 rv = gusb_win_get(ibuf, sz);
584 rv = gusb_win_get_bulk(ibuf, sz);
589 if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
590 m_receive_state = rs_frombulk;
601 if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
602 m_receive_state = rs_fromintr;
609 DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
610 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
617 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
618 buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
626 if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE)
break;
635 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
637 n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);
645 unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
651 WriteFile(m_usb_handle, obuf, sz, &rsz, NULL);
652 int err = GetLastError();
727 DataStream *GParentStream,
728 wxEvtHandler *MessageTarget,
731 m_parent_stream = GParentStream;
732 m_pMessageTarget = MessageTarget;
738GARMIN_Serial_Thread::~GARMIN_Serial_Thread(
void) {}
741void *GARMIN_Serial_Thread::Entry() {
744 m_bconnected =
false;
746 bool not_done =
true;
747 wxDateTime last_rx_time;
752 while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
758 while (!m_bdetected) {
760 int v_init = Garmin_GPS_Init(m_port);
762 for (
int i = 0; i < 4; i++) {
764 if (TestDestroy())
goto thread_exit;
765 if (!m_parent->m_Thread_run_flag)
goto thread_exit;
775 if (!Garmin_GPS_PVT_On(m_port)) {
777 m_bconnected =
false;
784 int ret = Garmin_GPS_GetPVT(&ppvt);
786 if ((mypvt.fix) >= 2 && (mypvt.fix <= 5)) {
790 oNMEA0183.TalkerID = _T (
"GM" );
793 oNMEA0183.Rmc.Position.Latitude.Set(-mypvt.lat, _T (
"S" ));
795 oNMEA0183.Rmc.Position.Latitude.Set(mypvt.lat, _T (
"N" ));
798 oNMEA0183.Rmc.Position.Longitude.Set(-mypvt.lon, _T (
"W" ));
800 oNMEA0183.Rmc.Position.Longitude.Set(mypvt.lon, _T (
"E" ));
804 sqrt(mypvt.east * mypvt.east + mypvt.north * mypvt.north) * 3.6 /
806 oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
809 double course = atan2(mypvt.east, mypvt.north);
810 if (course < 0) course += 2 * PI;
811 double cog = course * 180 / PI;
812 oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
814 oNMEA0183.Rmc.IsDataValid = NTrue;
816 oNMEA0183.Rmc.Write(snt);
817 wxString message = snt.Sentence;
819 if (m_pMessageTarget) {
820 OCPN_DataStreamEvent Nevent(wxEVT_OCPN_DATASTREAM, 0);
821 wxCharBuffer buffer = message.ToUTF8();
823 Nevent.SetNMEAString(buffer.data());
824 Nevent.SetStream(m_parent_stream);
826 m_pMessageTarget->AddPendingEvent(Nevent);
830 last_rx_time = wxDateTime::Now();
833 wxDateTime now = wxDateTime::Now();
834 if (last_rx_time.IsValid()) {
835 wxTimeSpan delta_time = now - last_rx_time;
836 if (delta_time.GetSeconds() > 5) {
838 m_bconnected =
false;
839 Garmin_GPS_ClosePortVerify();
848 Garmin_GPS_PVT_Off(m_port);
849 Garmin_GPS_ClosePortVerify();
853 while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
865 m_parent->m_Thread_run_flag = -1;
876 DataStream *GParentStream,
877 wxEvtHandler *MessageTarget,
878 unsigned int device_handle,
879 size_t max_tx_size) {
881 m_parent_stream = GParentStream;
882 m_pMessageTarget = MessageTarget;
883 m_max_tx_size = max_tx_size;
886 m_usb_handle = (HANDLE)(device_handle & 0xffff);
892GARMIN_USB_Thread::~GARMIN_USB_Thread() {}
894void *GARMIN_USB_Thread::Entry() {
896 int n_short_read = 0;
897 m_receive_state = rs_fromintr;
900 while (m_parent->m_Thread_run_flag > 0) {
901 if (TestDestroy())
goto thread_prexit;
905 int nr = gusb_cmd_get(&iresp,
sizeof(iresp));
907 if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_SDR)
909 unsigned char *t = (
unsigned char *)&(iresp.gusb_pkt.databuf[0]);
910 for (
int i = 0; i < 12; i++) {
911 m_sat_data[i].svid = *t++;
912 m_sat_data[i].snr = ((*t) << 8) + *(t + 1);
914 m_sat_data[i].elev = *t++;
915 m_sat_data[i].azmth = ((*t) << 8) + *(t + 1);
917 m_sat_data[i].status = *t++;
921 for (
int i = 0; i < 12; i++) {
922 if (m_sat_data[i].svid != 255) m_nSats++;
928 oNMEA0183.TalkerID = _T (
"GM" );
929 oNMEA0183.Gsv.SatsInView = m_nSats;
931 oNMEA0183.Gsv.Write(snt);
932 wxString message = snt.Sentence;
934 if (m_pMessageTarget) {
935 OCPN_DataStreamEvent Nevent(wxEVT_OCPN_DATASTREAM, 0);
936 wxCharBuffer buffer = message.ToUTF8();
938 Nevent.SetNMEAString(buffer.data());
939 Nevent.SetStream(m_parent_stream);
941 m_pMessageTarget->AddPendingEvent(Nevent);
946 if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_PVT)
951 if ((ppvt->fix) >= 2 && (ppvt->fix <= 5)) {
955 oNMEA0183.TalkerID = _T (
"GM" );
958 oNMEA0183.Rmc.Position.Latitude.Set(-ppvt->lat * 180. / PI,
961 oNMEA0183.Rmc.Position.Latitude.Set(ppvt->lat * 180. / PI,
965 oNMEA0183.Rmc.Position.Longitude.Set(-ppvt->lon * 180. / PI,
968 oNMEA0183.Rmc.Position.Longitude.Set(ppvt->lon * 180. / PI,
972 double sog = sqrt(ppvt->east * ppvt->east + ppvt->north * ppvt->north) *
974 oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
977 double course = atan2(ppvt->east, ppvt->north);
978 if (course < 0) course += 2 * PI;
979 double cog = course * 180 / PI;
980 oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
982 oNMEA0183.Rmc.IsDataValid = NTrue;
984 oNMEA0183.Rmc.Write(snt);
985 wxString message = snt.Sentence;
987 if (m_pMessageTarget) {
988 OCPN_DataStreamEvent Nevent(wxEVT_OCPN_DATASTREAM, 0);
989 wxCharBuffer buffer = message.ToUTF8();
991 Nevent.SetNMEAString(buffer.data());
992 Nevent.SetStream(m_parent_stream);
994 m_pMessageTarget->AddPendingEvent(Nevent);
1001 m_parent->m_Thread_run_flag = -1;
1007 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
1008 int orig_receive_state;
1010 orig_receive_state = m_receive_state;
1011 switch (m_receive_state) {
1013 rv = gusb_win_get(ibuf, sz);
1016 rv = gusb_win_get_bulk(ibuf, sz);
1021 if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
1022 m_receive_state = rs_frombulk;
1033 if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
1034 m_receive_state = rs_fromintr;
1043 DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
1044 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
1050 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
1051 buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
1059 if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE)
break;
1071 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
1073 n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);