/* * record_crypto_stats - write crypto statistics to file * * file format: * day (mjd) * time (s past midnight) * peer ip address * text message */ void record_crypto_stats( sockaddr_u *addr, const char *text /* text message */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&cryptostats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (cryptostats.fp != NULL) { if (addr == NULL) fprintf(cryptostats.fp, "%lu %s 0.0.0.0 %s\n", day, ulfptoa(&now, 3), text); else fprintf(cryptostats.fp, "%lu %s %s %s\n", day, ulfptoa(&now, 3), stoa(addr), text); fflush(cryptostats.fp); } }
/* * record_raw_stats - write raw timestamps to file * * file format * day (MJD) * time (s past midnight) * peer ip address * IP address * t1 t2 t3 t4 timestamps */ void record_raw_stats( sockaddr_u *srcadr, sockaddr_u *dstadr, l_fp *t1, /* originate timestamp */ l_fp *t2, /* receive timestamp */ l_fp *t3, /* transmit timestamp */ l_fp *t4 /* destination timestamp */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&rawstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (rawstats.fp != NULL) { fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s\n", day, ulfptoa(&now, 3), stoa(srcadr), dstadr ? stoa(dstadr) : "-", ulfptoa(t1, 9), ulfptoa(t2, 9), ulfptoa(t3, 9), ulfptoa(t4, 9)); fflush(rawstats.fp); } }
/* * record_sys_stats - write system statistics to file * * file format * day (MJD) * time (s past midnight) * time since reset * packets recieved * packets for this host * current version * old version * access denied * bad length or format * bad authentication * declined * rate exceeded * KoD sent */ void record_sys_stats(void) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&sysstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (sysstats.fp != NULL) { fprintf(sysstats.fp, "%lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", day, ulfptoa(&now, 3), current_time - sys_stattime, sys_received, sys_processed, sys_newversion, sys_oldversion, sys_restricted, sys_badlength, sys_badauth, sys_declined, sys_limitrejected, sys_kodsent); fflush(sysstats.fp); proto_clr_stats(); } }
/* * record_loop_stats - write loop filter statistics to file * * file format: * day (MJD) * time (s past midnight) * offset * frequency (PPM) * jitter * wnder (PPM) * time constant (log2) */ void record_loop_stats( double offset, /* offset */ double freq, /* frequency (PPM) */ double jitter, /* jitter */ double wander, /* wander (PPM) */ int spoll ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&loopstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (loopstats.fp != NULL) { fprintf(loopstats.fp, "%lu %s %.9f %.3f %.9f %.6f %d\n", day, ulfptoa(&now, 3), offset, freq * 1e6, jitter, wander * 1e6, spoll); fflush(loopstats.fp); } }
/* * record_peer_stats - write peer statistics to file * * file format: * day (MJD) * time (s past UTC midnight) * IP address * status word (hex) * offset * delay * dispersion * jitter */ void record_peer_stats( sockaddr_u *addr, int status, double offset, /* offset */ double delay, /* delay */ double dispersion, /* dispersion */ double jitter /* jitter */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&peerstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (peerstats.fp != NULL) { fprintf(peerstats.fp, "%lu %s %s %x %.9f %.9f %.9f %.9f\n", day, ulfptoa(&now, 3), stoa(addr), status, offset, delay, dispersion, jitter); fflush(peerstats.fp); } }
static void gpsd_parse( peerT * const peer , const l_fp * const rtime) { clockprocT * const pp = peer->procptr; gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr; json_ctx jctx; const char * clsid; l_fp tmpfp; DPRINTF(2, ("GPSD_JSON(%d): gpsd_parse: time %s '%s'\n", up->unit, ulfptoa(rtime, 6), up->buffer)); /* See if we can grab anything potentially useful */ if (!json_parse_record(&jctx, up->buffer)) return; /* Now dispatch over the objects we know */ clsid = json_object_lookup_string_default( &jctx, 0, "class", "-bad-repy-"); up->tc_recv += 1; if (!strcmp("VERSION", clsid)) process_version(peer, &jctx, rtime); else if (!strcmp("TPV", clsid)) process_tpv(peer, &jctx, rtime); else if (!strcmp("PPS", clsid)) process_pps(peer, &jctx, rtime); else if (!strcmp("WATCH", clsid)) process_watch(peer, &jctx, rtime); else return; /* nothing we know about... */ /* now aggregate TPV and PPS -- no PPS? just use TPV...*/ if (up->fl_tpv) { /* TODO: also check remote receive time stamps */ tmpfp = up->tpv_local; L_SUB(&tmpfp, &up->pps_local); if (up->fl_pps && 0 == tmpfp.l_ui) { refclock_process_offset( pp, up->tpv_stamp, up->pps_recvt, 0.0); if (up->ppscount < PPS_MAXCOUNT) up->ppscount += 1; } else { refclock_process_offset( pp, up->tpv_stamp, up->tpv_recvt, 0.0); if (up->ppscount > 0) up->ppscount -= 1; } up->fl_pps = 0; up->fl_tpv = 0; up->tc_good += 1; } }
/* * record_raw_stats - write raw timestamps to file * * file format * day (MJD) * time (s past midnight) * peer ip address * IP address * t1 t2 t3 t4 timestamps */ void record_raw_stats( sockaddr_u *srcadr, sockaddr_u *dstadr, l_fp *t1, /* originate timestamp */ l_fp *t2, /* receive timestamp */ l_fp *t3, /* transmit timestamp */ l_fp *t4, /* destination timestamp */ int leap, int version, int mode, int stratum, int ppoll, int precision, double root_delay, /* seconds */ double root_dispersion,/* seconds */ u_int32 refid ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&rawstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (rawstats.fp != NULL) { fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s %d %d %d %d %d %d %.6f %.6f %s\n", day, ulfptoa(&now, 3), stoa(srcadr), dstadr ? stoa(dstadr) : "-", ulfptoa(t1, 9), ulfptoa(t2, 9), ulfptoa(t3, 9), ulfptoa(t4, 9), leap, version, mode, stratum, ppoll, precision, root_delay, root_dispersion, refid_str(refid, stratum)); fflush(rawstats.fp); } }
/* * refclock_gtlin - groom next input line and extract timestamp * * This routine processes the timecode received from the clock and * strips the parity bit and control characters. It returns the number * of characters in the line followed by a NULL character ('\0'), which * is not included in the count. In case of an empty line, the previous * line is preserved. */ int refclock_gtlin( struct recvbuf *rbufp, /* receive buffer pointer */ char *lineptr, /* current line pointer */ int bmax, /* remaining characters in line */ l_fp *tsptr /* pointer to timestamp returned */ ) { const char *sp, *spend; char *dp, *dpend; int dlen; if (bmax <= 0) return (0); dp = lineptr; dpend = dp + bmax - 1; /* leave room for NUL pad */ sp = (const char *)rbufp->recv_buffer; spend = sp + rbufp->recv_length; while (sp != spend && dp != dpend) { char c; c = *sp++ & 0x7f; if (c >= 0x20 && c < 0x7f) *dp++ = c; } /* Get length of data written to the destination buffer. If * zero, do *not* place a NUL byte to preserve the previous * buffer content. */ dlen = dp - lineptr; if (dlen) *dp = '\0'; *tsptr = rbufp->recv_time; DPRINTF(2, ("refclock_gtlin: fd %d time %s timecode %d %s\n", rbufp->fd, ulfptoa(&rbufp->recv_time, 6), dlen, (dlen != 0) ? lineptr : "")); return (dlen); }
/* * record_proto_stats - write system statistics to file * * file format * day (MJD) * time (s past midnight) * text message */ void record_proto_stats( char *str /* text string */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&protostats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (protostats.fp != NULL) { fprintf(protostats.fp, "%lu %s %s\n", day, ulfptoa(&now, 3), str); fflush(protostats.fp); } }
/* * record_clock_stats - write clock statistics to file * * file format: * day (MJD) * time (s past midnight) * IP address * text message */ void record_clock_stats( sockaddr_u *addr, const char *text /* timecode string */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&clockstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (clockstats.fp != NULL) { fprintf(clockstats.fp, "%lu %s %s %s\n", day, ulfptoa(&now, 3), stoa(addr), text); fflush(clockstats.fp); } }
/* * refclock_gtraw - get next line/chunk of data * * This routine returns the raw data received from the clock in both * canonical or raw modes. The terminal interface routines map CR to LF. * In canonical mode this results in two lines, one containing data * followed by LF and another containing only LF. In raw mode the * interface routines can deliver arbitraty chunks of data from one * character to a maximum specified by the calling routine. In either * mode the routine returns the number of characters in the line * followed by a NULL character ('\0'), which is not included in the * count. * * *tsptr receives a copy of the buffer timestamp. */ int refclock_gtraw( struct recvbuf *rbufp, /* receive buffer pointer */ char *lineptr, /* current line pointer */ int bmax, /* remaining characters in line */ l_fp *tsptr /* pointer to timestamp returned */ ) { if (bmax <= 0) return (0); bmax -= 1; /* leave room for trailing NUL */ if (bmax > rbufp->recv_length) bmax = rbufp->recv_length; memcpy(lineptr, rbufp->recv_buffer, bmax); lineptr[bmax] = '\0'; *tsptr = rbufp->recv_time; DPRINTF(2, ("refclock_gtraw: fd %d time %s timecode %d %s\n", rbufp->fd, ulfptoa(&rbufp->recv_time, 6), bmax, lineptr)); return (bmax); }
char * uglydate( l_fp *ts ) { char *bp; char *timep; struct tm *tm; time_t sec; long msec; int year; timep = ulfptoa(ts, 6); /* returns max 17 characters */ LIB_GETBUF(bp); sec = ts->l_ui - JAN_1970; msec = ts->l_uf / 4294967; /* fract / (2**32/1000) */ tm = gmtime(&sec); if (ts->l_ui == 0) { /* * Probably not a real good thing to do. Oh, well. */ year = 0; tm->tm_yday = 0; tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; } else { year = tm->tm_year; while (year >= 100) year -= 100; } snprintf(bp, LIB_BUFLENGTH, "%17s %02d:%03d:%02d:%02d:%02d.%03ld", timep, year, tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec, msec); return bp; }
/* * tt560_poll - called by the transmit procedure */ static void tt560_poll( int unit, struct peer *peer ) { register struct tt560unit *up; struct refclockproc *pp; time_freeze_reg_t *tp; tt_mem_space_t *mp; int i; unsigned int *p_time_t, *tt_mem_t; /* * This is the main routine. It snatches the time from the TT560 * board and tacks on a local timestamp. */ pp = peer->procptr; up = (struct tt560unit *)pp->unitptr; mp = up->tt_mem; tp = &up->tt560rawt; p_time_t = (unsigned int *)tp; tt_mem_t = (unsigned int *)&mp->time_freeze_reg; *tt_mem_t = 0; /* update the time freeze register */ /* and copy time stamp to memory */ for (i=0; i < TIME_FREEZE_REG_LEN; i++) { *p_time_t = byte_swap(*tt_mem_t); p_time_t++; tt_mem_t++; } get_systime(&pp->lastrec); pp->polls++; /* * We get down to business, check the timecode format and decode * its contents. If the timecode has invalid length or is not in * proper format, we declare bad format and exit. Note: we * can't use the sec/usec conversion produced by the driver, * since the year may be suspect. All format error checking is * done by the sprintf() and sscanf() routines. */ sprintf(pp->a_lastcode, "%1x%1x%1x %1x%1x:%1x%1x:%1x%1x.%1x%1x%1x%1x%1x%1x %1x", tp->hun_day, tp->tens_day, tp->unit_day, tp->tens_hour, tp->unit_hour, tp->tens_min, tp->unit_min, tp->tens_sec, tp->unit_sec, tp->hun_ms, tp->tens_ms, tp->unit_ms, tp->hun_us, tp->tens_us, tp->unit_us, tp->status); pp->lencode = strlen(pp->a_lastcode); #ifdef DEBUG if (debug) printf("tt560: time %s timecode %d %s\n", ulfptoa(&pp->lastrec, 6), pp->lencode, pp->a_lastcode); #endif if (sscanf(pp->a_lastcode, "%3d %2d:%2d:%2d.%6ld", &pp->day, &pp->hour, &pp->minute, &pp->second, &pp->usec) != 5) { refclock_report(peer, CEVNT_BADTIME); return; } if ((tp->status & 0x6) != 0x6) pp->leap = LEAP_NOTINSYNC; else pp->leap = LEAP_NOWARNING; if (!refclock_process(pp)) { refclock_report(peer, CEVNT_BADTIME); return; } if (peer->burst > 0) return; if (pp->coderecv == pp->codeproc) { refclock_report(peer, CEVNT_TIMEOUT); return; } record_clock_stats(&peer->srcadr, pp->a_lastcode); refclock_receive(peer); peer->burst = NSTAGE; }
void test_UnsignedInteger(void) { l_fp test = {{3000000000UL}, 0}; TEST_ASSERT_EQUAL_STRING("3000000000.0", ulfptoa(&test, 1)); }
/* * refclock_gtlin - groom next input line and extract timestamp * * This routine processes the timecode received from the clock and * removes the parity bit and control characters. If a timestamp is * present in the timecode, as produced by the tty_clk STREAMS module, * it returns that as the timestamp; otherwise, it returns the buffer * timestamp. The routine return code is the number of characters in * the line. */ int refclock_gtlin( struct recvbuf *rbufp, /* receive buffer pointer */ char *lineptr, /* current line pointer */ int bmax, /* remaining characters in line */ l_fp *tsptr /* pointer to timestamp returned */ ) { char *dpt, *dpend, *dp; int i; l_fp trtmp, tstmp; char c; /* * Check for the presence of a timestamp left by the tty_clock * module and, if present, use that instead of the buffer * timestamp captured by the I/O routines. We recognize a * timestamp by noting its value is earlier than the buffer * timestamp, but not more than one second earlier. */ dpt = (char *)&rbufp->recv_space; dpend = dpt + rbufp->recv_length; trtmp = rbufp->recv_time; if (dpend >= dpt + 8) { if (buftvtots(dpend - 8, &tstmp)) { L_SUB(&trtmp, &tstmp); if (trtmp.l_ui == 0) { #ifdef DEBUG if (debug > 1) { printf( "refclock_gtlin: fd %d ldisc %s", rbufp->fd, lfptoa(&trtmp, 6)); get_systime(&trtmp); L_SUB(&trtmp, &tstmp); printf(" sigio %s\n", lfptoa(&trtmp, 6)); } #endif dpend -= 8; trtmp = tstmp; } else trtmp = rbufp->recv_time; } } /* * Edit timecode to remove control chars. Don't monkey with the * line buffer if the input buffer contains no ASCII printing * characters. */ if (dpend - dpt > bmax - 1) dpend = dpt + bmax - 1; for (dp = lineptr; dpt < dpend; dpt++) { c = *dpt & 0x7f; if (c >= ' ') *dp++ = c; } i = dp - lineptr; if (i > 0) *dp = '\0'; #ifdef DEBUG if (debug > 1 && i > 0) printf("refclock_gtlin: fd %d time %s timecode %d %s\n", rbufp->fd, ulfptoa(&trtmp, 6), i, lineptr); #endif *tsptr = trtmp; return (i); }
/* * refclock_gtraw - get next line/chunk of data * * This routine returns the raw data received from the clock in both * canonical or raw modes. The terminal interface routines map CR to LF. * In canonical mode this results in two lines, one containing data * followed by LF and another containing only LF. In raw mode the * interface routines can deliver arbitraty chunks of data from one * character to a maximum specified by the calling routine. In either * mode the routine returns the number of characters in the line * followed by a NULL character ('\0'), which is not included in the * count. * * If a timestamp is present in the timecode, as produced by the tty_clk * STREAMS module, it returns that as the timestamp; otherwise, it * returns the buffer timestamp. */ int refclock_gtraw( struct recvbuf *rbufp, /* receive buffer pointer */ char *lineptr, /* current line pointer */ int bmax, /* remaining characters in line */ l_fp *tsptr /* pointer to timestamp returned */ ) { char *dpt, *dpend, *dp; l_fp trtmp, tstmp; int i; /* * Check for the presence of a timestamp left by the tty_clock * module and, if present, use that instead of the buffer * timestamp captured by the I/O routines. We recognize a * timestamp by noting its value is earlier than the buffer * timestamp, but not more than one second earlier. */ dpt = (char *)rbufp->recv_buffer; dpend = dpt + rbufp->recv_length; trtmp = rbufp->recv_time; if (dpend >= dpt + 8) { if (buftvtots(dpend - 8, &tstmp)) { L_SUB(&trtmp, &tstmp); if (trtmp.l_ui == 0) { #ifdef DEBUG if (debug > 1) { printf( "refclock_gtlin: fd %d ldisc %s", rbufp->fd, lfptoa(&trtmp, 6)); get_systime(&trtmp); L_SUB(&trtmp, &tstmp); printf(" sigio %s\n", lfptoa(&trtmp, 6)); } #endif dpend -= 8; trtmp = tstmp; } else trtmp = rbufp->recv_time; } } /* * Copy the raw buffer to the user string. The string is padded * with a NULL, which is not included in the character count. */ if (dpend - dpt > bmax - 1) dpend = dpt + bmax - 1; for (dp = lineptr; dpt < dpend; dpt++) *dp++ = *dpt; *dp = '\0'; i = dp - lineptr; #ifdef DEBUG if (debug > 1) printf("refclock_gtraw: fd %d time %s timecode %d %s\n", rbufp->fd, ulfptoa(&trtmp, 6), i, lineptr); #endif *tsptr = trtmp; return (i); }
/* * tpro_poll - called by the transmit procedure */ static void tpro_poll( int unit, struct peer *peer ) { register struct tprounit *up; struct refclockproc *pp; struct tproval *tp; /* * This is the main routine. It snatches the time from the TPRO * board and tacks on a local timestamp. */ pp = peer->procptr; up = pp->unitptr; tp = &up->tprodata; if (read(pp->io.fd, (char *)tp, sizeof(struct tproval)) < 0) { refclock_report(peer, CEVNT_FAULT); return; } get_systime(&pp->lastrec); pp->polls++; /* * We get down to business, check the timecode format and decode * its contents. If the timecode has invalid length or is not in * proper format, we declare bad format and exit. Note: we * can't use the sec/usec conversion produced by the driver, * since the year may be suspect. All format error checking is * done by the snprintf() and sscanf() routines. * * Note that the refclockproc usec member has now become nsec. * We could either multiply the read-in usec value by 1000 or * we could pad the written string appropriately and read the * resulting value in already scaled. */ snprintf(pp->a_lastcode, sizeof(pp->a_lastcode), "%1x%1x%1x %1x%1x:%1x%1x:%1x%1x.%1x%1x%1x%1x%1x%1x %1x", tp->day100, tp->day10, tp->day1, tp->hour10, tp->hour1, tp->min10, tp->min1, tp->sec10, tp->sec1, tp->ms100, tp->ms10, tp->ms1, tp->usec100, tp->usec10, tp->usec1, tp->status); pp->lencode = strlen(pp->a_lastcode); #ifdef DEBUG if (debug) printf("tpro: time %s timecode %d %s\n", ulfptoa(&pp->lastrec, 6), pp->lencode, pp->a_lastcode); #endif if (sscanf(pp->a_lastcode, "%3d %2d:%2d:%2d.%6ld", &pp->day, &pp->hour, &pp->minute, &pp->second, &pp->nsec) != 5) { refclock_report(peer, CEVNT_BADTIME); return; } pp->nsec *= 1000; /* Convert usec to nsec */ if (!tp->status & 0x3) pp->leap = LEAP_NOTINSYNC; else pp->leap = LEAP_NOWARNING; if (!refclock_process(pp)) { refclock_report(peer, CEVNT_BADTIME); return; } if (pp->coderecv == pp->codeproc) { refclock_report(peer, CEVNT_TIMEOUT); return; } pp->lastref = pp->lastrec; record_clock_stats(&peer->srcadr, pp->a_lastcode); refclock_receive(peer); }