?? refclock_arc.c
字號:
(pp->day < 1) || (pp->day > 31) || (month < 1) || (month > 12) || (pp->year < 0) || (pp->year > 99)) { /* Data out of range. */ pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } if(peer->MODE == 0) { /* compatiblity to original version */ int bst = flags; /* Check that BST/UTC bits are the complement of one another. */ if(!(bst & 2) == !(bst & 4)) { pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } } if(status & 0x8) { msyslog(LOG_NOTICE, "ARCRON: battery low"); } /* Year-2000 alert! */ /* Attempt to wrap 2-digit date into sensible window. */ if(pp->year < YEAR_PIVOT) { pp->year += 100; } /* Y2KFixes */ pp->year += 1900; /* use full four-digit year */ /* Y2KFixes */ /* Attempt to do the right thing by screaming that the code will soon break when we get to the end of its useful life. What a hero I am... PLEASE FIX LEAP-YEAR AND WRAP CODE IN 209X! */ if(pp->year >= YEAR_PIVOT+2000-2 ) { /* Y2KFixes */ /*This should get attention B^> */ msyslog(LOG_NOTICE, "ARCRON: fix me! EITHER YOUR DATE IS BADLY WRONG or else I will break soon!"); }#ifdef DEBUG if(debug) { printf("arc: n=%d %02d:%02d:%02d %02d/%02d/%04d %1d %1d\n", n, pp->hour, pp->minute, pp->second, pp->day, month, pp->year, flags, status); }#endif /* The status value tested for is not strictly supported by the clock spec since the value of bit 2 (0x4) is claimed to be undefined for MSF, yet does seem to indicate if the last resync was successful or not. */ pp->leap = LEAP_NOWARNING; status &= 0x7; if(status == 0x3) { if(status != up->status) { msyslog(LOG_NOTICE, "ARCRON: signal acquired"); } } else { if(status != up->status) { msyslog(LOG_NOTICE, "ARCRON: signal lost"); pp->leap = LEAP_NOTINSYNC; /* MSF clock is free-running. */ up->status = status; pp->lencode = 0; refclock_report(peer, CEVNT_FAULT); return; } } up->status = status; if (peer->MODE == 0) { /* compatiblity to original version */ int bst = flags; pp->day += moff[month - 1]; if(isleap_4(pp->year) && month > 2) { pp->day++; }/* Y2KFixes */ /* Convert to UTC if required */ if(bst & 2) { pp->hour--; if (pp->hour < 0) { pp->hour = 23; pp->day--; /* If we try to wrap round the year * (BST on 1st Jan), reject.*/ if(pp->day < 0) { pp->lencode = 0; refclock_report(peer, CEVNT_BADTIME); return; } } } } if(peer->MODE > 0) { if(pp->sloppyclockflag & CLK_FLAG1) { struct tm local; struct tm *gmtp; time_t unixtime; /* * Convert to GMT for sites that distribute localtime. * This means we have to do Y2K conversion on the * 2-digit year; otherwise, we get the time wrong. */ local.tm_year = pp->year-1900; local.tm_mon = month-1; local.tm_mday = pp->day; local.tm_hour = pp->hour; local.tm_min = pp->minute; local.tm_sec = pp->second; switch (peer->MODE) { case 1: local.tm_isdst = (flags & 2); break; case 2: local.tm_isdst = (flags & 2); break; case 3: switch (flags & 3) { case 0: /* It is unclear exactly when the Arcron changes from DST->ST and ST->DST. Testing has shown this to be irregular. For the time being, let the OS decide. */ local.tm_isdst = 0;#ifdef DEBUG if (debug) printf ("arc: DST = 00 (0)\n"); #endif break; case 1: /* dst->st time */ local.tm_isdst = -1;#ifdef DEBUG if (debug) printf ("arc: DST = 01 (1)\n"); #endif break; case 2: /* st->dst time */ local.tm_isdst = -1;#ifdef DEBUG if (debug) printf ("arc: DST = 10 (2)\n"); #endif break; case 3: /* dst time */ local.tm_isdst = 1;#ifdef DEBUG if (debug) printf ("arc: DST = 11 (3)\n"); #endif break; } break; default: msyslog(LOG_NOTICE, "ARCRON: Invalid mode %d", peer->MODE); return; break; } unixtime = mktime (&local); if ((gmtp = gmtime (&unixtime)) == NULL) { pp->lencode = 0; refclock_report (peer, CEVNT_FAULT); return; } pp->year = gmtp->tm_year+1900; month = gmtp->tm_mon+1; pp->day = ymd2yd(pp->year,month,gmtp->tm_mday); /* pp->day = gmtp->tm_yday; */ pp->hour = gmtp->tm_hour; pp->minute = gmtp->tm_min; pp->second = gmtp->tm_sec;#ifdef DEBUG if (debug) { printf ("arc: time is %04d/%02d/%02d %02d:%02d:%02d UTC\n", pp->year,month,gmtp->tm_mday,pp->hour,pp->minute, pp->second); }#endif } else { /* * For more rational sites distributing UTC */ pp->day = ymd2yd(pp->year,month,pp->day); } } if (peer->MODE == 0) { /* compatiblity to original version */ /* If clock signal quality is * unknown, revert to default PRECISION...*/ if(up->quality == QUALITY_UNKNOWN) { peer->precision = PRECISION; } else { /* ...else improve precision if flag3 is set... */ peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? HIGHPRECISION : PRECISION); } } else { if ((status == 0x3) && (pp->sloppyclockflag & CLK_FLAG2)) { peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? HIGHPRECISION : PRECISION); } else if (up->quality == QUALITY_UNKNOWN) { peer->precision = PRECISION; } else { peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? HIGHPRECISION : PRECISION); } } /* Notice and log any change (eg from initial defaults) for flags. */ if(up->saved_flags != pp->sloppyclockflag) {#ifdef DEBUG msyslog(LOG_NOTICE, "ARCRON: flags enabled: %s%s%s%s", ((pp->sloppyclockflag & CLK_FLAG1) ? "1" : "."), ((pp->sloppyclockflag & CLK_FLAG2) ? "2" : "."), ((pp->sloppyclockflag & CLK_FLAG3) ? "3" : "."), ((pp->sloppyclockflag & CLK_FLAG4) ? "4" : ".")); /* Note effects of flags changing... */ if(debug) { printf("arc: PRECISION = %d.\n", peer->precision); }#endif up->saved_flags = pp->sloppyclockflag; } /* Note time of last believable timestamp. */ pp->lastrec = up->lastrec;#ifdef ARCRON_LEAPSECOND_KEEN /* Find out if a leap-second might just have happened... (ie is this the first hour of the first day of Jan or Jul?) */ if((pp->hour == 0) && (pp->day == 1) && ((month == 1) || (month == 7))) { if(possible_leap >= 0) { /* A leap may have happened, and no resync has started yet...*/ possible_leap = 1; } } else { /* Definitely not leap-second territory... */ possible_leap = 0; }#endif if (!refclock_process(pp)) { pp->lencode = 0; refclock_report(peer, CEVNT_BADTIME); return; } record_clock_stats(&peer->srcadr, pp->a_lastcode); refclock_receive(peer);}/* request_time() sends a time request to the clock with given peer. *//* This automatically reports a fault if necessary. *//* No data should be sent after this until arc_poll() returns. */static void request_time P((int, struct peer *));static voidrequest_time( int unit, struct peer *peer ){ struct refclockproc *pp = peer->procptr; register struct arcunit *up = (struct arcunit *)pp->unitptr;#ifdef DEBUG if(debug) { printf("arc: unit %d: requesting time.\n", unit); }#endif if (!send_slow(up, pp->io.fd, "o\r")) {#ifdef DEBUG if (debug) { printf("arc: unit %d: problem sending", unit); }#endif pp->lencode = 0; refclock_report(peer, CEVNT_FAULT); return; } pp->polls++;}/* * arc_poll - called by the transmit procedure */static voidarc_poll( int unit, struct peer *peer ){ register struct arcunit *up; struct refclockproc *pp; int resync_needed; /* Should we start a resync? */ pp = peer->procptr; up = (struct arcunit *)pp->unitptr;#if 0 pp->lencode = 0; memset(pp->a_lastcode, 0, sizeof(pp->a_lastcode));#endif#if 0 /* Flush input. */ tcflush(pp->io.fd, TCIFLUSH);#endif /* Resync if our next scheduled resync time is here or has passed. */ resync_needed = ( !(pp->sloppyclockflag & CLK_FLAG2) && (up->next_resync <= current_time) );#ifdef ARCRON_LEAPSECOND_KEEN /* Try to catch a potential leap-second insertion or deletion quickly. In addition to the normal NTP fun of clocks that don't report leap-seconds spooking their hosts, this clock does not even sample the radio sugnal the whole time, so may miss a leap-second insertion or deletion for up to a whole sample time. To try to minimise this effect, if in the first few minutes of the day immediately following a leap-second-insertion point (ie in the first hour of the first day of the first and sixth months), and if the last resync was in the previous day, and a resync is not already in progress, resync the clock immediately. */ if((possible_leap > 0) && /* Must be 00:XX 01/0{1,7}/XXXX. */ (!up->resyncing)) { /* No resync in progress yet. */ resync_needed = 1; possible_leap = -1; /* Prevent multiple resyncs. */ msyslog(LOG_NOTICE,"ARCRON: unit %d: checking for leap second",unit); }#endif /* Do a resync if required... */ if(resync_needed) { /* First, reset quality value to `unknown' so we can detect */ /* when a quality message has been responded to by this */ /* being set to some other value. */ up->quality = QUALITY_UNKNOWN; /* Note that we are resyncing... */ up->resyncing = 1; /* Now actually send the resync command and an immediate poll. */#ifdef DEBUG if(debug) { printf("arc: sending resync command (h\\r).\n"); }#endif msyslog(LOG_NOTICE, "ARCRON: unit %d: sending resync command", unit); send_slow(up, pp->io.fd, "h\r"); /* Schedule our next resync... */ up->next_resync = current_time + DEFAULT_RESYNC_TIME; /* Drop through to request time if appropriate. */ } /* If clock quality is too poor to trust, indicate a fault. */ /* If quality is QUALITY_UNKNOWN and ARCRON_KEEN is defined,*/ /* we'll cross our fingers and just hope that the thing */ /* synced so quickly we did not catch it---we'll */ /* double-check the clock is OK elsewhere. */ if(#ifdef ARCRON_KEEN (up->quality != QUALITY_UNKNOWN) &&#else (up->quality == QUALITY_UNKNOWN) ||#endif (up->quality < MIN_CLOCK_QUALITY_OK)) {#ifdef DEBUG if(debug) { printf("arc: clock quality %d too poor.\n", up->quality); }#endif pp->lencode = 0; refclock_report(peer, CEVNT_FAULT); return; } /* This is the normal case: request a timestamp. */ request_time(unit, peer);}#elseint refclock_arc_bs;#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -