[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
signature.asc
Description: PGP signature