r3074 - packages/opencpn/trunk/debian/patches

hamish-guest at alioth.debian.org hamish-guest at alioth.debian.org
Sat Jun 16 05:04:56 UTC 2012


Author: hamish-guest
Date: 2012-06-16 05:04:55 +0000 (Sat, 16 Jun 2012)
New Revision: 3074

Added:
   packages/opencpn/trunk/debian/patches/allow_harden_plugins.diff
   packages/opencpn/trunk/debian/patches/backport_libgps20_support.patch
Log:
add patches (deactivated pending field testing) allowing hardening flags to pass through to plugin builds and backporting libgps20 support from upstream 3.0.0 release

Added: packages/opencpn/trunk/debian/patches/allow_harden_plugins.diff
===================================================================
--- packages/opencpn/trunk/debian/patches/allow_harden_plugins.diff	                        (rev 0)
+++ packages/opencpn/trunk/debian/patches/allow_harden_plugins.diff	2012-06-16 05:04:55 UTC (rev 3074)
@@ -0,0 +1,41 @@
+Description: Don't clobber CFLAGS set by main debian/rules file (allows hardening flags to pass through)
+Author: Hamish Bowman <hamish_b yahoo com>
+Index: opencpn/plugins/grib_pi/CMakeLists.txt
+===================================================================
+--- opencpn/plugins/grib_pi/CMakeLists.txt	2011-08-02 23:30:34.000000000 +1200
++++ opencpn/plugins/grib_pi/CMakeLists.txt	2012-06-16 15:28:25.621929917 +1200
+@@ -32,7 +32,7 @@
+  ADD_DEFINITIONS( "-Wall -O3 -fexceptions -fvisibility=hidden" )
+ 
+  IF(NOT APPLE)
+-  SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
++  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic")
+  ELSE(NOT APPLE)
+   SET(CMAKE_SHARED_LINKER_FLAGS "-Wl -undefined dynamic_lookup")
+  ENDIF(NOT APPLE)
+Index: opencpn/plugins/dashboard_pi/CMakeLists.txt
+===================================================================
+--- opencpn/plugins/dashboard_pi/CMakeLists.txt	2011-08-02 23:30:34.000000000 +1200
++++ opencpn/plugins/dashboard_pi/CMakeLists.txt	2012-06-16 15:27:48.533933730 +1200
+@@ -33,7 +33,7 @@
+  ADD_DEFINITIONS( "-Wall -O3 -fexceptions -fvisibility=hidden" )
+ 
+  IF(NOT APPLE)
+-  SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
++  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic")
+  ELSE(NOT APPLE)
+   SET(CMAKE_SHARED_LINKER_FLAGS "-Wl -undefined dynamic_lookup")
+  ENDIF(NOT APPLE)
+Index: opencpn/plugins/demo_pi_sample/CMakeLists.txt
+===================================================================
+--- opencpn/plugins/demo_pi_sample/CMakeLists.txt	2011-08-02 23:30:34.000000000 +1200
++++ opencpn/plugins/demo_pi_sample/CMakeLists.txt	2012-06-16 15:30:12.885859634 +1200
+@@ -43,7 +43,7 @@
+  ADD_DEFINITIONS( "-Wall -g -fexceptions -fvisibility=hidden" )
+ 
+  IF(NOT APPLE)
+-  SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
++  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic")
+  ELSE(NOT APPLE)
+   SET(CMAKE_SHARED_LINKER_FLAGS "-Wl -undefined dynamic_lookup")
+  ENDIF(NOT APPLE)

Added: packages/opencpn/trunk/debian/patches/backport_libgps20_support.patch
===================================================================
--- packages/opencpn/trunk/debian/patches/backport_libgps20_support.patch	                        (rev 0)
+++ packages/opencpn/trunk/debian/patches/backport_libgps20_support.patch	2012-06-16 05:04:55 UTC (rev 3074)
@@ -0,0 +1,996 @@
+Description: Backport libgps20 support from OpenCPN 3.0.0
+Author: Hamish Bowman <hamish_b yahoo com> (cobbled together from selected upstream git pushes)
+Index: opencpn/include/nmea.h
+===================================================================
+--- opencpn/include/nmea.h.2.5.0	2012-06-16 14:26:09.047038616 +1200
++++ opencpn/include/nmea.h	2012-06-16 14:37:35.011497999 +1200
+@@ -206,9 +206,7 @@
+       wxSocketClient    *m_sock;
+ #endif
+ 
+-      struct gps_data_t *m_gps_data;
+       bool              m_busy;
+-      wxTimer           TimerLIBGPS;
+       wxTimer           TimerNMEA;
+       wxFrame           *m_parent_frame;
+       int               m_handler_id;
+@@ -218,6 +216,7 @@
+       wxMutex           *m_pShareMutex;
+       wxThread          *m_pSecondary_Thread;
+       wxMutex           *m_pPortMutex;
++      wxThread          *m_gpsd_thread;
+ 
+       bool              m_bGarmin_host;
+ 
+@@ -231,14 +230,6 @@
+       //    libgps dynamic load parameters
+       void              *m_lib_handle;
+ 
+-      struct gps_data_t *(*m_fn_gps_open)(char *, char *);
+-      int                (*m_fn_gps_close)(struct gps_data_t *);
+-      int                (*m_fn_gps_poll)(struct gps_data_t *);
+-      bool               (*m_fn_gps_waiting)(struct gps_data_t *);
+-      void               (*m_fn_gps_set_raw_hook)(struct gps_data_t *, void (*)(struct gps_data_t *, char *, size_t));
+-      int                (*m_fn_gps_stream)(struct gps_data_t *, unsigned int, void *);
+-      bool               m_bgps_present;
+-
+ 
+ 
+ DECLARE_EVENT_TABLE()
+@@ -319,6 +310,49 @@
+ 
+ };
+ 
++//-------------------------------------------------------------------------------------------------------------
++//
++//    GPSD Library Input Thread
++//
++//-------------------------------------------------------------------------------------------------------------
++
++class OCP_GPSD_Thread: public wxThread
++{
++
++      public:
++
++            OCP_GPSD_Thread(NMEAHandler *Launcher, wxWindow *MessageTarget, wxString &ip_addr, int api);
++            ~OCP_GPSD_Thread(void);
++            void *Entry();
++
++            void OnExit(void);
++
++      private:
++            bool OpenLibrary(void);
++            void CloseLibrary(void);
++
++            void ThreadMessage(const wxString &msg);          // Send a wxLogMessage to main program event loop
++            wxEvtHandler            *m_pMainEventHandler;
++            NMEAHandler             *m_launcher;
++            bool                    m_bgps_present;
++            int                     m_libgps_api;
++            wxString                m_GPSD_data_ip;
++
++            struct gps_data_t *m_pgps_data;
++
++            unsigned int            m_PACKET_SET;
++            unsigned int            m_TIME_SET;
++            unsigned int            m_LATLON_SET;
++            unsigned int            m_TRACK_SET;
++            unsigned int            m_SPEED_SET;
++            unsigned int            m_SATELLITE_SET;
++            unsigned int            m_ERROR_SET;
++            unsigned int            m_STATUS_SET;
++
++            struct gps_fix_t  *m_pfix;
++            int               *m_pstatus;
++            int               *m_psats_viz;
++};
+ 
+ 
+ //-------------------------------------------------------------------------------------------------------------
+Index: opencpn/src/nmea.cpp
+===================================================================
+--- opencpn/src/nmea.cpp.2.5.0	2012-06-16 14:26:22.143038483 +1200
++++ opencpn/src/nmea.cpp	2012-06-16 14:44:44.347538576 +1200
+@@ -52,14 +52,13 @@
+ #include "georef.h"
+ #include "garmin/jeeps/garmin_wrapper.h"
+ 
+-
+ #ifdef BUILD_WITH_LIBGPS
+       #ifdef __WXOSX__ // begin rdm
+             #define policy_t gps_policy_t
+             #include <gps.h>
+             #undef policy_t
+       #else
+-            #include <gps.h>
++      #include <gps.h>
+       #endif // end rdm
+ 
+       #include <dlfcn.h>
+@@ -82,6 +81,29 @@
+ extern bool             g_bDebugGPSD;
+ extern MyFrame          *gFrame;
+ 
++#ifdef BUILD_WITH_LIBGPS
++
++struct gps_data_t *(*s_fn_gps_open19)(char *, char *);
++int                (*s_fn_gps_open)(char *, char *, struct gps_data_t *);
++int                (*s_fn_gps_close)(struct gps_data_t *);
++int                (*s_fn_gps_poll)(struct gps_data_t *);
++bool               (*s_fn_gps_waiting)(struct gps_data_t *, unsigned int);
++int                (*s_fn_gps_stream)(struct gps_data_t *, unsigned int, void *);
++int                (*s_fn_gps_read)(struct gps_data_t *);
++
++
++//    libgps.so changes API frequently, and does not try very hard to preserve ABI compatibility.
++//    One consequence is that the structure "gps_data_t" may be larger than expected
++//    from the perspective of a dynamically loaded .so library.
++//    Since we cannot know this at build time, and cannot even detect it at run-time, all we can
++//    do is over-allocate the storage for our gps_data_t, and hope for the best.
++//    2X ought to be enough...
++
++struct gps_data_t gpsd_data;
++struct gps_data_t gpsd_data_expander;
++
++#endif
++
+ //------------------------------------------------------------------------------
+ //    NMEA Event Implementation
+ //------------------------------------------------------------------------------
+@@ -284,7 +306,6 @@
+ BEGIN_EVENT_TABLE(NMEAHandler, wxEvtHandler)
+ 
+  //           EVT_SOCKET(SOCKET_ID, NMEAHandler::OnSocketEvent)
+-            EVT_TIMER(TIMER_LIBGPS1, NMEAHandler::OnTimerLIBGPS)
+             EVT_TIMER(TIMER_NMEA1, NMEAHandler::OnTimerNMEA)
+ 
+   END_EVENT_TABLE()
+@@ -301,11 +322,9 @@
+ 
+       m_pdevmon = NULL;
+       m_pSecondary_Thread = NULL;
++      m_gpsd_thread = NULL;
+       SetSecThreadInActive();
+ 
+-      TimerLIBGPS.SetOwner(this, TIMER_LIBGPS1);
+-      TimerLIBGPS.Stop();
+-
+       TimerNMEA.SetOwner(this, TIMER_NMEA1);
+       TimerNMEA.Stop();
+ 
+@@ -319,9 +338,6 @@
+       m_gpsd_minor = 0;
+       m_bgot_version = false;
+ 
+-      m_gps_data = NULL;
+-      m_bgps_present = false;
+-
+       ThreadPositionData.FixTime = 0;
+       ThreadPositionData.kLat = 0.;
+       ThreadPositionData.kLon = 0.;
+@@ -403,22 +419,36 @@
+ #endif
+ 
+ #ifdef BUILD_WITH_LIBGPS
++
++#ifdef VERSION_SET
++#if VERSION_SET != 0x10000000
++#warning : VERSION_SET skew detected...gps.h include file is probably out of date
++#endif
++#endif
++
+         else if(m_data_source_string.Contains(_T("LIBGPS")))
+         {
+             wxString NMEA_data_ip;
+             NMEA_data_ip = m_data_source_string.Mid(7);         // extract the IP
++            int libgps_api = 0;
++            struct gps_data_t *pgps_data = &gpsd_data;
++            unsigned int d_VERSION_SET = VERSION_SET;
++//            printf("  VersionSet: %0X\n", d_VERSION_SET);
+ 
+ #define DYNAMIC_LOAD_LIBGPS 1
+ #ifdef DYNAMIC_LOAD_LIBGPS
+ 
+             wxString load1;
+             wxString load2;
++            wxString load3;
+ #ifndef __WXOSX__
+-            load1 = _T("libgps.so.19");
+-            load2 = _T("libgps.so");
++            load1 = _T("libgps.so");
++            load2 = _T("libgps.so.20");
++            load3 = _T("libgps.so.19");
+ #else
+-            load1 = _T("/opt/local/lib/libgps.19.dylib");
+-            load2 = _T("/opt/local/lib/libgps.dylib");
++            load1 = _T("/opt/local/lib/libgps.dylib");
++            load2 = _T("/opt/local/lib/libgps.20.dylib");
++            load3 = _T("/opt/local/lib/libgps.19.dylib");
+ #endif
+ 
+             m_lib_handle = dlopen(load1.fn_str(), RTLD_LAZY);
+@@ -442,38 +472,62 @@
+                   msg1 += load2;
+                   wxLogMessage(msg1);
+ 
++                  msg = _T("Attempting to load ");
++                  msg += load3;
++                  wxLogMessage(msg);
++
++                  m_lib_handle = dlopen(load3.fn_str(), RTLD_LAZY);
++            }
++
++            if(!m_lib_handle)
++            {
+                   wxString msg(_("Unable to load libgps"));
+                   OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_ERROR );
+                   md.ShowModal();
+                   return;
+             }
+-
+             else
+             {
+                   void *p = dlsym(m_lib_handle, "gps_open");
+-                  m_fn_gps_open =                  (gps_data_t *(*)(char *, char *))p;
++                  s_fn_gps_open19 =                  (gps_data_t *(*)(char *, char *))p;
++                  s_fn_gps_open =                    (int(*)(char *, char *, struct gps_data_t *))p;
+ 
+                   p = dlsym(m_lib_handle, "gps_close");
+-                  m_fn_gps_close =                 (int(*)(struct gps_data_t *))p;
++                  s_fn_gps_close =                 (int(*)(struct gps_data_t *))p;
+ 
+                   p = dlsym(m_lib_handle, "gps_poll");
+-                  m_fn_gps_poll =                (int(*)(struct gps_data_t *))p;
++                  s_fn_gps_poll =                (int(*)(struct gps_data_t *))p;
+ 
+                   p = dlsym(m_lib_handle, "gps_waiting");
+-                  m_fn_gps_waiting =              (bool(*)(struct gps_data_t *))p;
+-
+-                  p = dlsym(m_lib_handle, "gps_set_raw_hook");
+-                  m_fn_gps_set_raw_hook =          (void (*)(struct gps_data_t *, void (*)(struct gps_data_t *, char *, size_t)))p;
++                  s_fn_gps_waiting =              (bool(*)(struct gps_data_t *, unsigned int))p;
+ 
+                   p = dlsym(m_lib_handle, "gps_stream");
+-                  m_fn_gps_stream =                (int  (*)(struct gps_data_t *, unsigned int, void *))p;
++                  s_fn_gps_stream =                (int  (*)(struct gps_data_t *, unsigned int, void *))p;
++
++                  p = dlsym(m_lib_handle, "gps_read");
++                  s_fn_gps_read =                (int  (*)(struct gps_data_t *))p;
++
++
++                  //    We can make a simple determination of libgps API level
++                  if(s_fn_gps_poll)
++                  {
++                        wxLogMessage(_T("LIBGPS:  Using libgps API=19"));
++                        libgps_api = 19;
++                        d_VERSION_SET = 0x800u;
++                  }
++                  else if(s_fn_gps_read)
++                  {
++                        wxLogMessage(_T("LIBGPS:  Using libgps API=20"));
++                        libgps_api = 20;
++                        d_VERSION_SET = 1u<<28;
++                  }
+ 
+-                  if(!m_fn_gps_open          ||
+-                      !m_fn_gps_close        ||
+-                      !m_fn_gps_poll         ||
+-                      !m_fn_gps_waiting      ||
+-                      !m_fn_gps_set_raw_hook ||
+-                      !m_fn_gps_stream       )
++
++                  if((0 == libgps_api)     ||
++                      !s_fn_gps_open         ||
++                      !s_fn_gps_close        ||
++                      !s_fn_gps_waiting      ||
++                      !s_fn_gps_stream       )
+                   {
+                         wxString msg(NMEA_data_ip);
+                         msg.Prepend(_("Unable to initialize libgps.\n\ngpsd host is: "));
+@@ -488,98 +542,151 @@
+ 
+             //set up function pointers to required libgps functions
+ 
+-            m_fn_gps_open =                (gps_data_t *(*)(char *, char *))gps_open;
+-            m_fn_gps_close =               (int(*)(struct gps_data_t *))gps_close;
+-            m_fn_gps_poll =                (int(*)(struct gps_data_t *))gps_poll;
+-            m_fn_gps_waiting =             (bool(*)(struct gps_data_t *))gps_waiting;
+-            m_fn_gps_set_raw_hook =        (void (*)(struct gps_data_t *, void (*)(struct gps_data_t *, char *, size_t)))gps_set_raw_hook;
+-            m_fn_gps_stream =              (int  (*)(struct gps_data_t *, unsigned int, void *))gps_stream;
++            s_fn_gps_open =                (gps_data_t *(*)(char *, char *))gps_open;
++            s_fn_gps_close =               (int(*)(struct gps_data_t *))gps_close;
++            s_fn_gps_poll =                (int(*)(struct gps_data_t *))gps_poll;
++            s_fn_gps_waiting =             (bool(*)(struct gps_data_t *))gps_waiting;
++            s_fn_gps_stream =              (int  (*)(struct gps_data_t *, unsigned int, void *))gps_stream;
++            s_fun_gps_read =               (int  (*)(struct gps_data_t *)gps_read;
+ 
+ 
+ #endif
+ 
+             //    Try to open the library
+-            m_gps_data = m_fn_gps_open(NMEA_data_ip.char_str(), (char *)DEFAULT_GPSD_PORT);
++            int result_open;
+ 
+-            if(!m_gps_data)
++            if(19 == libgps_api)
+             {
+-                wxString msg(NMEA_data_ip);
+-                msg.Prepend(_("Call to gps_open failed.\nIs gpsd running?\n\ngpsd host is: "));
+-                OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_ERROR );
+-                md.ShowModal();
+-                return;
++                  struct gps_data_t *gps_19data = NULL;
++                  gps_19data = s_fn_gps_open19(NMEA_data_ip.char_str(), (char *)DEFAULT_GPSD_PORT);
++
++                  if(!gps_19data)
++                  {
++                      wxString msg(NMEA_data_ip);
++                      msg.Prepend(_("Call to gps_open failed.\nIs gpsd running?\n\ngpsd host is: "));
++                      msg.Append(_("\n\nContinuing libgps setup..."));
++                      OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_INFORMATION | wxOK );
++                      md.ShowModal();
++                  }
++                  else
++                  {
++                        result_open = 0;
++                        pgps_data = gps_19data;
++                  }
+             }
+ 
+-            int n_check_version = 5;            // check up to five times
+-            bool b_version_match = false;
+-            bool b_use_lib = false;
+-            bool b_version_set = false;
+-            struct version_t check_version;
+-            check_version.proto_major =0; check_version.proto_minor = 0;
++            else if(20 == libgps_api)
++            {
++                  result_open = s_fn_gps_open(NMEA_data_ip.char_str(), (char *)DEFAULT_GPSD_PORT, pgps_data);
++
++                  if (result_open != 0)
++                  {
++                        wxString msg(NMEA_data_ip);
++                        msg.Prepend(_("Call to gps_open failed.\nIs gpsd running?\n\ngpsd host is: "));
++                        msg.Append(_("\n\nContinuing libgps setup..."));
++                        OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_INFORMATION | wxOK );
++                        md.ShowModal();
++                   }
++                   else {
++                   }
++
++            }
++            else
++                  result_open = 1;        // not opened
+ 
+-            while(n_check_version)
++            bool b_use_lib = true;
++            if(!result_open)              // opened OK
+             {
+-            //    Check library version
+-                  if(m_fn_gps_waiting(m_gps_data))
+-                        m_fn_gps_poll(m_gps_data);
++                  int n_check_version = 5;            // check up to five times
++                  bool b_version_match = false;
++                  bool b_version_set = false;
++                  struct version_t check_version;
++                  check_version.proto_major =0; check_version.proto_minor = 0;
+ 
+-                  if(m_gps_data->set & VERSION_SET)
++                  while(n_check_version)
+                   {
+-                        b_version_set = true;
+-                        check_version = m_gps_data->version;
++                  //    Check library version
++                        if(s_fn_gps_waiting(pgps_data, 1000))
++                        {
++                              if(20 == libgps_api)
++                                    s_fn_gps_read(pgps_data);
++                              else if(19 == libgps_api)
++                                    s_fn_gps_poll(pgps_data);
++                        }
++
++//                        printf("  Version Poll/Read Set: %0X  %0X\n", (unsigned int)gps_data->set, d_VERSION_SET);
+ 
+-                        if((check_version.proto_major >= 3) && (check_version.proto_minor >= 0))
++                        if(pgps_data->set & d_VERSION_SET)
+                         {
+-                              b_version_match = true;
+-                              b_use_lib = true;
+-                              break;
++                              b_version_set = true;
++                              check_version = pgps_data->version;
++
++      //                        2.96 (libgps.so.20) gives 3.4
++                              if((check_version.proto_major >= 3) && (check_version.proto_minor >= 0))
++                              {
++                                    b_version_match = true;
++                                    break;
++                              }
++                              else
++                                    break;
+                         }
+-                        else
+-                              break;
++
++                        n_check_version--;
+                   }
+ 
+-                  n_check_version--;
+-            }
++#if 0
++                  if(!b_version_set)
++                  {
++                        wxString msg(_("Possible libgps API version mismatch.\nlibgps did not reasonably respond to version request\n\nWould you like to use this version of libgps anyway?"));
++                        OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT );
+ 
+-            if(!b_version_set)
+-            {
+-                  wxString msg(_("Possible libgps API version mismatch.\nlibgps did not reasonably respond to version request\n\nWould you like to use this version of libgps anyway?"));
+-                  OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT );
++                        if(wxID_YES == md.ShowModal())
++                              b_use_lib = true;
++                  }
+ 
+-                  if(wxID_YES == md.ShowModal())
+-                        b_use_lib = true;
+-            }
++                  if( b_version_set && !b_version_match )
++                  {
++                        wxString msg;
++                        msg.Printf(_("libgps API version mismatch.\nOpenCPN found version %d.%d, but requires at least version 3.0\n\n\
++      Would you like to use this version of libgps anyway?"),
++                              check_version.proto_major, check_version.proto_minor);
++                        OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT );
+ 
+-            if( b_version_set && !b_version_match )
++                        if(wxID_YES == md.ShowModal())
++                              b_use_lib = true;
++                  }
++#endif
++
++                 if( b_version_set && (libgps_api == 20)){
++                        wxString msg;
++                        msg.Printf(_T("LIBGPS: Found libgps version %d.%d"), check_version.proto_major,    check_version.proto_minor);
++                        wxLogMessage(msg);
++                        }
++                  else
++                        wxLogMessage(_T("LIBGPS: Version not determined"));
++
++
++                  s_fn_gps_close(pgps_data);
++                  pgps_data = NULL;
++            }
++            else              // Open did not work, but carry on anyway
+             {
+                   wxString msg;
+-                  msg.Printf(_("libgps API version mismatch.\nOpenCPN found version %d.%d, but requires at least version 3.0\n\n\
+-Would you like to use this version of libgps anyway?"),
+-                             check_version.proto_major, check_version.proto_minor);
+-                  OCPNMessageDialog md(m_parent_frame, msg, _("OpenCPN Message"), wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT );
+-
+-                  if(wxID_YES == md.ShowModal())
+-                        b_use_lib = true;
++                  msg.Printf(_T("LIBGPS: Initial Open()failed, assuming libgps version at least 3.0"));
++                  wxLogMessage(msg);
++                  b_use_lib = true;
+             }
+ 
+-            wxString msg;
+-            msg.Printf(_T("Found libgps version %d.%d"), check_version.proto_major, check_version.proto_minor);
+-            wxLogMessage(msg);
+-
+             if(b_use_lib)
+             {
+-                  m_fn_gps_stream(m_gps_data, WATCH_ENABLE, NULL);
+-                  TimerLIBGPS.Start(TIMER_LIBGPS_MSEC,wxTIMER_CONTINUOUS);
+-                  m_bgps_present = true;              // assume this for now....
++                  // Start the GPSD receiver thread
++                  m_gpsd_thread = new OCP_GPSD_Thread(this, frame, NMEA_data_ip, libgps_api );
++                  m_Thread_run_flag = 1;
++                  m_gpsd_thread->Run();
++
+             }
+             else
+-            {
+-                  m_fn_gps_close(m_gps_data);
+-                  m_gps_data = NULL;
+-
+                   return;
+-            }
+-
+         }
+ #endif
+ 
+@@ -668,15 +775,6 @@
+ 
+ void NMEAHandler::Close()
+ {
+-//    Kill off the libgpsd Socket if alive
+-#ifdef BUILD_WITH_LIBGPS
+-      if(m_gps_data)
+-      {
+-         m_fn_gps_close(m_gps_data);
+-         m_gps_data = NULL;
+-         TimerLIBGPS.Stop();
+-      }
+-#endif
+ 
+ #ifndef OCPN_NO_SOCKETS
+ //    Kill off the NMEA Socket if alive
+@@ -715,7 +813,35 @@
+           m_bsec_thread_active = false;
+       }
+ 
++//    Kill off the GPSD Thread if alive
++      if(m_gpsd_thread)
++      {
++            if(m_bsec_thread_active)              // Try to be sure thread object is still alive
++            {
++                  wxLogMessage(_T("Stopping GPSD Rx Thread"));
++
++                  m_Thread_run_flag = 0;
++                  int tsec = 5;
++                  while((m_Thread_run_flag >= 0) && (tsec--))
++                  {
++                        wxSleep(1);
++                  }
++
++                  wxString msg;
++                  if(m_Thread_run_flag < 0)
++                        msg.Printf(_T("Stopped in %d sec."), 5 - tsec);
++                  else
++                        msg.Printf(_T("Not Stopped after 5 sec."));
++                  wxLogMessage(msg);
++
++            }
++
++            m_gpsd_thread = NULL;
++            m_bsec_thread_active = false;
++      }
++
+ #ifdef __WXMSW__
++      //    Garmin
+       if(m_pdevmon)
+       {
+             m_pdevmon->Close();
+@@ -758,148 +884,6 @@
+ }
+ 
+ 
+-int ic;
+-void NMEAHandler::OnTimerLIBGPS(wxTimerEvent& event)
+-{
+-#ifdef BUILD_WITH_LIBGPS
+-      TimerLIBGPS.Stop();
+-
+-      if(g_bDebugGPSD) printf("%d\n", ic++);
+-
+-      m_bgps_present = false;
+-
+-      while(m_fn_gps_waiting(m_gps_data))
+-      {
+-            m_gps_data->set = 0;
+-
+-            m_fn_gps_poll(m_gps_data);
+-            if(g_bDebugGPSD) printf("  Poll Set: %0X\n", m_gps_data->set);
+-
+-            if (!(m_gps_data->set & PACKET_SET))
+-            {
+-                  if(g_bDebugGPSD)  printf("Probably lost GPSD\n");
+-                  m_bgps_present = false;
+-
+-                  break;                  // this is what happens when gpsd is killed or dies
+-            }
+-
+-
+-            m_bgps_present = true;
+-
+-/*
+-            //  Once again gpsd is proven to be crap....
+-            //  If we get a DEVICE_SET or DEVICELIST_SET with (activated==0), we will never again
+-            //  get an (activated > 0) message unless we wait 60 seconds before attaching again.
+-            //  Further, all clients have to be detached for 60 seconds....
+-            //
+-            //  So what is the point???
+-
+-            if (m_gps_data->set & (DEVICE_SET))
+-            {
+-                  if(g_bDebugGPSD)  printf("DEVICE_SET\n");
+-                  if(g_bDebugGPSD)  printf("Activated %g\n", m_gps_data->dev.activated);
+-
+-                  if (m_gps_data->dev.activated < 1.0)
+-                        m_bgps_present = false;
+-                  else
+-                        m_bgps_present = true;
+-            }
+-
+-            if (m_gps_data->set & DEVICELIST_SET)
+-            {
+-                  if (m_gps_data->devices.ndevices == 1)
+-                  {
+-                        if(g_bDebugGPSD) printf("DEVICELIST_SET\n");
+-                        if(g_bDebugGPSD) printf("Activated %g\n", m_gps_data->devices.list[0].activated);
+-
+-                        if (m_gps_data->devices.list[0].activated == 0)
+-                        {
+-                              if(g_bDebugGPSD)printf("---Being deactivated\n");
+-                              m_bgps_present = false;
+-                              break;
+-                        }
+-                        else
+-                        {
+-                              if(g_bDebugGPSD)printf("Active\n");
+-                              m_bgps_present = true;
+-                        }
+-                  }
+-            }
+-*/
+-
+-            if(!m_bgps_present)
+-            {
+-                  if(g_bDebugGPSD)printf("  no gps device\n");
+-            }
+-            else
+-            {
+-                  if(g_bDebugGPSD)printf("  GPS!\n");
+-            }
+-
+-
+-            if(m_gps_data->set & TIME_SET)
+-                  ThreadPositionData.FixTime = (time_t)m_gps_data->fix.time;
+-
+-            if(m_gps_data->set & LATLON_SET)
+-            {
+-                  if(g_bDebugGPSD) printf("  LATLON  %g  %g \n", m_gps_data->fix.latitude, m_gps_data->fix.longitude );
+-                  ThreadPositionData.kLat = m_gps_data->fix.latitude;
+-                  ThreadPositionData.kLon = m_gps_data->fix.longitude;
+-            }
+-
+-            if(m_gps_data->set & TRACK_SET)
+-            {
+-                  if(g_bDebugGPSD) printf("  TRACK_SET\n");
+-                  ThreadPositionData.kCog = 0.;
+-                  if(!wxIsNaN(m_gps_data->fix.track))
+-                        ThreadPositionData.kCog = m_gps_data->fix.track;
+-            }
+-
+-            if(m_gps_data->set & SPEED_SET)
+-            {
+-                  if(g_bDebugGPSD) printf("  SPEED_SET\n");
+-                  ThreadPositionData.kSog = 0.;
+-                  if(!wxIsNaN(m_gps_data->fix.speed))
+-                        ThreadPositionData.kSog = m_gps_data->fix.speed * 3600. / 1852.;      // convert from m/s to knots
+-            }
+-
+-            if(m_gps_data->set & SATELLITE_SET)
+-            {
+-                  if(g_bDebugGPSD) printf("  SATELLITE_SET  %d\n", m_gps_data->satellites_visible);
+-                  ThreadPositionData.nSats = m_gps_data->satellites_visible;
+-            }
+-
+-            if(m_gps_data->set & ERROR_SET)
+-            {
+-                  if(g_bDebugGPSD)
+-                  {
+-                        char error[sizeof(m_gps_data->error) + 1];
+-                        strncpy(error, m_gps_data->error, sizeof(m_gps_data->error));
+-                        printf("  ERROR_SET  %s\n", error);
+-                  }
+-
+-            }
+-
+-            if(m_bgps_present)  // GPS must be online
+-            {
+-                  if(g_bDebugGPSD) printf("  STATUS_SET: %d status %d\n", (m_gps_data->set & STATUS_SET) != 0, m_gps_data->status);
+-                  if((m_gps_data->set & STATUS_SET) && (m_gps_data->status > 0)) // and producing a fix
+-                  {
+-                        wxCommandEvent event( EVT_NMEA,  m_handler_id );
+-                        event.SetEventObject( (wxObject *)this );
+-                        event.SetExtraLong(EVT_NMEA_DIRECT);
+-                        event.SetClientData(&ThreadPositionData);
+-                        m_pParentEventHandler->AddPendingEvent(event);
+-                        if(g_bDebugGPSD)  printf(" Sending Event\n");
+-                   }
+-            }
+-      }
+-
+-      TimerLIBGPS.Start(TIMER_LIBGPS_MSEC,wxTIMER_CONTINUOUS);
+-#endif
+-}
+-
+-
+ void NMEAHandler::OnSocketEvent(wxSocketEvent& event)
+ {
+ #ifndef OCPN_NO_SOCKETS
+@@ -1810,6 +1794,291 @@
+ }
+ #endif
+ 
++
++
++
++
++///
++//-------------------------------------------------------------------------------------------------------------
++//
++//    GPSD Library Input Thread
++//
++//-------------------------------------------------------------------------------------------------------------
++
++int ic;
++
++OCP_GPSD_Thread::OCP_GPSD_Thread(NMEAHandler *Launcher, wxWindow *MessageTarget,
++                                  wxString &ip_addr, int api)
++
++{
++      m_launcher = Launcher;                        // This thread's immediate "parent"
++
++      m_pMainEventHandler = MessageTarget->GetEventHandler();
++
++      m_pgps_data = NULL;
++      m_libgps_api = api;
++      m_GPSD_data_ip = ip_addr;
++      if(api == 19) {
++            m_PACKET_SET = 0x20000000u;
++            m_TIME_SET   = 0x00000002u;
++            m_LATLON_SET = 0x00000008u;
++            m_TRACK_SET  = 0x00000040u;
++            m_SPEED_SET  = 0x00000020u;
++            m_SATELLITE_SET = 0x00010000u;
++            m_ERROR_SET     = 0x02000000u;
++            m_STATUS_SET    = 0x00000100u;
++
++      }
++      else {
++            m_PACKET_SET    = 1u<<25;
++            m_TIME_SET      = (1u<<2);
++            m_LATLON_SET    = (1u<<4);
++            m_TRACK_SET     = (1u<<7);
++            m_SPEED_SET     = (1u<<6);
++            m_SATELLITE_SET = (1u<<15);
++            m_ERROR_SET     = (1u<<31);
++            m_STATUS_SET    = (1u<<9);
++
++      }
++
++      Create();
++
++}
++
++OCP_GPSD_Thread::~OCP_GPSD_Thread(void)
++{
++}
++
++void OCP_GPSD_Thread::OnExit(void)
++{
++}
++
++
++//    Entry Point
++void *OCP_GPSD_Thread::Entry()
++{
++      m_launcher->SetSecThreadActive();               // I am alive
++
++      bool not_done = true;
++      wxString msg;
++      int lost_secs = 0;
++      bool b_try_reopen = false;
++
++//    The main loop
++
++      while((not_done) && (m_launcher->m_Thread_run_flag > 0))
++      {
++            if(TestDestroy())
++                  not_done = false;                               // smooth exit
++
++            if( m_launcher->IsPauseRequested())                 // external pause requested?
++            {
++            }
++
++#ifdef __POSIX__
++
++#ifdef BUILD_WITH_LIBGPS
++
++//      g_bDebugGPSD = true;
++
++            if(g_bDebugGPSD) printf("%d\n", ic++);
++            m_bgps_present = false;
++
++            if(!m_pgps_data)
++            {
++                  b_try_reopen = true;
++                  if(g_bDebugGPSD) printf("NULL m_gps_data\n");
++            }
++
++            else if(s_fn_gps_waiting(m_pgps_data, 1000000))          // 1 sec
++            {
++                  lost_secs = 0;
++                  m_pgps_data->set = 0;
++
++                  if(20 == m_libgps_api)
++                        s_fn_gps_read(m_pgps_data);
++                  else if(19 == m_libgps_api)
++                        s_fn_gps_poll(m_pgps_data);
++
++                  if(g_bDebugGPSD) printf("  Poll/Read Set: %0X\n", (unsigned int)m_pgps_data->set);
++
++                  if (!(m_pgps_data->set & m_PACKET_SET))  // this is what sometimes happens when gpsd is killed or dies
++                        b_try_reopen = true;
++
++
++                  m_bgps_present = true;
++
++                  if(m_pgps_data->set & m_TIME_SET)
++                        ThreadPositionData.FixTime = (time_t)m_pgps_data->fix.time;
++
++                  if(m_pgps_data->set & m_LATLON_SET)
++                  {
++                        if(g_bDebugGPSD) printf("  LATLON  %g  %g \n", m_pfix->latitude, m_pfix->longitude );
++                        ThreadPositionData.kLat = m_pfix->latitude;
++                        ThreadPositionData.kLon = m_pfix->longitude;
++                  }
++
++                  if(m_pgps_data->set & m_TRACK_SET)
++                  {
++                        if(g_bDebugGPSD) printf("  TRACK_SET\n");
++                        ThreadPositionData.kCog = 0.;
++                        if(!wxIsNaN(m_pfix->track))
++                              ThreadPositionData.kCog = m_pfix->track;
++                  }
++
++                  if(m_pgps_data->set & m_SPEED_SET)
++                  {
++                        if(g_bDebugGPSD) printf("  SPEED_SET\n");
++                        ThreadPositionData.kSog = 0.;
++                        if(!wxIsNaN(m_pfix->speed))
++                              ThreadPositionData.kSog = m_pfix->speed * 3600. / 1852.;      // convert from m/s to knots
++                  }
++
++                  if(m_pgps_data->set & m_SATELLITE_SET)
++                  {
++                        if(g_bDebugGPSD) printf("  SATELLITE_SET  %d\n", *m_psats_viz);
++                        ThreadPositionData.nSats = *m_psats_viz;
++                  }
++
++                  if((m_libgps_api != 19) && (m_pgps_data->set & m_ERROR_SET) )     // not (easily) available on API 19
++                  {
++                        if(g_bDebugGPSD)
++                        {
++                              char error[sizeof(m_pgps_data->error) + 1];
++                              strncpy(error, m_pgps_data->error, sizeof(m_pgps_data->error));
++                              error[sizeof(m_pgps_data->error)] = 0;
++                              printf("  ERROR_SET  %s\n", error);
++                        }
++
++                  }
++
++                  if(m_bgps_present)  // GPS must be online
++                  {
++                  // gpsd does not produce Hdt/Hdm  (new for OpenCPN 3.0.0+)
++                  //    ThreadPositionData.kHdm = NAN;
++                  //    ThreadPositionData.kHdt = NAN;
++
++                        if(g_bDebugGPSD) printf("  STATUS_SET: %d status %d\n", (m_pgps_data->set & m_STATUS_SET) != 0, *m_pstatus);
++                        if((m_pgps_data->set & m_STATUS_SET) && (*m_pstatus > 0)) // and producing a fix
++                        {
++                              wxCommandEvent event( EVT_NMEA);//,  m_handler_id );
++                              event.SetEventObject( (wxObject *)this );
++                              event.SetExtraLong(EVT_NMEA_DIRECT);
++                              event.SetClientData(&ThreadPositionData);
++                              m_pMainEventHandler->AddPendingEvent(event);
++
++                              if(g_bDebugGPSD)  printf(" Sending Event\n");
++                        }
++                  }
++            }
++            else {
++                  lost_secs++;
++                  if(m_libgps_api == 19)
++                        wxSleep(1);
++            }
++
++
++            if( (lost_secs >= 5) || b_try_reopen)
++            {
++                  {
++                        if(g_bDebugGPSD)  printf("Probably lost GPSD\n");
++                        m_bgps_present = false;
++
++                        CloseLibrary();
++                        if(OpenLibrary())
++                              if(g_bDebugGPSD)  printf(" Re-opened library\n");
++
++                        sleep(2);               // give libgps a chance to stabilize
++                        lost_secs = 0;
++                        b_try_reopen = false;
++
++                  }
++            }
++
++#endif
++#endif            //__POSIX__
++      }                          // the big while...
++
++      m_launcher->SetSecThreadInActive();             // I am dead
++      m_launcher->m_Thread_run_flag = -1;
++      return 0;
++}
++
++#ifdef __POSIX__
++
++bool OCP_GPSD_Thread::OpenLibrary(void)
++{
++#ifdef BUILD_WITH_LIBGPS
++            //    Try to open the library
++      if(19 == m_libgps_api)
++      {
++            m_pgps_data = s_fn_gps_open19(m_GPSD_data_ip.char_str(), (char *)DEFAULT_GPSD_PORT);
++
++            if(!m_pgps_data)
++            {
++                  if(g_bDebugGPSD) printf("  Could not (re)open libgps API 19\n");
++                  return false;
++            }
++
++            //    API version 19 structure layout differs from API V20.
++            //    We build with the API20 include file, so
++            //    we need to hack an adjusted pointer to the GPS fix location.
++            //    Once more, gpsd architects do it again......
++            int *t19 = (int *)m_pgps_data;
++            t19--;
++            struct gps_data_t *p19_adjust = (struct gps_data_t *)t19;
++            m_pfix = &(p19_adjust->fix);
++            m_pstatus = &(p19_adjust->status);
++            m_psats_viz = &(p19_adjust->satellites_visible);
++      }
++
++      else if(20 == m_libgps_api)
++      {
++            m_pgps_data = &gpsd_data;
++            int result_open = s_fn_gps_open(m_GPSD_data_ip.char_str(), (char *)DEFAULT_GPSD_PORT, m_pgps_data);
++
++            if (result_open != 0)
++            {
++                  if(g_bDebugGPSD) printf("  Could not (re)open libgps API 20\n");
++                  m_pgps_data = NULL;
++                  return false;
++            }
++            m_pfix = &(m_pgps_data->fix);
++            m_pstatus = &(m_pgps_data->status);
++            m_psats_viz = &(m_pgps_data->satellites_visible);
++
++      }
++
++      s_fn_gps_stream(m_pgps_data, WATCH_ENABLE, NULL);
++
++#endif
++      return true;
++
++}
++
++void OCP_GPSD_Thread::CloseLibrary(void)
++{
++#ifdef BUILD_WITH_LIBGPS
++
++      if(m_pgps_data && s_fn_gps_close)
++      {
++            s_fn_gps_close(m_pgps_data);
++            m_pgps_data = NULL;
++      }
++#endif
++}
++
++
++#endif          //__POSIX__
++
++
++
++
++
++
++
++
++
+ //-------------------------------------------------------------------------------------------------------------
+ //
+ //    NMEA Serial Input Thread




More information about the Pkg-grass-devel mailing list