Annotation of embedaddon/ntp/ntpd/refclock_hopfser.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *
        !             3:  * refclock_hopfser.c
        !             4:  * - clock driver for hopf serial boards (GPS or DCF77)
        !             5:  *
        !             6:  * Date: 30.03.2000 Revision: 01.10
        !             7:  *
        !             8:  * latest source and further information can be found at:
        !             9:  * http://www.ATLSoft.de/ntp
        !            10:  *
        !            11:  */
        !            12: 
        !            13: #ifdef HAVE_CONFIG_H
        !            14: # include "config.h"
        !            15: #endif
        !            16: 
        !            17: #if defined(REFCLOCK) && (defined(CLOCK_HOPF_SERIAL))
        !            18: 
        !            19: #include "ntpd.h"
        !            20: #include "ntp_io.h"
        !            21: #include "ntp_control.h"
        !            22: #include "ntp_refclock.h"
        !            23: #include "ntp_unixtime.h"
        !            24: #include "ntp_stdlib.h"
        !            25: 
        !            26: #if defined HAVE_SYS_MODEM_H
        !            27: # include <sys/modem.h>
        !            28: # ifndef __QNXNTO__
        !            29: #  define TIOCMSET MCSETA
        !            30: #  define TIOCMGET MCGETA
        !            31: #  define TIOCM_RTS MRTS
        !            32: # endif
        !            33: #endif
        !            34: 
        !            35: #ifdef HAVE_TERMIOS_H
        !            36: # ifdef TERMIOS_NEEDS__SVID3
        !            37: #  define _SVID3
        !            38: # endif
        !            39: # include <termios.h>
        !            40: # ifdef TERMIOS_NEEDS__SVID3
        !            41: #  undef _SVID3
        !            42: # endif
        !            43: #endif
        !            44: 
        !            45: #ifdef HAVE_SYS_IOCTL_H
        !            46: # include <sys/ioctl.h>
        !            47: #endif
        !            48: 
        !            49: #ifdef SYS_WINNT
        !            50: extern int async_write(int, const void *, unsigned int);
        !            51: #undef write
        !            52: #define write(fd, data, octets)        async_write(fd, data, octets)
        !            53: #endif
        !            54: 
        !            55: /*
        !            56:  * clock definitions
        !            57:  */
        !            58: #define        DESCRIPTION     "hopf Elektronik serial clock" /* Long name */
        !            59: #define        PRECISION       (-10)   /* precision assumed (about 1 ms) */
        !            60: #define        REFID           "hopf\0"        /* reference ID */
        !            61: /*
        !            62:  * I/O definitions
        !            63:  */
        !            64: #define        DEVICE          "/dev/hopfclock%d"      /* device name and unit */
        !            65: #define        SPEED232        B9600                   /* uart speed (9600 baud) */
        !            66: 
        !            67: 
        !            68: #define STX 0x02
        !            69: #define ETX 0x03
        !            70: #define CR  0x0c
        !            71: #define LF  0x0a
        !            72: 
        !            73: /* parse states */
        !            74: #define REC_QUEUE_EMPTY       0
        !            75: #define REC_QUEUE_FULL        1
        !            76: 
        !            77: #define        HOPF_OPMODE     0x0C    /* operation mode mask */
        !            78: #define HOPF_INVALID   0x00    /* no time code available */
        !            79: #define HOPF_INTERNAL  0x04    /* internal clock */
        !            80: #define HOPF_RADIO     0x08    /* radio clock */
        !            81: #define HOPF_RADIOHP   0x0C    /* high precision radio clock */
        !            82: 
        !            83: /*
        !            84:  * hopfclock unit control structure.
        !            85:  */
        !            86: struct hopfclock_unit {
        !            87:        l_fp    laststamp;      /* last receive timestamp */
        !            88:        short   unit;           /* NTP refclock unit number */
        !            89:        u_long  polled;         /* flag to detect noreplies */
        !            90:        char    leap_status;    /* leap second flag */
        !            91:        int     rpt_next;
        !            92: };
        !            93: 
        !            94: /*
        !            95:  * Function prototypes
        !            96:  */
        !            97: 
        !            98: static int     hopfserial_start        (int, struct peer *);
        !            99: static void    hopfserial_shutdown     (int, struct peer *);
        !           100: static void    hopfserial_receive      (struct recvbuf *);
        !           101: static void    hopfserial_poll         (int, struct peer *);
        !           102: /* static  void hopfserial_io          (struct recvbuf *); */
        !           103: /*
        !           104:  * Transfer vector
        !           105:  */
        !           106: struct refclock refclock_hopfser = {
        !           107:        hopfserial_start,       /* start up driver */
        !           108:        hopfserial_shutdown,    /* shut down driver */
        !           109:        hopfserial_poll,        /* transmit poll message */
        !           110:        noentry,                /* not used  */
        !           111:        noentry,                /* initialize driver (not used) */
        !           112:        noentry,                /* not used */
        !           113:        NOFLAGS                 /* not used */
        !           114: };
        !           115: 
        !           116: /*
        !           117:  * hopfserial_start - open the devices and initialize data for processing
        !           118:  */
        !           119: static int
        !           120: hopfserial_start (
        !           121:        int unit,
        !           122:        struct peer *peer
        !           123:        )
        !           124: {
        !           125:        register struct hopfclock_unit *up;
        !           126:        struct refclockproc *pp;
        !           127:        int fd;
        !           128:        char gpsdev[20];
        !           129: 
        !           130:        snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit);
        !           131: 
        !           132:        /* LDISC_STD, LDISC_RAW
        !           133:         * Open serial port. Use CLK line discipline, if available.
        !           134:         */
        !           135:        fd = refclock_open(gpsdev, SPEED232, LDISC_CLK);
        !           136:        if (fd <= 0) {
        !           137: #ifdef DEBUG
        !           138:                printf("hopfSerialClock(%d) start: open %s failed\n", unit, gpsdev);
        !           139: #endif
        !           140:                return 0;
        !           141:        }
        !           142: 
        !           143:        msyslog(LOG_NOTICE, "hopfSerialClock(%d) fd: %d dev: %s", unit, fd,
        !           144:                gpsdev);
        !           145: 
        !           146:        /*
        !           147:         * Allocate and initialize unit structure
        !           148:         */
        !           149:        up = emalloc(sizeof(*up));
        !           150:        memset(up, 0, sizeof(*up));
        !           151:        pp = peer->procptr;
        !           152:        pp->unitptr = (caddr_t)up;
        !           153:        pp->io.clock_recv = hopfserial_receive;
        !           154:        pp->io.srcclock = (caddr_t)peer;
        !           155:        pp->io.datalen = 0;
        !           156:        pp->io.fd = fd;
        !           157:        if (!io_addclock(&pp->io)) {
        !           158: #ifdef DEBUG
        !           159:                printf("hopfSerialClock(%d) io_addclock\n", unit);
        !           160: #endif
        !           161:                close(fd);
        !           162:                pp->io.fd = -1;
        !           163:                free(up);
        !           164:                pp->unitptr = NULL;
        !           165:                return (0);
        !           166:        }
        !           167: 
        !           168:        /*
        !           169:         * Initialize miscellaneous variables
        !           170:         */
        !           171:        pp->clockdesc = DESCRIPTION;
        !           172:        peer->precision = PRECISION;
        !           173:        peer->burst = NSTAGE;
        !           174:        memcpy((char *)&pp->refid, REFID, 4);
        !           175: 
        !           176:        up->leap_status = 0;
        !           177:        up->unit = (short) unit;
        !           178: 
        !           179:        return (1);
        !           180: }
        !           181: 
        !           182: 
        !           183: /*
        !           184:  * hopfserial_shutdown - shut down the clock
        !           185:  */
        !           186: static void
        !           187: hopfserial_shutdown (
        !           188:        int unit,
        !           189:        struct peer *peer
        !           190:        )
        !           191: {
        !           192:        register struct hopfclock_unit *up;
        !           193:        struct refclockproc *pp;
        !           194: 
        !           195:        pp = peer->procptr;
        !           196:        up = (struct hopfclock_unit *)pp->unitptr;
        !           197: 
        !           198:        if (-1 != pp->io.fd)
        !           199:                io_closeclock(&pp->io);
        !           200:        if (NULL != up)
        !           201:                free(up);
        !           202: }
        !           203: 
        !           204: 
        !           205: 
        !           206: /*
        !           207:  * hopfserial_receive - receive data from the serial interface
        !           208:  */
        !           209: 
        !           210: static void
        !           211: hopfserial_receive (
        !           212:        struct recvbuf *rbufp
        !           213:        )
        !           214: {
        !           215:        struct hopfclock_unit *up;
        !           216:        struct refclockproc *pp;
        !           217:        struct peer *peer;
        !           218: 
        !           219:        int             synch;  /* synchhronization indicator */
        !           220:        int             DoW;    /* Dow */
        !           221: 
        !           222:        int     day, month;     /* ddd conversion */
        !           223: 
        !           224:        /*
        !           225:         * Initialize pointers and read the timecode and timestamp.
        !           226:         */
        !           227:        peer = (struct peer *)rbufp->recv_srcclock;
        !           228:        pp = peer->procptr;
        !           229:        up = (struct hopfclock_unit *)pp->unitptr;
        !           230: 
        !           231:        if (up->rpt_next == 0 )
        !           232:                return;
        !           233: 
        !           234: 
        !           235:        up->rpt_next = 0; /* wait until next poll interval occur */
        !           236: 
        !           237:        pp->lencode = (u_short)refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &pp->lastrec);
        !           238: 
        !           239:        if (pp->lencode  == 0)
        !           240:                return;
        !           241: 
        !           242:        sscanf(pp->a_lastcode,
        !           243: #if 1
        !           244:               "%1x%1x%2d%2d%2d%2d%2d%2d",   /* ...cr,lf */
        !           245: #else
        !           246:               "%*c%1x%1x%2d%2d%2d%2d%2d%2d", /* stx...cr,lf,etx */
        !           247: #endif
        !           248:               &synch,
        !           249:               &DoW,
        !           250:               &pp->hour,
        !           251:               &pp->minute,
        !           252:               &pp->second,
        !           253:               &day,
        !           254:               &month,
        !           255:               &pp->year);
        !           256: 
        !           257: 
        !           258:        /*
        !           259:          Validate received values at least enough to prevent internal
        !           260:          array-bounds problems, etc.
        !           261:        */
        !           262:        if((pp->hour < 0) || (pp->hour > 23) ||
        !           263:           (pp->minute < 0) || (pp->minute > 59) ||
        !           264:           (pp->second < 0) || (pp->second > 60) /*Allow for leap seconds.*/ ||
        !           265:           (day < 1) || (day > 31) ||
        !           266:           (month < 1) || (month > 12) ||
        !           267:           (pp->year < 0) || (pp->year > 99)) {
        !           268:                /* Data out of range. */
        !           269:                refclock_report(peer, CEVNT_BADREPLY);
        !           270:                return;
        !           271:        }
        !           272:        /*
        !           273:          some preparations
        !           274:        */
        !           275:        pp->day    = ymd2yd(pp->year,month,day);
        !           276:        pp->leap=0;
        !           277: 
        !           278:        /* Year-2000 check! */
        !           279:        /* wrap 2-digit date into 4-digit */
        !           280: 
        !           281:        if(pp->year < YEAR_PIVOT) { pp->year += 100; }          /* < 98 */
        !           282:        pp->year += 1900;
        !           283: 
        !           284:        /* preparation for timecode ntpq rl command ! */
        !           285: 
        !           286: #if 0
        !           287:        snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
        !           288:                 "STATUS: %1X%1X, DATE: %02d.%02d.%04d  TIME: %02d:%02d:%02d",
        !           289:                 synch,
        !           290:                 DoW,
        !           291:                 day,
        !           292:                 month,
        !           293:                 pp->year,
        !           294:                 pp->hour,
        !           295:                 pp->minute,
        !           296:                 pp->second);
        !           297: 
        !           298:        pp->lencode = strlen(pp->a_lastcode);
        !           299:        if ((synch && 0xc) == 0 ){  /* time ok? */
        !           300:                refclock_report(peer, CEVNT_BADTIME);
        !           301:                pp->leap = LEAP_NOTINSYNC;
        !           302:                return;
        !           303:        }
        !           304: #endif
        !           305:        /*
        !           306:         * If clock has no valid status then report error and exit
        !           307:         */
        !           308:        if ((synch & HOPF_OPMODE) == HOPF_INVALID ){  /* time ok? */
        !           309:                refclock_report(peer, CEVNT_BADTIME);
        !           310:                pp->leap = LEAP_NOTINSYNC;
        !           311:                return;
        !           312:        }
        !           313: 
        !           314:        /*
        !           315:         * Test if time is running on internal quarz
        !           316:         * if CLK_FLAG1 is set, sychronize even if no radio operation
        !           317:         */
        !           318: 
        !           319:        if ((synch & HOPF_OPMODE) == HOPF_INTERNAL){
        !           320:                if ((pp->sloppyclockflag & CLK_FLAG1) == 0) {
        !           321:                        refclock_report(peer, CEVNT_BADTIME);
        !           322:                        pp->leap = LEAP_NOTINSYNC;
        !           323:                        return;
        !           324:                }
        !           325:        }
        !           326: 
        !           327: 
        !           328:        if (!refclock_process(pp)) {
        !           329:                refclock_report(peer, CEVNT_BADTIME);
        !           330:                return;
        !           331:        }
        !           332:        pp->lastref = pp->lastrec;
        !           333:        refclock_receive(peer);
        !           334: 
        !           335: #if 0
        !           336:        msyslog(LOG_ERR, " D:%x  D:%d D:%d",synch,pp->minute,pp->second);
        !           337: #endif
        !           338: 
        !           339:        record_clock_stats(&peer->srcadr, pp->a_lastcode);
        !           340: 
        !           341:        return;
        !           342: }
        !           343: 
        !           344: 
        !           345: /*
        !           346:  * hopfserial_poll - called by the transmit procedure
        !           347:  *
        !           348:  */
        !           349: static void
        !           350: hopfserial_poll (
        !           351:        int unit,
        !           352:        struct peer *peer
        !           353:        )
        !           354: {
        !           355:        register struct hopfclock_unit *up;
        !           356:        struct refclockproc *pp;
        !           357:        pp = peer->procptr;
        !           358: 
        !           359:        up = (struct hopfclock_unit *)pp->unitptr;
        !           360: 
        !           361:        pp->polls++;
        !           362:        up->rpt_next = 1;
        !           363: 
        !           364: #if 0
        !           365:        record_clock_stats(&peer->srcadr, pp->a_lastcode);
        !           366: #endif
        !           367: 
        !           368:        return;
        !           369: }
        !           370: 
        !           371: #else
        !           372: int refclock_hopfser_bs;
        !           373: #endif /* REFCLOCK */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>