35#include <netinet/tcp.h> 
   51#include <wx/datetime.h> 
   55#include <wx/tokenzr.h> 
   61#include "model/garmin_wrapper.h" 
   67#include "androidUTIL.h" 
   71static const long long lNaN = 0xfff8000000000000;
 
   72#define NAN (*(double *)&lNaN) 
   75#define N_DOG_TIMEOUT 5 
   79DEFINE_GUID(GARMIN_GUID1, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b,
 
   80            0xba, 0xe7, 0x22, 0xc0);
 
  100  SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
 
  101  PSID AdministratorsGroup;
 
  102  b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
 
  103                               DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
 
  104                               &AdministratorsGroup);
 
  106    if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) {
 
  109    FreeSid(AdministratorsGroup);
 
  118EVT_TIMER(TIMER_GARMIN1, GarminProtocolHandler::OnTimerGarmin1)
 
  122                                             SendMsgFunc send_msg_func,
 
  125  m_send_msg_func = send_msg_func;
 
  126  m_garmin_serial_thread = NULL;
 
  127  m_garmin_usb_thread = NULL;
 
  134  char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
 
  136  char pvt_off[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0};
 
  140    m_usb_handle = INVALID_HANDLE_VALUE;
 
  142    m_bneed_int_reset = 
true;
 
  143    m_receive_state = rs_fromintr;
 
  146    wxLogMessage(
"Searching for Garmin DeviceInterface and Device...");
 
  148    if (!FindGarminDeviceInterface()) {
 
  149      wxLogMessage(
"   Find:Is the Garmin USB driver installed?");
 
  151      if (!ResetGarminUSBDriver())
 
  152        wxLogMessage(
"   Reset:Is the Garmin USB Device plugged in?");
 
  162    m_garmin_serial_thread =
 
  165    m_Thread_run_flag = 1;
 
  166    m_garmin_serial_thread->Run();
 
  169  TimerGarmin1.SetOwner(
this, TIMER_GARMIN1);
 
  170  TimerGarmin1.Start(100);
 
  173GarminProtocolHandler::~GarminProtocolHandler() {}
 
  175void GarminProtocolHandler::Close() {
 
  182void GarminProtocolHandler::StopSerialThread() {
 
  183  if (m_garmin_serial_thread) {
 
  184    wxLogMessage(
"Stopping Garmin Serial thread");
 
  185    m_Thread_run_flag = 0;
 
  188    while ((m_Thread_run_flag >= 0) && (tsec--)) {
 
  193    if (m_Thread_run_flag < 0)
 
  194      msg.Printf(
"Stopped in %d sec.", 5 - tsec);
 
  196      msg.Printf(
"Not Stopped after 5 sec.");
 
  200  m_garmin_serial_thread = NULL;
 
  203void GarminProtocolHandler::StopIOThread(
bool b_pause) {
 
  204  if (b_pause) TimerGarmin1.Stop();
 
  206  if (m_garmin_usb_thread) {
 
  207    wxLogMessage(
"Stopping Garmin USB thread");
 
  208    m_Thread_run_flag = 0;
 
  211    while ((m_Thread_run_flag >= 0) && (tsec--)) {
 
  216    if (m_Thread_run_flag < 0)
 
  217      msg.Printf(
"Stopped in %d sec.", 5 - tsec);
 
  219      msg.Printf(
"Not Stopped after 5 sec.");
 
  223  m_garmin_usb_thread = NULL;
 
  226  if (m_busb && (m_usb_handle != INVALID_HANDLE_VALUE))
 
  227    CloseHandle(m_usb_handle);
 
  228  m_usb_handle = INVALID_HANDLE_VALUE;
 
  234void GarminProtocolHandler::RestartIOThread() {
 
  235  wxLogMessage(
"Restarting Garmin I/O thread");
 
  236  TimerGarmin1.Start(1000);
 
  239void GarminProtocolHandler::OnTimerGarmin1(wxTimerEvent &event) {
 
  240  char pvt_on[14] = {20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0};
 
  247    if (INVALID_HANDLE_VALUE == m_usb_handle) {
 
  248      if (INVALID_HANDLE_VALUE != garmin_usb_start()) {
 
  250        m_receive_state = rs_fromintr;
 
  251        gusb_cmd_send((
const garmin_usb_packet *)pvt_on, 
sizeof(pvt_on));
 
  255            this, m_send_msg_func, (wxIntPtr)m_usb_handle, m_max_tx_size);
 
  256        m_Thread_run_flag = 1;
 
  257        m_garmin_usb_thread->Run();
 
  263  TimerGarmin1.Start(1000);
 
  267bool GarminProtocolHandler::ResetGarminUSBDriver() {
 
  268  OSVERSIONINFO version_info;
 
  269  version_info.dwOSVersionInfoSize = 
sizeof(OSVERSIONINFO);
 
  271  if (GetVersionEx(&version_info)) {
 
  272    if (version_info.dwMajorVersion > 5) {
 
  273      if (!IsUserAdmin()) {
 
  275            "    GarminUSBDriver Reset skipped, requires elevated " 
  276            "privileges on Vista and later....");
 
  283  SP_DEVINFO_DATA devInfo;
 
  284  SP_PROPCHANGE_PARAMS pchange;
 
  286  devs = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
 
  287                             DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
 
  288  if (devs == INVALID_HANDLE_VALUE) 
return false;
 
  290  devInfo.cbSize = 
sizeof(devInfo);
 
  291  if (!SetupDiEnumDeviceInfo(devs, 0, &devInfo)) {
 
  292    wxLogMessage(
"   GarminUSBDriver Reset0 failed...");
 
  296  pchange.ClassInstallHeader.cbSize = 
sizeof(SP_CLASSINSTALL_HEADER);
 
  297  pchange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
 
  298  pchange.StateChange = DICS_PROPCHANGE;
 
  299  pchange.Scope = DICS_FLAG_CONFIGSPECIFIC;
 
  300  pchange.HwProfile = 0;
 
  302  if (!SetupDiSetClassInstallParams(devs, &devInfo, &pchange.ClassInstallHeader,
 
  304    wxLogMessage(
"   GarminUSBDriver Reset1 failed...");
 
  308  if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devs, &devInfo)) {
 
  309    wxLogMessage(
"   GarminUSBDriver Reset2 failed...");
 
  313  wxLogMessage(
"GarminUSBDriver Reset succeeded.");
 
  318bool GarminProtocolHandler::
 
  319    FindGarminDeviceInterface() {  
 
  323  SP_DEVINFO_DATA devInfo;
 
  325  hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
 
  326                                 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
 
  328  if (hdevinfo != INVALID_HANDLE_VALUE) {
 
  329    devInfo.cbSize = 
sizeof(devInfo);
 
  330    if (!SetupDiEnumDeviceInfo(hdevinfo, 0, &devInfo)) {
 
  338bool GarminProtocolHandler::IsGarminPlugged() {
 
  342  SP_DEVICE_INTERFACE_DATA infodata;
 
  345  hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
 
  346                                 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
 
  348  if (hdevinfo == INVALID_HANDLE_VALUE) 
return INVALID_HANDLE_VALUE;
 
  350  infodata.cbSize = 
sizeof(infodata);
 
  352  bool bgarmin_unit_found =
 
  353      (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
 
  356  if (!bgarmin_unit_found) 
return false;
 
  358  PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
 
  359  SP_DEVINFO_DATA devinfo;
 
  361  SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
 
  363  pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
 
  364  pdd->cbSize = 
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
 
  366  devinfo.cbSize = 
sizeof(SP_DEVINFO_DATA);
 
  367  if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
 
  378HANDLE GarminProtocolHandler::garmin_usb_start() {
 
  382  SP_DEVICE_INTERFACE_DATA infodata;
 
  385  hdevinfo = SetupDiGetClassDevs((GUID *)&GARMIN_GUID1, NULL, NULL,
 
  386                                 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
 
  388  if (hdevinfo == INVALID_HANDLE_VALUE) 
return INVALID_HANDLE_VALUE;
 
  390  infodata.cbSize = 
sizeof(infodata);
 
  392  bool bgarmin_unit_found =
 
  393      (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *)&GARMIN_GUID1, 0,
 
  396  if (!bgarmin_unit_found) 
return INVALID_HANDLE_VALUE;
 
  398  wxLogMessage(
"Garmin USB Device Found");
 
  400  if ((m_usb_handle == INVALID_HANDLE_VALUE) || (m_usb_handle == 0)) {
 
  401    PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL;
 
  402    SP_DEVINFO_DATA devinfo;
 
  404    SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, NULL, 0, &size, NULL);
 
  406    pdd = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(size);
 
  407    pdd->cbSize = 
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
 
  409    devinfo.cbSize = 
sizeof(SP_DEVINFO_DATA);
 
  410    if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &infodata, pdd, size, NULL,
 
  413          "   SetupDiGetDeviceInterfaceDetail failed for Garmin Device...");
 
  415      return INVALID_HANDLE_VALUE;
 
  423    if (m_bneed_int_reset) {
 
  424      ResetGarminUSBDriver();
 
  425      m_bneed_int_reset = 
false;
 
  428    m_usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ | GENERIC_WRITE, 0,
 
  429                              NULL, OPEN_EXISTING, 0, NULL);
 
  431    if (m_usb_handle == INVALID_HANDLE_VALUE) {
 
  433      msg.Printf(
"   (usb) CreateFile on '%s' failed", pdd->DevicePath);
 
  455  if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE,
 
  456                       NULL, 0, &m_max_tx_size, GARMIN_USB_INTERRUPT_DATA_SIZE,
 
  458    wxLogMessage(
"   Couldn't get Garmin USB packet size.");
 
  459    CloseHandle(m_usb_handle);
 
  460    m_usb_handle = INVALID_HANDLE_VALUE;
 
  461    return INVALID_HANDLE_VALUE;
 
  464  if (!gusb_syncup()) {
 
  465    CloseHandle(m_usb_handle);
 
  466    m_usb_handle = INVALID_HANDLE_VALUE;
 
  472bool GarminProtocolHandler::gusb_syncup() {
 
  473  static int unit_number;
 
  474  static const char oinit[12] = {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0,
 
  476  garmin_usb_packet iresp;
 
  483  m_receive_state = rs_fromintr;
 
  485  for (i = 0; i < 25; i++) {
 
  486    le_write16(&iresp.gusb_pkt.pkt_id[0], 0);
 
  487    le_write32(&iresp.gusb_pkt.datasz[0], 0);
 
  488    le_write32(&iresp.gusb_pkt.databuf[0], 0);
 
  490    if (gusb_cmd_send((
const garmin_usb_packet *)oinit, 
sizeof(oinit))) {
 
  491      gusb_cmd_get(&iresp, 
sizeof(iresp));
 
  493      if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) &&
 
  494          (le_read32(iresp.gusb_pkt.datasz) == 4)) {
 
  503        wxLogMessage(
"Successful Garmin USB syncup.");
 
  509  wxLogMessage(
"   Unable to establish Garmin USB syncup.");
 
  513int GarminProtocolHandler::gusb_cmd_send(
const garmin_usb_packet *opkt,
 
  517  unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
 
  519  rv = gusb_win_send(opkt, sz);
 
  529  if (sz && !(sz % m_max_tx_size)) {
 
  530    wxLogMessage(
"win_send_call1");
 
  531    gusb_win_send(opkt, 0);
 
  532    wxLogMessage(
"win_send_ret1");
 
  538int GarminProtocolHandler::gusb_cmd_get(garmin_usb_packet *ibuf, 
size_t sz) {
 
  540  unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
 
  541  int orig_receive_state;
 
  543  orig_receive_state = m_receive_state;
 
  544  switch (m_receive_state) {
 
  546      rv = gusb_win_get(ibuf, sz);
 
  549      rv = gusb_win_get_bulk(ibuf, sz);
 
  554  if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
 
  555    m_receive_state = rs_frombulk;
 
  566  if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
 
  567    m_receive_state = rs_fromintr;
 
  573int GarminProtocolHandler::gusb_win_get(garmin_usb_packet *ibuf, 
size_t sz) {
 
  574  DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
 
  575  unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
 
  582    if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
 
  583                         buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
 
  591    if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) 
break;
 
  596int GarminProtocolHandler::gusb_win_get_bulk(garmin_usb_packet *ibuf,
 
  600  unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
 
  602  n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);
 
  607int GarminProtocolHandler::gusb_win_send(
const garmin_usb_packet *opkt,
 
  610  unsigned char *obuf = (
unsigned char *)&opkt->dbuf[0];
 
  616  WriteFile(m_usb_handle, obuf, sz, &rsz, NULL);
 
  617  int err = GetLastError();
 
  690                                           SendMsgFunc send_msg_func,
 
  693  m_send_msg_func = send_msg_func;
 
  699GARMIN_Serial_Thread::~GARMIN_Serial_Thread() {}
 
  702void *GARMIN_Serial_Thread::Entry() {
 
  705  m_bconnected = 
false;
 
  707  bool not_done = 
true;
 
  708  wxDateTime last_rx_time;
 
  713  while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
 
  719    while (!m_bdetected) {
 
  721      int v_init = Garmin_GPS_Init(m_port);
 
  723        for (
int i = 0; i < 4; i++) {
 
  725          if (TestDestroy()) 
goto thread_exit;
 
  726          if (!m_parent->m_Thread_run_flag) 
goto thread_exit;
 
  736      if (!Garmin_GPS_PVT_On(m_port)) {
 
  738        m_bconnected = 
false;
 
  745      int ret = Garmin_GPS_GetPVT(&ppvt);
 
  747        if ((mypvt.fix) >= 2 && (mypvt.fix <= 5)) {
 
  750          NMEA0183 oNMEA0183(NmeaCtxFactory());
 
  751          oNMEA0183.TalkerID = 
"GM";
 
  754            oNMEA0183.Rmc.Position.Latitude.Set(-mypvt.lat, 
"S");
 
  756            oNMEA0183.Rmc.Position.Latitude.Set(mypvt.lat, 
"N");
 
  759            oNMEA0183.Rmc.Position.Longitude.Set(-mypvt.lon, 
"W");
 
  761            oNMEA0183.Rmc.Position.Longitude.Set(mypvt.lon, 
"E");
 
  765              sqrt(mypvt.east * mypvt.east + mypvt.north * mypvt.north) * 3.6 /
 
  767          oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
 
  770          double course = atan2(mypvt.east, mypvt.north);
 
  771          if (course < 0) course += 2 * PI;
 
  772          double cog = course * 180 / PI;
 
  773          oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
 
  775          oNMEA0183.Rmc.IsDataValid = NTrue;
 
  777          oNMEA0183.Rmc.Write(snt);
 
  780          auto msg = snt.Sentence.ToStdString();
 
  781          m_send_msg_func(std::vector<unsigned char>(msg.begin(), msg.end()));
 
  783          last_rx_time = wxDateTime::Now();
 
  786        wxDateTime now = wxDateTime::Now();
 
  787        if (last_rx_time.IsValid()) {
 
  788          wxTimeSpan delta_time = now - last_rx_time;
 
  789          if (delta_time.GetSeconds() > 5) {
 
  791            m_bconnected = 
false;
 
  792            Garmin_GPS_ClosePortVerify();
 
  801  Garmin_GPS_PVT_Off(m_port);
 
  802  Garmin_GPS_ClosePortVerify();
 
  804  while ((not_done) && (m_parent->m_Thread_run_flag > 0)) {
 
  816  m_parent->m_Thread_run_flag = -1;  
 
  825                                     SendMsgFunc send_msg_func,
 
  826                                     unsigned int device_handle,
 
  827                                     size_t max_tx_size) {
 
  829  m_send_msg_func = send_msg_func;
 
  830  m_max_tx_size = max_tx_size;
 
  833  m_usb_handle = (HANDLE)(device_handle & 0xffff);
 
  839GARMIN_USB_Thread::~GARMIN_USB_Thread() {}
 
  841void *GARMIN_USB_Thread::Entry() {
 
  842  garmin_usb_packet iresp = {{0}};
 
  843  int n_short_read = 0;
 
  844  m_receive_state = rs_fromintr;
 
  847  while (m_parent->m_Thread_run_flag > 0) {
 
  848    if (TestDestroy()) 
goto thread_prexit;  
 
  852    int nr = gusb_cmd_get(&iresp, 
sizeof(iresp));
 
  854    if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_SDR)  
 
  856      unsigned char *t = (
unsigned char *)&(iresp.gusb_pkt.databuf[0]);
 
  857      for (
int i = 0; i < 12; i++) {
 
  858        m_sat_data[i].svid = *t++;
 
  859        m_sat_data[i].snr = ((*t) << 8) + *(t + 1);
 
  861        m_sat_data[i].elev = *t++;
 
  862        m_sat_data[i].azmth = ((*t) << 8) + *(t + 1);
 
  864        m_sat_data[i].status = *t++;
 
  868      for (
int i = 0; i < 12; i++) {
 
  869        if (m_sat_data[i].svid != 255) m_nSats++;
 
  874      NMEA0183 oNMEA0183(NmeaCtxFactory());
 
  875      oNMEA0183.TalkerID = 
"GM";
 
  876      oNMEA0183.Gsv.SatsInView = m_nSats;
 
  878      oNMEA0183.Gsv.Write(snt);
 
  879      wxString msg = snt.Sentence;
 
  882      m_send_msg_func(std::vector<unsigned char>(msg.begin(), msg.end()));
 
  885    if (iresp.gusb_pkt.pkt_id[0] == GUSB_RESPONSE_PVT)  
 
  890      if ((ppvt->fix) >= 2 && (ppvt->fix <= 5)) {
 
  893        NMEA0183 oNMEA0183(NmeaCtxFactory());
 
  894        oNMEA0183.TalkerID = 
"GM";
 
  897          oNMEA0183.Rmc.Position.Latitude.Set(-ppvt->lat * 180. / PI, 
"S");
 
  899          oNMEA0183.Rmc.Position.Latitude.Set(ppvt->lat * 180. / PI, 
"N");
 
  902          oNMEA0183.Rmc.Position.Longitude.Set(-ppvt->lon * 180. / PI, 
"W");
 
  904          oNMEA0183.Rmc.Position.Longitude.Set(ppvt->lon * 180. / PI, 
"E");
 
  907        double sog = sqrt(ppvt->east * ppvt->east + ppvt->north * ppvt->north) *
 
  909        oNMEA0183.Rmc.SpeedOverGroundKnots = sog;
 
  912        double course = atan2(ppvt->east, ppvt->north);
 
  913        if (course < 0) course += 2 * PI;
 
  914        double cog = course * 180 / PI;
 
  915        oNMEA0183.Rmc.TrackMadeGoodDegreesTrue = cog;
 
  917        oNMEA0183.Rmc.IsDataValid = NTrue;
 
  919        oNMEA0183.Rmc.Write(snt);
 
  920        wxString msg = snt.Sentence;
 
  921        m_send_msg_func(std::vector<unsigned char>(msg.begin(), msg.end()));
 
  926  m_parent->m_Thread_run_flag = -1;
 
  930int GARMIN_USB_Thread::gusb_cmd_get(garmin_usb_packet *ibuf, 
size_t sz) {
 
  932  unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
 
  933  int orig_receive_state;
 
  935  orig_receive_state = m_receive_state;
 
  936  switch (m_receive_state) {
 
  938      rv = gusb_win_get(ibuf, sz);
 
  941      rv = gusb_win_get_bulk(ibuf, sz);
 
  946  if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) {
 
  947    m_receive_state = rs_frombulk;
 
  958  if ((m_receive_state == rs_frombulk) && (rv <= 0)) {
 
  959    m_receive_state = rs_fromintr;
 
  965int GARMIN_USB_Thread::gusb_win_get(garmin_usb_packet *ibuf, 
size_t sz) {
 
  968  DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
 
  969  unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
 
  975    if (!DeviceIoControl(m_usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0,
 
  976                         buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) {
 
  984    if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) 
break;
 
  991int GARMIN_USB_Thread::gusb_win_get_bulk(garmin_usb_packet *ibuf, 
size_t sz) {
 
  996  unsigned char *buf = (
unsigned char *)&ibuf->dbuf[0];
 
  998  n = ReadFile(m_usb_handle, buf, sz, &rsz, NULL);
 
Global variables stored in configuration file.
Wrapper for creating an NmeaContext based on global vars.