Annotation of embedaddon/ntp/ntpd/refclock_tpro.c, revision 1.1
1.1 ! misho 1: /*
! 2: * refclock_tpro - clock driver for the KSI/Odetics TPRO-S IRIG-B reader
! 3: */
! 4:
! 5: #ifdef HAVE_CONFIG_H
! 6: #include <config.h>
! 7: #endif
! 8:
! 9: #if defined(REFCLOCK) && defined(CLOCK_TPRO)
! 10:
! 11: #include "ntpd.h"
! 12: #include "ntp_io.h"
! 13: #include "ntp_refclock.h"
! 14: #include "ntp_unixtime.h"
! 15: #include "sys/tpro.h"
! 16: #include "ntp_stdlib.h"
! 17:
! 18: #include <stdio.h>
! 19: #include <ctype.h>
! 20:
! 21: /*
! 22: * This driver supports the KSI/Odetecs TPRO-S IRIG-B reader and TPRO-
! 23: * SAT GPS receiver for the Sun Microsystems SBus. It requires that the
! 24: * tpro.o device driver be installed and loaded.
! 25: */
! 26:
! 27: /*
! 28: * TPRO interface definitions
! 29: */
! 30: #define DEVICE "/dev/tpro%d" /* device name and unit */
! 31: #define PRECISION (-20) /* precision assumed (1 us) */
! 32: #define REFID "IRIG" /* reference ID */
! 33: #define DESCRIPTION "KSI/Odetics TPRO/S IRIG Interface" /* WRU */
! 34:
! 35: /*
! 36: * Unit control structure
! 37: */
! 38: struct tprounit {
! 39: struct tproval tprodata; /* data returned from tpro read */
! 40: };
! 41:
! 42: /*
! 43: * Function prototypes
! 44: */
! 45: static int tpro_start (int, struct peer *);
! 46: static void tpro_shutdown (int, struct peer *);
! 47: static void tpro_poll (int unit, struct peer *);
! 48:
! 49: /*
! 50: * Transfer vector
! 51: */
! 52: struct refclock refclock_tpro = {
! 53: tpro_start, /* start up driver */
! 54: tpro_shutdown, /* shut down driver */
! 55: tpro_poll, /* transmit poll message */
! 56: noentry, /* not used (old tpro_control) */
! 57: noentry, /* initialize driver (not used) */
! 58: noentry, /* not used (old tpro_buginfo) */
! 59: NOFLAGS /* not used */
! 60: };
! 61:
! 62:
! 63: /*
! 64: * tpro_start - open the TPRO device and initialize data for processing
! 65: */
! 66: static int
! 67: tpro_start(
! 68: int unit,
! 69: struct peer *peer
! 70: )
! 71: {
! 72: register struct tprounit *up;
! 73: struct refclockproc *pp;
! 74: char device[20];
! 75: int fd;
! 76:
! 77: /*
! 78: * Open TPRO device
! 79: */
! 80: snprintf(device, sizeof(device), DEVICE, unit);
! 81: fd = open(device, O_RDONLY | O_NDELAY, 0777);
! 82: if (fd == -1) {
! 83: msyslog(LOG_ERR, "tpro_start: open of %s: %m", device);
! 84: return (0);
! 85: }
! 86:
! 87: /*
! 88: * Allocate and initialize unit structure
! 89: */
! 90: up = emalloc(sizeof(*up));
! 91: memset(up, 0, sizeof(*up));
! 92: pp = peer->procptr;
! 93: pp->io.clock_recv = noentry;
! 94: pp->io.srcclock = (caddr_t)peer;
! 95: pp->io.datalen = 0;
! 96: pp->io.fd = fd;
! 97: pp->unitptr = (caddr_t)up;
! 98:
! 99: /*
! 100: * Initialize miscellaneous peer variables
! 101: */
! 102: peer->precision = PRECISION;
! 103: peer->burst = NSTAGE;
! 104: pp->clockdesc = DESCRIPTION;
! 105: memcpy((char *)&pp->refid, REFID, 4);
! 106: return (1);
! 107: }
! 108:
! 109:
! 110: /*
! 111: * tpro_shutdown - shut down the clock
! 112: */
! 113: static void
! 114: tpro_shutdown(
! 115: int unit,
! 116: struct peer *peer
! 117: )
! 118: {
! 119: register struct tprounit *up;
! 120: struct refclockproc *pp;
! 121:
! 122: pp = peer->procptr;
! 123: up = (struct tprounit *)pp->unitptr;
! 124: io_closeclock(&pp->io);
! 125: if (NULL != up)
! 126: free(up);
! 127: }
! 128:
! 129:
! 130: /*
! 131: * tpro_poll - called by the transmit procedure
! 132: */
! 133: static void
! 134: tpro_poll(
! 135: int unit,
! 136: struct peer *peer
! 137: )
! 138: {
! 139: register struct tprounit *up;
! 140: struct refclockproc *pp;
! 141: struct tproval *tp;
! 142:
! 143: /*
! 144: * This is the main routine. It snatches the time from the TPRO
! 145: * board and tacks on a local timestamp.
! 146: */
! 147: pp = peer->procptr;
! 148: up = (struct tprounit *)pp->unitptr;
! 149:
! 150: tp = &up->tprodata;
! 151: if (read(pp->io.fd, (char *)tp, sizeof(struct tproval)) < 0) {
! 152: refclock_report(peer, CEVNT_FAULT);
! 153: return;
! 154: }
! 155: get_systime(&pp->lastrec);
! 156: pp->polls++;
! 157:
! 158: /*
! 159: * We get down to business, check the timecode format and decode
! 160: * its contents. If the timecode has invalid length or is not in
! 161: * proper format, we declare bad format and exit. Note: we
! 162: * can't use the sec/usec conversion produced by the driver,
! 163: * since the year may be suspect. All format error checking is
! 164: * done by the sprintf() and sscanf() routines.
! 165: *
! 166: * Note that the refclockproc usec member has now become nsec.
! 167: * We could either multiply the read-in usec value by 1000 or
! 168: * we could pad the written string appropriately and read the
! 169: * resulting value in already scaled.
! 170: */
! 171: snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
! 172: "%1x%1x%1x %1x%1x:%1x%1x:%1x%1x.%1x%1x%1x%1x%1x%1x %1x",
! 173: tp->day100, tp->day10, tp->day1, tp->hour10, tp->hour1,
! 174: tp->min10, tp->min1, tp->sec10, tp->sec1, tp->ms100,
! 175: tp->ms10, tp->ms1, tp->usec100, tp->usec10, tp->usec1,
! 176: tp->status);
! 177: pp->lencode = strlen(pp->a_lastcode);
! 178: #ifdef DEBUG
! 179: if (debug)
! 180: printf("tpro: time %s timecode %d %s\n",
! 181: ulfptoa(&pp->lastrec, 6), pp->lencode,
! 182: pp->a_lastcode);
! 183: #endif
! 184: if (sscanf(pp->a_lastcode, "%3d %2d:%2d:%2d.%6ld", &pp->day,
! 185: &pp->hour, &pp->minute, &pp->second, &pp->nsec)
! 186: != 5) {
! 187: refclock_report(peer, CEVNT_BADTIME);
! 188: return;
! 189: }
! 190: pp->nsec *= 1000; /* Convert usec to nsec */
! 191: if (!tp->status & 0x3)
! 192: pp->leap = LEAP_NOTINSYNC;
! 193: else
! 194: pp->leap = LEAP_NOWARNING;
! 195: if (!refclock_process(pp)) {
! 196: refclock_report(peer, CEVNT_BADTIME);
! 197: return;
! 198: }
! 199: if (peer->burst > 0)
! 200: return;
! 201: if (pp->coderecv == pp->codeproc) {
! 202: refclock_report(peer, CEVNT_TIMEOUT);
! 203: return;
! 204: }
! 205: pp->lastref = pp->lastrec;
! 206: record_clock_stats(&peer->srcadr, pp->a_lastcode);
! 207: refclock_receive(peer);
! 208: peer->burst = NSTAGE;
! 209: }
! 210:
! 211: #else
! 212: int refclock_tpro_bs;
! 213: #endif /* REFCLOCK */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>