gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gpsd-dev] Autobaud broken


From: Eric S. Raymond
Subject: Re: [gpsd-dev] Autobaud broken
Date: Mon, 25 Nov 2013 22:28:48 -0500
User-agent: Mutt/1.5.21 (2010-09-15)

Gary E. Miller <address@hidden>:
> FYI, autobaud is broken in git head.  I need to manually set my SiRF III
> to 57,600.  Last week that was not the case.

The autobaud code hasn't changed since last week.

Here is a .c and .h diff from 3.10.  It's just core code, excluding
gp2udp and gpsmon, and I've removed bands that are comments only.
There's just not a lot there and none of it touches autobauding.
You're having some local problem.

diff --git a/gpsd.c b/gpsd.c
index c77f684..22fe14f 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -44,11 +44,6 @@
 
 #include "gpsd_config.h"
 
-#if defined(HAVE_LIBCAP) && !defined(S_SPLINT_S)
-#include <sys/capability.h>
-#include <sys/prctl.h>
-#endif /* HAVE_LIBCAP */
-
 #include "gpsd.h"
 #include "sockaddr.h"
 #include "gps_json.h"
@@ -2039,13 +2034,6 @@ int main(int argc, char *argv[])
        struct passwd *pw;
        struct stat stb;
 
-#if defined(HAVE_LIBCAP) && !defined(S_SPLINT_S)
-       /* set flag: keep privileges across setuid() call */
-       if (prctl(PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L) == -1)
-           gpsd_report(context.debug, LOG_ERR,
-                       "prctl(PR_SET_KEEPCAPS, 1L ) failed\n");
-#endif /* HAVE_LIBCAP */
-
        /* make default devices accessible even after we drop privileges */
        for (i = optind; i < argc; i++)
            /* coverity[toctou] */
@@ -2059,6 +2047,12 @@ int main(int argc, char *argv[])
         * of any compromises in the code.  It requires that all GPS
         * devices have their group read/write permissions set.
         */
+       /address@hidden@*/
+       if (setgroups(0, NULL) != 0)
+           gpsd_report(context.debug, LOG_ERROR,
+                       "setgroups() failed, errno %s\n",
+                       strerror(errno));
+       /address@hidden@*/
        /address@hidden@*/
 #ifdef GPSD_GROUP
        {
@@ -2087,21 +2081,6 @@ int main(int argc, char *argv[])
                            "setuid() failed, errno %s\n",
                            strerror(errno));
        /address@hidden@*/
-
- #if defined(HAVE_LIBCAP) && !defined(S_SPLINT_S)
-       /* drop root capabilities, except CAP_SYS_TIME for 1PPS support */
-       {
-           cap_t caps = cap_from_text("cap_sys_time=pe");
-
-           if (!caps)
-               gpsd_report(context.debug, LOG_ERR, "cap_from_text() 
failed.\n");
-           else if (cap_set_proc(caps) == -1) {
-               gpsd_report(context.debug, LOG_ERR,
-                           "cap_set_proc() failed to drop root privs\n");
-               cap_free(caps);
-           }
-       }
-#endif /* HAVE_LIBCAP */
     }
     gpsd_report(context.debug, LOG_INF,
                "running with effective group ID %d\n", getegid());
diff --git a/gpsd_json.c b/gpsd_json.c
index d80047c..4eb8bc1 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -213,10 +213,17 @@ void json_tpv_dump(const struct gps_device_t *session,
                           replylen - strlen(reply),
                           "\"epc\":%.2f,", gpsdata->fix.epc);
 #ifdef TIMING_ENABLE
-       if (policy->timing)
-           (void)snprintf(reply + strlen(reply),
-               replylen - strlen(reply),
-                          
"\"sor\":%f,\"chars\":%lu,\"sats\":%2d,\"rtime\":%f,\"week\":%u,\"tow\":%.3f,\"rollovers\":%d",
+       if (policy->timing) {
+#ifdef PPS_ENABLE
+           /address@hidden address@hidden/ /* splint is confused about struct 
timespec */
+           if (session->ppscount)
+               (void)snprintf(reply + strlen(reply), replylen - strlen(reply),
+                              "\"pps\":%.9f,", 
+                              session->ppslast.clock.tv_sec + 
session->ppslast.clock.tv_nsec / 1e9);
+           /address@hidden address@hidden/
+#endif /* PPS_ENABLE */
+           (void)snprintf(reply + strlen(reply), replylen - strlen(reply),
+                          
"\"sor\":%.9f,\"chars\":%lu,\"sats\":%2d,\"rtime\":%.9f,\"week\":%u,\"tow\":%.3f,\"rollovers\":%d",
                           session->sor,
                           session->chars,
                           gpsdata->satellites_used,
@@ -224,6 +231,7 @@ void json_tpv_dump(const struct gps_device_t *session,
                           session->context->gps_week,
                           session->context->gps_tow,
                           session->context->rollovers);
+       }
 #endif /* TIMING_ENABLE */
     }
     if (reply[strlen(reply) - 1] == ',')
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 0774c88..35c9a4b 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -943,7 +946,7 @@ static void gpsd_error_model(struct gps_device_t *session,
        }
        if ((fix->mode >= MODE_3D)
            && isnan(fix->epc) != 0 && fix->time > oldfix->time) {
-           if (oldfix->mode > MODE_3D && fix->mode > MODE_3D) {
+           if (oldfix->mode >= MODE_3D && fix->mode >= MODE_3D) {
                timestamp_t t = fix->time - oldfix->time;
                double e = oldfix->epv + fix->epv;
                /* if vertical uncertainties are zero this will be too */
@@ -1143,9 +1146,9 @@ gps_mask_t gpsd_poll(struct gps_device_t *session)
        timestamp_t now = timestamp();
        if (session->device_type != NULL && session->packet.start_time > 0) {
 #ifdef RECONFIGURE_ENABLE
-           const time_t min_cycle = session->device_type->min_cycle;
+           const double min_cycle = session->device_type->min_cycle;
 #else
-           const time_t min_cycle = 1;
+           const double min_cycle = 1;
 #endif /* RECONFIGURE_ENABLE */
            double quiet_time = (MINIMUM_QUIET_TIME * min_cycle);
            double gap = now - session->packet.start_time;
diff --git a/ntpshm.c b/ntpshm.c
index 109e4ea..fe8e450 100644
--- a/ntpshm.c
+++ b/ntpshm.c
@@ -351,7 +351,7 @@ static void chrony_send(struct gps_device_t *session, 
struct timedrift_t *td)
     sample.leap = session->context->leap_notify;
     sample.magic = SOCK_MAGIC;
     /address@hidden@*//* splint is confused about struct timespec */
-    TSTOTV(&sample.tv, &td->real);
+    TSTOTV(&sample.tv, &td->clock);
     /address@hidden@*/
     sample.offset = timespec_diff_ns(td->real, td->clock) / 1e9;
     /address@hidden@*/
diff --git a/ppsthread.c b/ppsthread.c
index fe1947b..96551fc 100644
--- a/ppsthread.c
+++ b/ppsthread.c
@@ -63,21 +76,36 @@ static pthread_mutex_t ppslast_mutex;
 static int init_kernel_pps(struct gps_device_t *session)
 /* return handle for kernel pps, or -1; requires root privileges */
 {
-    int ldisc = 18;   /* the PPS line discipline */
 #ifndef S_SPLINT_S
     pps_params_t pp;
 #endif /* S_SPLINT_S */
+    int ret;
+#ifdef linux
+    /* These variables are only needed by Linux to find /dev/ppsN. */
+    int ldisc = 18;   /* the PPS line discipline */
     glob_t globbuf;
     size_t i;             /* to match type of globbuf.gl_pathc */
     char pps_num = '\0';  /* /dev/pps[pps_num] is our device */
     char path[GPS_PATH_MAX] = "";
-    int ret;
+#endif
 
     session->kernelpps_handle = -1;
     if ( isatty(session->gpsdata.gps_fd) == 0 ) {
        gpsd_report(session->context->debug, LOG_INF, "KPPS gps_fd not a 
tty\n");
        return -1;
     }
+
+    /*
+     * This next code block abuses "ret" by storing the filedescriptor
+     * to use for RFC2783 calls.
+     */
+    ret = -1;
+#ifdef linux
+    /*
+     * On Linux, one must make calls to associate a serial port with a
+     * /dev/ppsN device and then grovel in system data to determine
+     * the association.
+     */
     /address@hidden@*/
     /* Attach the line PPS discipline, so no need to ldattach */
     /* This activates the magic /dev/pps0 device */
@@ -146,6 +174,19 @@ static int init_kernel_pps(struct gps_device_t *session)
                    "KPPS cannot open %s: %s\n", path, strerror(errno));
        return -1;
     }
+#else /* not linux */
+    /*
+     * On BSDs that support RFC2783, one uses the API calls on serial
+     * port file descriptor.
+     */
+    // cppcheck-suppress redundantAssignment
+    ret  = session->gpsdata.gps_fd;
+#endif
+    /* assert(ret >= 0); */
+    gpsd_report(session->context->debug, LOG_INF,
+               "RFC2783 fd is %d\n",
+               ret);
+
     /* RFC 2783 implies the time_pps_setcap() needs priviledges *
      * keep root a tad longer just in case */
     if ( 0 > time_pps_create(ret, &session->kernelpps_handle )) {
@@ -166,9 +207,16 @@ static int init_kernel_pps(struct gps_device_t *session)
                        LOG_INF, "KPPS caps %0x\n", caps);
         }
 
+#ifdef linux
         /* linux 2.6.34 can not PPS_ECHOASSERT | PPS_ECHOCLEAR */
         memset( (void *)&pp, 0, sizeof(pps_params_t));
         pp.mode = PPS_CAPTUREBOTH;
+#else /* not linux */
+       /*
+        * Attempt to follow RFC2783 as straightforwardly as possible.
+        */
+       pp.mode = PPS_TSFMT_TSPEC | PPS_CAPTUREBOTH;
+#endif
 #endif /* S_SPLINT_S */
 
         if ( 0 > time_pps_setparams(session->kernelpps_handle, &pp)) {
@@ -258,14 +306,36 @@ static /address@hidden@*/ void *gpsd_ppsmonitor(void *arg)
 #if defined(HAVE_SYS_TIMEPPS_H) && !defined(S_SPLINT_S)
         if ( 0 <= session->kernelpps_handle ) {
            struct timespec kernelpps_tv;
+#ifdef linux
+           /*
+            * \todo Explain the use of a non-NULL zero timespec,
+            * which means to return immediately with -1 (section
+            * 3.4.3).  Further, explain the non-sensical comment,
+            * because the intent of RFC2783 is that the timestamp has
+            * already been captured in the kernel, and we are merely
+            * fetching it here.
+            */
            /* on a quad core 2.4GHz Xeon this removes about 20uS of
             * latency, and about +/-5uS of jitter over the other method */
             memset( (void *)&kernelpps_tv, 0, sizeof(kernelpps_tv));
+#else /* not linux */
+           /*
+            * RFC2783 specifies that a NULL timeval means to wait.
+            */
+           kernelpps_tv.tv_sec = 1;
+           kernelpps_tv.tv_nsec = 0;
+#endif
            if ( 0 > time_pps_fetch(session->kernelpps_handle, PPS_TSFMT_TSPEC
                , &pi, &kernelpps_tv)) {
                gpsd_report(session->context->debug, LOG_ERROR,
                            "KPPS kernel PPS failed\n");
            } else {
+               /* Wait until we have both edges. */
+               if (pi.assert_sequence == 0 || pi.clear_sequence == 0) {
+                   usleep(100000);
+                   continue;
+               }
+
                // find the last edge
                // FIXME a bit simplistic, should hook into the
                 // cycle/duration check below.
@@ -282,15 +352,20 @@ static /address@hidden@*/ void *gpsd_ppsmonitor(void *arg)
                    edge_kpps = 0;
                    ts_kpps = pi.clear_timestamp;
                }
+               /*
+                * pps_seq_t is uint32_t on NetBSD, so cast to
+                * unsigned long as a wider-or-equal type to
+                * accomodate Linux's type.
+                */
                gpsd_report(session->context->debug, LOG_PROG,
                            "KPPS assert %ld.%09ld, sequence: %ld - "
                            "clear  %ld.%09ld, sequence: %ld\n",
                            pi.assert_timestamp.tv_sec,
                            pi.assert_timestamp.tv_nsec,
-                           pi.assert_sequence,
+                           (unsigned long) pi.assert_sequence,
                            pi.clear_timestamp.tv_sec,
                            pi.clear_timestamp.tv_nsec,
-                           pi.clear_sequence);
+                           (unsigned long) pi.clear_sequence);
                gpsd_report(session->context->debug, LOG_PROG,
                            "KPPS data: using %s\n",
                            edge_kpps ? "assert" : "clear");
-- 
                <a href="http://www.catb.org/~esr/";>Eric S. Raymond</a>

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]