Coverage Report

Created: 2026-02-26 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/ntpd/refclock_gpsdjson.c
Line
Count
Source
1
/*
2
 * refclock_gpsdjson.c - clock driver as GPSD JSON client
3
 *  Juergen Perlinger (perlinger@ntp.org)
4
 *  Feb 11, 2014 for the NTP project.
5
 *      The contents of 'html/copyright.html' apply.
6
 *
7
 *  Heavily inspired by refclock_nmea.c
8
 *
9
 * Special thanks to Gary Miller and Hal Murray for their comments and
10
 * ideas.
11
 *
12
 * Note: This will currently NOT work with Windows due to some
13
 * limitations:
14
 *
15
 *  - There is no GPSD for Windows. (There is an unofficial port to
16
 *    cygwin, but Windows is not officially supported.)
17
 *
18
 *  - To work properly, this driver needs PPS and TPV/TOFF sentences
19
 *    from GPSD. I don't see how the cygwin port should deal with the
20
 *    PPS signal.
21
 *
22
 *  - The device name matching must be done in a different way for
23
 *    Windows. (Can be done with COMxx matching, as done for NMEA.)
24
 *
25
 * Apart from those minor hickups, once GPSD has been fully ported to
26
 * Windows, there's no reason why this should not work there ;-) If this
27
 * is ever to happen at all is a different question.
28
 *
29
 * ---------------------------------------------------------------------
30
 *
31
 * This driver works slightly different from most others, as the PPS
32
 * information (if available) is also coming from GPSD via the data
33
 * connection. This makes using both the PPS data and the serial data
34
 * easier, but OTOH it's not possible to use the ATOM driver to feed a
35
 * raw PPS stream to the core of NTPD.
36
 *
37
 * To go around this, the driver can use a secondary clock unit
38
 * (units>=128) that operate in tandem with the primary clock unit
39
 * (unit%128). The primary clock unit does all the IO stuff and data
40
 * decoding; if a a secondary unit is attached to a primary unit, this
41
 * secondary unit is feed with the PPS samples only and can act as a PPS
42
 * source to the clock selection.
43
 *
44
 * The drawback is that the primary unit must be present for the
45
 * secondary unit to work.
46
 *
47
 * This design is a compromise to reduce the IO load for both NTPD and
48
 * GPSD; it also ensures that data is transmitted and evaluated only
49
 * once on the side of NTPD.
50
 *
51
 * ---------------------------------------------------------------------
52
 *
53
 * trouble shooting hints:
54
 *
55
 *   Enable and check the clock stats. Check if there are bad replies;
56
 *   there should be none. If there are actually bad replies, then the
57
 *   driver cannot parse all JSON records from GPSD, and some record
58
 *   types are vital for the operation of the driver. This indicates a
59
 *   problem on the protocol level.
60
 *
61
 *   When started on the command line with a debug level >= 2, the
62
 *   driver dumps the raw received data and the parser input to
63
 *   stdout. Since the debug level is global, NTPD starts to create a
64
 *   *lot* of output. It makes sense to pipe it through '(f)grep
65
 *   GPSD_JSON' before writing the result to disk.
66
 *
67
 *   A bit less intrusive is using netcat or telnet to connect to GPSD
68
 *   and snoop what NTPD would get. If you try this, you have to send a
69
 *   WATCH command to GPSD:
70
 *
71
 * ?WATCH={"device":"/dev/gps0","enable":true,"json":true,"pps":true};<CRLF>
72
 *
73
 *   should show you what GPSD has to say to NTPD. Replace "/dev/gps0"
74
 *   with the device link used by GPSD, if necessary.
75
 */
76
77
78
#ifdef HAVE_CONFIG_H
79
#include <config.h>
80
#endif
81
82
#include "ntp_types.h"
83
84
#if defined(REFCLOCK) && defined(CLOCK_GPSDJSON) && !defined(SYS_WINNT)
85
86
/* =====================================================================
87
 * Get the little JSMN library directly into our guts. Use the 'parent
88
 * link' feature for maximum speed.
89
 */
90
#define JSMN_PARENT_LINKS
91
#include "../libjsmn/jsmn.c"
92
93
/* =====================================================================
94
 * JSON parsing stuff
95
 */
96
97
0
#define JSMN_MAXTOK 350
98
0
#define INVALID_TOKEN (-1)
99
100
typedef struct json_ctx {
101
  char        * buf;
102
  int           ntok;
103
  jsmntok_t     tok[JSMN_MAXTOK];
104
} json_ctx;
105
106
typedef int tok_ref;
107
108
/* Not all targets have 'long long', and not all of them have 'strtoll'.
109
 * Sigh. We roll our own integer number parser.
110
 */
111
#ifdef HAVE_LONG_LONG
112
typedef signed   long long int json_int;
113
typedef unsigned long long int json_uint;
114
0
#define JSON_INT_MAX LLONG_MAX
115
0
#define JSON_INT_MIN LLONG_MIN
116
#else
117
typedef signed   long int json_int;
118
typedef unsigned long int json_uint;
119
#define JSON_INT_MAX LONG_MAX
120
#define JSON_INT_MIN LONG_MIN
121
#endif
122
123
/* =====================================================================
124
 * header stuff we need
125
 */
126
127
#include <netdb.h>
128
#include <unistd.h>
129
#include <fcntl.h>
130
#include <string.h>
131
#include <ctype.h>
132
#include <math.h>
133
134
#include <sys/types.h>
135
#include <sys/socket.h>
136
#include <sys/stat.h>
137
#include <netinet/tcp.h>
138
139
#if defined(HAVE_SYS_POLL_H)
140
# include <sys/poll.h>
141
#elif defined(HAVE_SYS_SELECT_H)
142
# include <sys/select.h>
143
#else
144
# error need poll() or select()
145
#endif
146
147
#include "ntpd.h"
148
#include "ntp_io.h"
149
#include "ntp_unixtime.h"
150
#include "ntp_refclock.h"
151
#include "ntp_stdlib.h"
152
#include "ntp_calendar.h"
153
#include "ntp_clockdev.h"
154
#include "timespecops.h"
155
156
/* get operation modes from mode word.
157
158
 * + SERIAL (default) evaluates only serial time information ('STI') as
159
 *   provided by TPV and TOFF records. TPV evaluation suffers from a
160
 *   bigger jitter than TOFF, sine it does not contain the receive time
161
 *   from GPSD and therefore the receive time of NTPD must be
162
 *   substituted for it. The network latency makes this a second rate
163
 *   guess.
164
 *
165
 *   If TOFF records are detected in the data stream, the timing
166
 *   information is gleaned from this record -- it contains the local
167
 *   receive time stamp from GPSD and therefore eliminates the
168
 *   transmission latency between GPSD and NTPD. The timing information
169
 *   from TPV is ignored once a TOFF is detected or expected.
170
 *
171
 *   TPV is still used to check the fix status, so the driver can stop
172
 *   feeding samples when GPSD says that the time information is
173
 *   effectively unreliable.
174
 *
175
 * + STRICT means only feed clock samples when a valid STI/PPS pair is
176
 *   available. Combines the reference time from STI with the pulse time
177
 *   from PPS. Masks the serial data jitter as long PPS is available,
178
 *   but can rapidly deteriorate once PPS drops out.
179
 *
180
 * + AUTO tries to use STI/PPS pairs if available for some time, and if
181
 *   this fails for too long switches back to STI only until the PPS
182
 *   signal becomes available again. See the HTML docs for this driver
183
 *   about the gotchas and why this is not the default.
184
 */
185
0
#define MODE_OP_MASK   0x03
186
0
#define MODE_OP_STI    0
187
0
#define MODE_OP_STRICT 1
188
0
#define MODE_OP_AUTO   2
189
0
#define MODE_OP_MAXVAL 2
190
0
#define MODE_OP_MODE(x)   ((x) & MODE_OP_MASK)
191
192
0
#define PRECISION (-9)  /* precision assumed (about 2 ms) */
193
0
#define PPS_PRECISION (-20)  /* precision assumed (about 1 us) */
194
0
#define REFID   "GPSD"  /* reference id */
195
0
#define DESCRIPTION "GPSD JSON client clock" /* who we are */
196
197
#define MAX_PDU_LEN 8192  /* multi-GNSS reports can be HUGE */
198
0
#define TICKOVER_LOW  10
199
#define TICKOVER_HIGH 120
200
0
#define LOGTHROTTLE 3600
201
202
/* Primary channel PPS avilability dance:
203
 * Every good PPS sample gets us a credit of PPS_INCCOUNT points, every
204
 * bad/missing PPS sample costs us a debit of PPS_DECCOUNT points. When
205
 * the account reaches the upper limit we change to a mode where only
206
 * PPS-augmented samples are fed to the core; when the account drops to
207
 * zero we switch to a mode where TPV-only timestamps are fed to the
208
 * core.
209
 * This reduces the chance of rapid alternation between raw and
210
 * PPS-augmented time stamps.
211
 */
212
0
#define PPS_MAXCOUNT  60  /* upper limit of account  */
213
#define PPS_INCCOUNT     3  /* credit for good samples */
214
#define PPS_DECCOUNT     1  /* debit for bad samples   */
215
216
/* The secondary (PPS) channel uses a different strategy to avoid old
217
 * PPS samples in the median filter.
218
 */
219
0
#define PPS2_MAXCOUNT 10
220
221
#ifndef BOOL
222
0
# define BOOL int
223
#endif
224
#ifndef TRUE
225
# define TRUE 1
226
#endif
227
#ifndef FALSE
228
# define FALSE 0
229
#endif
230
231
#define PROTO_VERSION(hi,lo) \
232
0
      ((((uint32_t)(hi) << 16) & 0xFFFF0000u) | \
233
0
       ((uint32_t)(lo) & 0x0FFFFu))
234
235
/* some local typedefs: The NTPD formatting style cries for short type
236
 * names, and we provide them locally. Note:the suffix '_t' is reserved
237
 * for the standard; I use a capital T instead.
238
 */
239
typedef struct peer         peerT;
240
typedef struct refclockproc clockprocT;
241
typedef struct addrinfo     addrinfoT;
242
243
/* =====================================================================
244
 * We use the same device name scheme as does the NMEA driver; since
245
 * GPSD supports the same links, we can select devices by a fixed name.
246
 */
247
static const char * s_dev_stem = "/dev/gps";
248
249
/* =====================================================================
250
 * forward declarations for transfer vector and the vector itself
251
 */
252
253
static  void  gpsd_init (void);
254
static  int gpsd_start  (int, peerT *);
255
static  void  gpsd_shutdown (int, peerT *);
256
static  void  gpsd_receive  (struct recvbuf *);
257
static  void  gpsd_poll (int, peerT *);
258
static  void  gpsd_control  (int, const struct refclockstat *,
259
         struct refclockstat *, peerT *);
260
static  void  gpsd_timer  (int, peerT *);
261
262
static  int     myasprintf(char**, char const*, ...) NTP_PRINTF(2, 3);
263
264
static void     enter_opmode(peerT *peer, int mode);
265
static void leave_opmode(peerT *peer, int mode);
266
267
struct refclock refclock_gpsdjson = {
268
  gpsd_start,   /* start up driver */
269
  gpsd_shutdown,    /* shut down driver */
270
  gpsd_poll,    /* transmit poll message */
271
  gpsd_control,   /* fudge control */
272
  gpsd_init,    /* initialize driver */
273
  noentry,    /* buginfo */
274
  gpsd_timer    /* called once per second */
275
};
276
277
/* =====================================================================
278
 * our local clock unit and data
279
 */
280
struct gpsd_unit;
281
typedef struct gpsd_unit gpsd_unitT;
282
283
struct gpsd_unit {
284
  /* links for sharing between master/slave units */
285
  gpsd_unitT *next_unit;
286
  size_t      refcount;
287
288
  /* data for the secondary PPS channel */
289
  peerT      *pps_peer;
290
291
  /* unit and operation modes */
292
  int      unit;
293
  int      mode;
294
  char    *logname; /* cached name for log/print */
295
  char    * device; /* device name of unit */
296
297
  /* current line protocol version */
298
  uint32_t proto_version;
299
300
  /* PPS time stamps primary + secondary channel */
301
  l_fp pps_local; /* when we received the PPS message */
302
  l_fp pps_stamp; /* related reference time */
303
  l_fp pps_recvt; /* when GPSD detected the pulse */
304
  l_fp pps_stamp2;/* related reference time (secondary) */
305
  l_fp pps_recvt2;/* when GPSD detected the pulse (secondary)*/
306
  int  ppscount;  /* PPS counter (primary unit) */
307
  int  ppscount2; /* PPS counter (secondary unit) */
308
309
  /* TPV or TOFF serial time information */
310
  l_fp sti_local; /* when we received the TPV/TOFF message */
311
  l_fp sti_stamp; /* effective GPS time stamp */
312
  l_fp sti_recvt; /* when GPSD got the fix */
313
314
  /* precision estimates */
315
  int16_t     sti_prec; /* serial precision based on EPT */
316
  int16_t     pps_prec; /* PPS precision from GPSD or above */
317
318
  /* fudge values for correction, mirrored as 'l_fp' */
319
  l_fp pps_fudge;   /* PPS fudge primary channel */
320
  l_fp pps_fudge2;  /* PPS fudge secondary channel */
321
  l_fp sti_fudge;   /* TPV/TOFF serial data fudge */
322
323
  /* Flags to indicate available data */
324
  int fl_nosync: 1; /* GPSD signals bad quality */
325
  int fl_sti   : 1; /* valid TPV/TOFF seen (have time) */
326
  int fl_pps   : 1; /* valid pulse seen */
327
  int fl_pps2  : 1; /* valid pulse seen for PPS channel */
328
  int fl_rawsti: 1; /* permit raw TPV/TOFF time stamps */
329
  int fl_vers  : 1; /* have protocol version */
330
  int fl_watch : 1; /* watch reply seen */
331
  /* protocol flags */
332
  int pf_nsec  : 1; /* have nanosec PPS info */
333
  int pf_toff  : 1; /* have TOFF record for timing */
334
335
  /* admin stuff for sockets and device selection */
336
  int         fdt;  /* current connecting socket */
337
  addrinfoT * addr; /* next address to try */
338
  u_int       tickover; /* timeout countdown */
339
  u_int       tickpres; /* timeout preset */
340
341
  /* tallies for the various events */
342
  u_int       tc_recv;  /* received known records */
343
  u_int       tc_breply;  /* bad replies / parsing errors */
344
  u_int       tc_nosync;  /* TPV / sample cycles w/o fix */
345
  u_int       tc_sti_recv;/* received serial time info records */
346
  u_int       tc_sti_used;/* used        --^-- */
347
  u_int       tc_pps_recv;/* received PPS timing info records */
348
  u_int       tc_pps_used;/* used        --^-- */
349
350
  /* log bloat throttle */
351
  u_int       logthrottle;/* seconds to next log slot */
352
353
  /* The parse context for the current record */
354
  json_ctx    json_parse;
355
356
  /* record assemby buffer and saved length */
357
  int  buflen;
358
  char buffer[MAX_PDU_LEN];
359
};
360
361
/* =====================================================================
362
 * static local helpers forward decls
363
 */
364
static void gpsd_init_socket(peerT * const peer);
365
static void gpsd_test_socket(peerT * const peer);
366
static void gpsd_stop_socket(peerT * const peer);
367
368
static void gpsd_parse(peerT * const peer,
369
           const l_fp  * const rtime);
370
static BOOL convert_ascii_time(l_fp * fp, const char * gps_time);
371
static void save_ltc(clockprocT * const pp, const char * const tc);
372
static int  syslogok(clockprocT * const pp, gpsd_unitT * const up);
373
static void log_data(peerT *peer, int level, const char *what,
374
         const char *buf, size_t len);
375
static int16_t clamped_precision(int rawprec);
376
377
/* =====================================================================
378
 * local / static stuff
379
 */
380
381
static const char * const s_req_version =
382
    "?VERSION;\r\n";
383
384
/* We keep a static list of network addresses for 'localhost:gpsd' or a
385
 * fallback alias of it, and we try to connect to them in round-robin
386
 * fashion. The service lookup is done during the driver init
387
 * function to minmise the impact of 'getaddrinfo()'.
388
 *
389
 * Alas, the init function is called even if there are no clocks
390
 * configured for this driver. So it makes sense to defer the logging of
391
 * any errors or other notifications until the first clock unit is
392
 * started -- otherwise there might be syslog entries from a driver that
393
 * is not used at all.
394
 */
395
static addrinfoT  *s_gpsd_addr;
396
static gpsd_unitT *s_clock_units;
397
398
/* list of service/socket names we want to resolve against */
399
static const char * const s_svctab[][2] = {
400
  { "localhost", "gpsd" },
401
  { "localhost", "2947" },
402
  { "127.0.0.1", "2947" },
403
  { NULL, NULL }
404
};
405
406
/* list of address resolution errors and index of service entry that
407
 * finally worked.
408
 */
409
static int s_svcerr[sizeof(s_svctab)/sizeof(s_svctab[0])];
410
static int s_svcidx;
411
412
/* =====================================================================
413
 * log throttling
414
 */
415
static int/*BOOL*/
416
syslogok(
417
  clockprocT * const pp,
418
  gpsd_unitT * const up)
419
0
{
420
0
  int res = (0 != (pp->sloppyclockflag & CLK_FLAG3))
421
0
         || (0           == up->logthrottle )
422
0
         || (LOGTHROTTLE == up->logthrottle );
423
0
  if (res)
424
0
    up->logthrottle = LOGTHROTTLE;
425
0
  return res;
426
0
}
427
428
/* =====================================================================
429
 * the clock functions
430
 */
431
432
/* ---------------------------------------------------------------------
433
 * Init: This currently just gets the socket address for the GPS daemon
434
 */
435
static void
436
gpsd_init(void)
437
0
{
438
0
  addrinfoT   hints;
439
0
  int         rc, idx;
440
441
0
  memset(s_svcerr, 0, sizeof(s_svcerr));
442
0
  memset(&hints, 0, sizeof(hints));
443
0
  hints.ai_family   = AF_UNSPEC;
444
0
  hints.ai_protocol = IPPROTO_TCP;
445
0
  hints.ai_socktype = SOCK_STREAM;
446
447
0
  for (idx = 0; s_svctab[idx][0] && !s_gpsd_addr; idx++) {
448
0
    rc = getaddrinfo(s_svctab[idx][0], s_svctab[idx][1],
449
0
         &hints, &s_gpsd_addr);
450
0
    s_svcerr[idx] = rc;
451
0
    if (0 == rc)
452
0
      break;
453
0
    s_gpsd_addr = NULL;
454
0
  }
455
0
  s_svcidx = idx;
456
0
}
457
458
/* ---------------------------------------------------------------------
459
 * Init Check: flush pending log messages and check if we can proceed
460
 */
461
static int/*BOOL*/
462
gpsd_init_check(void)
463
0
{
464
0
  int idx;
465
466
  /* Check if there is something to log */
467
0
  if (s_svcidx == 0)
468
0
    return (s_gpsd_addr != NULL);
469
470
  /* spool out the resolver errors */
471
0
  for (idx = 0; idx < s_svcidx; ++idx) {
472
0
    msyslog(LOG_WARNING,
473
0
      "GPSD_JSON: failed to resolve '%s:%s', rc=%d (%s)",
474
0
      s_svctab[idx][0], s_svctab[idx][1],
475
0
      s_svcerr[idx], gai_strerror(s_svcerr[idx]));
476
0
  }
477
478
  /* check if it was fatal, or if we can proceed */
479
0
  if (s_gpsd_addr == NULL)
480
0
    msyslog(LOG_ERR, "%s",
481
0
      "GPSD_JSON: failed to get socket address, giving up.");
482
0
  else if (idx != 0)
483
0
    msyslog(LOG_WARNING,
484
0
      "GPSD_JSON: using '%s:%s' instead of '%s:%s'",
485
0
      s_svctab[idx][0], s_svctab[idx][1],
486
0
      s_svctab[0][0], s_svctab[0][1]);
487
488
  /* make sure this gets logged only once and tell if we can
489
   * proceed or not
490
   */
491
0
  s_svcidx = 0;
492
0
  return (s_gpsd_addr != NULL);
493
0
}
494
495
/* ---------------------------------------------------------------------
496
 * Start: allocate a unit pointer and set up the runtime data
497
 */
498
static int
499
gpsd_start(
500
  int     unit,
501
  peerT * peer)
502
0
{
503
0
  clockprocT  * const pp = peer->procptr;
504
0
  gpsd_unitT  * up;
505
0
  gpsd_unitT ** uscan    = &s_clock_units;
506
0
  const char  *tmpName;
507
508
0
  struct stat sb;
509
0
  char *    devname = NULL;
510
511
  /* check if we can proceed at all or if init failed */
512
0
  if ( ! gpsd_init_check())
513
0
    return FALSE;
514
515
  /* search for matching unit */
516
0
  while ((up = *uscan) != NULL && up->unit != (unit & 0x7F))
517
0
    uscan = &up->next_unit;
518
0
  if (up == NULL) {
519
    /* alloc unit, add to list and increment use count ASAP. */
520
0
    up = emalloc_zero(sizeof(*up));
521
0
    *uscan = up;
522
0
    ++up->refcount;
523
524
    /* initialize the unit structure */
525
0
    up->logname  = estrdup(refnumtoa(&peer->srcadr));
526
0
    up->unit     = unit & 0x7F;
527
0
    up->fdt      = -1;
528
0
    up->addr     = s_gpsd_addr;
529
0
    up->tickpres = TICKOVER_LOW;
530
531
    /* Create the device name and check for a Character
532
     * Device. It's assumed that GPSD was started with the
533
     * same link, so the names match. (If this is not
534
     * practicable, we will have to read the symlink, if
535
     * any, so we can get the true device file.)
536
     */
537
0
    tmpName = clockdev_lookup(&peer->srcadr, 0);
538
0
    if (NULL != tmpName) {
539
0
      up->device = estrdup(tmpName);
540
0
    } else if (-1 == myasprintf(&up->device, "%s%u", s_dev_stem, up->unit)) {
541
0
      msyslog(LOG_ERR, "%s: clock device name too long",
542
0
        up->logname);
543
0
      goto dev_fail;
544
0
    }
545
0
    devname = up->device;
546
0
    up->device = ntp_realpath(devname);
547
0
    if (NULL == up->device) {
548
0
      msyslog(LOG_ERR, "%s: '%s' has no absolute path",
549
0
        up->logname, devname);
550
0
      goto dev_fail;
551
0
    }
552
0
    free(devname);
553
0
    devname = NULL;
554
0
    if (-1 == lstat(up->device, &sb)) {
555
0
      msyslog(LOG_ERR, "%s: '%s' not accessible",
556
0
        up->logname, up->device);
557
0
      goto dev_fail;
558
0
    }
559
0
    if (!S_ISCHR(sb.st_mode)) {
560
0
      msyslog(LOG_ERR, "%s: '%s' is not a character device",
561
0
        up->logname, up->device);
562
0
      goto dev_fail;
563
0
    }
564
0
  } else {
565
    /* All set up, just increment use count. */
566
0
    ++up->refcount;
567
0
  }
568
  
569
  /* setup refclock processing */
570
0
  pp->unitptr = (caddr_t)up;
571
0
  pp->io.fd         = -1;
572
0
  pp->io.clock_recv = gpsd_receive;
573
0
  pp->io.srcclock   = peer;
574
0
  pp->io.datalen    = 0;
575
0
  pp->a_lastcode[0] = '\0';
576
0
  pp->lencode       = 0;
577
0
  pp->clockdesc     = DESCRIPTION;
578
0
  memcpy(&pp->refid, REFID, 4);
579
580
  /* Initialize miscellaneous variables */
581
0
  if (unit >= 128)
582
0
    peer->precision = PPS_PRECISION;
583
0
  else
584
0
    peer->precision = PRECISION;
585
586
  /* If the daemon name lookup failed, just give up now. */
587
0
  if (NULL == up->addr) {
588
0
    msyslog(LOG_ERR, "%s: no GPSD socket address, giving up",
589
0
      up->logname);
590
0
    goto dev_fail;
591
0
  }
592
593
0
  LOGIF(CLOCKINFO,
594
0
        (LOG_NOTICE, "%s: startup, device is '%s'",
595
0
         refnumtoa(&peer->srcadr), up->device));
596
0
  up->mode = MODE_OP_MODE(peer->ttl);
597
0
  if (up->mode > MODE_OP_MAXVAL)
598
0
    up->mode = 0;
599
0
  if (unit >= 128)
600
0
    up->pps_peer = peer;
601
0
  else
602
0
    enter_opmode(peer, up->mode);
603
0
  return TRUE;
604
605
0
dev_fail:
606
  /* On failure, remove all UNIT ressources and declare defeat. */
607
0
  free(devname);
608
0
  INSIST (up);
609
0
  if (!--up->refcount) {
610
0
    *uscan = up->next_unit;
611
0
    free(up->device);
612
0
    free(up);
613
0
  }
614
615
0
  pp->unitptr = (caddr_t)NULL;
616
0
  return FALSE;
617
0
}
618
619
/* ------------------------------------------------------------------ */
620
621
static void
622
gpsd_shutdown(
623
  int     unit,
624
  peerT * peer)
625
0
{
626
0
  clockprocT * const pp = peer->procptr;
627
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
628
0
  gpsd_unitT ** uscan   = &s_clock_units;
629
630
0
  UNUSED_ARG(unit);
631
632
  /* The unit pointer might have been removed already. */
633
0
  if (up == NULL)
634
0
    return;
635
636
  /* now check if we must close IO resources */
637
0
  if (peer != up->pps_peer) {
638
0
    if (-1 != pp->io.fd) {
639
0
      DPRINTF(1, ("%s: closing clock, fd=%d\n",
640
0
            up->logname, pp->io.fd));
641
0
      io_closeclock(&pp->io);
642
0
      pp->io.fd = -1;
643
0
    }
644
0
    if (up->fdt != -1)
645
0
      close(up->fdt);
646
0
  }
647
  /* decrement use count and eventually remove this unit. */
648
0
  if (!--up->refcount) {
649
    /* unlink this unit */
650
0
    while (*uscan != NULL)
651
0
      if (*uscan == up)
652
0
        *uscan = up->next_unit;
653
0
      else
654
0
        uscan = &(*uscan)->next_unit;
655
0
    free(up->logname);
656
0
    free(up->device);
657
0
    free(up);
658
0
  }
659
0
  pp->unitptr = (caddr_t)NULL;
660
0
  LOGIF(CLOCKINFO,
661
0
        (LOG_NOTICE, "%s: shutdown", refnumtoa(&peer->srcadr)));
662
0
}
663
664
/* ------------------------------------------------------------------ */
665
666
static void
667
gpsd_receive(
668
  struct recvbuf * rbufp)
669
0
{
670
  /* declare & init control structure ptrs */
671
0
  peerT    * const peer = rbufp->recv_peer;
672
0
  clockprocT * const pp   = peer->procptr;
673
0
  gpsd_unitT * const up   = (gpsd_unitT *)pp->unitptr;
674
675
0
  const char *psrc, *esrc;
676
0
  char       *pdst, *edst, ch;
677
678
  /* log the data stream, if this is enabled */
679
0
  log_data(peer, 3, "recv", (const char*)rbufp->recv_buffer,
680
0
     (size_t)rbufp->recv_length);
681
682
683
  /* Since we're getting a raw stream data, we must assemble lines
684
   * in our receive buffer. We can't use neither 'refclock_gtraw'
685
   * not 'refclock_gtlin' here...  We process chars until we reach
686
   * an EoL (that is, line feed) but we truncate the message if it
687
   * does not fit the buffer.  GPSD might truncate messages, too,
688
   * so dealing with truncated buffers is necessary anyway.
689
   */
690
0
  psrc = (const char*)rbufp->recv_buffer;
691
0
  esrc = psrc + rbufp->recv_length;
692
693
0
  pdst = up->buffer + up->buflen;
694
0
  edst = up->buffer + sizeof(up->buffer) - 1; /* for trailing NUL */
695
696
0
  while (psrc != esrc) {
697
0
    ch = *psrc++;
698
0
    if (ch == '\n') {
699
      /* trim trailing whitespace & terminate buffer */
700
0
      while (pdst != up->buffer && pdst[-1] <= ' ')
701
0
        --pdst;
702
0
      *pdst = '\0';
703
      /* process data and reset buffer */
704
0
      up->buflen = pdst - up->buffer;
705
0
      gpsd_parse(peer, &rbufp->recv_time);
706
0
      pdst = up->buffer;
707
0
    } else if (pdst != edst) {
708
      /* add next char, ignoring leading whitespace */
709
0
      if (ch > ' ' || pdst != up->buffer)
710
0
        *pdst++ = ch;
711
0
    }
712
0
  }
713
0
  up->buflen   = pdst - up->buffer;
714
0
  up->tickover = TICKOVER_LOW;
715
0
}
716
717
/* ------------------------------------------------------------------ */
718
719
static void
720
poll_primary(
721
  peerT      * const peer ,
722
  clockprocT * const pp   ,
723
  gpsd_unitT * const up   )
724
0
{
725
0
  if (pp->coderecv != pp->codeproc) {
726
    /* all is well */
727
0
    pp->lastref = pp->lastrec;
728
0
    refclock_report(peer, CEVNT_NOMINAL);
729
0
    refclock_receive(peer);
730
0
  } else {
731
    /* Not working properly, admit to it. If we have no
732
     * connection to GPSD, declare the clock as faulty. If
733
     * there were bad replies, this is handled as the major
734
     * cause, and everything else is just a timeout.
735
     */
736
0
    peer->precision = PRECISION;
737
0
    if (-1 == pp->io.fd)
738
0
      refclock_report(peer, CEVNT_FAULT);
739
0
    else if (0 != up->tc_breply)
740
0
      refclock_report(peer, CEVNT_BADREPLY);
741
0
    else
742
0
      refclock_report(peer, CEVNT_TIMEOUT);
743
0
  }
744
745
0
  if (pp->sloppyclockflag & CLK_FLAG4)
746
0
    mprintf_clock_stats(
747
0
      &peer->srcadr,"%u %u %u %u %u %u %u",
748
0
      up->tc_recv,
749
0
      up->tc_breply, up->tc_nosync,
750
0
      up->tc_sti_recv, up->tc_sti_used,
751
0
      up->tc_pps_recv, up->tc_pps_used);
752
753
  /* clear tallies for next round */
754
0
  up->tc_breply   = 0;
755
0
  up->tc_recv     = 0;
756
0
  up->tc_nosync   = 0;
757
0
  up->tc_sti_recv = 0;
758
0
  up->tc_sti_used = 0;
759
0
  up->tc_pps_recv = 0;
760
0
  up->tc_pps_used = 0;
761
0
}
762
763
static void
764
poll_secondary(
765
  peerT      * const peer ,
766
  clockprocT * const pp   ,
767
  gpsd_unitT * const up   )
768
0
{
769
0
  if (pp->coderecv != pp->codeproc) {
770
    /* all is well */
771
0
    pp->lastref = pp->lastrec;
772
0
    refclock_report(peer, CEVNT_NOMINAL);
773
0
    refclock_receive(peer);
774
0
  } else {
775
0
    peer->precision = PPS_PRECISION;
776
0
    peer->flags &= ~FLAG_PPS;
777
0
    refclock_report(peer, CEVNT_TIMEOUT);
778
0
  }
779
0
}
780
781
static void
782
gpsd_poll(
783
  int     unit,
784
  peerT * peer)
785
0
{
786
0
  clockprocT * const pp = peer->procptr;
787
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
788
789
0
  ++pp->polls;
790
0
  if (peer == up->pps_peer)
791
0
    poll_secondary(peer, pp, up);
792
0
  else
793
0
    poll_primary(peer, pp, up);
794
0
}
795
796
/* ------------------------------------------------------------------ */
797
798
static void
799
gpsd_control(
800
  int                         unit,
801
  const struct refclockstat * in_st,
802
  struct refclockstat       * out_st,
803
  peerT                     * peer  )
804
0
{
805
0
  clockprocT * const pp = peer->procptr;
806
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
807
808
0
  if (peer == up->pps_peer) {
809
0
    DTOLFP(pp->fudgetime1, &up->pps_fudge2);
810
0
    if ( ! (pp->sloppyclockflag & CLK_FLAG1))
811
0
      peer->flags &= ~FLAG_PPS;
812
0
  } else {
813
    /* save preprocessed fudge times */
814
0
    DTOLFP(pp->fudgetime1, &up->pps_fudge);
815
0
    DTOLFP(pp->fudgetime2, &up->sti_fudge);
816
817
0
    if (MODE_OP_MODE(up->mode ^ peer->ttl)) {
818
0
      leave_opmode(peer, up->mode);
819
0
      up->mode = MODE_OP_MODE(peer->ttl);
820
0
      enter_opmode(peer, up->mode);
821
0
    }
822
0
  }
823
0
 }
824
825
/* ------------------------------------------------------------------ */
826
827
static void
828
timer_primary(
829
  peerT      * const peer ,
830
  clockprocT * const pp   ,
831
  gpsd_unitT * const up   )
832
0
{
833
0
  int rc;
834
835
  /* This is used for timeout handling. Nothing that needs
836
   * sub-second precison happens here, so receive/connect/retry
837
   * timeouts are simply handled by a count down, and then we
838
   * decide what to do by the socket values.
839
   *
840
   * Note that the timer stays at zero here, unless some of the
841
   * functions set it to another value.
842
   */
843
0
  if (up->logthrottle)
844
0
    --up->logthrottle;
845
0
  if (up->tickover)
846
0
    --up->tickover;
847
0
  switch (up->tickover) {
848
0
  case 4:
849
    /* If we are connected to GPSD, try to get a live signal
850
     * by querying the version. Otherwise just check the
851
     * socket to become ready.
852
     */
853
0
    if (-1 != pp->io.fd) {
854
0
      size_t rlen = strlen(s_req_version);
855
0
      DPRINTF(2, ("%s: timer livecheck: '%s'\n",
856
0
            up->logname, s_req_version));
857
0
      log_data(peer, 2, "send", s_req_version, rlen);
858
0
      rc = write(pp->io.fd, s_req_version, rlen);
859
0
      (void)rc;
860
0
    } else if (-1 != up->fdt) {
861
0
      gpsd_test_socket(peer);
862
0
    }
863
0
    break;
864
865
0
  case 0:
866
0
    if (-1 != pp->io.fd)
867
0
      gpsd_stop_socket(peer);
868
0
    else if (-1 != up->fdt)
869
0
      gpsd_test_socket(peer);
870
0
    else if (NULL != s_gpsd_addr)
871
0
      gpsd_init_socket(peer);
872
0
    break;
873
874
0
  default:
875
0
    if (-1 == pp->io.fd && -1 != up->fdt)
876
0
      gpsd_test_socket(peer);
877
0
  }
878
0
}
879
880
static void
881
timer_secondary(
882
  peerT      * const peer ,
883
  clockprocT * const pp   ,
884
  gpsd_unitT * const up   )
885
0
{
886
  /* Reduce the count by one. Flush sample buffer and clear PPS
887
   * flag when this happens.
888
   */
889
0
  up->ppscount2 = max(0, (up->ppscount2 - 1));
890
0
  if (0 == up->ppscount2) {
891
0
    if (pp->coderecv != pp->codeproc) {
892
0
      refclock_report(peer, CEVNT_TIMEOUT);
893
0
      pp->coderecv = pp->codeproc;
894
0
    }
895
0
    peer->flags &= ~FLAG_PPS;
896
0
  }
897
0
}
898
899
static void
900
gpsd_timer(
901
  int     unit,
902
  peerT * peer)
903
0
{
904
0
  clockprocT * const pp = peer->procptr;
905
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
906
907
0
  if (peer == up->pps_peer)
908
0
    timer_secondary(peer, pp, up);
909
0
  else
910
0
    timer_primary(peer, pp, up);
911
0
}
912
913
/* =====================================================================
914
 * handle opmode switches
915
 */
916
917
static void
918
enter_opmode(
919
  peerT *peer,
920
  int    mode)
921
0
{
922
0
  clockprocT * const pp = peer->procptr;
923
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
924
925
0
  DPRINTF(1, ("%s: enter operation mode %d\n",
926
0
        up->logname, MODE_OP_MODE(mode)));
927
928
0
  if (MODE_OP_MODE(mode) == MODE_OP_AUTO) {
929
0
    up->fl_rawsti = 0;
930
0
    up->ppscount  = PPS_MAXCOUNT / 2;
931
0
  }
932
0
  up->fl_pps = 0;
933
0
  up->fl_sti = 0;
934
0
}
935
936
/* ------------------------------------------------------------------ */
937
938
static void
939
leave_opmode(
940
  peerT *peer,
941
  int    mode)
942
0
{
943
0
  clockprocT * const pp = peer->procptr;
944
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
945
946
0
  DPRINTF(1, ("%s: leaving operation mode %d\n",
947
0
        up->logname, MODE_OP_MODE(mode)));
948
949
0
  if (MODE_OP_MODE(mode) == MODE_OP_AUTO) {
950
0
    up->fl_rawsti = 0;
951
0
    up->ppscount  = 0;
952
0
  }
953
0
  up->fl_pps = 0;
954
0
  up->fl_sti = 0;
955
0
}
956
957
/* =====================================================================
958
 * operation mode specific evaluation
959
 */
960
961
static void
962
add_clock_sample(
963
  peerT      * const peer ,
964
  clockprocT * const pp   ,
965
  l_fp               stamp,
966
  l_fp               recvt)
967
0
{
968
0
  pp->lastref = stamp;
969
0
  if (pp->coderecv == pp->codeproc)
970
0
    refclock_report(peer, CEVNT_NOMINAL);
971
0
  refclock_process_offset(pp, stamp, recvt, 0.0);
972
0
}
973
974
/* ------------------------------------------------------------------ */
975
976
static void
977
eval_strict(
978
  peerT      * const peer ,
979
  clockprocT * const pp   ,
980
  gpsd_unitT * const up   )
981
0
{
982
0
  if (up->fl_sti && up->fl_pps) {
983
    /* use TPV reference time + PPS receive time */
984
0
    add_clock_sample(peer, pp, up->sti_stamp, up->pps_recvt);
985
0
    peer->precision = up->pps_prec;
986
    /* both packets consumed now... */
987
0
    up->fl_pps = 0;
988
0
    up->fl_sti = 0;
989
0
    ++up->tc_sti_used;
990
0
  }
991
0
}
992
993
/* ------------------------------------------------------------------ */
994
/* PPS processing for the secondary channel. GPSD provides us with full
995
 * timing information, so there's no danger of PLL-locking to the wrong
996
 * second. The belts and suspenders needed for the raw ATOM clock are
997
 * unnecessary here.
998
 */
999
static void
1000
eval_pps_secondary(
1001
  peerT      * const peer ,
1002
  clockprocT * const pp   ,
1003
  gpsd_unitT * const up   )
1004
0
{
1005
0
  if (up->fl_pps2) {
1006
    /* feed data */
1007
0
    add_clock_sample(peer, pp, up->pps_stamp2, up->pps_recvt2);
1008
0
    peer->precision = up->pps_prec;
1009
    /* PPS peer flag logic */
1010
0
    up->ppscount2 = min(PPS2_MAXCOUNT, (up->ppscount2 + 2));
1011
0
    if ((PPS2_MAXCOUNT == up->ppscount2) &&
1012
0
        (pp->sloppyclockflag & CLK_FLAG1) )
1013
0
      peer->flags |= FLAG_PPS;
1014
    /* mark time stamp as burned... */
1015
0
    up->fl_pps2 = 0;
1016
0
    ++up->tc_pps_used;
1017
0
  }
1018
0
}
1019
1020
/* ------------------------------------------------------------------ */
1021
1022
static void
1023
eval_serial(
1024
  peerT      * const peer ,
1025
  clockprocT * const pp   ,
1026
  gpsd_unitT * const up   )
1027
0
{
1028
0
  if (up->fl_sti) {
1029
0
    add_clock_sample(peer, pp, up->sti_stamp, up->sti_recvt);
1030
0
    peer->precision = up->sti_prec;
1031
    /* mark time stamp as burned... */
1032
0
    up->fl_sti = 0;
1033
0
    ++up->tc_sti_used;
1034
0
  }
1035
0
}
1036
1037
/* ------------------------------------------------------------------ */
1038
static void
1039
eval_auto(
1040
  peerT      * const peer ,
1041
  clockprocT * const pp   ,
1042
  gpsd_unitT * const up   )
1043
0
{
1044
  /* If there's no TPV available, stop working here... */
1045
0
  if (!up->fl_sti)
1046
0
    return;
1047
1048
  /* check how to handle STI+PPS: Can PPS be used to augment STI
1049
   * (or vice versae), do we drop the sample because there is a
1050
   * temporary missing PPS signal, or do we feed on STI time
1051
   * stamps alone?
1052
   *
1053
   * Do a counter/threshold dance to decide how to proceed.
1054
   */
1055
0
  if (up->fl_pps) {
1056
0
    up->ppscount = min(PPS_MAXCOUNT,
1057
0
           (up->ppscount + PPS_INCCOUNT));
1058
0
    if ((PPS_MAXCOUNT == up->ppscount) && up->fl_rawsti) {
1059
0
      up->fl_rawsti = 0;
1060
0
      msyslog(LOG_INFO,
1061
0
        "%s: expect valid PPS from now",
1062
0
        up->logname);
1063
0
    }
1064
0
  } else {
1065
0
    up->ppscount = max(0, (up->ppscount - PPS_DECCOUNT));
1066
0
    if ((0 == up->ppscount) && !up->fl_rawsti) {
1067
0
      up->fl_rawsti = -1;
1068
0
      msyslog(LOG_WARNING,
1069
0
        "%s: use TPV alone from now",
1070
0
        up->logname);
1071
0
    }
1072
0
  }
1073
1074
  /* now eventually feed the sample */
1075
0
  if (up->fl_rawsti)
1076
0
    eval_serial(peer, pp, up);
1077
0
  else
1078
0
    eval_strict(peer, pp, up);
1079
0
}
1080
1081
/* =====================================================================
1082
 * JSON parsing stuff
1083
 */
1084
1085
/* ------------------------------------------------------------------ */
1086
/* Parse a decimal integer with a possible sign. Works like 'strtoll()'
1087
 * or 'strtol()', but with a fixed base of 10 and without eating away
1088
 * leading whitespace. For the error codes, the handling of the end
1089
 * pointer and the return values see 'strtol()'.
1090
 */
1091
static json_int
1092
strtojint(
1093
  const char *cp, char **ep)
1094
0
{
1095
0
  json_uint     accu, limit_lo, limit_hi;
1096
0
  int           flags; /* bit 0: overflow; bit 1: sign */
1097
0
  const char  * hold;
1098
1099
  /* pointer union to circumvent a tricky/sticky const issue */
1100
0
  union { const char * c; char * v; } vep;
1101
1102
  /* store initial value of 'cp' -- see 'strtol()' */
1103
0
  vep.c = cp;
1104
1105
  /* Eat away an optional sign and set the limits accordingly: The
1106
   * high limit is the maximum absolute value that can be returned,
1107
   * and the low limit is the biggest value that does not cause an
1108
   * overflow when multiplied with 10. Avoid negation overflows.
1109
   */
1110
0
  if (*cp == '-') {
1111
0
    cp += 1;
1112
0
    flags    = 2;
1113
0
    limit_hi = (json_uint)-(JSON_INT_MIN + 1) + 1;
1114
0
  } else {
1115
0
    cp += (*cp == '+');
1116
0
    flags    = 0;
1117
0
    limit_hi = (json_uint)JSON_INT_MAX;
1118
0
  }
1119
0
  limit_lo = limit_hi / 10;
1120
1121
  /* Now try to convert a sequence of digits. */
1122
0
  hold = cp;
1123
0
  accu = 0;
1124
0
  while (isdigit(*(const u_char*)cp)) {
1125
0
    flags |= (accu > limit_lo);
1126
0
    accu = accu * 10 + (*(const u_char*)cp++ - '0');
1127
0
    flags |= (accu > limit_hi);
1128
0
  }
1129
  /* Check for empty conversion (no digits seen). */
1130
0
  if (hold != cp)
1131
0
    vep.c = cp;
1132
0
  else
1133
0
    errno = EINVAL; /* accu is still zero */
1134
  /* Check for range overflow */
1135
0
  if (flags & 1) {
1136
0
    errno = ERANGE;
1137
0
    accu  = limit_hi;
1138
0
  }
1139
  /* If possible, store back the end-of-conversion pointer */
1140
0
  if (ep)
1141
0
    *ep = vep.v;
1142
  /* If negative, return the negated result if the accu is not
1143
   * zero. Avoid negation overflows.
1144
   */
1145
0
  if ((flags & 2) && accu)
1146
0
    return -(json_int)(accu - 1) - 1;
1147
0
  else
1148
0
    return (json_int)accu;
1149
0
}
1150
1151
/* ------------------------------------------------------------------ */
1152
1153
static tok_ref
1154
json_token_skip(
1155
  const json_ctx * ctx,
1156
  tok_ref          tid)
1157
0
{
1158
0
  if (tid >= 0 && tid < ctx->ntok) {
1159
0
    int len = ctx->tok[tid].size;
1160
    /* For arrays and objects, the size is the number of
1161
     * ITEMS in the compound. Thats the number of objects in
1162
     * the array, and the number of key/value pairs for
1163
     * objects. In theory, the key must be a string, and we
1164
     * could simply skip one token before skipping the
1165
     * value, which can be anything. We're a bit paranoid
1166
     * and lazy at the same time: We simply double the
1167
     * number of tokens to skip and fall through into the
1168
     * array processing when encountering an object.
1169
     */
1170
0
    switch (ctx->tok[tid].type) {
1171
0
    case JSMN_OBJECT:
1172
0
      len *= 2;
1173
      /* FALLTHROUGH */
1174
0
    case JSMN_ARRAY:
1175
0
      for (++tid; len; --len)
1176
0
        tid = json_token_skip(ctx, tid);
1177
0
      break;
1178
      
1179
0
    default:
1180
0
      ++tid;
1181
0
      break;
1182
0
    }
1183
    /* The next condition should never be true, but paranoia
1184
     * prevails...
1185
     */
1186
0
    if (tid < 0 || tid > ctx->ntok)
1187
0
      tid = ctx->ntok;
1188
0
  }
1189
0
  return tid;
1190
0
}
1191
1192
/* ------------------------------------------------------------------ */
1193
1194
static int
1195
json_object_lookup(
1196
  const json_ctx * ctx ,
1197
  tok_ref          tid ,
1198
  const char     * key ,
1199
  int              what)
1200
0
{
1201
0
  int len;
1202
1203
0
  if (tid < 0 || tid >= ctx->ntok ||
1204
0
      ctx->tok[tid].type != JSMN_OBJECT)
1205
0
    return INVALID_TOKEN;
1206
  
1207
0
  len = ctx->tok[tid].size;
1208
0
  for (++tid; len && tid+1 < ctx->ntok; --len) {
1209
0
    if (ctx->tok[tid].type != JSMN_STRING) { /* Blooper! */
1210
0
      tid = json_token_skip(ctx, tid); /* skip key */
1211
0
      tid = json_token_skip(ctx, tid); /* skip val */
1212
0
    } else if (strcmp(key, ctx->buf + ctx->tok[tid].start)) {
1213
0
      tid = json_token_skip(ctx, tid+1); /* skip key+val */
1214
0
    } else if (what < 0 || (u_int)what == ctx->tok[tid+1].type) {
1215
0
      return tid + 1;
1216
0
    } else {
1217
0
      break;
1218
0
    }
1219
    /* if skipping ahead returned an error, bail out here. */
1220
0
    if (tid < 0)
1221
0
      break;
1222
0
  }
1223
0
  return INVALID_TOKEN;
1224
0
}
1225
1226
/* ------------------------------------------------------------------ */
1227
1228
static const char*
1229
json_object_lookup_primitive(
1230
  const json_ctx * ctx,
1231
  tok_ref          tid,
1232
  const char     * key)
1233
0
{
1234
0
  tid = json_object_lookup(ctx, tid, key, JSMN_PRIMITIVE);
1235
0
  if (INVALID_TOKEN  != tid)
1236
0
    return ctx->buf + ctx->tok[tid].start;
1237
0
  else
1238
0
    return NULL;
1239
0
}
1240
/* ------------------------------------------------------------------ */
1241
/* look up a boolean value. This essentially returns a tribool:
1242
 * 0->false, 1->true, (-1)->error/undefined
1243
 */
1244
static int
1245
json_object_lookup_bool(
1246
  const json_ctx * ctx,
1247
  tok_ref          tid,
1248
  const char     * key)
1249
0
{
1250
0
  const char *cp;
1251
0
  cp  = json_object_lookup_primitive(ctx, tid, key);
1252
0
  switch ( cp ? *cp : '\0') {
1253
0
  case 't': return  1;
1254
0
  case 'f': return  0;
1255
0
  default : return -1;
1256
0
  }
1257
0
}
1258
1259
/* ------------------------------------------------------------------ */
1260
1261
static const char*
1262
json_object_lookup_string(
1263
  const json_ctx * ctx,
1264
  tok_ref          tid,
1265
  const char     * key)
1266
0
{
1267
0
  tid = json_object_lookup(ctx, tid, key, JSMN_STRING);
1268
0
  if (INVALID_TOKEN != tid)
1269
0
    return ctx->buf + ctx->tok[tid].start;
1270
0
  return NULL;
1271
0
}
1272
1273
static const char*
1274
json_object_lookup_string_default(
1275
  const json_ctx * ctx,
1276
  tok_ref          tid,
1277
  const char     * key,
1278
  const char     * def)
1279
0
{
1280
0
  tid = json_object_lookup(ctx, tid, key, JSMN_STRING);
1281
0
  if (INVALID_TOKEN != tid)
1282
0
    return ctx->buf + ctx->tok[tid].start;
1283
0
  return def;
1284
0
}
1285
1286
/* ------------------------------------------------------------------ */
1287
1288
static json_int
1289
json_object_lookup_int(
1290
  const json_ctx * ctx,
1291
  tok_ref          tid,
1292
  const char     * key)
1293
0
{
1294
0
  json_int     ret;
1295
0
  const char * cp;
1296
0
  char       * ep;
1297
1298
0
  cp = json_object_lookup_primitive(ctx, tid, key);
1299
0
  if (NULL != cp) {
1300
0
    ret = strtojint(cp, &ep);
1301
0
    if (cp != ep && '\0' == *ep)
1302
0
      return ret;
1303
0
  } else {
1304
0
    errno = EINVAL;
1305
0
  }
1306
0
  return 0;
1307
0
}
1308
1309
static json_int
1310
json_object_lookup_int_default(
1311
  const json_ctx * ctx,
1312
  tok_ref          tid,
1313
  const char     * key,
1314
  json_int         def)
1315
0
{
1316
0
  json_int     ret;
1317
0
  const char * cp;
1318
0
  char       * ep;
1319
1320
0
  cp = json_object_lookup_primitive(ctx, tid, key);
1321
0
  if (NULL != cp) {
1322
0
    ret = strtojint(cp, &ep);
1323
0
    if (cp != ep && '\0' == *ep)
1324
0
      return ret;
1325
0
  }
1326
0
  return def;
1327
0
}
1328
1329
/* ------------------------------------------------------------------ */
1330
#if 0 /* currently unused */
1331
static double
1332
json_object_lookup_float(
1333
  const json_ctx * ctx,
1334
  tok_ref          tid,
1335
  const char     * key)
1336
{
1337
  double       ret;
1338
  const char * cp;
1339
  char       * ep;
1340
1341
  cp = json_object_lookup_primitive(ctx, tid, key);
1342
  if (NULL != cp) {
1343
    ret = strtod(cp, &ep);
1344
    if (cp != ep && '\0' == *ep)
1345
      return ret;
1346
  } else {
1347
    errno = EINVAL;
1348
  }
1349
  return 0.0;
1350
}
1351
#endif
1352
1353
static double
1354
json_object_lookup_float_default(
1355
  const json_ctx * ctx,
1356
  tok_ref          tid,
1357
  const char     * key,
1358
  double           def)
1359
0
{
1360
0
  double       ret;
1361
0
  const char * cp;
1362
0
  char       * ep;
1363
1364
0
  cp = json_object_lookup_primitive(ctx, tid, key);
1365
0
  if (NULL != cp) {
1366
0
    ret = strtod(cp, &ep);
1367
0
    if (cp != ep && '\0' == *ep)
1368
0
      return ret;
1369
0
  }
1370
0
  return def;
1371
0
}
1372
1373
/* ------------------------------------------------------------------ */
1374
1375
static BOOL
1376
json_parse_record(
1377
  json_ctx * ctx,
1378
  char     * buf,
1379
  size_t     len)
1380
0
{
1381
0
  jsmn_parser jsm;
1382
0
  int         idx, rc;
1383
1384
0
  jsmn_init(&jsm);
1385
0
  rc = jsmn_parse(&jsm, buf, len, ctx->tok, JSMN_MAXTOK);
1386
0
  if (rc <= 0)
1387
0
    return FALSE;
1388
0
  ctx->buf  = buf;
1389
0
  ctx->ntok = rc;
1390
1391
0
  if (JSMN_OBJECT != ctx->tok[0].type)
1392
0
    return FALSE; /* not object!?! */
1393
1394
  /* Make all tokens NUL terminated by overwriting the
1395
   * terminator symbol. Makes string compares and number parsing a
1396
   * lot easier!
1397
   */
1398
0
  for (idx = 0; idx < ctx->ntok; ++idx)
1399
0
    if (ctx->tok[idx].end > ctx->tok[idx].start)
1400
0
      ctx->buf[ctx->tok[idx].end] = '\0';
1401
0
  return TRUE;
1402
0
}
1403
1404
1405
/* =====================================================================
1406
 * static local helpers
1407
 */
1408
static BOOL
1409
get_binary_time(
1410
  l_fp       * const dest     ,
1411
  json_ctx   * const jctx     ,
1412
  const char * const time_name,
1413
  const char * const frac_name,
1414
  long               fscale   )
1415
0
{
1416
0
  BOOL            retv = FALSE;
1417
0
  struct timespec ts;
1418
1419
0
  errno = 0;
1420
0
  ts.tv_sec  = (time_t)json_object_lookup_int(jctx, 0, time_name);
1421
0
  ts.tv_nsec = (long  )json_object_lookup_int(jctx, 0, frac_name);
1422
0
  if (0 == errno) {
1423
0
    ts.tv_nsec *= fscale;
1424
0
    *dest = tspec_stamp_to_lfp(ts);
1425
0
    retv  = TRUE;
1426
0
  }
1427
0
  return retv;
1428
0
}
1429
1430
/* ------------------------------------------------------------------ */
1431
/* Process a WATCH record
1432
 *
1433
 * Currently this is only used to recognise that the device is present
1434
 * and that we're listed subscribers.
1435
 */
1436
static void
1437
process_watch(
1438
  peerT      * const peer ,
1439
  json_ctx   * const jctx ,
1440
  const l_fp * const rtime)
1441
0
{
1442
0
  clockprocT * const pp = peer->procptr;
1443
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1444
1445
0
  const char * path;
1446
1447
0
  path = json_object_lookup_string(jctx, 0, "device");
1448
0
  if (NULL == path || strcmp(path, up->device))
1449
0
    return;
1450
1451
0
  if (json_object_lookup_bool(jctx, 0, "enable") > 0 &&
1452
0
      json_object_lookup_bool(jctx, 0, "json"  ) > 0  )
1453
0
    up->fl_watch = -1;
1454
0
  else
1455
0
    up->fl_watch = 0;
1456
0
  DPRINTF(2, ("%s: process_watch, enabled=%d\n",
1457
0
        up->logname, (up->fl_watch & 1)));
1458
0
}
1459
1460
/* ------------------------------------------------------------------ */
1461
1462
static void
1463
process_version(
1464
  peerT      * const peer ,
1465
  json_ctx   * const jctx ,
1466
  const l_fp * const rtime)
1467
0
{
1468
0
  clockprocT * const pp = peer->procptr;
1469
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1470
1471
0
  int    len;
1472
0
  char * buf;
1473
0
  const char *revision;
1474
0
  const char *release;
1475
0
  uint16_t    pvhi, pvlo;
1476
1477
  /* get protocol version number */
1478
0
  revision = json_object_lookup_string_default(
1479
0
    jctx, 0, "rev", "(unknown)");
1480
0
  release  = json_object_lookup_string_default(
1481
0
    jctx, 0, "release", "(unknown)");
1482
0
  errno = 0;
1483
0
  pvhi = (uint16_t)json_object_lookup_int(jctx, 0, "proto_major");
1484
0
  pvlo = (uint16_t)json_object_lookup_int(jctx, 0, "proto_minor");
1485
1486
0
  if (0 == errno) {
1487
0
    if ( ! up->fl_vers)
1488
0
      msyslog(LOG_INFO,
1489
0
        "%s: GPSD revision=%s release=%s protocol=%u.%u",
1490
0
        up->logname, revision, release,
1491
0
        pvhi, pvlo);
1492
0
    up->proto_version = PROTO_VERSION(pvhi, pvlo);
1493
0
    up->fl_vers = -1;
1494
0
  } else {
1495
0
    if (syslogok(pp, up))
1496
0
      msyslog(LOG_INFO,
1497
0
        "%s: could not evaluate version data",
1498
0
        up->logname);
1499
0
    return;
1500
0
  }
1501
  /* With the 3.9 GPSD protocol, '*_musec' vanished from the PPS
1502
   * record and was replace by '*_nsec'.
1503
   */
1504
0
  up->pf_nsec = -(up->proto_version >= PROTO_VERSION(3,9));
1505
1506
  /* With the 3.10 protocol we can get TOFF records for better
1507
   * timing information.
1508
   */
1509
0
  up->pf_toff = -(up->proto_version >= PROTO_VERSION(3,10));
1510
1511
  /* request watch for our GPS device if not yet watched.
1512
   *
1513
   * The version string is also sent as a life signal, if we have
1514
   * seen useable data. So if we're already watching the device,
1515
   * skip the request.
1516
   *
1517
   * Reuse the input buffer, which is no longer needed in the
1518
   * current cycle. Also assume that we can write the watch
1519
   * request in one sweep into the socket; since we do not do
1520
   * output otherwise, this should always work.  (Unless the
1521
   * TCP/IP window size gets lower than the length of the
1522
   * request. We handle that when it happens.)
1523
   */
1524
0
  if (up->fl_watch)
1525
0
    return;
1526
1527
  /* The logon string is actually the ?WATCH command of GPSD,
1528
   * using JSON data and selecting the GPS device name we created
1529
   * from our unit number. We have an old and a newer version that
1530
   * request PPS (and TOFF) transmission.
1531
   */
1532
0
  snprintf(up->buffer, sizeof(up->buffer),
1533
0
     "?WATCH={\"device\":\"%s\",\"enable\":true,\"json\":true%s};\r\n",
1534
0
     up->device, (up->pf_toff ? ",\"pps\":true" : ""));
1535
0
  buf = up->buffer;
1536
0
  len = strlen(buf);
1537
0
  log_data(peer, 2, "send", buf, len);
1538
0
  if (len != write(pp->io.fd, buf, len) && (syslogok(pp, up))) {
1539
    /* Note: if the server fails to read our request, the
1540
     * resulting data timeout will take care of the
1541
     * connection!
1542
     */
1543
0
    msyslog(LOG_ERR, "%s: failed to write watch request (%m)",
1544
0
      up->logname);
1545
0
  }
1546
0
}
1547
1548
/* ------------------------------------------------------------------ */
1549
1550
static void
1551
process_tpv(
1552
  peerT      * const peer ,
1553
  json_ctx   * const jctx ,
1554
  const l_fp * const rtime)
1555
0
{
1556
0
  clockprocT * const pp = peer->procptr;
1557
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1558
1559
0
  const char * gps_time;
1560
0
  int          gps_mode;
1561
0
  double       ept;
1562
0
  int          xlog2;
1563
1564
0
  gps_mode = (int)json_object_lookup_int_default(
1565
0
    jctx, 0, "mode", 0);
1566
1567
0
  gps_time = json_object_lookup_string(
1568
0
    jctx, 0, "time");
1569
1570
  /* accept time stamps only in 2d or 3d fix */
1571
0
  if (gps_mode < 2 || NULL == gps_time) {
1572
    /* receiver has no fix; tell about and avoid stale data */
1573
0
    if ( ! up->pf_toff)
1574
0
      ++up->tc_sti_recv;
1575
0
    ++up->tc_nosync;
1576
0
    up->fl_sti    = 0;
1577
0
    up->fl_pps    = 0;
1578
0
    up->fl_nosync = -1;
1579
0
    return;
1580
0
  }
1581
0
  up->fl_nosync = 0;
1582
1583
  /* convert clock and set resulting ref time, but only if the
1584
   * TOFF sentence is *not* available
1585
   */
1586
0
  if ( ! up->pf_toff) {
1587
0
    ++up->tc_sti_recv;
1588
    /* save last time code to clock data */
1589
0
    save_ltc(pp, gps_time);
1590
    /* now parse the time string */
1591
0
    if (convert_ascii_time(&up->sti_stamp, gps_time)) {
1592
0
      DPRINTF(2, ("%s: process_tpv, stamp='%s',"
1593
0
            " recvt='%s' mode=%u\n",
1594
0
            up->logname,
1595
0
            gmprettydate(&up->sti_stamp),
1596
0
            gmprettydate(&up->sti_recvt),
1597
0
            gps_mode));
1598
1599
      /* have to use local receive time as substitute
1600
       * for the real receive time: TPV does not tell
1601
       * us.
1602
       */
1603
0
      up->sti_local = *rtime;
1604
0
      up->sti_recvt = *rtime;
1605
0
      L_SUB(&up->sti_recvt, &up->sti_fudge);
1606
0
      up->fl_sti = -1;
1607
0
    } else {
1608
0
      ++up->tc_breply;
1609
0
      up->fl_sti = 0;
1610
0
    }
1611
0
  }
1612
1613
  /* Set the precision from the GPSD data
1614
   * Use the ETP field for an estimation of the precision of the
1615
   * serial data. If ETP is not available, use the default serial
1616
   * data presion instead. (Note: The PPS branch has a different
1617
   * precision estimation, since it gets the proper value directly
1618
   * from GPSD!)
1619
   */
1620
0
  ept = json_object_lookup_float_default(jctx, 0, "ept", 2.0e-3);
1621
0
  ept = frexp(fabs(ept)*0.70710678, &xlog2); /* ~ sqrt(0.5) */
1622
0
  if (ept < 0.25)
1623
0
    xlog2 = INT_MIN;
1624
0
  if (ept > 2.0)
1625
0
    xlog2 = INT_MAX;
1626
0
  up->sti_prec = clamped_precision(xlog2);
1627
0
}
1628
1629
/* ------------------------------------------------------------------ */
1630
1631
static void
1632
process_pps(
1633
  peerT      * const peer ,
1634
  json_ctx   * const jctx ,
1635
  const l_fp * const rtime)
1636
0
{
1637
0
  clockprocT * const pp = peer->procptr;
1638
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1639
1640
0
  int xlog2;
1641
1642
0
  ++up->tc_pps_recv;
1643
1644
  /* Bail out if there's indication that time sync is bad or
1645
   * if we're explicitely requested to ignore PPS data.
1646
   */
1647
0
  if (up->fl_nosync)
1648
0
    return;
1649
1650
0
  up->pps_local = *rtime;
1651
  /* Now grab the time values. 'clock_*' is the event time of the
1652
   * pulse measured on the local system clock; 'real_*' is the GPS
1653
   * reference time GPSD associated with the pulse.
1654
   */
1655
0
  if (up->pf_nsec) {
1656
0
    if ( ! get_binary_time(&up->pps_recvt2, jctx,
1657
0
               "clock_sec", "clock_nsec", 1))
1658
0
      goto fail;
1659
0
    if ( ! get_binary_time(&up->pps_stamp2, jctx,
1660
0
               "real_sec", "real_nsec", 1))
1661
0
      goto fail;
1662
0
  } else {
1663
0
    if ( ! get_binary_time(&up->pps_recvt2, jctx,
1664
0
               "clock_sec", "clock_musec", 1000))
1665
0
      goto fail;
1666
0
    if ( ! get_binary_time(&up->pps_stamp2, jctx,
1667
0
               "real_sec", "real_musec", 1000))
1668
0
      goto fail;
1669
0
  }
1670
1671
  /* Try to read the precision field from the PPS record. If it's
1672
   * not there, take the precision from the serial data.
1673
   */
1674
0
  xlog2 = json_object_lookup_int_default(
1675
0
      jctx, 0, "precision", up->sti_prec);
1676
0
  up->pps_prec = clamped_precision(xlog2);
1677
  
1678
  /* Get fudged receive times for primary & secondary unit */
1679
0
  up->pps_recvt = up->pps_recvt2;
1680
0
  L_SUB(&up->pps_recvt , &up->pps_fudge );
1681
0
  L_SUB(&up->pps_recvt2, &up->pps_fudge2);
1682
0
  pp->lastrec = up->pps_recvt;
1683
1684
  /* Map to nearest full second as reference time stamp for the
1685
   * primary channel. Sanity checks are done in evaluation step.
1686
   */
1687
0
  up->pps_stamp = up->pps_recvt;
1688
0
  L_ADDUF(&up->pps_stamp, 0x80000000u);
1689
0
  up->pps_stamp.l_uf = 0;
1690
1691
0
  if (NULL != up->pps_peer)
1692
0
    save_ltc(up->pps_peer->procptr,
1693
0
       gmprettydate(&up->pps_stamp2));
1694
0
  DPRINTF(2, ("%s: PPS record processed,"
1695
0
        " stamp='%s', recvt='%s'\n",
1696
0
        up->logname,
1697
0
        gmprettydate(&up->pps_stamp2),
1698
0
        gmprettydate(&up->pps_recvt2)));
1699
  
1700
0
  up->fl_pps  = (0 != (pp->sloppyclockflag & CLK_FLAG2)) - 1;
1701
0
  up->fl_pps2 = -1;
1702
0
  return;
1703
1704
0
  fail:
1705
0
  DPRINTF(1, ("%s: PPS record processing FAILED\n",
1706
0
        up->logname));
1707
0
  ++up->tc_breply;
1708
0
}
1709
1710
/* ------------------------------------------------------------------ */
1711
1712
static void
1713
process_toff(
1714
  peerT      * const peer ,
1715
  json_ctx   * const jctx ,
1716
  const l_fp * const rtime)
1717
0
{
1718
0
  clockprocT * const pp = peer->procptr;
1719
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1720
1721
0
  ++up->tc_sti_recv;
1722
1723
  /* remember this! */
1724
0
  up->pf_toff = -1;
1725
1726
  /* bail out if there's indication that time sync is bad */
1727
0
  if (up->fl_nosync)
1728
0
    return;
1729
1730
0
  if ( ! get_binary_time(&up->sti_recvt, jctx,
1731
0
             "clock_sec", "clock_nsec", 1))
1732
0
      goto fail;
1733
0
  if ( ! get_binary_time(&up->sti_stamp, jctx,
1734
0
             "real_sec", "real_nsec", 1))
1735
0
      goto fail;
1736
0
  L_SUB(&up->sti_recvt, &up->sti_fudge);
1737
0
  up->sti_local = *rtime;
1738
0
  up->fl_sti    = -1;
1739
1740
0
  save_ltc(pp, gmprettydate(&up->sti_stamp));
1741
0
  DPRINTF(2, ("%s: TOFF record processed,"
1742
0
        " stamp='%s', recvt='%s'\n",
1743
0
        up->logname,
1744
0
        gmprettydate(&up->sti_stamp),
1745
0
        gmprettydate(&up->sti_recvt)));
1746
0
  return;
1747
1748
0
  fail:
1749
0
  DPRINTF(1, ("%s: TOFF record processing FAILED\n",
1750
0
        up->logname));
1751
0
  ++up->tc_breply;
1752
0
}
1753
1754
/* ------------------------------------------------------------------ */
1755
1756
static void
1757
gpsd_parse(
1758
  peerT      * const peer ,
1759
  const l_fp * const rtime)
1760
0
{
1761
0
  clockprocT * const pp = peer->procptr;
1762
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1763
1764
0
  const char * clsid;
1765
1766
0
        DPRINTF(2, ("%s: gpsd_parse: time %s '%.*s'\n",
1767
0
                    up->logname, ulfptoa(rtime, 6),
1768
0
        up->buflen, up->buffer));
1769
1770
  /* See if we can grab anything potentially useful. JSMN does not
1771
   * need a trailing NUL, but it needs the number of bytes to
1772
   * process. */
1773
0
  if (!json_parse_record(&up->json_parse, up->buffer, up->buflen)) {
1774
0
    ++up->tc_breply;
1775
0
    return;
1776
0
  }
1777
  
1778
  /* Now dispatch over the objects we know */
1779
0
  clsid = json_object_lookup_string(&up->json_parse, 0, "class");
1780
0
  if (NULL == clsid) {
1781
0
    ++up->tc_breply;
1782
0
    return;
1783
0
  }
1784
1785
0
  if      (!strcmp("TPV", clsid))
1786
0
    process_tpv(peer, &up->json_parse, rtime);
1787
0
  else if (!strcmp("PPS", clsid))
1788
0
    process_pps(peer, &up->json_parse, rtime);
1789
0
  else if (!strcmp("TOFF", clsid))
1790
0
    process_toff(peer, &up->json_parse, rtime);
1791
0
  else if (!strcmp("VERSION", clsid))
1792
0
    process_version(peer, &up->json_parse, rtime);
1793
0
  else if (!strcmp("WATCH", clsid))
1794
0
    process_watch(peer, &up->json_parse, rtime);
1795
0
  else
1796
0
    return; /* nothing we know about... */
1797
0
  ++up->tc_recv;
1798
1799
  /* if possible, feed the PPS side channel */
1800
0
  if (up->pps_peer)
1801
0
    eval_pps_secondary(
1802
0
      up->pps_peer, up->pps_peer->procptr, up);
1803
1804
  /* check PPS vs. STI receive times:
1805
   * If STI is before PPS, then clearly the STI is too old. If PPS
1806
   * is before STI by more than one second, then PPS is too old.
1807
   * Weed out stale time stamps & flags.
1808
   */
1809
0
  if (up->fl_pps && up->fl_sti) {
1810
0
    l_fp diff;
1811
0
    diff = up->sti_local;
1812
0
    L_SUB(&diff, &up->pps_local);
1813
0
    if (diff.l_i > 0)
1814
0
      up->fl_pps = 0; /* pps too old */
1815
0
    else if (diff.l_i < 0)
1816
0
      up->fl_sti = 0; /* serial data too old */
1817
0
  }
1818
1819
  /* dispatch to the mode-dependent processing functions */
1820
0
  switch (up->mode) {
1821
0
  default:
1822
0
  case MODE_OP_STI:
1823
0
    eval_serial(peer, pp, up);
1824
0
    break;
1825
1826
0
  case MODE_OP_STRICT:
1827
0
    eval_strict(peer, pp, up);
1828
0
    break;
1829
1830
0
  case MODE_OP_AUTO:
1831
0
    eval_auto(peer, pp, up);
1832
0
    break;
1833
0
  }
1834
0
}
1835
1836
/* ------------------------------------------------------------------ */
1837
1838
static void
1839
gpsd_stop_socket(
1840
  peerT * const peer)
1841
0
{
1842
0
  clockprocT * const pp = peer->procptr;
1843
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1844
1845
0
  if (-1 != pp->io.fd) {
1846
0
    if (syslogok(pp, up))
1847
0
      msyslog(LOG_INFO,
1848
0
        "%s: closing socket to GPSD, fd=%d",
1849
0
        up->logname, pp->io.fd);
1850
0
    else
1851
0
      DPRINTF(1, ("%s: closing socket to GPSD, fd=%d\n",
1852
0
            up->logname, pp->io.fd));
1853
0
    io_closeclock(&pp->io);
1854
0
    pp->io.fd = -1;
1855
0
  }
1856
0
  up->tickover = up->tickpres;
1857
0
  up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH);
1858
0
  up->fl_vers  = 0;
1859
0
  up->fl_sti   = 0;
1860
0
  up->fl_pps   = 0;
1861
0
  up->fl_watch = 0;
1862
0
}
1863
1864
/* ------------------------------------------------------------------ */
1865
1866
static void
1867
gpsd_init_socket(
1868
  peerT * const peer)
1869
0
{
1870
0
  clockprocT * const pp = peer->procptr;
1871
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1872
0
  addrinfoT  * ai;
1873
0
  int          rc;
1874
0
  int          ov;
1875
1876
  /* draw next address to try */
1877
0
  if (NULL == up->addr)
1878
0
    up->addr = s_gpsd_addr;
1879
0
  ai = up->addr;
1880
0
  up->addr = ai->ai_next;
1881
1882
  /* try to create a matching socket */
1883
0
  up->fdt = socket(
1884
0
    ai->ai_family, ai->ai_socktype, ai->ai_protocol);
1885
0
  if (-1 == up->fdt) {
1886
0
    if (syslogok(pp, up))
1887
0
      msyslog(LOG_ERR,
1888
0
        "%s: cannot create GPSD socket: %m",
1889
0
        up->logname);
1890
0
    goto no_socket;
1891
0
  }
1892
1893
  /* Make sure the socket is non-blocking. Connect/reconnect and
1894
   * IO happen in an event-driven environment, and synchronous
1895
   * operations wreak havoc on that.
1896
   */
1897
0
  rc = fcntl(up->fdt, F_SETFL, O_NONBLOCK, 1);
1898
0
  if (-1 == rc) {
1899
0
    if (syslogok(pp, up))
1900
0
      msyslog(LOG_ERR,
1901
0
        "%s: cannot set GPSD socket to non-blocking: %m",
1902
0
        up->logname);
1903
0
    goto no_socket;
1904
0
  }
1905
  /* Disable nagling. The way both GPSD and NTPD handle the
1906
   * protocol makes it record-oriented, and in most cases
1907
   * complete records (JSON serialised objects) will be sent in
1908
   * one sweep. Nagling gives not much advantage but adds another
1909
   * delay, which can worsen the situation for some packets.
1910
   */
1911
0
  ov = 1;
1912
0
  rc = setsockopt(up->fdt, IPPROTO_TCP, TCP_NODELAY,
1913
0
      (void *)&ov, sizeof(ov));
1914
0
  if (-1 == rc) {
1915
0
    if (syslogok(pp, up))
1916
0
      msyslog(LOG_INFO,
1917
0
        "%s: cannot disable TCP nagle: %m",
1918
0
        up->logname);
1919
0
  }
1920
1921
  /* Start a non-blocking connect. There might be a synchronous
1922
   * connection result we have to handle.
1923
   */
1924
0
  rc = connect(up->fdt, ai->ai_addr, ai->ai_addrlen);
1925
0
  if (-1 == rc) {
1926
0
    if (errno == EINPROGRESS) {
1927
0
      DPRINTF(1, ("%s: async connect pending, fd=%d\n",
1928
0
            up->logname, up->fdt));
1929
0
      return;
1930
0
    }
1931
1932
0
    if (syslogok(pp, up))
1933
0
      msyslog(LOG_ERR,
1934
0
        "%s: cannot connect GPSD socket: %m",
1935
0
        up->logname);
1936
0
    goto no_socket;
1937
0
  }
1938
1939
  /* We had a successful synchronous connect, so we add the
1940
   * refclock processing ASAP. We still have to wait for the
1941
   * version string and apply the watch command later on, but we
1942
   * might as well get the show on the road now.
1943
   */
1944
0
  DPRINTF(1, ("%s: new socket connection, fd=%d\n",
1945
0
        up->logname, up->fdt));
1946
1947
0
  pp->io.fd = up->fdt;
1948
0
  up->fdt   = -1;
1949
0
  if (0 == io_addclock(&pp->io)) {
1950
0
    if (syslogok(pp, up))
1951
0
      msyslog(LOG_ERR,
1952
0
        "%s: failed to register with I/O engine",
1953
0
        up->logname);
1954
0
    goto no_socket;
1955
0
  }
1956
1957
0
  return;
1958
1959
0
  no_socket:
1960
0
  if (-1 != pp->io.fd)
1961
0
    close(pp->io.fd);
1962
0
  if (-1 != up->fdt)
1963
0
    close(up->fdt);
1964
0
  pp->io.fd    = -1;
1965
0
  up->fdt      = -1;
1966
0
  up->tickover = up->tickpres;
1967
0
  up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH);
1968
0
}
1969
1970
/* ------------------------------------------------------------------ */
1971
1972
static void
1973
gpsd_test_socket(
1974
  peerT * const peer)
1975
0
{
1976
0
  clockprocT * const pp = peer->procptr;
1977
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1978
1979
0
  int       ec, rc;
1980
0
  socklen_t lc;
1981
1982
  /* Check if the non-blocking connect was finished by testing the
1983
   * socket for writeability. Use the 'poll()' API if available
1984
   * and 'select()' otherwise.
1985
   */
1986
0
  DPRINTF(2, ("%s: check connect, fd=%d\n",
1987
0
        up->logname, up->fdt));
1988
1989
0
#if defined(HAVE_SYS_POLL_H)
1990
0
  {
1991
0
    struct pollfd pfd;
1992
1993
0
    pfd.events = POLLOUT;
1994
0
    pfd.fd     = up->fdt;
1995
0
    rc = poll(&pfd, 1, 0);
1996
0
    if (1 != rc || !(pfd.revents & POLLOUT))
1997
0
      return;
1998
0
  }
1999
#elif defined(HAVE_SYS_SELECT_H)
2000
  {
2001
    struct timeval tout;
2002
    fd_set         wset;
2003
2004
    memset(&tout, 0, sizeof(tout));
2005
    FD_ZERO(&wset);
2006
    FD_SET(up->fdt, &wset);
2007
    rc = select(up->fdt+1, NULL, &wset, NULL, &tout);
2008
    if (0 == rc || !(FD_ISSET(up->fdt, &wset)))
2009
      return;
2010
  }
2011
#else
2012
# error Blooper! That should have been found earlier!
2013
#endif
2014
2015
  /* next timeout is a full one... */
2016
0
  up->tickover = TICKOVER_LOW;
2017
2018
  /* check for socket error */
2019
0
  ec = 0;
2020
0
  lc = sizeof(ec);
2021
0
  rc = getsockopt(up->fdt, SOL_SOCKET, SO_ERROR, (void *)&ec, &lc);
2022
0
  if (-1 == rc || 0 != ec) {
2023
0
    const char *errtxt;
2024
0
    if (0 == ec)
2025
0
      ec = errno;
2026
0
    errtxt = strerror(ec);
2027
0
    if (syslogok(pp, up))
2028
0
      msyslog(LOG_ERR,
2029
0
        "%s: async connect to GPSD failed,"
2030
0
        " fd=%d, ec=%d(%s)",
2031
0
        up->logname, up->fdt, ec, errtxt);
2032
0
    else
2033
0
      DPRINTF(1, ("%s: async connect to GPSD failed,"
2034
0
        " fd=%d, ec=%d(%s)\n",
2035
0
            up->logname, up->fdt, ec, errtxt));
2036
0
    goto no_socket;
2037
0
  } else {
2038
0
    DPRINTF(1, ("%s: async connect to GPSD succeeded, fd=%d\n",
2039
0
          up->logname, up->fdt));
2040
0
  }
2041
2042
  /* swap socket FDs, and make sure the clock was added */
2043
0
  pp->io.fd = up->fdt;
2044
0
  up->fdt   = -1;
2045
0
  if (0 == io_addclock(&pp->io)) {
2046
0
    if (syslogok(pp, up))
2047
0
      msyslog(LOG_ERR,
2048
0
        "%s: failed to register with I/O engine",
2049
0
        up->logname);
2050
0
    goto no_socket;
2051
0
  }
2052
0
  return;
2053
2054
0
  no_socket:
2055
0
  if (-1 != up->fdt) {
2056
0
    DPRINTF(1, ("%s: closing socket, fd=%d\n",
2057
0
          up->logname, up->fdt));
2058
0
    close(up->fdt);
2059
0
  }
2060
0
  up->fdt      = -1;
2061
0
  up->tickover = up->tickpres;
2062
0
  up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH);
2063
0
}
2064
2065
/* =====================================================================
2066
 * helper stuff
2067
 */
2068
2069
/* -------------------------------------------------------------------
2070
 * store a properly clamped precision value
2071
 */
2072
static int16_t
2073
clamped_precision(
2074
  int rawprec)
2075
0
{
2076
0
  if (rawprec > 0)
2077
0
    rawprec = 0;
2078
0
  if (rawprec < -32)
2079
0
    rawprec = -32;
2080
0
  return (int16_t)rawprec;
2081
0
}
2082
2083
/* -------------------------------------------------------------------
2084
 * Convert a GPSD timestamp (ISO8601 Format) to an l_fp
2085
 */
2086
static BOOL
2087
convert_ascii_time(
2088
  l_fp       * fp      ,
2089
  const char * gps_time)
2090
0
{
2091
0
  char           *ep;
2092
0
  struct tm       gd;
2093
0
  struct timespec ts;
2094
0
  uint32_t        dw;
2095
2096
  /* Use 'strptime' to take the brunt of the work, then parse
2097
   * the fractional part manually, starting with a digit weight of
2098
   * 10^8 nanoseconds.
2099
   */
2100
0
  ts.tv_nsec = 0;
2101
0
  ep = strptime(gps_time, "%Y-%m-%dT%H:%M:%S", &gd);
2102
0
  if (NULL == ep)
2103
0
    return FALSE; /* could not parse the mandatory stuff! */
2104
0
  if (*ep == '.') {
2105
0
    dw = 100000000u;
2106
0
    while (isdigit(*(u_char*)++ep)) {
2107
0
      ts.tv_nsec += (*(u_char*)ep - '0') * dw;
2108
0
      dw /= 10u;
2109
0
    }
2110
0
  }
2111
0
  if (ep[0] != 'Z' || ep[1] != '\0')
2112
0
    return FALSE; /* trailing garbage */
2113
2114
  /* Now convert the whole thing into a 'l_fp'. We do not use
2115
   * 'mkgmtime()' since its not standard and going through the
2116
   * calendar routines is not much effort, either.
2117
   */
2118
0
  ts.tv_sec = (ntpcal_tm_to_rd(&gd) - DAY_NTP_STARTS) * SECSPERDAY
2119
0
            + ntpcal_tm_to_daysec(&gd);
2120
0
  *fp = tspec_intv_to_lfp(ts);
2121
2122
0
  return TRUE;
2123
0
}
2124
2125
/* -------------------------------------------------------------------
2126
 * Save the last timecode string, making sure it's properly truncated
2127
 * if necessary and NUL terminated in any case.
2128
 */
2129
static void
2130
save_ltc(
2131
  clockprocT * const pp,
2132
  const char * const tc)
2133
0
{
2134
0
  size_t len = 0;
2135
  
2136
0
  if (tc) {
2137
0
    len = strlen(tc);
2138
0
    if (len >= sizeof(pp->a_lastcode))
2139
0
      len = sizeof(pp->a_lastcode) - 1;
2140
0
    memcpy(pp->a_lastcode, tc, len);
2141
0
  }
2142
0
  pp->lencode = (u_short)len;
2143
0
  pp->a_lastcode[len] = '\0';
2144
0
}
2145
2146
/* -------------------------------------------------------------------
2147
 * asprintf replacement... it's not available everywhere...
2148
 */
2149
static int
2150
myasprintf(
2151
  char      ** spp,
2152
  char const * fmt,
2153
  ...             )
2154
0
{
2155
0
  size_t alen, plen;
2156
2157
0
  alen = 32;
2158
0
  *spp = NULL;
2159
0
  do {
2160
0
    va_list va;
2161
2162
0
    alen += alen;
2163
0
    free(*spp);
2164
0
    *spp = (char*)malloc(alen);
2165
0
    if (NULL == *spp)
2166
0
      return -1;
2167
2168
0
    va_start(va, fmt);
2169
0
    plen = (size_t)vsnprintf(*spp, alen, fmt, va);
2170
0
    va_end(va);
2171
0
  } while (plen >= alen);
2172
2173
0
  return (int)plen;
2174
0
}
2175
2176
/* -------------------------------------------------------------------
2177
 * dump a raw data buffer
2178
 */
2179
2180
static char *
2181
add_string(
2182
  char *dp,
2183
  char *ep,
2184
  const char *sp)
2185
0
{
2186
0
  while (dp != ep && *sp)
2187
0
    *dp++ = *sp++;
2188
0
  return dp;
2189
0
}
2190
2191
static void
2192
log_data(
2193
  peerT      *peer,
2194
  int         level,
2195
  const char *what,
2196
  const char *buf ,
2197
  size_t      len )
2198
0
{
2199
  /* we're running single threaded with regards to the clocks. */
2200
0
  static char s_lbuf[2048];
2201
2202
0
  clockprocT * const pp = peer->procptr;
2203
0
  gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
2204
2205
0
  if (debug >= level) {
2206
0
    const char *sptr = buf;
2207
0
    const char *stop = buf + len;
2208
0
    char       *dptr = s_lbuf;
2209
0
    char       *dtop = s_lbuf + sizeof(s_lbuf) - 1; /* for NUL */
2210
2211
0
    while (sptr != stop && dptr != dtop) {
2212
0
      u_char uch = (u_char)*sptr++;
2213
0
      if (uch == '\\') {
2214
0
        dptr = add_string(dptr, dtop, "\\\\");
2215
0
      } else if (isprint(uch)) {
2216
0
        *dptr++ = (char)uch;
2217
0
      } else {
2218
0
        char fbuf[6];
2219
        snprintf(fbuf, sizeof(fbuf), "\\%03o", uch);
2220
0
        dptr = add_string(dptr, dtop, fbuf);
2221
0
      }
2222
0
    }
2223
0
    *dptr = '\0';
2224
0
    mprintf("%s[%s]: '%s'\n", up->logname, what, s_lbuf);
2225
0
  }
2226
0
}
2227
2228
2229
#else
2230
NONEMPTY_TRANSLATION_UNIT
2231
#endif /* REFCLOCK && CLOCK_GPSDJSON */