41#include <netinet/tcp.h>
50#include <wx/datetime.h>
54#include <wx/tokenzr.h>
65#include "model/config_vars.h"
67#include "model/garmin_wrapper.h"
68#include "model/garmin_protocol_mgr.h"
69#include "model/nmea_ctx_factory.h"
73#include "androidUTIL.h"
77static const long long lNaN = 0xfff8000000000000;
78#define NAN (*(double *)&lNaN)
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);
124EVT_TIMER(TIMER_GARMIN1, GarminProtocolHandler::OnTimerGarmin1)
128 SendMsgFunc send_msg_func,
131 m_send_msg_func = send_msg_func;
132 m_garmin_serial_thread = NULL;
133 m_garmin_usb_thread = NULL;
140 char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
142 char pvt_off[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0};
146 m_usb_handle = INVALID_HANDLE_VALUE;
148 m_bneed_int_reset =
true;
149 m_receive_state = rs_fromintr;
152 wxLogMessage(_T(
"Searching for Garmin DeviceInterface and Device..."));
154 if (!FindGarminDeviceInterface()) {
155 wxLogMessage(_T(
" Find:Is the Garmin USB driver installed?"));
157 if (!ResetGarminUSBDriver())
158 wxLogMessage(_T(
" Reset:Is the Garmin USB Device plugged in?"));
168 m_garmin_serial_thread =
171 m_Thread_run_flag = 1;
172 m_garmin_serial_thread->Run();
175 TimerGarmin1.SetOwner(
this, TIMER_GARMIN1);
176 TimerGarmin1.Start(100);
179GarminProtocolHandler::~GarminProtocolHandler() {}
181void GarminProtocolHandler::Close(
void) {
188void GarminProtocolHandler::StopSerialThread(
void) {
189 if (m_garmin_serial_thread) {
190 wxLogMessage(_T(
"Stopping Garmin Serial thread"));
191 m_Thread_run_flag = 0;
194 while ((m_Thread_run_flag >= 0) && (tsec--)) {
199 if (m_Thread_run_flag < 0)
200 msg.Printf(_T(
"Stopped in %d sec."), 5 - tsec);
202 msg.Printf(_T(
"Not Stopped after 5 sec."));
206 m_garmin_serial_thread = NULL;
209void GarminProtocolHandler::StopIOThread(
bool b_pause) {
210 if (b_pause) TimerGarmin1.Stop();
212 if (m_garmin_usb_thread) {
213 wxLogMessage(_T(
"Stopping Garmin USB thread"));
214 m_Thread_run_flag = 0;
217 while ((m_Thread_run_flag >= 0) && (tsec--)) {
222 if (m_Thread_run_flag < 0)
223 msg.Printf(_T(
"Stopped in %d sec."), 5 - tsec);
225 msg.Printf(_T(
"Not Stopped after 5 sec."));
229 m_garmin_usb_thread = NULL;
232 if (m_busb && (m_usb_handle != INVALID_HANDLE_VALUE))
233 CloseHandle(m_usb_handle);
234 m_usb_handle = INVALID_HANDLE_VALUE;
240void GarminProtocolHandler::RestartIOThread(
void) {
241 wxLogMessage(_T(
"Restarting Garmin I/O thread"));
242 TimerGarmin1.Start(1000);
245void GarminProtocolHandler::OnTimerGarmin1(wxTimerEvent &event) {
246 char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
253 if (INVALID_HANDLE_VALUE == m_usb_handle) {
254 if (INVALID_HANDLE_VALUE != garmin_usb_start()) {
256 m_receive_state = rs_fromintr;
257 gusb_cmd_send((
const garmin_usb_packet *)pvt_on,
sizeof(pvt_on));
261 this, m_send_msg_func, (wxIntPtr)m_usb_handle, m_max_tx_size);
262 m_Thread_run_flag = 1;
263 m_garmin_usb_thread->Run();
269 TimerGarmin1.Start(1000);
273bool GarminProtocolHandler::ResetGarminUSBDriver() {
274 OSVERSIONINFO version_info;
275 version_info.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
277 if (GetVersionEx(&version_info)) {
278 if (version_info.dwMajorVersion > 5) {
279 if (!IsUserAdmin()) {
281 _T(
" GarminUSBDriver Reset skipped, requires elevated ")
282 _T(
"privileges on Vista and later...."));
289 SP_DEVINFO_DATA devInfo;
290 SP_PROPCHANGE_PARAMS pchange;
292 devs = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
293 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
294 if (devs == INVALID_HANDLE_VALUE)
return false;
296 devInfo.cbSize =
sizeof(devInfo);
297 if (!SetupDiEnumDeviceInfo(devs, 0, &devInfo)) {
298 wxLogMessage(_T(
" GarminUSBDriver Reset0 failed..."));
302 pchange.ClassInstallHeader.cbSize =
sizeof(SP_CLASSINSTALL_HEADER);
303 pchange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
304 pchange.StateChange = DICS_PROPCHANGE;
305 pchange.Scope = DICS_FLAG_CONFIGSPECIFIC;
306 pchange.HwProfile = 0;
308 if (!SetupDiSetClassInstallParams(devs, &devInfo, &pchange.ClassInstallHeader,
310 wxLogMessage(_T(
" GarminUSBDriver Reset1 failed..."));
314 if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devs, &devInfo)) {
315 wxLogMessage(_T(
" GarminUSBDriver Reset2 failed..."));
319 wxLogMessage(_T(
"GarminUSBDriver Reset succeeded."));
324bool GarminProtocolHandler::
325 FindGarminDeviceInterface() {
329 SP_DEVINFO_DATA devInfo;
331 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
332 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
334 if (hdevinfo != INVALID_HANDLE_VALUE) {
335 devInfo.cbSize =
sizeof(devInfo);
336 if (!SetupDiEnumDeviceInfo(hdevinfo, 0, &devInfo)) {
344bool GarminProtocolHandler::IsGarminPlugged() {
348 SP_DEVICE_INTERFACE_DATA infodata;
351 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
352 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
354 if (hdevinfo == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
356 infodata.cbSize =
sizeof(infodata);
358 bool bgarmin_unit_found =
359 (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
362 if (!bgarmin_unit_found)
return false;
364 PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
365 SP_DEVINFO_DATA devinfo;
367 SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
369 pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
370 pdd->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
372 devinfo.cbSize =
sizeof(SP_DEVINFO_DATA);
373 if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
384HANDLE GarminProtocolHandler::garmin_usb_start() {
388 SP_DEVICE_INTERFACE_DATA infodata;
391 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
392 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
394 if (hdevinfo == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
396 infodata.cbSize =
sizeof(infodata);
398 bool bgarmin_unit_found =
399 (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
402 if (!bgarmin_unit_found)
return INVALID_HANDLE_VALUE;
404 wxLogMessage(_T(
"Garmin USB Device Found"));
406 if ((m_usb_handle == INVALID_HANDLE_VALUE) || (m_usb_handle == 0)) {
407 PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
408 SP_DEVINFO_DATA devinfo;
410 SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
412 pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
413 pdd->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
415 devinfo.cbSize =
sizeof(SP_DEVINFO_DATA);
416 if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
419 _T(
" SetupDiGetDeviceInterfaceDetail failed for Garmin Device..."));
421 return INVALID_HANDLE_VALUE;
429 if (m_bneed_int_reset) {
430 ResetGarminUSBDriver();
431 m_bneed_int_reset =
false;
434 m_usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ | GENERIC_WRITE, 0,
435 NULL, OPEN_EXISTING, 0, NULL);
437 if (m_usb_handle == INVALID_HANDLE_VALUE) {
439 msg.Printf(_T(
" (usb) CreateFile on '%s' failed"), pdd->DevicePath);
461 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE,
462 NULL, 0, &m_max_tx_size, GARMIN_USB_INTERRUPT_DATA_SIZE,
464 wxLogMessage(_T(
" Couldn't get Garmin USB packet size."));
465 CloseHandle(m_usb_handle);
466 m_usb_handle = INVALID_HANDLE_VALUE;
467 return INVALID_HANDLE_VALUE;
470 if (!gusb_syncup()) {
471 CloseHandle(m_usb_handle);
472 m_usb_handle = INVALID_HANDLE_VALUE;
478bool GarminProtocolHandler::gusb_syncup(
void) {
479 static int unit_number;
480 static const char oinit[12] = {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0,
482 garmin_usb_packet iresp;
489 m_receive_state = rs_fromintr;
491 for (i = 0; i < 25; i++) {
492 le_write16(&iresp.gusb_pkt.pkt_id[0], 0);
493 le_write32(&iresp.gusb_pkt.datasz[0], 0);
494 le_write32(&iresp.gusb_pkt.databuf[0], 0);
496 if (gusb_cmd_send((
const garmin_usb_packet *)oinit,
sizeof(oinit))) {
497 gusb_cmd_get(&iresp,
sizeof(iresp));
499 if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) &&
500 (le_read32(iresp.gusb_pkt.datasz) == 4)) {
509 wxLogMessage(_T(
"Successful Garmin USB syncup."));
515 wxLogMessage(_T(
" Unable to establish Garmin USB syncup."));
519int GarminProtocolHandler::gusb_cmd_send(
const garmin_usb_packet *opkt,
523 unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
525 rv = gusb_win_send(opkt, sz);
535 if (sz && !(sz % m_max_tx_size)) {
536 wxLogMessage(_T(
"win_send_call1"));
537 gusb_win_send(opkt, 0);
538 wxLogMessage(_T(
"win_send_ret1"));
544int GarminProtocolHandler::gusb_cmd_get(garmin_usb_packet *ibuf,
size_t sz) {
546 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
547 int orig_receive_state;
549 orig_receive_state = m_receive_state;
550 switch (m_receive_state) {
552 rv = gusb_win_get(ibuf, sz);
555 rv = gusb_win_get_bulk(ibuf, sz);
560 if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
561 m_receive_state = rs_frombulk;
572 if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
573 m_receive_state = rs_fromintr;
579int GarminProtocolHandler::gusb_win_get(garmin_usb_packet *ibuf,
size_t sz) {
580 DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
581 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
588 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
589 buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
597 if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE)
break;
602int GarminProtocolHandler::gusb_win_get_bulk(garmin_usb_packet *ibuf,
606 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
608 n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);
613int GarminProtocolHandler::gusb_win_send(
const garmin_usb_packet *opkt,
616 unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
622 WriteFile(m_usb_handle, obuf, sz, &rsz, NULL);
623 int err = GetLastError();
696 SendMsgFunc send_msg_func,
699 m_send_msg_func = send_msg_func;
705GARMIN_Serial_Thread::~GARMIN_Serial_Thread(
void) {}
708void *GARMIN_Serial_Thread::Entry() {
711 m_bconnected =
false;
713 bool not_done =
true;
714 wxDateTime last_rx_time;
719 while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
725 while (!m_bdetected) {
727 int v_init = Garmin_GPS_Init(m_port);
729 for (
int i = 0; i < 4; i++) {
731 if (TestDestroy())
goto thread_exit;
732 if (!m_parent->m_Thread_run_flag)
goto thread_exit;
742 if (!Garmin_GPS_PVT_On(m_port)) {
744 m_bconnected =
false;
751 int ret = Garmin_GPS_GetPVT(&ppvt);
753 if ((mypvt.fix) >= 2 && (mypvt.fix <= 5)) {
756 NMEA0183 oNMEA0183(NmeaCtxFactory());
757 oNMEA0183.TalkerID = _T (
"GM" );
760 oNMEA0183.Rmc.Position.Latitude.Set(-mypvt.lat, _T (
"S" ));
762 oNMEA0183.Rmc.Position.Latitude.Set(mypvt.lat, _T (
"N" ));
765 oNMEA0183.Rmc.Position.Longitude.Set(-mypvt.lon, _T (
"W" ));
767 oNMEA0183.Rmc.Position.Longitude.Set(mypvt.lon, _T (
"E" ));
771 sqrt(mypvt.east * mypvt.east + mypvt.north * mypvt.north) * 3.6 /
773 oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
776 double course = atan2(mypvt.east, mypvt.north);
777 if (course < 0) course += 2 * PI;
778 double cog = course * 180 / PI;
779 oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
781 oNMEA0183.Rmc.IsDataValid = NTrue;
783 oNMEA0183.Rmc.Write(snt);
786 auto msg = snt.Sentence.ToStdString();
787 m_send_msg_func(std::vector<unsigned char>(msg.begin(), msg.end()));
789 last_rx_time = wxDateTime::Now();
792 wxDateTime now = wxDateTime::Now();
793 if (last_rx_time.IsValid()) {
794 wxTimeSpan delta_time = now - last_rx_time;
795 if (delta_time.GetSeconds() > 5) {
797 m_bconnected =
false;
798 Garmin_GPS_ClosePortVerify();
807 Garmin_GPS_PVT_Off(m_port);
808 Garmin_GPS_ClosePortVerify();
810 while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
822 m_parent->m_Thread_run_flag = -1;
831 SendMsgFunc send_msg_func,
832 unsigned int device_handle,
833 size_t max_tx_size) {
835 m_send_msg_func = send_msg_func;
836 m_max_tx_size = max_tx_size;
839 m_usb_handle = (HANDLE)(device_handle & 0xffff);
845GARMIN_USB_Thread::~GARMIN_USB_Thread() {}
847void *GARMIN_USB_Thread::Entry() {
848 garmin_usb_packet iresp = {{0}};
849 int n_short_read = 0;
850 m_receive_state = rs_fromintr;
853 while (m_parent->m_Thread_run_flag > 0) {
854 if (TestDestroy())
goto thread_prexit;
858 int nr = gusb_cmd_get(&iresp,
sizeof(iresp));
860 if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_SDR)
862 unsigned char *t = (
unsigned char *)&(iresp.gusb_pkt.databuf[0]);
863 for (
int i = 0; i < 12; i++) {
864 m_sat_data[i].svid = *t++;
865 m_sat_data[i].snr = ((*t) << 8) + *(t + 1);
867 m_sat_data[i].elev = *t++;
868 m_sat_data[i].azmth = ((*t) << 8) + *(t + 1);
870 m_sat_data[i].status = *t++;
874 for (
int i = 0; i < 12; i++) {
875 if (m_sat_data[i].svid != 255) m_nSats++;
880 NMEA0183 oNMEA0183(NmeaCtxFactory());
881 oNMEA0183.TalkerID = _T (
"GM" );
882 oNMEA0183.Gsv.SatsInView = m_nSats;
884 oNMEA0183.Gsv.Write(snt);
885 wxString msg = snt.Sentence;
888 m_send_msg_func(std::vector<unsigned char>(msg.begin(), msg.end()));
891 if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_PVT)
896 if ((ppvt->fix) >= 2 && (ppvt->fix <= 5)) {
899 NMEA0183 oNMEA0183(NmeaCtxFactory());
900 oNMEA0183.TalkerID = _T (
"GM" );
903 oNMEA0183.Rmc.Position.Latitude.Set(-ppvt->lat * 180. / PI,
906 oNMEA0183.Rmc.Position.Latitude.Set(ppvt->lat * 180. / PI,
910 oNMEA0183.Rmc.Position.Longitude.Set(-ppvt->lon * 180. / PI,
913 oNMEA0183.Rmc.Position.Longitude.Set(ppvt->lon * 180. / PI,
917 double sog = sqrt(ppvt->east * ppvt->east + ppvt->north * ppvt->north) *
919 oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
922 double course = atan2(ppvt->east, ppvt->north);
923 if (course < 0) course += 2 * PI;
924 double cog = course * 180 / PI;
925 oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
927 oNMEA0183.Rmc.IsDataValid = NTrue;
929 oNMEA0183.Rmc.Write(snt);
930 wxString msg = snt.Sentence;
931 m_send_msg_func(std::vector<unsigned char>(msg.begin(), msg.end()));
936 m_parent->m_Thread_run_flag = -1;
940int GARMIN_USB_Thread::gusb_cmd_get(garmin_usb_packet *ibuf,
size_t sz) {
942 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
943 int orig_receive_state;
945 orig_receive_state = m_receive_state;
946 switch (m_receive_state) {
948 rv = gusb_win_get(ibuf, sz);
951 rv = gusb_win_get_bulk(ibuf, sz);
956 if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
957 m_receive_state = rs_frombulk;
968 if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
969 m_receive_state = rs_fromintr;
975int GARMIN_USB_Thread::gusb_win_get(garmin_usb_packet *ibuf,
size_t sz) {
978 DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
979 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
985 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
986 buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
994 if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE)
break;
1001int GARMIN_USB_Thread::gusb_win_get_bulk(garmin_usb_packet *ibuf,
size_t sz) {
1006 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
1008 n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);