clk_sel240x.c revision 275970
193836Stmm////////////////////////////////////////////////////////////////////////////// 293836Stmm// Copyright (c) 2009,2012 - 393836Stmm// Schweitzer Engineering Laboratories, Inc. <opensource@selinc.com> 493836Stmm////////////////////////////////////////////////////////////////////////////// 593836Stmm 693836Stmm// Need to have _XOPEN_SOURCE defined for time.h to give the 793836Stmm// correct strptime signature. As per feature_test_macros(7), 893836Stmm// define this before including any header files. 993836Stmm 1093836Stmm// #ifndef _XOPEN_SOURCE 1193836Stmm// #define _XOPEN_SOURCE 1293836Stmm// #endif 1393836Stmm 1493836Stmm#ifdef HAVE_CONFIG_H 1593836Stmm# include <config.h> 1693836Stmm#endif 1793836Stmm 1893836Stmm#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SEL240X) 1993836Stmm 2093836Stmm#include "ntp_syslog.h" 2193836Stmm#include "ntp_types.h" 2293836Stmm#include "ntp_fp.h" 2393836Stmm#include "ntp_unixtime.h" 2493836Stmm#include "ntp_calendar.h" 2593836Stmm#include "ntp_machine.h" 2693836Stmm#include "ntp_stdlib.h" 2793836Stmm 2893836Stmm#include "parse.h" 2993836Stmm 3093836Stmm#ifndef PARSESTREAM 3193836Stmm# include <stdio.h> 3293836Stmm#else 3393836Stmm# include "sys/parsestreams.h" 3493836Stmm#endif 3593836Stmm 36137813Smarius#include <time.h> 3793836Stmm 3893836Stmm////////////////////////////////////////////////////////////////////////////// 39119418Sobrien// The B8 output has the following format B8 = '\x01YYYY:ddd:hh:mm:ssq\r\n' 40119418Sobrien// where q = ' ' locked 41119418Sobrien// '.' <1 us 4293836Stmm// '*' <10 us 43137813Smarius// '#' <100 us 4493836Stmm// '?' >100 us 4593836Stmm// 4693836Stmm// Based on this we need to recored the stime when we receive the <SOH> 4793836Stmm// character and end it when we see the \n. 4893836Stmm// 4993836Stmm// The q or quality character indicates satellite lock and sync. For the 50146416Smarius// purposes of NTP we are going to call it valid when we receive anything but 51146416Smarius// a '?'. But we are only going to call it synced when we receive a ' ' 52146416Smarius////////////////////////////////////////////////////////////////////////////// 53146416Smarius 5493836Stmmstatic unsigned long inp_sel240x( parse_t *parseio, 5593836Stmm unsigned int ch, 5693836Stmm timestamp_t *tstamp); 57119352Smarcelstatic unsigned long cvt_sel240x( unsigned char *buffer, 58137813Smarius int size, 5993836Stmm struct format *format, 6093836Stmm clocktime_t *clock_time, 6193836Stmm void *local ); 62137813Smarius 63146416Smarius// Parse clock format structure describing the message above 64146416Smariusstatic struct format sel240x_fmt = 6593836Stmm{ { { 6, 3 }, 6693836Stmm { 0, 0 }, 6793836Stmm { 1, 4 }, 6893836Stmm { 10, 2 }, 6993836Stmm { 13, 2 }, 7093836Stmm { 16, 2 }, 7193836Stmm { 0, 0 }, 7293836Stmm { 0, 0 }, 7393836Stmm { 0, 0 }, 7493836Stmm { 0, 0 }, 75137813Smarius { 0, 0 }, 7693836Stmm { 0, 0 } 7793836Stmm }, 7893836Stmm (const unsigned char *)"\x01 : : : : \x0d\x0a", 7993836Stmm 0 80137813Smarius}; 8193836Stmm 8293836Stmm// Structure desctibing the parser 8393836Stmmclockformat_t clock_sel240x = 84146416Smarius{ 8593836Stmm inp_sel240x, 86137813Smarius cvt_sel240x, 87137813Smarius pps_one, 88146416Smarius (void*)&sel240x_fmt, 89146416Smarius "SEL B8", 90146416Smarius 25, 91146416Smarius 0 92146416Smarius}; 93137813Smarius 9493836Stmm////////////////////////////////////////////////////////////////////////////// 9593836Stmmstatic unsigned long 96137813Smariusinp_sel240x( parse_t *parseio, 9793836Stmm unsigned int ch, 9893836Stmm timestamp_t *tstamp 9993836Stmm ) 10093836Stmm{ 10193836Stmm unsigned long rc; 10293836Stmm 10393836Stmm parseprintf( DD_PARSE, 10493836Stmm ("inp_sel240x(0x%lx, 0x%x, ...)\n",(long)parseio, ch)); 105137813Smarius 106137813Smarius switch( ch ) 10793836Stmm { 108137813Smarius case '\x01': 109137813Smarius parseio->parse_index = 1; 110137813Smarius parseio->parse_data[0] = ch; 111137813Smarius parseio->parse_dtime.parse_stime = *tstamp; 112137813Smarius rc = PARSE_INP_SKIP; 113146416Smarius break; 114146416Smarius case '\n': 115146416Smarius if( (rc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP ) 116146416Smarius { 117146416Smarius rc = parse_end( parseio ); 118146416Smarius } 119146416Smarius break; 120146416Smarius default: 121146416Smarius rc = parse_addchar( parseio, ch ); 122135481Smarius } 123135481Smarius 124146416Smarius return rc; 125146416Smarius} 126146416Smarius 127146416Smarius////////////////////////////////////////////////////////////////////////////// 128146416Smariusstatic unsigned long 129146416Smariuscvt_sel240x( unsigned char *buffer, 130146416Smarius int size, 131146416Smarius struct format *format, 132146416Smarius clocktime_t *clock_time, 133146416Smarius void *local 134146416Smarius ) 135146416Smarius{ 136146416Smarius unsigned long rc = CVT_NONE; 137146416Smarius 138146416Smarius if( Strok(buffer, format->fixed_string) ) 139146416Smarius { 140146416Smarius struct tm ptime; 141146416Smarius buffer++; 142146416Smarius buffer = (unsigned char *) strptime( 14393836Stmm (const char *)buffer, "%Y:%j:%H:%M:%S", &ptime ); 14493836Stmm if( *(buffer+1) != '\x0d' ) 145146416Smarius { 146146416Smarius rc = CVT_FAIL | CVT_BADFMT; 147146416Smarius } 148146416Smarius else 149146416Smarius { 150161837Smarius clock_time->day = ptime.tm_mday; 151146416Smarius clock_time->month = ptime.tm_mon + 1; 152146416Smarius clock_time->year = ptime.tm_year + 1900; 15393836Stmm clock_time->hour = ptime.tm_hour; 15493836Stmm clock_time->minute = ptime.tm_min; 15593836Stmm clock_time->second = ptime.tm_sec; 15693836Stmm clock_time->usecond = 0; 15793836Stmm clock_time->utcoffset = 0; 15893836Stmm clock_time->flags = PARSEB_UTC; 15993836Stmm 16093836Stmm if( *buffer == '?' ) 16193836Stmm { 16293836Stmm clock_time->flags |= PARSEB_POWERUP; 163137813Smarius } 164137813Smarius else if( *buffer != ' ' ) 16593836Stmm { 16693836Stmm clock_time->flags |= PARSEB_NOSYNC; 167146416Smarius } 16893836Stmm 169137813Smarius rc = CVT_OK; 170137813Smarius } 171137813Smarius } 172146416Smarius 17393836Stmm return rc; 174137813Smarius} 17593836Stmm 176137813Smarius#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */ 17793836Stmmint clk_sel240x_bs; 178137813Smarius#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */ 179135481Smarius