40 #include <arpa/inet.h>
41 #include <netinet/tcp.h>
44 #include <wx/wxprec.h>
50 #include <wx/datetime.h>
53 #include <wx/string.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"
78 static const long long lNaN = 0xfff8000000000000;
79 #define NAN (*(double *)&lNaN)
82 #define N_DOG_TIMEOUT 5
86 DEFINE_GUID(GARMIN_GUID1, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b,
87 0xba, 0xe7, 0x22, 0xc0);
97 BOOL IsUserAdmin(VOID)
108 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
109 PSID AdministratorsGroup;
110 b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
111 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
112 &AdministratorsGroup);
114 if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) {
117 FreeSid(AdministratorsGroup);
126 EVT_TIMER(TIMER_GARMIN1, GarminProtocolHandler::OnTimerGarmin1)
130 wxEvtHandler *MessageTarget,
133 m_pMainEventHandler = MessageTarget;
134 m_garmin_serial_thread = NULL;
135 m_garmin_usb_thread = NULL;
142 char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
144 char pvt_off[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0};
148 m_usb_handle = INVALID_HANDLE_VALUE;
150 m_bneed_int_reset =
true;
151 m_receive_state = rs_fromintr;
154 wxLogMessage(_T(
"Searching for Garmin DeviceInterface and Device..."));
156 if (!FindGarminDeviceInterface()) {
157 wxLogMessage(_T(
" Find:Is the Garmin USB driver installed?"));
159 if (!ResetGarminUSBDriver())
160 wxLogMessage(_T(
" Reset:Is the Garmin USB Device plugged in?"));
170 m_garmin_serial_thread =
173 m_Thread_run_flag = 1;
174 m_garmin_serial_thread->Run();
177 TimerGarmin1.SetOwner(
this, TIMER_GARMIN1);
178 TimerGarmin1.Start(100);
181 GarminProtocolHandler::~GarminProtocolHandler() {}
183 void GarminProtocolHandler::Close(
void) {
190 void GarminProtocolHandler::StopSerialThread(
void) {
191 if (m_garmin_serial_thread) {
192 wxLogMessage(_T(
"Stopping Garmin Serial thread"));
193 m_Thread_run_flag = 0;
196 while ((m_Thread_run_flag >= 0) && (tsec--)) {
201 if (m_Thread_run_flag < 0)
202 msg.Printf(_T(
"Stopped in %d sec."), 5 - tsec);
204 msg.Printf(_T(
"Not Stopped after 5 sec."));
208 m_garmin_serial_thread = NULL;
211 void GarminProtocolHandler::StopIOThread(
bool b_pause) {
212 if (b_pause) TimerGarmin1.Stop();
214 if (m_garmin_usb_thread) {
215 wxLogMessage(_T(
"Stopping Garmin USB thread"));
216 m_Thread_run_flag = 0;
219 while ((m_Thread_run_flag >= 0) && (tsec--)) {
224 if (m_Thread_run_flag < 0)
225 msg.Printf(_T(
"Stopped in %d sec."), 5 - tsec);
227 msg.Printf(_T(
"Not Stopped after 5 sec."));
231 m_garmin_usb_thread = NULL;
234 if (m_busb && (m_usb_handle != INVALID_HANDLE_VALUE))
235 CloseHandle(m_usb_handle);
236 m_usb_handle = INVALID_HANDLE_VALUE;
242 void GarminProtocolHandler::RestartIOThread(
void) {
243 wxLogMessage(_T(
"Restarting Garmin I/O thread"));
244 TimerGarmin1.Start(1000);
247 void GarminProtocolHandler::OnTimerGarmin1(wxTimerEvent &event) {
248 char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
255 if (INVALID_HANDLE_VALUE == m_usb_handle) {
256 if (INVALID_HANDLE_VALUE != garmin_usb_start()) {
258 m_receive_state = rs_fromintr;
259 gusb_cmd_send((
const garmin_usb_packet *)pvt_on,
sizeof(pvt_on));
262 m_garmin_usb_thread =
264 (wxIntPtr)m_usb_handle, m_max_tx_size);
265 m_Thread_run_flag = 1;
266 m_garmin_usb_thread->Run();
272 TimerGarmin1.Start(1000);
276 bool GarminProtocolHandler::ResetGarminUSBDriver() {
277 OSVERSIONINFO version_info;
278 version_info.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
280 if (GetVersionEx(&version_info)) {
281 if (version_info.dwMajorVersion > 5) {
282 if (!IsUserAdmin()) {
284 _T(
" GarminUSBDriver Reset skipped, requires elevated ")
285 _T(
"privileges on Vista and later...."));
292 SP_DEVINFO_DATA devInfo;
293 SP_PROPCHANGE_PARAMS pchange;
295 devs = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
296 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
297 if (devs == INVALID_HANDLE_VALUE)
return false;
299 devInfo.cbSize =
sizeof(devInfo);
300 if (!SetupDiEnumDeviceInfo(devs, 0, &devInfo)) {
301 wxLogMessage(_T(
" GarminUSBDriver Reset0 failed..."));
305 pchange.ClassInstallHeader.cbSize =
sizeof(SP_CLASSINSTALL_HEADER);
306 pchange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
307 pchange.StateChange = DICS_PROPCHANGE;
308 pchange.Scope = DICS_FLAG_CONFIGSPECIFIC;
309 pchange.HwProfile = 0;
311 if (!SetupDiSetClassInstallParams(devs, &devInfo, &pchange.ClassInstallHeader,
313 wxLogMessage(_T(
" GarminUSBDriver Reset1 failed..."));
317 if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devs, &devInfo)) {
318 wxLogMessage(_T(
" GarminUSBDriver Reset2 failed..."));
322 wxLogMessage(_T(
"GarminUSBDriver Reset succeeded."));
327 bool GarminProtocolHandler::
328 FindGarminDeviceInterface() {
332 SP_DEVINFO_DATA devInfo;
334 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
335 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
337 if (hdevinfo != INVALID_HANDLE_VALUE) {
338 devInfo.cbSize =
sizeof(devInfo);
339 if (!SetupDiEnumDeviceInfo(hdevinfo, 0, &devInfo)) {
347 bool GarminProtocolHandler::IsGarminPlugged() {
351 SP_DEVICE_INTERFACE_DATA infodata;
354 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
355 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
357 if (hdevinfo == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
359 infodata.cbSize =
sizeof(infodata);
361 bool bgarmin_unit_found =
362 (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
365 if (!bgarmin_unit_found)
return false;
367 PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
368 SP_DEVINFO_DATA devinfo;
370 SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
372 pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
373 pdd->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
375 devinfo.cbSize =
sizeof(SP_DEVINFO_DATA);
376 if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
387 HANDLE GarminProtocolHandler::garmin_usb_start() {
391 SP_DEVICE_INTERFACE_DATA infodata;
394 hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
395 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
397 if (hdevinfo == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
399 infodata.cbSize =
sizeof(infodata);
401 bool bgarmin_unit_found =
402 (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
405 if (!bgarmin_unit_found)
return INVALID_HANDLE_VALUE;
407 wxLogMessage(_T(
"Garmin USB Device Found"));
409 if ((m_usb_handle == INVALID_HANDLE_VALUE) || (m_usb_handle == 0)) {
410 PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
411 SP_DEVINFO_DATA devinfo;
413 SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
415 pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
416 pdd->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
418 devinfo.cbSize =
sizeof(SP_DEVINFO_DATA);
419 if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
422 _T(
" SetupDiGetDeviceInterfaceDetail failed for Garmin Device..."));
424 return INVALID_HANDLE_VALUE;
432 if (m_bneed_int_reset) {
433 ResetGarminUSBDriver();
434 m_bneed_int_reset =
false;
437 m_usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ | GENERIC_WRITE, 0,
438 NULL, OPEN_EXISTING, 0, NULL);
440 if (m_usb_handle == INVALID_HANDLE_VALUE) {
442 msg.Printf(_T(
" (usb) CreateFile on '%s' failed"), pdd->DevicePath);
464 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE,
465 NULL, 0, &m_max_tx_size, GARMIN_USB_INTERRUPT_DATA_SIZE,
467 wxLogMessage(_T(
" Couldn't get Garmin USB packet size."));
468 CloseHandle(m_usb_handle);
469 m_usb_handle = INVALID_HANDLE_VALUE;
470 return INVALID_HANDLE_VALUE;
473 if (!gusb_syncup()) {
474 CloseHandle(m_usb_handle);
475 m_usb_handle = INVALID_HANDLE_VALUE;
481 bool GarminProtocolHandler::gusb_syncup(
void) {
482 static int unit_number;
483 static const char oinit[12] = {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0,
485 garmin_usb_packet iresp;
492 m_receive_state = rs_fromintr;
494 for (i = 0; i < 25; i++) {
495 le_write16(&iresp.gusb_pkt.pkt_id[0], 0);
496 le_write32(&iresp.gusb_pkt.datasz[0], 0);
497 le_write32(&iresp.gusb_pkt.databuf[0], 0);
499 if (gusb_cmd_send((
const garmin_usb_packet *)oinit,
sizeof(oinit))) {
500 gusb_cmd_get(&iresp,
sizeof(iresp));
502 if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) &&
503 (le_read32(iresp.gusb_pkt.datasz) == 4)) {
512 wxLogMessage(_T(
"Successful Garmin USB syncup."));
518 wxLogMessage(_T(
" Unable to establish Garmin USB syncup."));
522 int GarminProtocolHandler::gusb_cmd_send(
const garmin_usb_packet *opkt,
526 unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
528 rv = gusb_win_send(opkt, sz);
538 if (sz && !(sz % m_max_tx_size)) {
539 wxLogMessage(_T(
"win_send_call1"));
540 gusb_win_send(opkt, 0);
541 wxLogMessage(_T(
"win_send_ret1"));
547 int GarminProtocolHandler::gusb_cmd_get(garmin_usb_packet *ibuf,
size_t sz) {
549 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
550 int orig_receive_state;
552 orig_receive_state = m_receive_state;
553 switch (m_receive_state) {
555 rv = gusb_win_get(ibuf, sz);
558 rv = gusb_win_get_bulk(ibuf, sz);
563 if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
564 m_receive_state = rs_frombulk;
575 if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
576 m_receive_state = rs_fromintr;
582 int GarminProtocolHandler::gusb_win_get(garmin_usb_packet *ibuf,
size_t sz) {
583 DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
584 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
591 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
592 buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
600 if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE)
break;
605 int GarminProtocolHandler::gusb_win_get_bulk(garmin_usb_packet *ibuf,
609 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
611 n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);
616 int GarminProtocolHandler::gusb_win_send(
const garmin_usb_packet *opkt,
619 unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
625 WriteFile(m_usb_handle, obuf, sz, &rsz, NULL);
626 int err = GetLastError();
699 wxEvtHandler *MessageTarget,
702 m_pMessageTarget = MessageTarget;
708 GARMIN_Serial_Thread::~GARMIN_Serial_Thread(
void) {}
711 void *GARMIN_Serial_Thread::Entry() {
714 m_bconnected =
false;
716 bool not_done =
true;
717 wxDateTime last_rx_time;
719 #ifdef USE_GARMINHOST
722 while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
728 while (!m_bdetected) {
730 int v_init = Garmin_GPS_Init(m_port);
732 for (
int i = 0; i < 4; i++) {
734 if (TestDestroy())
goto thread_exit;
735 if (!m_parent->m_Thread_run_flag)
goto thread_exit;
745 if (!Garmin_GPS_PVT_On(m_port)) {
747 m_bconnected =
false;
754 int ret = Garmin_GPS_GetPVT(&ppvt);
756 if ((mypvt.fix) >= 2 && (mypvt.fix <= 5)) {
759 NMEA0183 oNMEA0183(NmeaCtxFactory());
760 oNMEA0183.TalkerID = _T (
"GM" );
763 oNMEA0183.Rmc.Position.Latitude.Set(-mypvt.lat, _T (
"S" ));
765 oNMEA0183.Rmc.Position.Latitude.Set(mypvt.lat, _T (
"N" ));
768 oNMEA0183.Rmc.Position.Longitude.Set(-mypvt.lon, _T (
"W" ));
770 oNMEA0183.Rmc.Position.Longitude.Set(mypvt.lon, _T (
"E" ));
774 sqrt(mypvt.east * mypvt.east + mypvt.north * mypvt.north) * 3.6 /
776 oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
779 double course = atan2(mypvt.east, mypvt.north);
780 if (course < 0) course += 2 * PI;
781 double cog = course * 180 / PI;
782 oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
784 oNMEA0183.Rmc.IsDataValid = NTrue;
786 oNMEA0183.Rmc.Write(snt);
787 wxString message = snt.Sentence;
790 auto buffer = std::make_shared<std::vector<unsigned char>>();
791 std::vector<unsigned char>* vec = buffer.get();
792 for (
unsigned int i=0 ; i < message.Length() ; i++){
793 vec->push_back(message[i]);
795 if (m_pMessageTarget) {
797 Nevent.SetPayload(buffer);
798 m_pMessageTarget->AddPendingEvent(Nevent);
801 last_rx_time = wxDateTime::Now();
804 wxDateTime now = wxDateTime::Now();
805 if (last_rx_time.IsValid()) {
806 wxTimeSpan delta_time = now - last_rx_time;
807 if (delta_time.GetSeconds() > 5) {
809 m_bconnected =
false;
810 Garmin_GPS_ClosePortVerify();
819 Garmin_GPS_PVT_Off(m_port);
820 Garmin_GPS_ClosePortVerify();
822 while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
834 m_parent->m_Thread_run_flag = -1;
843 wxEvtHandler *MessageTarget,
844 unsigned int device_handle,
845 size_t max_tx_size) {
847 m_pMessageTarget = MessageTarget;
848 m_max_tx_size = max_tx_size;
851 m_usb_handle = (HANDLE)(device_handle & 0xffff);
857 GARMIN_USB_Thread::~GARMIN_USB_Thread() {}
859 void *GARMIN_USB_Thread::Entry() {
860 garmin_usb_packet iresp = {{0}};
861 int n_short_read = 0;
862 m_receive_state = rs_fromintr;
865 while (m_parent->m_Thread_run_flag > 0) {
866 if (TestDestroy())
goto thread_prexit;
870 int nr = gusb_cmd_get(&iresp,
sizeof(iresp));
872 if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_SDR)
874 unsigned char *t = (
unsigned char *)&(iresp.gusb_pkt.databuf[0]);
875 for (
int i = 0; i < 12; i++) {
876 m_sat_data[i].svid = *t++;
877 m_sat_data[i].snr = ((*t) << 8) + *(t + 1);
879 m_sat_data[i].elev = *t++;
880 m_sat_data[i].azmth = ((*t) << 8) + *(t + 1);
882 m_sat_data[i].status = *t++;
886 for (
int i = 0; i < 12; i++) {
887 if (m_sat_data[i].svid != 255) m_nSats++;
892 NMEA0183 oNMEA0183(NmeaCtxFactory());
893 oNMEA0183.TalkerID = _T (
"GM" );
894 oNMEA0183.Gsv.SatsInView = m_nSats;
896 oNMEA0183.Gsv.Write(snt);
897 wxString message = snt.Sentence;
900 auto buffer = std::make_shared<std::vector<unsigned char>>();
901 std::vector<unsigned char>* vec = buffer.get();
902 for (
unsigned int i=0 ; i < message.Length() ; i++){
903 vec->push_back(message[i]);
905 if (m_pMessageTarget) {
907 Nevent.SetPayload(buffer);
908 m_pMessageTarget->AddPendingEvent(Nevent);
912 if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_PVT)
917 if ((ppvt->fix) >= 2 && (ppvt->fix <= 5)) {
920 NMEA0183 oNMEA0183(NmeaCtxFactory());
921 oNMEA0183.TalkerID = _T (
"GM" );
924 oNMEA0183.Rmc.Position.Latitude.Set(-ppvt->lat * 180. / PI,
927 oNMEA0183.Rmc.Position.Latitude.Set(ppvt->lat * 180. / PI,
931 oNMEA0183.Rmc.Position.Longitude.Set(-ppvt->lon * 180. / PI,
934 oNMEA0183.Rmc.Position.Longitude.Set(ppvt->lon * 180. / PI,
938 double sog = sqrt(ppvt->east * ppvt->east + ppvt->north * ppvt->north) *
940 oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
943 double course = atan2(ppvt->east, ppvt->north);
944 if (course < 0) course += 2 * PI;
945 double cog = course * 180 / PI;
946 oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
948 oNMEA0183.Rmc.IsDataValid = NTrue;
950 oNMEA0183.Rmc.Write(snt);
951 wxString message = snt.Sentence;
954 auto buffer = std::make_shared<std::vector<unsigned char>>();
955 std::vector<unsigned char>* vec = buffer.get();
956 for (
unsigned int i=0 ; i < message.Length() ; i++){
957 vec->push_back(message[i]);
959 if (m_pMessageTarget) {
961 Nevent.SetPayload(buffer);
962 m_pMessageTarget->AddPendingEvent(Nevent);
968 m_parent->m_Thread_run_flag = -1;
972 int GARMIN_USB_Thread::gusb_cmd_get(garmin_usb_packet *ibuf,
size_t sz) {
974 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
975 int orig_receive_state;
977 orig_receive_state = m_receive_state;
978 switch (m_receive_state) {
980 rv = gusb_win_get(ibuf, sz);
983 rv = gusb_win_get_bulk(ibuf, sz);
988 if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
989 m_receive_state = rs_frombulk;
1000 if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
1001 m_receive_state = rs_fromintr;
1007 int GARMIN_USB_Thread::gusb_win_get(garmin_usb_packet *ibuf,
size_t sz) {
1010 DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
1011 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
1017 if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
1018 buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
1026 if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE)
break;
1033 int GARMIN_USB_Thread::gusb_win_get_bulk(garmin_usb_packet *ibuf,
size_t sz) {
1038 unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
1040 n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);