Lines Matching defs:??

10 #if defined(REFCLOCK) && defined(CLOCK_ARBITER)
23 #define write(fd, data, octets) async_write(fd, data, octets)
28 * The claimed accuracy of this clock is 100 ns relative to the PPS
29 * output when receiving four or more satellites.
31 * The receiver should be configured before starting the NTP daemon, in
32 * order to establish reliable position and operating conditions. It
33 * does not initiate surveying or hold mode. For use with NTP, the
34 * daylight savings time feature should be disables (D0 command) and the
35 * broadcast mode set to operate in UTC (BU command).
37 * The timecode format supported by this driver is selected by the poll
38 * sequence "B5", which initiates a line in the following format to be
39 * repeated once per second until turned off by the "B0" poll sequence.
41 * Format B5 (24 ASCII printing characters):
43 * <cr><lf>i yy ddd hh:mm:ss.000bbb
45 * on-time = <cr>
47 * yy = year of century
48 * ddd = day of year
49 * hh:mm:ss = hours, minutes, seconds
50 * .000 = fraction of second (not used)
53 * The alarm condition is indicated by a '?' at i, which indicates the
54 * receiver is not synchronized. In normal operation, a line consisting
55 * of the timecode followed by the time quality character (TQ) followed
56 * by the receiver status string (SR) is written to the clockstats file.
57 * The time quality character is encoded in IEEE P1344 standard:
59 * Format TQ (IEEE P1344 estimated worst-case time quality)
63 * 4 clock unlocked, accuracy < 1 us
64 * 5 clock unlocked, accuracy < 10 us
65 * 6 clock unlocked, accuracy < 100 us
66 * 7 clock unlocked, accuracy < 1 ms
67 * 8 clock unlocked, accuracy < 10 ms
68 * 9 clock unlocked, accuracy < 100 ms
70 * B clock unlocked, accuracy < 10 s
72 * The status string is encoded as follows:
74 * Format SR (25 ASCII printing characters)
76 * V=vv S=ss T=t P=pdop E=ee
78 * vv = satellites visible
79 * ss = relative signal strength
81 * pdop = position dilution of precision (meters)
82 * ee = hardware errors
84 * If flag4 is set, an additional line consisting of the receiver
85 * latitude (LA), longitude (LO), elevation (LH) (meters), and data
86 * buffer (DB) is written to this file. If channel B is enabled for
87 * deviation mode and connected to a 1-PPS signal, the last two numbers
88 * on the line are the deviation and standard deviation averaged over
89 * the last 15 seconds.
99 #define PRECISION (-20) /* precision assumed (about 1 us) */
100 #define REFID "GPS " /* reference ID */
102 #define LENARB 24 /* format B5 timecode length */
103 #define MAXSTA 40 /* max length of status string */
104 #define MAXPOS 80 /* max length of position string */
112 #define COMMAND_HALT_BCAST ( (peer->MODE % 2) ? "O0" : "B0" )
113 #define COMMAND_START_BCAST ( (peer->MODE % 2) ? "O5" : "B5" )
121 char qualchar; /* IEEE P1344 quality (TQ command) */
122 char status[MAXSTA]; /* receiver status (SR command) */
138 arb_start, /* start up driver */
157 register struct arbunit *up;
158 struct refclockproc *pp;
159 int fd;
160 char device[20];
163 * Open serial port. Use CLK line discipline, if available.
166 fd = refclock_open(device, SPEED232, LDISC_CLK);
167 if (fd <= 0)
173 up = emalloc_zero(sizeof(*up));
174 pp = peer->procptr;
175 pp->io.clock_recv = arb_receive;
176 pp->io.srcclock = peer;
177 pp->io.datalen = 0;
178 pp->io.fd = fd;
179 if (!io_addclock(&pp->io)) {
180 close(fd);
181 pp->io.fd = -1;
182 free(up);
185 pp->unitptr = up;
191 pp->clockdesc = DESCRIPTION;
192 memcpy((char *)&pp->refid, REFID, 4);
193 if (peer->MODE > 1) {
195 close(fd);
196 pp->io.fd = -1;
197 free(up);
201 if(debug) { printf("arbiter: mode = %d.\n", peer->MODE); }
203 write(pp->io.fd, COMMAND_HALT_BCAST, 2);
217 register struct arbunit *up;
218 struct refclockproc *pp;
220 pp = peer->procptr;
221 up = pp->unitptr;
222 if (-1 != pp->io.fd)
223 io_closeclock(&pp->io);
224 if (NULL != up)
225 free(up);
237 register struct arbunit *up;
238 struct refclockproc *pp;
249 pp = peer->procptr;
250 up = pp->unitptr;
254 * Note we get a buffer and timestamp for both a <cr> and <lf>,
255 * but only the <cr> timestamp is retained. The program first
256 * sends a TQ and expects the echo followed by the time quality
257 * character. It then sends a B5 starting the timecode broadcast
258 * and expects the echo followed some time later by the on-time
259 * character <cr> and then the <lf> beginning the timecode
260 * itself. Finally, at the <cr> beginning the next timecode at
261 * the next second, the program sends a B0 shutting down the
264 * If flag4 is set, the program snatches the latitude, longitude
265 * and elevation and writes it to the clockstats file.
267 if (temp == 0)
270 pp->lastrec = up->laststamp;
271 up->laststamp = trtmp;
272 if (temp < 3)
275 if (up->tcswitch == 0) {
278 * Collect statistics. If nothing is recogized, just
280 * timecodes for awhile after the B0 command.
282 * If flag4 is not set, send TQ, SR, B5. If flag4 is
283 * sset, send TQ, SR, LA, LO, LH, DB, B5. When the
284 * median filter is full, send B0.
286 if (!strncmp(tbuf, "TQ", 2)) {
287 up->qualchar = tbuf[2];
288 write(pp->io.fd, "SR", 2);
291 } else if (!strncmp(tbuf, "SR", 2)) {
292 strlcpy(up->status, tbuf + 2,
293 sizeof(up->status));
294 if (pp->sloppyclockflag & CLK_FLAG4)
295 write(pp->io.fd, "LA", 2);
297 write(pp->io.fd, COMMAND_START_BCAST, 2);
300 } else if (!strncmp(tbuf, "LA", 2)) {
301 strlcpy(up->latlon, tbuf + 2, sizeof(up->latlon));
302 write(pp->io.fd, "LO", 2);
305 } else if (!strncmp(tbuf, "LO", 2)) {
306 strlcat(up->latlon, " ", sizeof(up->latlon));
307 strlcat(up->latlon, tbuf + 2, sizeof(up->latlon));
308 write(pp->io.fd, "LH", 2);
311 } else if (!strncmp(tbuf, "LH", 2)) {
312 strlcat(up->latlon, " ", sizeof(up->latlon));
313 strlcat(up->latlon, tbuf + 2, sizeof(up->latlon));
314 write(pp->io.fd, "DB", 2);
317 } else if (!strncmp(tbuf, "DB", 2)) {
318 strlcat(up->latlon, " ", sizeof(up->latlon));
319 strlcat(up->latlon, tbuf + 2, sizeof(up->latlon));
320 record_clock_stats(&peer->srcadr, up->latlon);
322 if (debug)
323 printf("arbiter: %s\n", up->latlon);
325 write(pp->io.fd, COMMAND_START_BCAST, 2);
330 * We get down to business, check the timecode format and decode
331 * its contents. If the timecode has valid length, but not in
332 * proper format, we declare bad format and exit. If the
334 * B0 amputates the broadcast, we just quietly steal away. Note
335 * that the time quality character and receiver status string is
336 * tacked on the end for clockstats display.
338 up->tcswitch++;
339 if (up->tcswitch <= 1 || temp < LENARB)
343 * Timecode format B5: "i yy ddd hh:mm:ss.000 "
345 strlcpy(pp->a_lastcode, tbuf, sizeof(pp->a_lastcode));
346 pp->a_lastcode[LENARB - 2] = up->qualchar;
347 strlcat(pp->a_lastcode, up->status, sizeof(pp->a_lastcode));
348 pp->lencode = strlen(pp->a_lastcode);
350 if (sscanf(pp->a_lastcode, "%c%2d %3d %2d:%2d:%2d",
351 &syncchar, &pp->year, &pp->day, &pp->hour,
352 &pp->minute, &pp->second) != 6) {
354 write(pp->io.fd, COMMAND_HALT_BCAST, 2);
359 * We decode the clock dispersion from the time quality
362 switch (up->qualchar) {
365 pp->disp = 1e-7;
366 pp->lastref = pp->lastrec;
369 case '4': /* unlock accuracy < 1 us */
370 pp->disp = 1e-6;
373 case '5': /* unlock accuracy < 10 us */
374 pp->disp = 1e-5;
377 case '6': /* unlock accuracy < 100 us */
378 pp->disp = 1e-4;
381 case '7': /* unlock accuracy < 1 ms */
382 pp->disp = .001;
385 case '8': /* unlock accuracy < 10 ms */
386 pp->disp = .01;
389 case '9': /* unlock accuracy < 100 ms */
390 pp->disp = .1;
394 pp->disp = 1;
397 case 'B': /* unlock accuracy < 10 s */
398 pp->disp = 10;
402 pp->disp = MAXDISPERSE;
404 write(pp->io.fd, COMMAND_HALT_BCAST, 2);
408 pp->disp = MAXDISPERSE;
410 write(pp->io.fd, COMMAND_HALT_BCAST, 2);
413 if (syncchar != ' ')
414 pp->leap = LEAP_NOTINSYNC;
416 pp->leap = LEAP_NOWARNING;
419 * Process the new sample in the median filter and determine the
422 if (!refclock_process(pp))
424 else if (peer->disp > MAXDISTANCE)
427 /* if (up->tcswitch >= MAXSTAGE) { */
428 write(pp->io.fd, COMMAND_HALT_BCAST, 2);
434 * arb_poll - called by the transmit procedure
442 register struct arbunit *up;
443 struct refclockproc *pp;
446 * Time to poll the clock. The Arbiter clock responds to a "B5"
447 * by returning a timecode in the format specified above.
448 * Transmission occurs once per second, unless turned off by a
449 * "B0". Note there is no checking on state, since this may not
450 * be the only customer reading the clock. Only one customer
451 * need poll the clock; all others just listen in.
453 pp = peer->procptr;
454 up = pp->unitptr;
455 pp->polls++;
456 up->tcswitch = 0;
457 if (write(pp->io.fd, "TQ", 2) != 2)
461 * Process median filter samples. If none received, declare a
464 if (pp->coderecv == pp->codeproc) {
469 record_clock_stats(&peer->srcadr, pp->a_lastcode);
471 if (debug)
473 pp->lencode, pp->a_lastcode);