xref: /freebsd/contrib/ntp/libparse/clk_sel240x.c (revision f5f40dd63bc7acbb5312b26ac1ea1103c12352a6)
12b15cb3dSCy Schubert //////////////////////////////////////////////////////////////////////////////
22b15cb3dSCy Schubert // Copyright (c) 2009,2012 -
32b15cb3dSCy Schubert //        Schweitzer Engineering Laboratories, Inc. <opensource@selinc.com>
42b15cb3dSCy Schubert //////////////////////////////////////////////////////////////////////////////
52b15cb3dSCy Schubert 
62b15cb3dSCy Schubert // Need to have _XOPEN_SOURCE defined for time.h to give the
72b15cb3dSCy Schubert // correct strptime signature.  As per feature_test_macros(7),
82b15cb3dSCy Schubert // define this before including any header files.
92b15cb3dSCy Schubert 
102b15cb3dSCy Schubert // #ifndef _XOPEN_SOURCE
112b15cb3dSCy Schubert // #define _XOPEN_SOURCE
122b15cb3dSCy Schubert // #endif
132b15cb3dSCy Schubert 
142b15cb3dSCy Schubert #ifdef HAVE_CONFIG_H
152b15cb3dSCy Schubert # include <config.h>
162b15cb3dSCy Schubert #endif
172b15cb3dSCy Schubert 
182b15cb3dSCy Schubert #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SEL240X)
192b15cb3dSCy Schubert 
202b15cb3dSCy Schubert #include "ntp_syslog.h"
212b15cb3dSCy Schubert #include "ntp_types.h"
222b15cb3dSCy Schubert #include "ntp_fp.h"
232b15cb3dSCy Schubert #include "ntp_unixtime.h"
242b15cb3dSCy Schubert #include "ntp_calendar.h"
252b15cb3dSCy Schubert #include "ntp_machine.h"
262b15cb3dSCy Schubert #include "ntp_stdlib.h"
272b15cb3dSCy Schubert 
282b15cb3dSCy Schubert #include "parse.h"
292b15cb3dSCy Schubert 
302b15cb3dSCy Schubert #ifndef PARSESTREAM
312b15cb3dSCy Schubert # include <stdio.h>
322b15cb3dSCy Schubert #else
332b15cb3dSCy Schubert # include "sys/parsestreams.h"
342b15cb3dSCy Schubert #endif
352b15cb3dSCy Schubert 
362b15cb3dSCy Schubert #include <time.h>
372b15cb3dSCy Schubert 
382b15cb3dSCy Schubert //////////////////////////////////////////////////////////////////////////////
392b15cb3dSCy Schubert // The B8 output has the following format B8 = '\x01YYYY:ddd:hh:mm:ssq\r\n'
402b15cb3dSCy Schubert //    where q = ' ' locked
412b15cb3dSCy Schubert //              '.' <1 us
422b15cb3dSCy Schubert //              '*' <10 us
432b15cb3dSCy Schubert //              '#' <100 us
442b15cb3dSCy Schubert //              '?' >100 us
452b15cb3dSCy Schubert //
462b15cb3dSCy Schubert // Based on this we need to recored the stime when we receive the <SOH>
472b15cb3dSCy Schubert // character and end it when we see the \n.
482b15cb3dSCy Schubert //
492b15cb3dSCy Schubert // The q or quality character indicates satellite lock and sync.   For the
502b15cb3dSCy Schubert // purposes of NTP we are going to call it valid when we receive anything but
512b15cb3dSCy Schubert // a '?'.  But we are only going to call it synced when we receive a ' '
522b15cb3dSCy Schubert //////////////////////////////////////////////////////////////////////////////
532b15cb3dSCy Schubert 
54a25439b6SCy Schubert static parse_inp_fnc_t inp_sel240x;
55a25439b6SCy Schubert static parse_cvt_fnc_t cvt_sel240x;
562b15cb3dSCy Schubert 
572b15cb3dSCy Schubert // Parse clock format structure describing the message above
582b15cb3dSCy Schubert static struct format sel240x_fmt =
592b15cb3dSCy Schubert { { {  6, 3 },
602b15cb3dSCy Schubert     {  0, 0 },
612b15cb3dSCy Schubert     {  1, 4 },
622b15cb3dSCy Schubert     { 10, 2 },
632b15cb3dSCy Schubert     { 13, 2 },
642b15cb3dSCy Schubert     { 16, 2 },
652b15cb3dSCy Schubert     {  0, 0 },
662b15cb3dSCy Schubert     {  0, 0 },
672b15cb3dSCy Schubert     {  0, 0 },
682b15cb3dSCy Schubert     {  0, 0 },
692b15cb3dSCy Schubert     {  0, 0 },
702b15cb3dSCy Schubert     {  0, 0 }
712b15cb3dSCy Schubert   },
722b15cb3dSCy Schubert   (const unsigned char *)"\x01    :   :  :  :   \x0d\x0a",
732b15cb3dSCy Schubert   0
742b15cb3dSCy Schubert };
752b15cb3dSCy Schubert 
762b15cb3dSCy Schubert // Structure desctibing the parser
772b15cb3dSCy Schubert clockformat_t clock_sel240x =
782b15cb3dSCy Schubert {
792b15cb3dSCy Schubert 	inp_sel240x,
802b15cb3dSCy Schubert 	cvt_sel240x,
812b15cb3dSCy Schubert 	pps_one,
822b15cb3dSCy Schubert 	(void*)&sel240x_fmt,
832b15cb3dSCy Schubert 	"SEL B8",
842b15cb3dSCy Schubert 	25,
852b15cb3dSCy Schubert 	0
862b15cb3dSCy Schubert };
872b15cb3dSCy Schubert 
882b15cb3dSCy Schubert //////////////////////////////////////////////////////////////////////////////
892b15cb3dSCy Schubert static unsigned long
902b15cb3dSCy Schubert inp_sel240x( parse_t      *parseio,
91a25439b6SCy Schubert 	     char         ch,
922b15cb3dSCy Schubert 	     timestamp_t  *tstamp
932b15cb3dSCy Schubert 	   )
942b15cb3dSCy Schubert {
952b15cb3dSCy Schubert 	unsigned long rc;
962b15cb3dSCy Schubert 
972b15cb3dSCy Schubert 	parseprintf( DD_PARSE,
982b15cb3dSCy Schubert 	             ("inp_sel240x(0x%lx, 0x%x, ...)\n",(long)parseio, ch));
992b15cb3dSCy Schubert 
1002b15cb3dSCy Schubert 	switch( ch )
1012b15cb3dSCy Schubert 	{
1022b15cb3dSCy Schubert 	case '\x01':
1032b15cb3dSCy Schubert 		parseio->parse_index = 1;
1042b15cb3dSCy Schubert 		parseio->parse_data[0] = ch;
1052b15cb3dSCy Schubert 		parseio->parse_dtime.parse_stime = *tstamp;
1062b15cb3dSCy Schubert 		rc = PARSE_INP_SKIP;
1072b15cb3dSCy Schubert 		break;
1082b15cb3dSCy Schubert 	case '\n':
1092b15cb3dSCy Schubert 		if( (rc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP )
1102b15cb3dSCy Schubert 		{
1112b15cb3dSCy Schubert 			rc = parse_end( parseio );
1122b15cb3dSCy Schubert 		}
1132b15cb3dSCy Schubert 		break;
1142b15cb3dSCy Schubert 	default:
1152b15cb3dSCy Schubert 		rc = parse_addchar( parseio, ch );
1162b15cb3dSCy Schubert 	}
1172b15cb3dSCy Schubert 
1182b15cb3dSCy Schubert 	return rc;
1192b15cb3dSCy Schubert }
1202b15cb3dSCy Schubert 
1212b15cb3dSCy Schubert //////////////////////////////////////////////////////////////////////////////
1222b15cb3dSCy Schubert static unsigned long
1232b15cb3dSCy Schubert cvt_sel240x( unsigned char *buffer,
1242b15cb3dSCy Schubert 	     int            size,
1252b15cb3dSCy Schubert 	     struct format *format,
1262b15cb3dSCy Schubert 	     clocktime_t   *clock_time,
1272b15cb3dSCy Schubert 	     void          *local
1282b15cb3dSCy Schubert 	   )
1292b15cb3dSCy Schubert {
1302b15cb3dSCy Schubert 	unsigned long rc = CVT_NONE;
1312b15cb3dSCy Schubert 
1322b15cb3dSCy Schubert 	if( Strok(buffer, format->fixed_string) )
1332b15cb3dSCy Schubert 	{
1342b15cb3dSCy Schubert 		struct tm ptime;
1352b15cb3dSCy Schubert 		buffer++;
1362b15cb3dSCy Schubert 		buffer = (unsigned char *) strptime(
1372b15cb3dSCy Schubert 			(const char *)buffer, "%Y:%j:%H:%M:%S", &ptime );
1382b15cb3dSCy Schubert 		if( *(buffer+1) != '\x0d' )
1392b15cb3dSCy Schubert 		{
1402b15cb3dSCy Schubert 			rc = CVT_FAIL | CVT_BADFMT;
1412b15cb3dSCy Schubert 		}
1422b15cb3dSCy Schubert 		else
1432b15cb3dSCy Schubert 		{
1442b15cb3dSCy Schubert 			clock_time->day = ptime.tm_mday;
1452b15cb3dSCy Schubert 			clock_time->month = ptime.tm_mon + 1;
1462b15cb3dSCy Schubert 			clock_time->year = ptime.tm_year + 1900;
1472b15cb3dSCy Schubert 			clock_time->hour = ptime.tm_hour;
1482b15cb3dSCy Schubert 			clock_time->minute = ptime.tm_min;
1492b15cb3dSCy Schubert 			clock_time->second = ptime.tm_sec;
1502b15cb3dSCy Schubert 			clock_time->usecond = 0;
1512b15cb3dSCy Schubert 			clock_time->utcoffset = 0;
1522b15cb3dSCy Schubert 			clock_time->flags = PARSEB_UTC;
1532b15cb3dSCy Schubert 
1542b15cb3dSCy Schubert 			if( *buffer == '?' )
1552b15cb3dSCy Schubert 			{
1562b15cb3dSCy Schubert 				clock_time->flags |= PARSEB_POWERUP;
1572b15cb3dSCy Schubert 			}
1582b15cb3dSCy Schubert 			else if( *buffer != ' ' )
1592b15cb3dSCy Schubert 			{
1602b15cb3dSCy Schubert 				clock_time->flags |= PARSEB_NOSYNC;
1612b15cb3dSCy Schubert 			}
1622b15cb3dSCy Schubert 
1632b15cb3dSCy Schubert 			rc = CVT_OK;
1642b15cb3dSCy Schubert 		}
1652b15cb3dSCy Schubert 	}
1662b15cb3dSCy Schubert 
1672b15cb3dSCy Schubert 	return rc;
1682b15cb3dSCy Schubert }
1692b15cb3dSCy Schubert 
1702b15cb3dSCy Schubert #else  /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */
171*f5f40dd6SCy Schubert NONEMPTY_TRANSLATION_UNIT
1722b15cb3dSCy Schubert #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */
173