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