1c0b746e5SOllivier Robert /* 2ea906c41SOllivier Robert * /src/NTP/ntp4-dev/libparse/clk_hopf6021.c,v 4.10 2004/11/14 15:29:41 kardel RELEASE_20050508_A 3c0b746e5SOllivier Robert * 4ea906c41SOllivier Robert * clk_hopf6021.c,v 4.10 2004/11/14 15:29:41 kardel RELEASE_20050508_A 5c0b746e5SOllivier Robert * 6c0b746e5SOllivier Robert * Radiocode Clocks HOPF Funkuhr 6021 mit serieller Schnittstelle 7c0b746e5SOllivier Robert * base code version from 24th Nov 1995 - history at end 8c0b746e5SOllivier Robert * 9c0b746e5SOllivier Robert * Created by F.Schnekenbuehl <frank@comsys.dofn.de> from clk_rcc8000.c 10c0b746e5SOllivier Robert * Nortel DASA Network Systems GmbH, Department: ND250 11c0b746e5SOllivier Robert * A Joint venture of Daimler-Benz Aerospace and Nortel 12c0b746e5SOllivier Robert * 13c0b746e5SOllivier Robert * This program is distributed in the hope that it will be useful, 14c0b746e5SOllivier Robert * but WITHOUT ANY WARRANTY; without even the implied warranty of 15c0b746e5SOllivier Robert * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16c0b746e5SOllivier Robert * 17c0b746e5SOllivier Robert */ 18c0b746e5SOllivier Robert 19c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 20c0b746e5SOllivier Robert # include <config.h> 21c0b746e5SOllivier Robert #endif 22c0b746e5SOllivier Robert 23*f5f40dd6SCy Schubert #include "ntp_types.h" 2482aa1470SCy Schubert 25c0b746e5SOllivier Robert #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_HOPF6021) 26c0b746e5SOllivier Robert 27c0b746e5SOllivier Robert #include "ntp_fp.h" 28c0b746e5SOllivier Robert #include "ntp_unixtime.h" 29c0b746e5SOllivier Robert #include "ntp_calendar.h" 30c0b746e5SOllivier Robert 31c0b746e5SOllivier Robert #include "parse.h" 32c0b746e5SOllivier Robert 33c0b746e5SOllivier Robert #ifndef PARSESTREAM 34c0b746e5SOllivier Robert #include "ntp_stdlib.h" 35c0b746e5SOllivier Robert #include <stdio.h> 36c0b746e5SOllivier Robert #else 37c0b746e5SOllivier Robert #include "sys/parsestreams.h" 382b15cb3dSCy Schubert extern int printf (const char *, ...); 39c0b746e5SOllivier Robert #endif 40c0b746e5SOllivier Robert 41e6bfd18dSCy Schubert #include "ascii.h" 42e6bfd18dSCy Schubert 43c0b746e5SOllivier Robert /* 44c0b746e5SOllivier Robert * hopf Funkuhr 6021 45c0b746e5SOllivier Robert * used with 9600,8N1, 46c0b746e5SOllivier Robert * UTC ueber serielle Schnittstelle 47c0b746e5SOllivier Robert * Sekundenvorlauf ON 48c0b746e5SOllivier Robert * ETX zum Sekundenvorlauf ON 49c0b746e5SOllivier Robert * Datenstring 6021 50c0b746e5SOllivier Robert * Ausgabe Uhrzeit und Datum 51c0b746e5SOllivier Robert * Senden mit Steuerzeichen 52c0b746e5SOllivier Robert * Senden sekuendlich 53c0b746e5SOllivier Robert */ 54c0b746e5SOllivier Robert 55c0b746e5SOllivier Robert /* 56c0b746e5SOllivier Robert * Type 6021 Serial Output format 57c0b746e5SOllivier Robert * 58c0b746e5SOllivier Robert * 000000000011111111 / char 59c0b746e5SOllivier Robert * 012345678901234567 \ position 60c0b746e5SOllivier Robert * sABHHMMSSDDMMYYnre Actual 61c0b746e5SOllivier Robert * C4110046231195 Parse 62c0b746e5SOllivier Robert * s enr Check 63c0b746e5SOllivier Robert * 64c0b746e5SOllivier Robert * s = STX (0x02), e = ETX (0x03) 65c0b746e5SOllivier Robert * n = NL (0x0A), r = CR (0x0D) 66c0b746e5SOllivier Robert * 67c0b746e5SOllivier Robert * A B - Status and weekday 68c0b746e5SOllivier Robert * 69c0b746e5SOllivier Robert * A - Status 70c0b746e5SOllivier Robert * 71c0b746e5SOllivier Robert * 8 4 2 1 72c0b746e5SOllivier Robert * x x x 0 - no announcement 73c0b746e5SOllivier Robert * x x x 1 - Summertime - wintertime - summertime announcement 74c0b746e5SOllivier Robert * x x 0 x - Wintertime 75c0b746e5SOllivier Robert * x x 1 x - Summertime 76c0b746e5SOllivier Robert * 0 0 x x - Time/Date invalid 77c0b746e5SOllivier Robert * 0 1 x x - Internal clock used 78c0b746e5SOllivier Robert * 1 0 x x - Radio clock 79c0b746e5SOllivier Robert * 1 1 x x - Radio clock highprecision 80c0b746e5SOllivier Robert * 81c0b746e5SOllivier Robert * B - 8 4 2 1 82c0b746e5SOllivier Robert * 0 x x x - MESZ/MEZ 83c0b746e5SOllivier Robert * 1 x x x - UTC 84c0b746e5SOllivier Robert * x 0 0 1 - Monday 85c0b746e5SOllivier Robert * x 0 1 0 - Tuesday 86c0b746e5SOllivier Robert * x 0 1 1 - Wednesday 87c0b746e5SOllivier Robert * x 1 0 0 - Thursday 88c0b746e5SOllivier Robert * x 1 0 1 - Friday 89c0b746e5SOllivier Robert * x 1 1 0 - Saturday 90c0b746e5SOllivier Robert * x 1 1 1 - Sunday 91c0b746e5SOllivier Robert */ 92c0b746e5SOllivier Robert 93c0b746e5SOllivier Robert #define HOPF_DSTWARN 0x01 /* DST switch warning */ 94c0b746e5SOllivier Robert #define HOPF_DST 0x02 /* DST in effect */ 95c0b746e5SOllivier Robert 96c0b746e5SOllivier Robert #define HOPF_MODE 0x0C /* operation mode mask */ 97c0b746e5SOllivier Robert #define HOPF_INVALID 0x00 /* no time code available */ 98c0b746e5SOllivier Robert #define HOPF_INTERNAL 0x04 /* internal clock */ 99c0b746e5SOllivier Robert #define HOPF_RADIO 0x08 /* radio clock */ 100c0b746e5SOllivier Robert #define HOPF_RADIOHP 0x0C /* high precision radio clock */ 101c0b746e5SOllivier Robert 102c0b746e5SOllivier Robert #define HOPF_UTC 0x08 /* time code in UTC */ 103c0b746e5SOllivier Robert #define HOPF_WMASK 0x07 /* mask for weekday code */ 104c0b746e5SOllivier Robert 105c0b746e5SOllivier Robert static struct format hopf6021_fmt = 106c0b746e5SOllivier Robert { 107c0b746e5SOllivier Robert { 108c0b746e5SOllivier Robert { 9, 2 }, {11, 2}, { 13, 2}, /* Day, Month, Year */ 109c0b746e5SOllivier Robert { 3, 2 }, { 5, 2}, { 7, 2}, /* Hour, Minute, Second */ 110c0b746e5SOllivier Robert { 2, 1 }, { 1, 1}, { 0, 0}, /* Weekday, Flags, Zone */ 111c0b746e5SOllivier Robert /* ... */ 112c0b746e5SOllivier Robert }, 113c0b746e5SOllivier Robert (const unsigned char *)"\002 \n\r\003", 114c0b746e5SOllivier Robert 0 115c0b746e5SOllivier Robert }; 116c0b746e5SOllivier Robert 117c0b746e5SOllivier Robert #define OFFS(x) format->field_offsets[(x)].offset 118c0b746e5SOllivier Robert #define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length) 119c0b746e5SOllivier Robert 120a25439b6SCy Schubert static parse_cvt_fnc_t cvt_hopf6021; 121a25439b6SCy Schubert static parse_inp_fnc_t inp_hopf6021; 122f391d6bcSXin LI static unsigned char hexval(unsigned char); 123c0b746e5SOllivier Robert 124c0b746e5SOllivier Robert clockformat_t clock_hopf6021 = 125c0b746e5SOllivier Robert { 126c0b746e5SOllivier Robert inp_hopf6021, /* HOPF 6021 input handling */ 127c0b746e5SOllivier Robert cvt_hopf6021, /* Radiocode clock conversion */ 128c0b746e5SOllivier Robert 0, /* no direct PPS monitoring */ 129c0b746e5SOllivier Robert (void *)&hopf6021_fmt, /* conversion configuration */ 130c0b746e5SOllivier Robert "hopf Funkuhr 6021", /* clock format name */ 131c0b746e5SOllivier Robert 19, /* string buffer */ 132c0b746e5SOllivier Robert 0 /* private data length, no private data */ 133c0b746e5SOllivier Robert }; 134c0b746e5SOllivier Robert 135a25439b6SCy Schubert /* parse_cvt_fnc_t cvt_hopf6021 */ 136a25439b6SCy Schubert static u_long 137c0b746e5SOllivier Robert cvt_hopf6021( 138c0b746e5SOllivier Robert unsigned char *buffer, 139c0b746e5SOllivier Robert int size, 140c0b746e5SOllivier Robert struct format *format, 141c0b746e5SOllivier Robert clocktime_t *clock_time, 142c0b746e5SOllivier Robert void *local 143c0b746e5SOllivier Robert ) 144c0b746e5SOllivier Robert { 145c0b746e5SOllivier Robert unsigned char status,weekday; 146c0b746e5SOllivier Robert 147c0b746e5SOllivier Robert if (!Strok(buffer, format->fixed_string)) 148c0b746e5SOllivier Robert { 149c0b746e5SOllivier Robert return CVT_NONE; 150c0b746e5SOllivier Robert } 151c0b746e5SOllivier Robert 152c0b746e5SOllivier Robert if ( STOI(O_DAY, &clock_time->day) || 153c0b746e5SOllivier Robert STOI(O_MONTH, &clock_time->month) || 154c0b746e5SOllivier Robert STOI(O_YEAR, &clock_time->year) || 155c0b746e5SOllivier Robert STOI(O_HOUR, &clock_time->hour) || 156c0b746e5SOllivier Robert STOI(O_MIN, &clock_time->minute) || 157c0b746e5SOllivier Robert STOI(O_SEC, &clock_time->second) 158c0b746e5SOllivier Robert ) 159c0b746e5SOllivier Robert { 160c0b746e5SOllivier Robert return CVT_FAIL|CVT_BADFMT; 161c0b746e5SOllivier Robert } 162c0b746e5SOllivier Robert 163c0b746e5SOllivier Robert clock_time->usecond = 0; 164f391d6bcSXin LI clock_time->flags = 0; 165c0b746e5SOllivier Robert 166f391d6bcSXin LI status = hexval(buffer[OFFS(O_FLAGS)]); 167f391d6bcSXin LI weekday = hexval(buffer[OFFS(O_WDAY)]); 168c0b746e5SOllivier Robert 169c0b746e5SOllivier Robert if ((status == 0xFF) || (weekday == 0xFF)) 170c0b746e5SOllivier Robert { 171c0b746e5SOllivier Robert return CVT_FAIL|CVT_BADFMT; 172c0b746e5SOllivier Robert } 173c0b746e5SOllivier Robert 174c0b746e5SOllivier Robert if (weekday & HOPF_UTC) 175c0b746e5SOllivier Robert { 176c0b746e5SOllivier Robert clock_time->flags |= PARSEB_UTC; 177f391d6bcSXin LI clock_time->utcoffset = 0; 178c0b746e5SOllivier Robert } 179f391d6bcSXin LI else if (status & HOPF_DST) 180c0b746e5SOllivier Robert { 181c0b746e5SOllivier Robert clock_time->flags |= PARSEB_DST; 182c0b746e5SOllivier Robert clock_time->utcoffset = -2*60*60; /* MET DST */ 183c0b746e5SOllivier Robert } 184c0b746e5SOllivier Robert else 185c0b746e5SOllivier Robert { 186c0b746e5SOllivier Robert clock_time->utcoffset = -1*60*60; /* MET */ 187c0b746e5SOllivier Robert } 188c0b746e5SOllivier Robert 189f391d6bcSXin LI if (status & HOPF_DSTWARN) 190f391d6bcSXin LI { 191f391d6bcSXin LI clock_time->flags |= PARSEB_ANNOUNCE; 192f391d6bcSXin LI } 193c0b746e5SOllivier Robert 194c0b746e5SOllivier Robert switch (status & HOPF_MODE) 195c0b746e5SOllivier Robert { 196f391d6bcSXin LI default: /* dummy: we cover all 4 cases. */ 197c0b746e5SOllivier Robert case HOPF_INVALID: /* Time/Date invalid */ 198c0b746e5SOllivier Robert clock_time->flags |= PARSEB_POWERUP; 199c0b746e5SOllivier Robert break; 200c0b746e5SOllivier Robert 201c0b746e5SOllivier Robert case HOPF_INTERNAL: /* internal clock */ 202c0b746e5SOllivier Robert clock_time->flags |= PARSEB_NOSYNC; 203c0b746e5SOllivier Robert break; 204c0b746e5SOllivier Robert 205c0b746e5SOllivier Robert case HOPF_RADIO: /* Radio clock */ 206c0b746e5SOllivier Robert case HOPF_RADIOHP: /* Radio clock high precision */ 207c0b746e5SOllivier Robert break; 208c0b746e5SOllivier Robert } 209c0b746e5SOllivier Robert 210c0b746e5SOllivier Robert return CVT_OK; 211c0b746e5SOllivier Robert } 212c0b746e5SOllivier Robert 213c0b746e5SOllivier Robert /* 214a25439b6SCy Schubert * parse_inp_fnc_t inp_hopf6021 215c0b746e5SOllivier Robert * 216a25439b6SCy Schubert * grab data from input stream 217c0b746e5SOllivier Robert */ 218c0b746e5SOllivier Robert static u_long 219c0b746e5SOllivier Robert inp_hopf6021( 220c0b746e5SOllivier Robert parse_t *parseio, 221a25439b6SCy Schubert char ch, 222c0b746e5SOllivier Robert timestamp_t *tstamp 223c0b746e5SOllivier Robert ) 224c0b746e5SOllivier Robert { 225c0b746e5SOllivier Robert unsigned int rtc; 226c0b746e5SOllivier Robert 2273311ff84SXin LI parseprintf(DD_PARSE, ("inp_hopf6021(0x%p, 0x%x, ...)\n", (void*)parseio, ch)); 228c0b746e5SOllivier Robert 229c0b746e5SOllivier Robert switch (ch) 230c0b746e5SOllivier Robert { 231c0b746e5SOllivier Robert case ETX: 232c0b746e5SOllivier Robert parseprintf(DD_PARSE, ("inp_hopf6021: EOL seen\n")); 233c0b746e5SOllivier Robert parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */ 234c0b746e5SOllivier Robert if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) 235c0b746e5SOllivier Robert return parse_end(parseio); 236c0b746e5SOllivier Robert else 237c0b746e5SOllivier Robert return rtc; 238c0b746e5SOllivier Robert 239c0b746e5SOllivier Robert default: 240c0b746e5SOllivier Robert return parse_addchar(parseio, ch); 241c0b746e5SOllivier Robert } 242c0b746e5SOllivier Robert } 243c0b746e5SOllivier Robert 244f391d6bcSXin LI /* 245f391d6bcSXin LI * convert a hex-digit to numeric value 246f391d6bcSXin LI */ 247f391d6bcSXin LI static unsigned char 248f391d6bcSXin LI hexval( 249f391d6bcSXin LI unsigned char ch 250f391d6bcSXin LI ) 251f391d6bcSXin LI { 252f391d6bcSXin LI unsigned int dv; 253f391d6bcSXin LI 254f391d6bcSXin LI if ((dv = ch - '0') >= 10u) 255f391d6bcSXin LI { 256f391d6bcSXin LI if ((dv -= 'A'-'0') < 6u || (dv -= 'a'-'A') < 6u) 257f391d6bcSXin LI { 258f391d6bcSXin LI dv += 10; 259f391d6bcSXin LI } 260f391d6bcSXin LI else 261f391d6bcSXin LI { 262f391d6bcSXin LI dv = 0xFF; 263f391d6bcSXin LI } 264f391d6bcSXin LI } 265f391d6bcSXin LI return (unsigned char)dv; 266f391d6bcSXin LI } 267f391d6bcSXin LI 268c0b746e5SOllivier Robert #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_HOPF6021) */ 269e6bfd18dSCy Schubert NONEMPTY_TRANSLATION_UNIT 270c0b746e5SOllivier Robert #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_HOPF6021) */ 271c0b746e5SOllivier Robert 272c0b746e5SOllivier Robert /* 273c0b746e5SOllivier Robert * History: 274c0b746e5SOllivier Robert * 275c0b746e5SOllivier Robert * clk_hopf6021.c,v 276ea906c41SOllivier Robert * Revision 4.10 2004/11/14 15:29:41 kardel 277ea906c41SOllivier Robert * support PPSAPI, upgrade Copyright to Berkeley style 278ea906c41SOllivier Robert * 279a151a66cSOllivier Robert * Revision 4.7 1999/11/28 09:13:49 kardel 280a151a66cSOllivier Robert * RECON_4_0_98F 281a151a66cSOllivier Robert * 282c0b746e5SOllivier Robert * Revision 4.6 1998/11/15 20:27:57 kardel 283c0b746e5SOllivier Robert * Release 4.0.73e13 reconcilation 284c0b746e5SOllivier Robert * 285c0b746e5SOllivier Robert * Revision 4.5 1998/06/14 21:09:35 kardel 286c0b746e5SOllivier Robert * Sun acc cleanup 287c0b746e5SOllivier Robert * 288c0b746e5SOllivier Robert * Revision 4.4 1998/06/13 12:02:38 kardel 289c0b746e5SOllivier Robert * fix SYSV clock name clash 290c0b746e5SOllivier Robert * 291c0b746e5SOllivier Robert * Revision 4.3 1998/06/12 15:22:27 kardel 292c0b746e5SOllivier Robert * fix prototypes 293c0b746e5SOllivier Robert * 294c0b746e5SOllivier Robert * Revision 4.2 1998/06/12 09:13:25 kardel 295c0b746e5SOllivier Robert * conditional compile macros fixed 296c0b746e5SOllivier Robert * printf prototype 297c0b746e5SOllivier Robert * 298c0b746e5SOllivier Robert * Revision 4.1 1998/05/24 09:39:52 kardel 299c0b746e5SOllivier Robert * implementation of the new IO handling model 300c0b746e5SOllivier Robert * 301c0b746e5SOllivier Robert * Revision 4.0 1998/04/10 19:45:29 kardel 302c0b746e5SOllivier Robert * Start 4.0 release version numbering 303c0b746e5SOllivier Robert * 304c0b746e5SOllivier Robert * from V3 3.6 log info deleted 1998/04/11 kardel 305c0b746e5SOllivier Robert */ 306