refclock_hopfpci.c [plain text]
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if defined(REFCLOCK) && defined(CLOCK_HOPF_PCI)
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_refclock.h"
#include "ntp_unixtime.h"
#include "ntp_stdlib.h"
#undef fileno
#include <ctype.h>
#undef fileno
#ifndef SYS_WINNT
# include <sys/ipc.h>
# include <assert.h>
# include <unistd.h>
# include <stdio.h>
# include "hopf6039.h"
#else
# include "hopf_PCI_io.h"
#endif
#define PRECISION (-10)
#define REFID "hopf"
#define DESCRIPTION "hopf Elektronik PCI radio board"
#define NSAMPLES 3
#ifndef SYS_WINNT
# define DEVICE "/dev/hopf6039"
#else
# define DEVICE "hopf6039"
#endif
#define LEWAPWAR 0x20
#define HOPF_OPMODE 0xC0
#define HOPF_INVALID 0x00
#define HOPF_INTERNAL 0x40
#define HOPF_RADIO 0x80
#define HOPF_RADIOHP 0xC0
struct hopfclock_unit {
short unit;
char leap_status;
};
int fd;
static int hopfpci_start (int, struct peer *);
static void hopfpci_shutdown (int, struct peer *);
static void hopfpci_poll (int unit, struct peer *);
struct refclock refclock_hopfpci = {
hopfpci_start,
hopfpci_shutdown,
hopfpci_poll,
noentry,
noentry,
noentry,
NOFLAGS
};
static int
hopfpci_start(
int unit,
struct peer *peer
)
{
struct refclockproc *pp;
struct hopfclock_unit *up;
up = (struct hopfclock_unit *) emalloc(sizeof(struct hopfclock_unit));
if (!(up)) {
msyslog(LOG_ERR, "hopfPCIClock(%d) emalloc: %m",unit);
#ifdef DEBUG
printf("hopfPCIClock(%d) emalloc\n",unit);
#endif
return (0);
}
memset((char *)up, 0, sizeof(struct hopfclock_unit));
#ifndef SYS_WINNT
fd = open(DEVICE,O_RDWR);
#else
if (!OpenHopfDevice()){
msyslog(LOG_ERR,"Start: %s unit: %d failed!",DEVICE,unit);
return (0);
}
#endif
pp = peer->procptr;
pp->io.clock_recv = noentry;
pp->io.srcclock = (caddr_t)peer;
pp->io.datalen = 0;
pp->io.fd = -1;
pp->unitptr = (caddr_t)up;
get_systime(&pp->lastrec);
if (pp->unitptr!=0) {
memcpy((char *)&pp->refid, REFID, 4);
peer->precision = PRECISION;
pp->clockdesc = DESCRIPTION;
up->leap_status = 0;
up->unit = (short) unit;
return (1);
}
else {
return 0;
}
}
static void
hopfpci_shutdown(
int unit,
struct peer *peer
)
{
struct refclockproc *pp;
register struct hopfpciTime *up;
pp = peer->procptr;
up = (struct hopfpciTime *)pp->unitptr;
#ifndef SYS_WINNT
close(fd);
#else
CloseHopfDevice();
#endif
}
static void
hopfpci_poll(
int unit,
struct peer *peer
)
{
struct refclockproc *pp;
register struct hopfpciTime *up;
HOPFTIME m_time;
pp = peer->procptr;
up = (struct hopfpciTime *)pp->unitptr;
#ifndef SYS_WINNT
ioctl(fd,HOPF_CLOCK_GET_UTC,&m_time);
#else
GetHopfSystemTime(&m_time);
#endif
pp->polls++;
pp->day = ymd2yd(m_time.wYear,m_time.wMonth,m_time.wDay);
pp->hour = m_time.wHour;
pp->minute = m_time.wMinute;
pp->second = m_time.wSecond;
pp->msec=m_time.wMilliseconds;
pp->usec=0;
if (m_time.wStatus & LEWAPWAR)
pp->leap = LEAP_ADDSECOND;
else
pp->leap = LEAP_NOWARNING;
sprintf(pp->a_lastcode,"ST: %02X T: %02d:%02d:%02d.%03d D: %02d.%02d.%04d",
m_time.wStatus, pp->hour, pp->minute, pp->second, pp->msec,
m_time.wDay, m_time.wMonth, m_time.wYear);
pp->lencode = strlen(pp->a_lastcode);
get_systime(&pp->lastrec);
if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INVALID) {
refclock_report(peer, CEVNT_BADTIME);
pp->leap = LEAP_NOTINSYNC;
return;
}
if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INTERNAL){
if ((pp->sloppyclockflag & CLK_FLAG1) == 0) {
refclock_report(peer, CEVNT_BADTIME);
pp->leap = LEAP_NOTINSYNC;
return;
}
}
if (!refclock_process(pp)) {
refclock_report(peer, CEVNT_BADTIME);
return;
}
refclock_receive(peer);
record_clock_stats(&peer->srcadr, pp->a_lastcode);
return;
}
#else
int refclock_hopfpci_bs;
#endif