refclock_bancomm.c [plain text]
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(REFCLOCK) && defined(CLOCK_BANC)
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_refclock.h"
#include "ntp_unixtime.h"
#include "ntp_stdlib.h"
#include <stdio.h>
#include <syslog.h>
#include <ctype.h>
struct btfp_time
{
unsigned short btfp_time[5];
};
#define BTFPIOC ( 'b'<< 8 )
#define IOCIO( l, n ) ( BTFPIOC | n )
#define IOCIOR( l, n, s ) ( BTFPIOC | n )
#define IOCIORN( l, n, s ) ( BTFPIOC | n )
#define IOCIOWN( l, n, s ) ( BTFPIOC | n )
#define RUNLOCK IOCIOR(b, 19, int )
#define RCR0 IOCIOR(b, 22, int )
#define WCR0 IOCIOWN(b, 23, int)
#define READTIME IOCIORN(b, 32, sizeof( struct btfp_time ))
#define VMEFD "/dev/btfp0"
struct vmedate {
unsigned short year;
unsigned short day;
unsigned short hr;
unsigned short mn;
unsigned short sec;
unsigned long frac;
unsigned short status;
};
#define VMEPRECISION (-21)
#define USNOREFID "BTFP"
#define VMEREFID "BTFP"
#define VMEDESCRIPTION "Bancomm bc635 TFP"
#define VMEHSREFID 0x7f7f1000
#define GMT 0
extern u_long current_time;
extern int debug;
struct vmeunit {
struct vmedate vmedata;
u_long lasttime;
};
static void vme_init (void);
static int vme_start (int, struct peer *);
static void vme_shutdown (int, struct peer *);
static void vme_receive (struct recvbuf *);
static void vme_poll (int unit, struct peer *);
struct vmedate *get_datumtime(struct vmedate *);
struct refclock refclock_bancomm = {
vme_start,
vme_shutdown,
vme_poll,
noentry,
noentry,
noentry,
NOFLAGS
};
int fd_vme;
int regvalue;
static int
vme_start(
int unit,
struct peer *peer
)
{
register struct vmeunit *vme;
struct refclockproc *pp;
int dummy;
char vmedev[20];
#ifdef DEBUG
printf("Opening DATUM VME DEVICE \n");
#endif
if ( (fd_vme = open(VMEFD, O_RDWR)) < 0) {
msyslog(LOG_ERR, "vme_start: failed open of %s: %m", vmedev);
return (0);
}
else {
if( ioctl( fd_vme, RUNLOCK, &dummy ) )
msyslog(LOG_ERR, "vme_start: RUNLOCK failed %m");
regvalue = 0;
if( ioctl( fd_vme, WCR0, ®value ) )
msyslog(LOG_ERR, "vme_start: WCR0 failed %m");
}
vme = (struct vmeunit *)emalloc(sizeof(struct vmeunit));
bzero((char *)vme, sizeof(struct vmeunit));
pp = peer->procptr;
pp->unitptr = (caddr_t) vme;
pp->timestarted = current_time;
pp->io.clock_recv = vme_receive;
pp->io.srcclock = (caddr_t)peer;
pp->io.datalen = 0;
pp->io.fd = fd_vme;
peer->precision = VMEPRECISION;
memcpy(&pp->refid, USNOREFID,4);
return (1);
}
static void
vme_shutdown(
int unit,
struct peer *peer
)
{
register struct vmeunit *vme;
struct refclockproc *pp;
pp = peer->procptr;
vme = (struct vmeunit *)pp->unitptr;
io_closeclock(&pp->io);
pp->unitptr = NULL;
free(vme);
}
static void
vme_receive(
struct recvbuf *rbufp
)
{
}
static void
vme_poll(
int unit,
struct peer *peer
)
{
struct vmedate *tptr;
struct vmeunit *vme;
struct refclockproc *pp;
time_t tloc;
struct tm *tadr;
pp = peer->procptr;
vme = (struct vmeunit *)pp->unitptr;
tptr = &vme->vmedata;
if ((tptr = get_datumtime(tptr)) == NULL ) {
refclock_report(peer, CEVNT_BADREPLY);
return;
}
get_systime(&pp->lastrec);
pp->polls++;
vme->lasttime = current_time;
time(&tloc);
tadr = gmtime(&tloc);
tptr->year = (unsigned short)(tadr->tm_year + 1900);
sprintf(pp->a_lastcode,
"%3.3d %2.2d:%2.2d:%2.2d.%.6ld %1d",
tptr->day,
tptr->hr,
tptr->mn,
tptr->sec,
tptr->frac,
tptr->status);
pp->lencode = (u_short) strlen(pp->a_lastcode);
pp->day = tptr->day;
pp->hour = tptr->hr;
pp->minute = tptr->mn;
pp->second = tptr->sec;
pp->usec = tptr->frac;
#ifdef DEBUG
if (debug)
printf("pp: %3d %02d:%02d:%02d.%06ld %1x\n",
pp->day, pp->hour, pp->minute, pp->second,
pp->usec, tptr->status);
#endif
if (tptr->status ) {
refclock_report(peer, CEVNT_BADREPLY);
return;
}
if (!refclock_process(pp)) {
refclock_report(peer, CEVNT_BADTIME);
return;
}
record_clock_stats(&peer->srcadr, pp->a_lastcode);
refclock_receive(peer);
}
struct vmedate *
get_datumtime(struct vmedate *time_vme)
{
unsigned short status;
char cbuf[7];
struct btfp_time vts;
if ( time_vme == (struct vmedate *)NULL) {
time_vme = (struct vmedate *)malloc(sizeof(struct vmedate ));
}
if( ioctl(fd_vme, READTIME, &vts))
msyslog(LOG_ERR, "get_datumtime error: %m");
#ifdef CHECK
sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) +
((vts.btfp_time[ 1 ] & 0xff00) >> 8));
if (isdigit(cbuf[0]) && isdigit(cbuf[1]) && isdigit(cbuf[2]) )
time_vme->day = (unsigned short)atoi(cbuf);
else
time_vme->day = (unsigned short) 0;
sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff);
if (isdigit(cbuf[0]) && isdigit(cbuf[1]))
time_vme->hr = (unsigned short)atoi(cbuf);
else
time_vme->hr = (unsigned short) 0;
sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8);
if (isdigit(cbuf[0]) && isdigit(cbuf[1]))
time_vme->mn = (unsigned short)atoi(cbuf);
else
time_vme->mn = (unsigned short) 0;
sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff);
if (isdigit(cbuf[0]) && isdigit(cbuf[1]))
time_vme->sec = (unsigned short)atoi(cbuf);
else
time_vme->sec = (unsigned short) 0;
sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ],
vts.btfp_time[ 4 ]>>8);
if (isdigit(cbuf[0]) && isdigit(cbuf[1]) && isdigit(cbuf[2])
&& isdigit(cbuf[3]) && isdigit(cbuf[4]) && isdigit(cbuf[5]))
time_vme->frac = (u_long) atoi(cbuf);
else
time_vme->frac = (u_long) 0;
#else
sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) +
((vts.btfp_time[ 1 ] & 0xff00) >> 8));
time_vme->day = (unsigned short)atoi(cbuf);
sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff);
time_vme->hr = (unsigned short)atoi(cbuf);
sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8);
time_vme->mn = (unsigned short)atoi(cbuf);
sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff);
time_vme->sec = (unsigned short)atoi(cbuf);
sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ],
vts.btfp_time[ 4 ]>>8);
time_vme->frac = (u_long) atoi(cbuf);
#endif
status = (vts.btfp_time[0] & 0x0010) >>4;
time_vme->status = status;
if (status) {
return ((void *)NULL);
}
else
return (time_vme);
}
#else
int refclock_bancomm_bs;
#endif