gpsd-dev
[Top][All Lists]
Advanced

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

Re: [gpsd-dev] Autobaud broken


From: Gary E. Miller
Subject: Re: [gpsd-dev] Autobaud broken
Date: Mon, 25 Nov 2013 19:35:04 -0800

Yo Eric!

Local maybe, but also new, and certainly broken.  I never tested the exact
3.10, so maybe it got broken before.  Gonna be a busy week for me, family
already here for Thanskgiving, but I'll poke at it.  More pressing to me
is the broken PPS since I can work around the autobaud.

On Mon, 25 Nov 2013 22:28:48 -0500
"Eric S. Raymond" <address@hidden> wrote:

> 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");




RGDS
GARY
---------------------------------------------------------------------------
Gary E. Miller Rellim 109 NW Wilmington Ave., Suite E, Bend, OR 97701
        address@hidden  Tel:+1(541)382-8588

Attachment: signature.asc
Description: PGP signature


reply via email to

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