#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_HOPF6021)
#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include "ntp_fp.h"
#include "ntp_unixtime.h"
#include "ntp_calendar.h"
#include "ascii.h"
#include "parse.h"
#ifndef PARSESTREAM
#include "ntp_stdlib.h"
#include <stdio.h>
#else
#include "sys/parsestreams.h"
extern void printf P((const char *, ...));
#endif
#define HOPF_DSTWARN 0x01
#define HOPF_DST 0x02
#define HOPF_MODE 0x0C
#define HOPF_INVALID 0x00
#define HOPF_INTERNAL 0x04
#define HOPF_RADIO 0x08
#define HOPF_RADIOHP 0x0C
#define HOPF_UTC 0x08
#define HOPF_WMASK 0x07
static struct format hopf6021_fmt =
{
{
{ 9, 2 }, {11, 2}, { 13, 2},
{ 3, 2 }, { 5, 2}, { 7, 2},
{ 2, 1 }, { 1, 1}, { 0, 0},
},
(const unsigned char *)"\002 \n\r\003",
0
};
#define OFFS(x) format->field_offsets[(x)].offset
#define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length)
#define hexval(x) (('0' <= (x) && (x) <= '9') ? (x) - '0' : \
('a' <= (x) && (x) <= 'f') ? (x) - 'a' + 10 : \
('A' <= (x) && (x) <= 'F') ? (x) - 'A' + 10 : \
-1)
static unsigned long cvt_hopf6021 P((unsigned char *, int, struct format *, clocktime_t *, void *));
static unsigned long inp_hopf6021 P((parse_t *, unsigned int, timestamp_t *));
clockformat_t clock_hopf6021 =
{
inp_hopf6021,
cvt_hopf6021,
0,
(void *)&hopf6021_fmt,
"hopf Funkuhr 6021",
19,
0
};
static unsigned long
cvt_hopf6021(
unsigned char *buffer,
int size,
struct format *format,
clocktime_t *clock_time,
void *local
)
{
unsigned char status,weekday;
if (!Strok(buffer, format->fixed_string))
{
return CVT_NONE;
}
if ( STOI(O_DAY, &clock_time->day) ||
STOI(O_MONTH, &clock_time->month) ||
STOI(O_YEAR, &clock_time->year) ||
STOI(O_HOUR, &clock_time->hour) ||
STOI(O_MIN, &clock_time->minute) ||
STOI(O_SEC, &clock_time->second)
)
{
return CVT_FAIL|CVT_BADFMT;
}
clock_time->usecond = 0;
clock_time->utcoffset = 0;
status = hexval(buffer[OFFS(O_FLAGS)]);
weekday= hexval(buffer[OFFS(O_WDAY)]);
if ((status == 0xFF) || (weekday == 0xFF))
{
return CVT_FAIL|CVT_BADFMT;
}
clock_time->flags = 0;
if (weekday & HOPF_UTC)
{
clock_time->flags |= PARSEB_UTC;
}
else
{
if (status & HOPF_DST)
{
clock_time->flags |= PARSEB_DST;
clock_time->utcoffset = -2*60*60;
}
else
{
clock_time->utcoffset = -1*60*60;
}
}
clock_time->flags |= (status & HOPF_DSTWARN) ? PARSEB_ANNOUNCE : 0;
switch (status & HOPF_MODE)
{
case HOPF_INVALID:
clock_time->flags |= PARSEB_POWERUP;
break;
case HOPF_INTERNAL:
clock_time->flags |= PARSEB_NOSYNC;
break;
case HOPF_RADIO:
case HOPF_RADIOHP:
break;
default:
return CVT_FAIL|CVT_BADFMT;
}
return CVT_OK;
}
static u_long
inp_hopf6021(
parse_t *parseio,
unsigned int ch,
timestamp_t *tstamp
)
{
unsigned int rtc;
parseprintf(DD_PARSE, ("inp_hopf6021(0x%x, 0x%x, ...)\n", (int)parseio, (int)ch));
switch (ch)
{
case ETX:
parseprintf(DD_PARSE, ("inp_hopf6021: EOL seen\n"));
parseio->parse_dtime.parse_stime = *tstamp;
if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
return parse_end(parseio);
else
return rtc;
default:
return parse_addchar(parseio, ch);
}
}
#else
int clk_hopf6021_bs;
#endif