Lines Matching +full:reset +full:- +full:bps
2 * refclock_arc - clock driver for ARCRON MSF/DCF/WWVB receivers
35 Modifications by Damon Hart-Davis, <d@hd.org>, 1997.
37 Modifications by Christopher Price, <cprice@cs-home.com>, 2003.
44 Orginally developed and used with ntp3-5.85 by Derek Mulcahy.
46 Built against ntp3-5.90 on Solaris 2.5 using gcc 2.7.2.
52 -------------------------------------------------------------------------------
62 -------------------------------------------------------------------------------
69 2001-02-17 comp.protocols.time.ntp
89 -------------------------------------------------------------------------------
95 It works (after a fashion) on both Solaris-1 and Solaris-2.
97 I am currently using ntp3-5.85. I have been running the code for
114 -------------------------------------------------------------------------------
121 off-line once two time polls failed to gain responses.
123 2) Avoiding (at least on Solaris-2) terminal becoming the controlling
124 terminal of the process when we do a low-level open().
127 defined) to try to resync quickly after a potential leap-second
130 4) Code significantly slimmer at run-time than V1.0.
140 2) PRECISION should be -4/-5 (63ms/31ms) for the following reasons:
153 *day*, we can imagine that it is not, and is free-running. We
160 may effectively be free-running with respect to the host clock
172 By default, PRECISION is set to -4, but experience, especially at a
174 this to be altered to -5. (Note that skews of +/- 10ms are to be
175 expected from the clock from time-to-time.) This improvement of
199 clashing with any regular event at a regular time-past-the-hour
216 median-filter size from the typical (previous) value of 3. I
223 inter-character time but without introducting jitter and delay in
230 MSF---thus we should never end up syncing to completely the wrong
234 refclock median-filter routines to get round small bug in 3-5.90
236 bit due NTP Version 4 upgrade - dlm.
238 9) We would appear to have a year-2000 problem with this clock since
239 it returns only the two least-significant digits of the year. But
240 ntpd ignores the year and uses the local-system year instead, so
242 sensible thing with the dates, wrapping them into a 100-year
254 TO-DO LIST
266 * Add very slow auto-adjustment up to a value of +/- time2 to correct
267 for long-term errors in the clock value (time2 defaults to 0 so the
314 /* 7. day of week 1-monday 7-sunday */
342 /* This bit is zero after reset and one after the first */
347 if so what signal quality (0--5) is available.
382 #define PRECISION (-4) /* Precision (~63 ms). */
383 #define HIGHPRECISION (-5) /* If things are going well... */
399 #define BITTIME 0x0DA740E /* Time for 1 bit at 300bps. */
400 #define CHARTIME10 0x8888888 /* Time for 10-bit char at 300bps. */
401 #define CHARTIME11 0x962FC96 /* Time for 11-bit char at 300bps. */
402 #define CHARTIME /* Time for char at 300bps. */ \
406 /* Allow for UART to accept char half-way through final stop bit. */
407 #define INITIALOFFSET ((u_int32)(-BITTIME/2))
413 is on-time. The values are represented as the fractional part of
493 int quality; /* Quality of reception 0--5 for unit. */
494 /* We may also use the values -1 or 6 internally. */
495 u_long quality_stamp; /* Next time to reset quality average. */
507 /* The flag `possible_leap' is set non-zero when any MSF unit
508 thinks a leap-second may have happened.
517 non-negative, the receive routine sets it to a positive value to
523 indicate that a leap-triggered resync has been started. Having
536 #define QUALITY_UNKNOWN -1 /* Indicates unknown clock quality. */
565 peer->procptr->nextaction = current_time + QUEUETICK; \
568 /* Placeholder event handler---does nothing safely---soaks up loose tick. */
595 struct refclockproc *pp = peer->procptr; in arc_event_handler()
596 register struct arcunit *up = pp->unitptr; in arc_event_handler()
603 c = up->cmdqueue[0]; /* Next char to be sent. */ in arc_event_handler()
606 { up->cmdqueue[i] = up->cmdqueue[i+1]; } in arc_event_handler()
610 if(write(pp->io.fd, &c, 1) != 1) { in arc_event_handler()
611 msyslog(LOG_NOTICE, "ARCRON: write to fd %d failed", pp->io.fd); in arc_event_handler()
614 else if(debug) { printf("arc: sent `%2.2x', fd %d.\n", c, pp->io.fd); } in arc_event_handler()
622 * arc_start - open the devices and initialize data for processing
648 temp_fd = refclock_open(&peer->srcadr, device, SPEED, LDISC_CLK); in arc_start()
660 temp_fd = -1; /* not used after this, at *this* time. */ in arc_start()
663 if (-1 == fcntl(fd, F_SETFL, 0)) /* clear the descriptor flags */ in arc_start()
704 pp = peer->procptr; in arc_start()
705 pp->io.clock_recv = arc_receive; in arc_start()
706 pp->io.srcclock = peer; in arc_start()
707 pp->io.datalen = 0; in arc_start()
708 pp->io.fd = fd; in arc_start()
709 if (!io_addclock(&pp->io)) { in arc_start()
711 pp->io.fd = -1; in arc_start()
715 pp->unitptr = up; in arc_start()
720 peer->precision = PRECISION; in arc_start()
721 peer->stratum = 2; /* Default to stratum 2 not 0. */ in arc_start()
722 pp->clockdesc = DESCRIPTION; in arc_start()
723 if (peer->MODE > 3) { in arc_start()
724 msyslog(LOG_NOTICE, "ARCRON: Invalid mode %d", peer->MODE); in arc_start()
728 if(debug) { printf("arc: mode = %d.\n", peer->MODE); } in arc_start()
730 switch (peer->MODE) { in arc_start()
732 memcpy((char *)&pp->refid, REFID_MSF, 4); in arc_start()
735 memcpy((char *)&pp->refid, REFID_DCF77, 4); in arc_start()
738 memcpy((char *)&pp->refid, REFID_WWVB, 4); in arc_start()
741 memcpy((char *)&pp->refid, REFID, 4); in arc_start()
745 up->next_resync = current_time + INITIAL_RESYNC_DELAY + (67*unit)%1009; in arc_start()
748 up->resyncing = 0; /* Not resyncing yet. */ in arc_start()
749 up->saved_flags = 0; /* Default is all flags off. */ in arc_start()
753 for(i = CMDQUEUELEN; i >= 0; --i) { up->cmdqueue[i] = '\0'; } in arc_start()
758 up->quality = QUALITY_UNKNOWN; /* Trust the clock immediately. */ in arc_start()
760 up->quality = MIN_CLOCK_QUALITY;/* Don't trust the clock yet. */ in arc_start()
763 peer->procptr->action = arc_event_handler; in arc_start()
772 * arc_shutdown - shut down the clock
783 peer->procptr->action = dummy_event_handler; in arc_shutdown()
785 pp = peer->procptr; in arc_shutdown()
786 up = pp->unitptr; in arc_shutdown()
787 if (-1 != pp->io.fd) in arc_shutdown()
788 io_closeclock(&pp->io); in arc_shutdown()
805 { if(up->cmdqueue[CMDQUEUELEN - 1 - spaceleft] != '\0') { break; } } in space_left()
830 msyslog(LOG_NOTICE, "ARCRON: send-buffer overrun (%d/%d)", in send_slow()
837 while(*s && spaceleft > 0) { up->cmdqueue[CMDQUEUELEN - spaceleft--] = *s++; } in send_slow()
847 *val = (p[0] - '0') * 10 + p[1] - '0'; in get2()
855 *val = p[0] - '0'; in get1()
866 * arc_receive - receive data from the serial interface
889 peer = rbufp->recv_peer; in arc_receive()
890 pp = peer->procptr; in arc_receive()
891 up = pp->unitptr; in arc_receive()
898 if((up->resyncing) && (space_left(up) == CMDQUEUELEN)) { in arc_receive()
900 if(debug > 1) { printf("arc: inserting signal-quality poll.\n"); } in arc_receive()
902 send_slow(up, pp->io.fd, "g\r"); in arc_receive()
913 assumption also works if receive the characters one-by-one.) in arc_receive()
915 arc_last_offset = pp->lencode+rbufp->recv_length - 1; in arc_receive()
925 `on-time' character. in arc_receive()
936 c = rbufp->recv_buffer[0]; in arc_receive()
937 if((pp->a_lastcode[0] == 'o') && in arc_receive()
939 (pp->lencode == 1) && in arc_receive()
941 ((pp->lencode != 1) || (c != '\r')) && in arc_receive()
945 timestamp = rbufp->recv_time; in arc_receive()
947 if(debug) { /* Show \r as `R', other non-printing char as `?'. */ in arc_receive()
948 printf("arc: stamp -->%c<-- (%d chars rcvd)\n", in arc_receive()
950 rbufp->recv_length); in arc_receive()
955 Now correct timestamp by offset of last byte received---we in arc_receive()
970 pp->lencode = 0; in arc_receive()
979 "arc: %s%d char(s) rcvd, the last for lastcode[%d]; -%sms offset applied.\n", in arc_receive()
980 ((rbufp->recv_length > 1) ? "*** " : ""), in arc_receive()
981 rbufp->recv_length, in arc_receive()
1001 if(L_ISZERO(&(up->lastrec)) || in arc_receive()
1002 L_ISGEQ(&(up->lastrec), ×tamp)) in arc_receive()
1009 if(!L_ISZERO(&(up->lastrec))) { in arc_receive()
1011 diff = up->lastrec; in arc_receive()
1013 printf("arc: adjusted timestamp by -%sms.\n", in arc_receive()
1019 up->lastrec = timestamp; in arc_receive()
1028 if(pp->lencode >= LENARC) { in arc_receive()
1030 if(debug && (rbufp->recv_buffer[0] != '\r')) in arc_receive()
1031 { printf("arc: rubbish in pp->a_lastcode[].\n"); } in arc_receive()
1033 pp->lencode = 0; in arc_receive()
1038 for(i = 0; i < rbufp->recv_length; i++) { in arc_receive()
1039 if(pp->lencode >= LENARC) { break; } /* Avoid overflow... */ in arc_receive()
1040 c = rbufp->recv_buffer[i]; in arc_receive()
1043 if(c != '\r' && c != 'h') { pp->a_lastcode[pp->lencode++] = c; } in arc_receive()
1052 if((c == 'o') && (pp->lencode == 1)) { in arc_receive()
1053 L_CLR(&(up->lastrec)); in arc_receive()
1059 if (pp->lencode == 0) return; in arc_receive()
1062 if(pp->a_lastcode[0] == 'g') { in arc_receive()
1065 if(pp->lencode < 3) { return; } /* Need more data... */ in arc_receive()
1066 r = (pp->a_lastcode[1] & 0x7f); /* Strip parity. */ in arc_receive()
1067 q = (pp->a_lastcode[2] & 0x7f); /* Strip parity. */ in arc_receive()
1077 if (up->quality_stamp < current_time) { in arc_receive()
1083 up->quality_stamp = in arc_receive()
1084 current_time + 60 - cal.second + 5; in arc_receive()
1094 } else if( /* (r == '2') && */ up->resyncing) { in arc_receive()
1095 up->quality = quality_average; in arc_receive()
1100 up->quality, in arc_receive()
1101 quality_action(up->quality)); in arc_receive()
1106 up->quality, in arc_receive()
1107 quality_action(up->quality)); in arc_receive()
1108 up->resyncing = 0; /* Resync is over. */ in arc_receive()
1115 if((up->quality == QUALITY_UNKNOWN) || in arc_receive()
1116 (up->quality < MIN_CLOCK_QUALITY_OK)) in arc_receive()
1117 { up->next_resync = current_time + RETRY_RESYNC_TIME; } in arc_receive()
1120 pp->lencode = 0; in arc_receive()
1125 if(pp->a_lastcode[0] != 'o') { in arc_receive()
1126 pp->lencode = 0; in arc_receive()
1132 if(pp->lencode < LENARC) { return; } in arc_receive()
1141 if(L_ISZERO(&(up->lastrec))) { in arc_receive()
1145 pp->lencode = 0; in arc_receive()
1155 pp->a_lastcode[pp->lencode] = ((up->quality == QUALITY_UNKNOWN) ? in arc_receive()
1156 '6' : ('0' + up->quality)); in arc_receive()
1157 pp->a_lastcode[pp->lencode + 1] = '\0'; /* Terminate for printf(). */ in arc_receive()
1160 /* We don't use the micro-/milli- second part... */ in arc_receive()
1161 pp->usec = 0; in arc_receive()
1162 pp->msec = 0; in arc_receive()
1164 /* We don't use the nano-second part... */ in arc_receive()
1165 pp->nsec = 0; in arc_receive()
1168 if (pp->a_lastcode[0] != 'o' in arc_receive()
1169 || !get2(pp->a_lastcode + 1, &pp->hour) in arc_receive()
1170 || !get2(pp->a_lastcode + 3, &pp->minute) in arc_receive()
1171 || !get2(pp->a_lastcode + 5, &pp->second) in arc_receive()
1172 || !get1(pp->a_lastcode + 7, &wday) in arc_receive()
1173 || !get2(pp->a_lastcode + 8, &pp->day) in arc_receive()
1174 || !get2(pp->a_lastcode + 10, &month) in arc_receive()
1175 || !get2(pp->a_lastcode + 12, &pp->year)) { in arc_receive()
1180 pp->lencode = 0; in arc_receive()
1184 flags = pp->a_lastcode[14]; in arc_receive()
1185 status = pp->a_lastcode[15]; in arc_receive()
1193 array-bounds problems, etc. in arc_receive()
1195 if((pp->hour < 0) || (pp->hour > 23) || in arc_receive()
1196 (pp->minute < 0) || (pp->minute > 59) || in arc_receive()
1197 (pp->second < 0) || (pp->second > 60) /*Allow for leap seconds.*/ || in arc_receive()
1199 (pp->day < 1) || (pp->day > 31) || in arc_receive()
1201 (pp->year < 0) || (pp->year > 99)) { in arc_receive()
1203 pp->lencode = 0; in arc_receive()
1209 if(peer->MODE == 0) { /* compatiblity to original version */ in arc_receive()
1213 pp->lencode = 0; in arc_receive()
1220 /* Year-2000 alert! */ in arc_receive()
1221 /* Attempt to wrap 2-digit date into sensible window. */ in arc_receive()
1222 if(pp->year < YEAR_PIVOT) { pp->year += 100; } /* Y2KFixes */ in arc_receive()
1223 pp->year += 1900; /* use full four-digit year */ /* Y2KFixes */ in arc_receive()
1227 hero I am... PLEASE FIX LEAP-YEAR AND WRAP CODE IN 209X! in arc_receive()
1229 if(pp->year >= YEAR_PIVOT+2000-2 ) { /* Y2KFixes */ in arc_receive()
1238 pp->hour, pp->minute, pp->second, in arc_receive()
1239 pp->day, month, pp->year, flags, status); in arc_receive()
1249 pp->leap = LEAP_NOWARNING; in arc_receive()
1252 if(status != up->status) in arc_receive()
1255 if(status != up->status) { in arc_receive()
1257 pp->leap = LEAP_NOTINSYNC; /* MSF clock is free-running. */ in arc_receive()
1258 up->status = status; in arc_receive()
1259 pp->lencode = 0; in arc_receive()
1264 up->status = status; in arc_receive()
1266 if (peer->MODE == 0) { /* compatiblity to original version */ in arc_receive()
1269 pp->day += moff[month - 1]; in arc_receive()
1271 if(isleap_4(pp->year) && month > 2) { pp->day++; }/* Y2KFixes */ in arc_receive()
1275 pp->hour--; in arc_receive()
1276 if (pp->hour < 0) { in arc_receive()
1277 pp->hour = 23; in arc_receive()
1278 pp->day--; in arc_receive()
1281 if(pp->day < 0) { in arc_receive()
1282 pp->lencode = 0; in arc_receive()
1290 if(peer->MODE > 0) { in arc_receive()
1291 if(pp->sloppyclockflag & CLK_FLAG1) { in arc_receive()
1299 * 2-digit year; otherwise, we get the time wrong. in arc_receive()
1304 local.tm_year = pp->year-1900; in arc_receive()
1305 local.tm_mon = month-1; in arc_receive()
1306 local.tm_mday = pp->day; in arc_receive()
1307 local.tm_hour = pp->hour; in arc_receive()
1308 local.tm_min = pp->minute; in arc_receive()
1309 local.tm_sec = pp->second; in arc_receive()
1310 switch (peer->MODE) { in arc_receive()
1320 Arcron changes from DST->ST and in arc_receive()
1321 ST->DST. Testing has shown this in arc_receive()
1330 case 1: /* dst->st time */ in arc_receive()
1331 local.tm_isdst = -1; in arc_receive()
1337 case 2: /* st->dst time */ in arc_receive()
1338 local.tm_isdst = -1; in arc_receive()
1355 peer->MODE); in arc_receive()
1362 pp->lencode = 0; in arc_receive()
1366 pp->year = gmtp->tm_year+1900; in arc_receive()
1367 month = gmtp->tm_mon+1; in arc_receive()
1368 pp->day = ymd2yd(pp->year,month,gmtp->tm_mday); in arc_receive()
1369 /* pp->day = gmtp->tm_yday; */ in arc_receive()
1370 pp->hour = gmtp->tm_hour; in arc_receive()
1371 pp->minute = gmtp->tm_min; in arc_receive()
1372 pp->second = gmtp->tm_sec; in arc_receive()
1377 pp->year,month,gmtp->tm_mday,pp->hour,pp->minute, in arc_receive()
1378 pp->second); in arc_receive()
1386 pp->day = ymd2yd(pp->year,month,pp->day); in arc_receive()
1390 if (peer->MODE == 0) { /* compatiblity to original version */ in arc_receive()
1393 if(up->quality == QUALITY_UNKNOWN) { in arc_receive()
1394 peer->precision = PRECISION; in arc_receive()
1396 peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? in arc_receive()
1400 if ((status == 0x3) && (pp->sloppyclockflag & CLK_FLAG2)) { in arc_receive()
1401 peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? in arc_receive()
1403 } else if (up->quality == QUALITY_UNKNOWN) { in arc_receive()
1404 peer->precision = PRECISION; in arc_receive()
1406 peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? in arc_receive()
1412 if(up->saved_flags != pp->sloppyclockflag) { in arc_receive()
1415 ((pp->sloppyclockflag & CLK_FLAG1) ? "1" : "."), in arc_receive()
1416 ((pp->sloppyclockflag & CLK_FLAG2) ? "2" : "."), in arc_receive()
1417 ((pp->sloppyclockflag & CLK_FLAG3) ? "3" : "."), in arc_receive()
1418 ((pp->sloppyclockflag & CLK_FLAG4) ? "4" : ".")); in arc_receive()
1421 printf("arc: PRECISION = %d.\n", peer->precision); in arc_receive()
1424 up->saved_flags = pp->sloppyclockflag; in arc_receive()
1428 pp->lastrec = up->lastrec; in arc_receive()
1431 /* Find out if a leap-second might just have happened... in arc_receive()
1434 if((pp->hour == 0) && in arc_receive()
1435 (pp->day == 1) && in arc_receive()
1442 /* Definitely not leap-second territory... */ in arc_receive()
1448 pp->lencode = 0; in arc_receive()
1452 record_clock_stats(&peer->srcadr, pp->a_lastcode); in arc_receive()
1467 struct refclockproc *pp = peer->procptr; in request_time()
1468 register struct arcunit *up = pp->unitptr; in request_time()
1472 if (!send_slow(up, pp->io.fd, "o\r")) { in request_time()
1478 pp->lencode = 0; in request_time()
1482 pp->polls++; in request_time()
1486 * arc_poll - called by the transmit procedure
1498 pp = peer->procptr; in arc_poll()
1499 up = pp->unitptr; in arc_poll()
1501 pp->lencode = 0; in arc_poll()
1502 memset(pp->a_lastcode, 0, sizeof(pp->a_lastcode)); in arc_poll()
1507 tcflush(pp->io.fd, TCIFLUSH); in arc_poll()
1511 resync_needed = ( !(pp->sloppyclockflag & CLK_FLAG2) && in arc_poll()
1512 (up->next_resync <= current_time) ); in arc_poll()
1516 Try to catch a potential leap-second insertion or deletion quickly. in arc_poll()
1519 leap-seconds spooking their hosts, this clock does not even in arc_poll()
1521 leap-second insertion or deletion for up to a whole sample in arc_poll()
1525 the day immediately following a leap-second-insertion point in arc_poll()
1533 (!up->resyncing)) { /* No resync in progress yet. */ in arc_poll()
1535 possible_leap = -1; /* Prevent multiple resyncs. */ in arc_poll()
1542 /* First, reset quality value to `unknown' so we can detect */ in arc_poll()
1545 up->quality = QUALITY_UNKNOWN; in arc_poll()
1548 up->resyncing = 1; in arc_poll()
1555 send_slow(up, pp->io.fd, "h\r"); in arc_poll()
1558 up->next_resync = current_time + DEFAULT_RESYNC_TIME; in arc_poll()
1566 /* synced so quickly we did not catch it---we'll */ in arc_poll()
1567 /* double-check the clock is OK elsewhere. */ in arc_poll()
1570 (up->quality != QUALITY_UNKNOWN) && in arc_poll()
1572 (up->quality == QUALITY_UNKNOWN) || in arc_poll()
1574 (up->quality < MIN_CLOCK_QUALITY_OK)) { in arc_poll()
1577 printf("arc: clock quality %d too poor.\n", up->quality); in arc_poll()
1580 pp->lencode = 0; in arc_poll()