76
76
* ee = hardware errors
78
78
* If flag4 is set, an additional line consisting of the receiver
79
* latitude (LA), longitude (LO) and elevation (LH) (meters) is written
80
* to this file. If channel B is enabled for deviation mode and connected
81
* to a 1-PPS signal, the last two numbers on the line are the deviation
82
* and standard deviation averaged over the last 15 seconds.
79
* latitude (LA), longitude (LO), elevation (LH) (meters), and data
80
* buffer (DB) is written to this file. If channel B is enabled for
81
* deviation mode and connected to a 1-PPS signal, the last two numbers
82
* on the line are the deviation and standard deviation averaged over
83
* the last 15 seconds.
85
* PPS calibration fudge time1 .001240
88
91
#define DEVICE "/dev/gps%d" /* device name and unit */
89
92
#define SPEED232 B9600 /* uart speed (9600 baud) */
90
93
#define PRECISION (-20) /* precision assumed (about 1 us) */
91
#define REFID "GPS " /* reference ID */
94
#define REFID "GPS " /* reference ID */
92
95
#define DESCRIPTION "Arbiter 1088A/B GPS Receiver" /* WRU */
94
96
#define LENARB 24 /* format B5 timecode length */
95
#define MAXSTA 30 /* max length of status string */
96
#define MAXPOS 70 /* max length of position string */
97
#define MAXSTA 40 /* max length of status string */
98
#define MAXPOS 80 /* max length of position string */
99
101
* ARB unit control structure
241
245
pp->lastrec = up->laststamp;
242
246
up->laststamp = trtmp;
245
250
if (up->tcswitch == 0) {
248
253
* Collect statistics. If nothing is recogized, just
249
254
* ignore; sometimes the clock doesn't stop spewing
250
* timecodes for awhile after the B0 commant.
255
* timecodes for awhile after the B0 command.
257
* If flag4 is not set, send TQ, SR, B5. If flag4 is
258
* sset, send TQ, SR, LA, LO, LH, DB, B5. When the
259
* median filter is full, send B0.
252
if (!strncmp(pp->a_lastcode, "TQ", 2)) {
253
up->qualchar = pp->a_lastcode[2];
261
if (!strncmp(tbuf, "TQ", 2)) {
262
up->qualchar = tbuf[2];
254
263
write(pp->io.fd, "SR", 2);
255
} else if (!strncmp(pp->a_lastcode, "SR", 2)) {
256
strcpy(up->status, pp->a_lastcode + 2);
266
} else if (!strncmp(tbuf, "SR", 2)) {
267
strcpy(up->status, tbuf + 2);
257
268
if (pp->sloppyclockflag & CLK_FLAG4)
258
269
write(pp->io.fd, "LA", 2);
260
271
write(pp->io.fd, "B5", 2);
263
} else if (!strncmp(pp->a_lastcode, "LA", 2)) {
264
strcpy(up->latlon, pp->a_lastcode + 2);
274
} else if (!strncmp(tbuf, "LA", 2)) {
275
strcpy(up->latlon, tbuf + 2);
265
276
write(pp->io.fd, "LO", 2);
266
} else if (!strncmp(pp->a_lastcode, "LO", 2)) {
279
} else if (!strncmp(tbuf, "LO", 2)) {
267
280
strcat(up->latlon, " ");
268
strcat(up->latlon, pp->a_lastcode + 2);
281
strcat(up->latlon, tbuf + 2);
269
282
write(pp->io.fd, "LH", 2);
270
} else if (!strncmp(pp->a_lastcode, "LH", 2)) {
285
} else if (!strncmp(tbuf, "LH", 2)) {
271
286
strcat(up->latlon, " ");
272
strcat(up->latlon, pp->a_lastcode + 2);
287
strcat(up->latlon, tbuf + 2);
273
288
write(pp->io.fd, "DB", 2);
274
} else if (!strncmp(pp->a_lastcode, "DB", 2)) {
291
} else if (!strncmp(tbuf, "DB", 2)) {
275
292
strcat(up->latlon, " ");
276
strcat(up->latlon, pp->a_lastcode + 2);
293
strcat(up->latlon, tbuf + 2);
277
294
record_clock_stats(&peer->srcadr, up->latlon);
297
printf("arbiter: %s\n", up->latlon);
278
299
write(pp->io.fd, "B5", 2);
286
304
* We get down to business, check the timecode format and decode
291
309
* that the time quality character and receiver status string is
292
310
* tacked on the end for clockstats display.
294
if (pp->lencode == LENARB) {
296
* Timecode format B5: "i yy ddd hh:mm:ss.000 "
298
pp->a_lastcode[LENARB - 2] = up->qualchar;
299
strcat(pp->a_lastcode, up->status);
301
if (sscanf(pp->a_lastcode, "%c%2d %3d %2d:%2d:%2d",
302
&syncchar, &pp->year, &pp->day, &pp->hour,
303
&pp->minute, &pp->second) != 6) {
304
refclock_report(peer, CEVNT_BADREPLY);
305
write(pp->io.fd, "B0", 2);
309
write(pp->io.fd, "B0", 2);
313
if (up->tcswitch <= 1 || temp < LENARB)
317
* Timecode format B5: "i yy ddd hh:mm:ss.000 "
319
strncpy(pp->a_lastcode, tbuf, BMAX);
320
pp->a_lastcode[LENARB - 2] = up->qualchar;
321
strcat(pp->a_lastcode, up->status);
322
pp->lencode = strlen(pp->a_lastcode);
324
if (sscanf(pp->a_lastcode, "%c%2d %3d %2d:%2d:%2d",
325
&syncchar, &pp->year, &pp->day, &pp->hour,
326
&pp->minute, &pp->second) != 6) {
327
refclock_report(peer, CEVNT_BADREPLY);
328
write(pp->io.fd, "B0", 2);
315
333
* We decode the clock dispersion from the time quality
404
422
* Transmission occurs once per second, unless turned off by a
405
423
* "B0". Note there is no checking on state, since this may not
406
424
* be the only customer reading the clock. Only one customer
407
* need poll the clock; all others just listen in. If nothing is
408
* heard from the clock for two polls, declare a timeout and
425
* need poll the clock; all others just listen in.
411
427
pp = peer->procptr;
412
428
up = (struct arbunit *)pp->unitptr;
413
430
up->tcswitch = 0;
414
if (write(pp->io.fd, "TQ", 2) != 2) {
431
if (write(pp->io.fd, "TQ", 2) != 2)
415
432
refclock_report(peer, CEVNT_FAULT);
435
* Process median filter samples. If none received, declare a
436
* timeout and keep going.
419
438
if (pp->coderecv == pp->codeproc) {
420
439
refclock_report(peer, CEVNT_TIMEOUT);
423
pp->lastref = pp->lastrec;
424
442
refclock_receive(peer);
425
443
record_clock_stats(&peer->srcadr, pp->a_lastcode);
446
printf("arbiter: timecode %d %s\n",
447
pp->lencode, pp->a_lastcode);