Coverage Report

Created: 2023-05-19 06:16

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