summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/refclock_neoclock4x.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
committerroberto <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
commit4ded1c1fa0bc21c61f91a2dbe864835986745121 (patch)
tree16d100fbc9dae63888d48b464e471ba0e5065193 /contrib/ntp/ntpd/refclock_neoclock4x.c
parent8b5a86d4fda08a9c68231415812edcb26be52f79 (diff)
downloadFreeBSD-src-4ded1c1fa0bc21c61f91a2dbe864835986745121.zip
FreeBSD-src-4ded1c1fa0bc21c61f91a2dbe864835986745121.tar.gz
Flatten the dist and various 4.n.n trees in preparation of future ntp imports.
Diffstat (limited to 'contrib/ntp/ntpd/refclock_neoclock4x.c')
-rw-r--r--contrib/ntp/ntpd/refclock_neoclock4x.c1068
1 files changed, 0 insertions, 1068 deletions
diff --git a/contrib/ntp/ntpd/refclock_neoclock4x.c b/contrib/ntp/ntpd/refclock_neoclock4x.c
deleted file mode 100644
index 082b1cf..0000000
--- a/contrib/ntp/ntpd/refclock_neoclock4x.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- *
- * Refclock_neoclock4x.c
- * - NeoClock4X driver for DCF77 or FIA Timecode
- *
- * Date: 2003-07-07 v1.13
- *
- * see http://www.linum.com/redir/jump/id=neoclock4x&action=redir
- * for details about the NeoClock4X device
- *
- * Copyright (C) 2002-2003 by Linum Software GmbH <neoclock4x@linum.com>
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#if defined(REFCLOCK) && (defined(CLOCK_NEOCLOCK4X))
-
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <ctype.h>
-
-#include "ntpd.h"
-#include "ntp_io.h"
-#include "ntp_control.h"
-#include "ntp_refclock.h"
-#include "ntp_unixtime.h"
-#include "ntp_stdlib.h"
-
-#if defined HAVE_SYS_MODEM_H
-# include <sys/modem.h>
-# define TIOCMSET MCSETA
-# define TIOCMGET MCGETA
-# define TIOCM_RTS MRTS
-#endif
-
-#ifdef HAVE_TERMIOS_H
-# ifdef TERMIOS_NEEDS__SVID3
-# define _SVID3
-# endif
-# include <termios.h>
-# ifdef TERMIOS_NEEDS__SVID3
-# undef _SVID3
-# endif
-#endif
-
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-
-/*
- * If you want the driver for whatever reason to not use
- * the TX line to send anything to your NeoClock4X
- * device you must tell the NTP refclock driver which
- * firmware you NeoClock4X device uses.
- *
- * If you want to enable this feature change the "#if 0"
- * line to "#if 1" and make sure that the defined firmware
- * matches the firmware off your NeoClock4X receiver!
- *
- */
-
-#if 0
-#define NEOCLOCK4X_FIRMWARE NEOCLOCK4X_FIRMWARE_VERSION_A
-#endif
-
-#define NEOCLOCK4X_FIRMWARE_VERSION_A 'A'
-
-#define NEOCLOCK4X_TIMECODELEN 37
-
-#define NEOCLOCK4X_OFFSET_SERIAL 3
-#define NEOCLOCK4X_OFFSET_RADIOSIGNAL 9
-#define NEOCLOCK4X_OFFSET_DAY 12
-#define NEOCLOCK4X_OFFSET_MONTH 14
-#define NEOCLOCK4X_OFFSET_YEAR 16
-#define NEOCLOCK4X_OFFSET_HOUR 18
-#define NEOCLOCK4X_OFFSET_MINUTE 20
-#define NEOCLOCK4X_OFFSET_SECOND 22
-#define NEOCLOCK4X_OFFSET_HSEC 24
-#define NEOCLOCK4X_OFFSET_DOW 26
-#define NEOCLOCK4X_OFFSET_TIMESOURCE 28
-#define NEOCLOCK4X_OFFSET_DSTSTATUS 29
-#define NEOCLOCK4X_OFFSET_QUARZSTATUS 30
-#define NEOCLOCK4X_OFFSET_ANTENNA1 31
-#define NEOCLOCK4X_OFFSET_ANTENNA2 33
-#define NEOCLOCK4X_OFFSET_CRC 35
-
-#define NEOCLOCK4X_DRIVER_VERSION "1.12 (2003-01-10)"
-
-struct neoclock4x_unit {
- l_fp laststamp; /* last receive timestamp */
- short unit; /* NTP refclock unit number */
- u_long polled; /* flag to detect noreplies */
- char leap_status; /* leap second flag */
- int recvnow;
-
- char firmware[80];
- char firmwaretag;
- char serial[7];
- char radiosignal[4];
- char timesource;
- char dststatus;
- char quarzstatus;
- int antenna1;
- int antenna2;
- int utc_year;
- int utc_month;
- int utc_day;
- int utc_hour;
- int utc_minute;
- int utc_second;
- int utc_msec;
-};
-
-static int neoclock4x_start P((int, struct peer *));
-static void neoclock4x_shutdown P((int, struct peer *));
-static void neoclock4x_receive P((struct recvbuf *));
-static void neoclock4x_poll P((int, struct peer *));
-static void neoclock4x_control P((int, struct refclockstat *, struct refclockstat *, struct peer *));
-
-static int neol_atoi_len P((const char str[], int *, int));
-static int neol_hexatoi_len P((const char str[], int *, int));
-static void neol_jdn_to_ymd P((unsigned long, int *, int *, int *));
-static void neol_localtime P((unsigned long, int* , int*, int*, int*, int*, int*));
-static unsigned long neol_mktime P((int, int, int, int, int, int));
-#if 0
-static void neol_mdelay P((int));
-#endif
-#if !defined(NEOCLOCK4X_FIRMWARE)
-static int neol_query_firmware P((int, int, char *, int));
-static int neol_check_firmware P((int, const char*, char *));
-#endif
-
-struct refclock refclock_neoclock4x = {
- neoclock4x_start, /* start up driver */
- neoclock4x_shutdown, /* shut down driver */
- neoclock4x_poll, /* transmit poll message */
- neoclock4x_control,
- noentry, /* initialize driver (not used) */
- noentry, /* not used */
- NOFLAGS /* not used */
-};
-
-static int
-neoclock4x_start(int unit,
- struct peer *peer)
-{
- struct neoclock4x_unit *up;
- struct refclockproc *pp;
- int fd;
- char dev[20];
- int sl232;
-#if defined(HAVE_TERMIOS)
- struct termios termsettings;
-#endif
-#if !defined(NEOCLOCK4X_FIRMWARE)
- int tries;
-#endif
-
- (void) snprintf(dev, sizeof(dev)-1, "/dev/neoclock4x-%d", unit);
-
- /* LDISC_STD, LDISC_RAW
- * Open serial port. Use CLK line discipline, if available.
- */
- fd = refclock_open(dev, B2400, LDISC_CLK);
- if(fd <= 0)
- {
- return (0);
- }
-
-#if defined(HAVE_TERMIOS)
- if(tcgetattr(fd, &termsettings) < 0)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): (tcgetattr) can't query serial port settings: %m", unit);
- (void) close(fd);
- return (0);
- }
-
- /* 2400 Baud 8N2 */
- termsettings.c_cflag &= ~PARENB;
- termsettings.c_cflag |= CSTOPB;
- termsettings.c_cflag &= ~CSIZE;
- termsettings.c_cflag |= CS8;
-
- if(tcsetattr(fd, TCSANOW, &termsettings) < 0)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): (tcsetattr) can't set serial port 2400 8N2: %m", unit);
- (void) close(fd);
- return (0);
- }
-#elif defined(HAVE_SYSV_TTYS)
- if(ioctl(fd, TCGETA, &termsettings) < 0)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): (TCGETA) can't query serial port settings: %m", unit);
- (void) close(fd);
- return (0);
- }
-
- /* 2400 Baud 8N2 */
- termsettings.c_cflag &= ~PARENB;
- termsettings.c_cflag |= CSTOPB;
- termsettings.c_cflag &= ~CSIZE;
- termsettings.c_cflag |= CS8;
-
- if(ioctl(fd, TCSETA, &termsettings) < 0)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): (TSGETA) can't set serial port 2400 8N2: %m", unit);
- (void) close(fd);
- return (0);
- }
-#else
- msyslog(LOG_EMERG, "NeoClock4X(%d): don't know how to set port to 2400 8N2 with this OS!", unit);
- (void) close(fd);
- return (0);
-#endif
-
-#if defined(TIOCMSET) && (defined(TIOCM_RTS) || defined(CIOCM_RTS))
- /* turn on RTS, and DTR for power supply */
- /* NeoClock4x is powered from serial line */
- if(ioctl(fd, TIOCMGET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): can't query RTS/DTR state: %m", unit);
- (void) close(fd);
- return (0);
- }
-#ifdef TIOCM_RTS
- sl232 = sl232 | TIOCM_DTR | TIOCM_RTS; /* turn on RTS, and DTR for power supply */
-#else
- sl232 = sl232 | CIOCM_DTR | CIOCM_RTS; /* turn on RTS, and DTR for power supply */
-#endif
- if(ioctl(fd, TIOCMSET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): can't set RTS/DTR to power neoclock4x: %m", unit);
- (void) close(fd);
- return (0);
- }
-#else
- msyslog(LOG_EMERG, "NeoClock4X(%d): don't know how to set DTR/RTS to power NeoClock4X with this OS!",
- unit);
- (void) close(fd);
- return (0);
-#endif
-
- up = (struct neoclock4x_unit *) emalloc(sizeof(struct neoclock4x_unit));
- if(!(up))
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): can't allocate memory for: %m",unit);
- (void) close(fd);
- return (0);
- }
-
- memset((char *)up, 0, sizeof(struct neoclock4x_unit));
- pp = peer->procptr;
- pp->clockdesc = "NeoClock4X";
- pp->unitptr = (caddr_t)up;
- pp->io.clock_recv = neoclock4x_receive;
- pp->io.srcclock = (caddr_t)peer;
- pp->io.datalen = 0;
- pp->io.fd = fd;
- /*
- * no fudge time is given by user!
- * use 169.583333 ms to compensate the serial line delay
- * formula is:
- * 2400 Baud / 11 bit = 218.18 charaters per second
- * (NeoClock4X timecode len)
- */
- pp->fudgetime1 = (NEOCLOCK4X_TIMECODELEN * 11) / 2400.0;
-
- /*
- * Initialize miscellaneous variables
- */
- peer->precision = -10;
- peer->burst = NSTAGE;
- memcpy((char *)&pp->refid, "neol", 4);
-
- up->leap_status = 0;
- up->unit = unit;
- strcpy(up->firmware, "?");
- up->firmwaretag = '?';
- strcpy(up->serial, "?");
- strcpy(up->radiosignal, "?");
- up->timesource = '?';
- up->dststatus = '?';
- up->quarzstatus = '?';
- up->antenna1 = -1;
- up->antenna2 = -1;
- up->utc_year = 0;
- up->utc_month = 0;
- up->utc_day = 0;
- up->utc_hour = 0;
- up->utc_minute = 0;
- up->utc_second = 0;
- up->utc_msec = 0;
-
-#if defined(NEOCLOCK4X_FIRMWARE)
-#if NEOCLOCK4X_FIRMWARE == NEOCLOCK4X_FIRMWARE_VERSION_A
- strcpy(up->firmware, "(c) 2002 NEOL S.A. FRANCE / L0.01 NDF:A:* (compile time)");
- up->firmwaretag = 'A';
-#else
- msyslog(LOG_EMERG, "NeoClock4X(%d): Unkown firmware defined at compile time for NeoClock4X",
- unit);
- (void) close(fd);
- pp->io.fd = -1;
- free(pp->unitptr);
- pp->unitptr = NULL;
- return (0);
-#endif
-#else
- for(tries=0; tries < 5; tries++)
- {
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_INFO, "NeoClock4X(%d): checking NeoClock4X firmware version (%d/5)", unit, tries);
- /* wait 3 seconds for receiver to power up */
- sleep(3);
- if(neol_query_firmware(pp->io.fd, up->unit, up->firmware, sizeof(up->firmware)))
- {
- break;
- }
- }
-
- /* can I handle this firmware version? */
- if(!neol_check_firmware(up->unit, up->firmware, &up->firmwaretag))
- {
- (void) close(fd);
- pp->io.fd = -1;
- free(pp->unitptr);
- pp->unitptr = NULL;
- return (0);
- }
-#endif
-
- if(!io_addclock(&pp->io))
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): error add peer to ntpd: %m", unit);
- (void) close(fd);
- pp->io.fd = -1;
- free(pp->unitptr);
- pp->unitptr = NULL;
- return (0);
- }
-
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_INFO, "NeoClock4X(%d): receiver setup successful done", unit);
-
- return (1);
-}
-
-static void
-neoclock4x_shutdown(int unit,
- struct peer *peer)
-{
- struct neoclock4x_unit *up;
- struct refclockproc *pp;
- int sl232;
-
- if(NULL != peer)
- {
- pp = peer->procptr;
- if(pp != NULL)
- {
- up = (struct neoclock4x_unit *)pp->unitptr;
- if(up != NULL)
- {
- if(-1 != pp->io.fd)
- {
-#if defined(TIOCMSET) && (defined(TIOCM_RTS) || defined(CIOCM_RTS))
- /* turn on RTS, and DTR for power supply */
- /* NeoClock4x is powered from serial line */
- if(ioctl(pp->io.fd, TIOCMGET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): can't query RTS/DTR state: %m",
- unit);
- }
-#ifdef TIOCM_RTS
- /* turn on RTS, and DTR for power supply */
- sl232 &= ~(TIOCM_DTR | TIOCM_RTS);
-#else
- /* turn on RTS, and DTR for power supply */
- sl232 &= ~(CIOCM_DTR | CIOCM_RTS);
-#endif
- if(ioctl(pp->io.fd, TIOCMSET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): can't set RTS/DTR to power neoclock4x: %m",
- unit);
- }
-#endif
- io_closeclock(&pp->io);
- }
- free(up);
- pp->unitptr = NULL;
- }
- }
- }
-
- msyslog(LOG_ERR, "NeoClock4X(%d): shutdown", unit);
-
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_INFO, "NeoClock4X(%d): receiver shutdown done", unit);
-}
-
-static void
-neoclock4x_receive(struct recvbuf *rbufp)
-{
- struct neoclock4x_unit *up;
- struct refclockproc *pp;
- struct peer *peer;
- unsigned long calc_utc;
- int day;
- int month; /* ddd conversion */
- int c;
- int dsec;
- unsigned char calc_chksum;
- int recv_chksum;
-
- peer = (struct peer *)rbufp->recv_srcclock;
- pp = peer->procptr;
- up = (struct neoclock4x_unit *)pp->unitptr;
-
- /* wait till poll interval is reached */
- if(0 == up->recvnow)
- return;
-
- /* reset poll interval flag */
- up->recvnow = 0;
-
- /* read last received timecode */
- pp->lencode = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &pp->lastrec);
- pp->leap = LEAP_NOWARNING;
-
- if(NEOCLOCK4X_TIMECODELEN != pp->lencode)
- {
- NLOG(NLOG_CLOCKEVENT)
- msyslog(LOG_WARNING, "NeoClock4X(%d): received data has invalid length, expected %d bytes, received %d bytes: %s",
- up->unit, NEOCLOCK4X_TIMECODELEN, pp->lencode, pp->a_lastcode);
- refclock_report(peer, CEVNT_BADREPLY);
- return;
- }
-
- neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_CRC], &recv_chksum, 2);
-
- /* calculate checksum */
- calc_chksum = 0;
- for(c=0; c < NEOCLOCK4X_OFFSET_CRC; c++)
- {
- calc_chksum += pp->a_lastcode[c];
- }
- if(recv_chksum != calc_chksum)
- {
- NLOG(NLOG_CLOCKEVENT)
- msyslog(LOG_WARNING, "NeoClock4X(%d): received data has invalid chksum: %s",
- up->unit, pp->a_lastcode);
- refclock_report(peer, CEVNT_BADREPLY);
- return;
- }
-
- /* Allow synchronization even is quartz clock is
- * never initialized.
- * WARNING: This is dangerous!
- */
- up->quarzstatus = pp->a_lastcode[NEOCLOCK4X_OFFSET_QUARZSTATUS];
- if(0==(pp->sloppyclockflag & CLK_FLAG2))
- {
- if('I' != up->quarzstatus)
- {
- NLOG(NLOG_CLOCKEVENT)
- msyslog(LOG_NOTICE, "NeoClock4X(%d): quartz clock is not initialized: %s",
- up->unit, pp->a_lastcode);
- pp->leap = LEAP_NOTINSYNC;
- refclock_report(peer, CEVNT_BADDATE);
- return;
- }
- }
- if('I' != up->quarzstatus)
- {
- NLOG(NLOG_CLOCKEVENT)
- msyslog(LOG_NOTICE, "NeoClock4X(%d): using uninitialized quartz clock for time synchronization: %s",
- up->unit, pp->a_lastcode);
- }
-
- /*
- * If NeoClock4X is not synchronized to a radio clock
- * check if we're allowed to synchronize with the quartz
- * clock.
- */
- up->timesource = pp->a_lastcode[NEOCLOCK4X_OFFSET_TIMESOURCE];
- if(0==(pp->sloppyclockflag & CLK_FLAG2))
- {
- if('A' != up->timesource)
- {
- /* not allowed to sync with quartz clock */
- if(0==(pp->sloppyclockflag & CLK_FLAG1))
- {
- refclock_report(peer, CEVNT_BADTIME);
- pp->leap = LEAP_NOTINSYNC;
- return;
- }
- }
- }
-
- /* this should only used when first install is done */
- if(pp->sloppyclockflag & CLK_FLAG4)
- {
- msyslog(LOG_DEBUG, "NeoClock4X(%d): received data: %s",
- up->unit, pp->a_lastcode);
- }
-
- /* 123456789012345678901234567890123456789012345 */
- /* S/N123456DCF1004021010001202ASX1213CR\r\n */
-
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_YEAR], &pp->year, 2);
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_MONTH], &month, 2);
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_DAY], &day, 2);
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_HOUR], &pp->hour, 2);
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_MINUTE], &pp->minute, 2);
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_SECOND], &pp->second, 2);
- neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_HSEC], &dsec, 2);
- pp->nsec = dsec * 10000; /* convert 1/100s from neoclock to nanoseconds */
-
- memcpy(up->radiosignal, &pp->a_lastcode[NEOCLOCK4X_OFFSET_RADIOSIGNAL], 3);
- up->radiosignal[3] = 0;
- memcpy(up->serial, &pp->a_lastcode[NEOCLOCK4X_OFFSET_SERIAL], 6);
- up->serial[6] = 0;
- up->dststatus = pp->a_lastcode[NEOCLOCK4X_OFFSET_DSTSTATUS];
- neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_ANTENNA1], &up->antenna1, 2);
- neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_ANTENNA2], &up->antenna2, 2);
-
- /*
- Validate received values at least enough to prevent internal
- array-bounds problems, etc.
- */
- if((pp->hour < 0) || (pp->hour > 23) ||
- (pp->minute < 0) || (pp->minute > 59) ||
- (pp->second < 0) || (pp->second > 60) /*Allow for leap seconds.*/ ||
- (day < 1) || (day > 31) ||
- (month < 1) || (month > 12) ||
- (pp->year < 0) || (pp->year > 99)) {
- /* Data out of range. */
- NLOG(NLOG_CLOCKEVENT)
- msyslog(LOG_WARNING, "NeoClock4X(%d): date/time out of range: %s",
- up->unit, pp->a_lastcode);
- refclock_report(peer, CEVNT_BADDATE);
- return;
- }
-
- /* Year-2000 check not needed anymore. Same problem
- * will arise at 2099 but what should we do...?
- *
- * wrap 2-digit date into 4-digit
- *
- * if(pp->year < YEAR_PIVOT)
- * {
- * pp->year += 100;
- * }
- */
- pp->year += 2000;
-
- /* adjust NeoClock4X local time to UTC */
- calc_utc = neol_mktime(pp->year, month, day, pp->hour, pp->minute, pp->second);
- calc_utc -= 3600;
- /* adjust NeoClock4X daylight saving time if needed */
- if('S' == up->dststatus)
- calc_utc -= 3600;
- neol_localtime(calc_utc, &pp->year, &month, &day, &pp->hour, &pp->minute, &pp->second);
-
- /*
- some preparations
- */
- pp->day = ymd2yd(pp->year, month, day);
- pp->leap = 0;
-
- if(pp->sloppyclockflag & CLK_FLAG4)
- {
- msyslog(LOG_DEBUG, "NeoClock4X(%d): calculated UTC date/time: %04d-%02d-%02d %02d:%02d:%02d.%03ld",
- up->unit,
- pp->year, month, day,
- pp->hour, pp->minute, pp->second, pp->nsec/1000);
- }
-
- up->utc_year = pp->year;
- up->utc_month = month;
- up->utc_day = day;
- up->utc_hour = pp->hour;
- up->utc_minute = pp->minute;
- up->utc_second = pp->second;
- up->utc_msec = pp->nsec/1000;
-
- if(!refclock_process(pp))
- {
- NLOG(NLOG_CLOCKEVENT)
- msyslog(LOG_WARNING, "NeoClock4X(%d): refclock_process failed!", up->unit);
- refclock_report(peer, CEVNT_FAULT);
- return;
- }
- refclock_receive(peer);
-
- /* report good status */
- refclock_report(peer, CEVNT_NOMINAL);
-
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
-}
-
-static void
-neoclock4x_poll(int unit,
- struct peer *peer)
-{
- struct neoclock4x_unit *up;
- struct refclockproc *pp;
-
- pp = peer->procptr;
- up = (struct neoclock4x_unit *)pp->unitptr;
-
- pp->polls++;
- up->recvnow = 1;
-}
-
-static void
-neoclock4x_control(int unit,
- struct refclockstat *in,
- struct refclockstat *out,
- struct peer *peer)
-{
- struct neoclock4x_unit *up;
- struct refclockproc *pp;
-
- if(NULL == peer)
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit);
- return;
- }
-
- pp = peer->procptr;
- if(NULL == pp)
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit);
- return;
- }
-
- up = (struct neoclock4x_unit *)pp->unitptr;
- if(NULL == up)
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit);
- return;
- }
-
- if(NULL != in)
- {
- /* check to see if a user supplied time offset is given */
- if(in->haveflags & CLK_HAVETIME1)
- {
- pp->fudgetime1 = in->fudgetime1;
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_NOTICE, "NeoClock4X(%d): using fudgetime1 with %0.5fs from ntp.conf.",
- unit, pp->fudgetime1);
- }
-
- /* notify */
- if(pp->sloppyclockflag & CLK_FLAG1)
- {
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_NOTICE, "NeoClock4X(%d): quartz clock is used to synchronize time if radio clock has no reception.", unit);
- }
- else
- {
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_NOTICE, "NeoClock4X(%d): time is only adjusted with radio signal reception.", unit);
- }
- }
-
- if(NULL != out)
- {
- static char outstatus[800]; /* status output buffer */
- char *tt;
- char tmpbuf[80];
-
- outstatus[0] = '\0';
- out->kv_list = (struct ctl_var *)0;
- out->type = REFCLK_NEOCLOCK4X;
-
- snprintf(tmpbuf, sizeof(tmpbuf)-1,
- "%04d-%02d-%02d %02d:%02d:%02d.%03d",
- up->utc_year, up->utc_month, up->utc_day,
- up->utc_hour, up->utc_minute, up->utc_second,
- up->utc_msec);
- tt = add_var(&out->kv_list, sizeof(tmpbuf)-1, RO|DEF);
- snprintf(tt, sizeof(tmpbuf)-1, "calc_utc=\"%s\"", tmpbuf);
-
- tt = add_var(&out->kv_list, 40, RO|DEF);
- snprintf(tt, 39, "radiosignal=\"%s\"", up->radiosignal);
- tt = add_var(&out->kv_list, 40, RO|DEF);
- snprintf(tt, 39, "antenna1=\"%d\"", up->antenna1);
- tt = add_var(&out->kv_list, 40, RO|DEF);
- snprintf(tt, 39, "antenna2=\"%d\"", up->antenna2);
- tt = add_var(&out->kv_list, 40, RO|DEF);
- if('A' == up->timesource)
- snprintf(tt, 39, "timesource=\"radio\"");
- else if('C' == up->timesource)
- snprintf(tt, 39, "timesource=\"quartz\"");
- else
- snprintf(tt, 39, "timesource=\"unknown\"");
- tt = add_var(&out->kv_list, 40, RO|DEF);
- if('I' == up->quarzstatus)
- snprintf(tt, 39, "quartzstatus=\"synchronized\"");
- else if('X' == up->quarzstatus)
- snprintf(tt, 39, "quartzstatus=\"not synchronized\"");
- else
- snprintf(tt, 39, "quartzstatus=\"unknown\"");
- tt = add_var(&out->kv_list, 40, RO|DEF);
- if('S' == up->dststatus)
- snprintf(tt, 39, "dststatus=\"summer\"");
- else if('W' == up->dststatus)
- snprintf(tt, 39, "dststatus=\"winter\"");
- else
- snprintf(tt, 39, "dststatus=\"unknown\"");
- tt = add_var(&out->kv_list, 80, RO|DEF);
- snprintf(tt, 79, "firmware=\"%s\"", up->firmware);
- tt = add_var(&out->kv_list, 40, RO|DEF);
- snprintf(tt, 39, "firmwaretag=\"%c\"", up->firmwaretag);
- tt = add_var(&out->kv_list, 80, RO|DEF);
- snprintf(tt, 79, "driver version=\"%s\"", NEOCLOCK4X_DRIVER_VERSION);
- tt = add_var(&out->kv_list, 80, RO|DEF);
- snprintf(tt, 79, "serialnumber=\"%s\"", up->serial);
- }
-}
-
-static int
-neol_hexatoi_len(const char str[],
- int *result,
- int maxlen)
-{
- int hexdigit;
- int i;
- int n = 0;
-
- for(i=0; isxdigit(str[i]) && i < maxlen; i++)
- {
- hexdigit = isdigit(str[i]) ? toupper(str[i]) - '0' : toupper(str[i]) - 'A' + 10;
- n = 16 * n + hexdigit;
- }
- *result = n;
- return (n);
-}
-
-static int
-neol_atoi_len(const char str[],
- int *result,
- int maxlen)
-{
- int digit;
- int i;
- int n = 0;
-
- for(i=0; isdigit(str[i]) && i < maxlen; i++)
- {
- digit = str[i] - '0';
- n = 10 * n + digit;
- }
- *result = n;
- return (n);
-}
-
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static unsigned long
-neol_mktime(int year,
- int mon,
- int day,
- int hour,
- int min,
- int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 . 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
-static void
-neol_localtime(unsigned long utc,
- int* year,
- int* month,
- int* day,
- int* hour,
- int* min,
- int* sec)
-{
- *sec = utc % 60;
- utc /= 60;
- *min = utc % 60;
- utc /= 60;
- *hour = utc % 24;
- utc /= 24;
-
- /* JDN Date 1/1/1970 */
- neol_jdn_to_ymd(utc + 2440588L, year, month, day);
-}
-
-static void
-neol_jdn_to_ymd(unsigned long jdn,
- int *yy,
- int *mm,
- int *dd)
-{
- unsigned long x, z, m, d, y;
- unsigned long daysPer400Years = 146097UL;
- unsigned long fudgedDaysPer4000Years = 1460970UL + 31UL;
-
- x = jdn + 68569UL;
- z = 4UL * x / daysPer400Years;
- x = x - (daysPer400Years * z + 3UL) / 4UL;
- y = 4000UL * (x + 1) / fudgedDaysPer4000Years;
- x = x - 1461UL * y / 4UL + 31UL;
- m = 80UL * x / 2447UL;
- d = x - 2447UL * m / 80UL;
- x = m / 11UL;
- m = m + 2UL - 12UL * x;
- y = 100UL * (z - 49UL) + y + x;
-
- *yy = (int)y;
- *mm = (int)m;
- *dd = (int)d;
-}
-
-#if 0
-/*
- * delay in milliseconds
- */
-static void
-neol_mdelay(int milliseconds)
-{
- struct timeval tv;
-
- if(milliseconds)
- {
- tv.tv_sec = 0;
- tv.tv_usec = milliseconds * 1000;
- select(1, NULL, NULL, NULL, &tv);
- }
-}
-#endif
-
-#if !defined(NEOCLOCK4X_FIRMWARE)
-static int
-neol_query_firmware(int fd,
- int unit,
- char *firmware,
- int maxlen)
-{
- char tmpbuf[256];
- int len;
- int lastsearch;
- unsigned char c;
- int last_c_was_crlf;
- int last_crlf_conv_len;
- int init;
- int read_errors;
- int flag = 0;
- int chars_read;
-
- /* wait a little bit */
- sleep(1);
- if(-1 != write(fd, "V", 1))
- {
- /* wait a little bit */
- sleep(1);
- memset(tmpbuf, 0x00, sizeof(tmpbuf));
-
- len = 0;
- lastsearch = 0;
- last_c_was_crlf = 0;
- last_crlf_conv_len = 0;
- init = 1;
- read_errors = 0;
- chars_read = 0;
- for(;;)
- {
- if(read_errors > 5)
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): can't read firmware version (timeout)", unit);
- strcpy(tmpbuf, "unknown due to timeout");
- break;
- }
- if(chars_read > 500)
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): can't read firmware version (garbage)", unit);
- strcpy(tmpbuf, "unknown due to garbage input");
- break;
- }
- if(-1 == read(fd, &c, 1))
- {
- if(EAGAIN != errno)
- {
- msyslog(LOG_DEBUG, "NeoClock4x(%d): read: %s", unit ,strerror(errno));
- read_errors++;
- }
- else
- {
- sleep(1);
- }
- continue;
- }
- else
- {
- chars_read++;
- }
-
- if(init)
- {
- if(0xA9 != c) /* wait for (c) char in input stream */
- continue;
-
- strcpy(tmpbuf, "(c)");
- len = 3;
- init = 0;
- continue;
- }
-
-#if 0
- msyslog(LOG_NOTICE, "NeoClock4X(%d): firmware %c = %02Xh", unit, c, c);
-#endif
-
- if(0x0A == c || 0x0D == c)
- {
- if(last_c_was_crlf)
- {
- char *ptr;
- ptr = strstr(&tmpbuf[lastsearch], "S/N");
- if(NULL != ptr)
- {
- tmpbuf[last_crlf_conv_len] = 0;
- flag = 1;
- break;
- }
- /* convert \n to / */
- last_crlf_conv_len = len;
- tmpbuf[len++] = ' ';
- tmpbuf[len++] = '/';
- tmpbuf[len++] = ' ';
- lastsearch = len;
- }
- last_c_was_crlf = 1;
- }
- else
- {
- last_c_was_crlf = 0;
- if(0x00 != c)
- tmpbuf[len++] = (char) c;
- }
- tmpbuf[len] = '\0';
- if(len > sizeof(tmpbuf)-5)
- break;
- }
- }
- else
- {
- msyslog(LOG_ERR, "NeoClock4X(%d): can't query firmware version", unit);
- strcpy(tmpbuf, "unknown error");
- }
- strncpy(firmware, tmpbuf, maxlen);
- firmware[maxlen] = '\0';
-
- if(flag)
- {
- NLOG(NLOG_CLOCKINFO)
- msyslog(LOG_INFO, "NeoClock4X(%d): firmware version: %s", unit, firmware);
- }
-
- return (flag);
-}
-
-static int
-neol_check_firmware(int unit,
- const char *firmware,
- char *firmwaretag)
-{
- char *ptr;
-
- *firmwaretag = '?';
- ptr = strstr(firmware, "NDF:");
- if(NULL != ptr)
- {
- if((strlen(firmware) - strlen(ptr)) >= 7)
- {
- if(':' == *(ptr+5) && '*' == *(ptr+6))
- *firmwaretag = *(ptr+4);
- }
- }
-
- if('A' != *firmwaretag)
- {
- msyslog(LOG_CRIT, "NeoClock4X(%d): firmware version \"%c\" not supported with this driver version!", unit, *firmwaretag);
- return (0);
- }
-
- return (1);
-}
-#endif
-
-#else
-int refclock_neoclock4x_bs;
-#endif /* REFCLOCK */
-
-/*
- * History:
- * refclock_neoclock4x.c
- *
- * 2002/04/27 cjh
- * Revision 1.0 first release
- *
- * 2002/07/15 cjh
- * preparing for bitkeeper reposity
- *
- * 2002/09/09 cjh
- * Revision 1.1
- * - don't assume sprintf returns an int anymore
- * - change the way the firmware version is read
- * - some customers would like to put a device called
- * data diode to the NeoClock4X device to disable
- * the write line. We need to now the firmware
- * version even in this case. We made a compile time
- * definition in this case. The code was previously
- * only available on request.
- *
- * 2003/01/08 cjh
- * Revision 1.11
- * - changing xprinf to xnprinf to avoid buffer overflows
- * - change some logic
- * - fixed memory leaks if drivers can't initialize
- *
- * 2003/01/10 cjh
- * Revision 1.12
- * - replaced ldiv
- * - add code to support FreeBSD
- *
- * 2003/07/07 cjh
- * Revision 1.13
- * - fix reporting of clock status
- * changes. previously a bad clock
- * status was never reset.
- */
OpenPOWER on IntegriCloud