1*2b15cb3dSCy Schubert ////////////////////////////////////////////////////////////////////////////// 2*2b15cb3dSCy Schubert // Copyright (c) 2009,2012 - 3*2b15cb3dSCy Schubert // Schweitzer Engineering Laboratories, Inc. <opensource@selinc.com> 4*2b15cb3dSCy Schubert ////////////////////////////////////////////////////////////////////////////// 5*2b15cb3dSCy Schubert 6*2b15cb3dSCy Schubert // Need to have _XOPEN_SOURCE defined for time.h to give the 7*2b15cb3dSCy Schubert // correct strptime signature. As per feature_test_macros(7), 8*2b15cb3dSCy Schubert // define this before including any header files. 9*2b15cb3dSCy Schubert 10*2b15cb3dSCy Schubert // #ifndef _XOPEN_SOURCE 11*2b15cb3dSCy Schubert // #define _XOPEN_SOURCE 12*2b15cb3dSCy Schubert // #endif 13*2b15cb3dSCy Schubert 14*2b15cb3dSCy Schubert #ifdef HAVE_CONFIG_H 15*2b15cb3dSCy Schubert # include <config.h> 16*2b15cb3dSCy Schubert #endif 17*2b15cb3dSCy Schubert 18*2b15cb3dSCy Schubert #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SEL240X) 19*2b15cb3dSCy Schubert 20*2b15cb3dSCy Schubert #include "ntp_syslog.h" 21*2b15cb3dSCy Schubert #include "ntp_types.h" 22*2b15cb3dSCy Schubert #include "ntp_fp.h" 23*2b15cb3dSCy Schubert #include "ntp_unixtime.h" 24*2b15cb3dSCy Schubert #include "ntp_calendar.h" 25*2b15cb3dSCy Schubert #include "ntp_machine.h" 26*2b15cb3dSCy Schubert #include "ntp_stdlib.h" 27*2b15cb3dSCy Schubert 28*2b15cb3dSCy Schubert #include "parse.h" 29*2b15cb3dSCy Schubert 30*2b15cb3dSCy Schubert #ifndef PARSESTREAM 31*2b15cb3dSCy Schubert # include <stdio.h> 32*2b15cb3dSCy Schubert #else 33*2b15cb3dSCy Schubert # include "sys/parsestreams.h" 34*2b15cb3dSCy Schubert #endif 35*2b15cb3dSCy Schubert 36*2b15cb3dSCy Schubert #include <time.h> 37*2b15cb3dSCy Schubert 38*2b15cb3dSCy Schubert ////////////////////////////////////////////////////////////////////////////// 39*2b15cb3dSCy Schubert // The B8 output has the following format B8 = '\x01YYYY:ddd:hh:mm:ssq\r\n' 40*2b15cb3dSCy Schubert // where q = ' ' locked 41*2b15cb3dSCy Schubert // '.' <1 us 42*2b15cb3dSCy Schubert // '*' <10 us 43*2b15cb3dSCy Schubert // '#' <100 us 44*2b15cb3dSCy Schubert // '?' >100 us 45*2b15cb3dSCy Schubert // 46*2b15cb3dSCy Schubert // Based on this we need to recored the stime when we receive the <SOH> 47*2b15cb3dSCy Schubert // character and end it when we see the \n. 48*2b15cb3dSCy Schubert // 49*2b15cb3dSCy Schubert // The q or quality character indicates satellite lock and sync. For the 50*2b15cb3dSCy Schubert // purposes of NTP we are going to call it valid when we receive anything but 51*2b15cb3dSCy Schubert // a '?'. But we are only going to call it synced when we receive a ' ' 52*2b15cb3dSCy Schubert ////////////////////////////////////////////////////////////////////////////// 53*2b15cb3dSCy Schubert 54*2b15cb3dSCy Schubert static unsigned long inp_sel240x( parse_t *parseio, 55*2b15cb3dSCy Schubert unsigned int ch, 56*2b15cb3dSCy Schubert timestamp_t *tstamp); 57*2b15cb3dSCy Schubert static unsigned long cvt_sel240x( unsigned char *buffer, 58*2b15cb3dSCy Schubert int size, 59*2b15cb3dSCy Schubert struct format *format, 60*2b15cb3dSCy Schubert clocktime_t *clock_time, 61*2b15cb3dSCy Schubert void *local ); 62*2b15cb3dSCy Schubert 63*2b15cb3dSCy Schubert // Parse clock format structure describing the message above 64*2b15cb3dSCy Schubert static struct format sel240x_fmt = 65*2b15cb3dSCy Schubert { { { 6, 3 }, 66*2b15cb3dSCy Schubert { 0, 0 }, 67*2b15cb3dSCy Schubert { 1, 4 }, 68*2b15cb3dSCy Schubert { 10, 2 }, 69*2b15cb3dSCy Schubert { 13, 2 }, 70*2b15cb3dSCy Schubert { 16, 2 }, 71*2b15cb3dSCy Schubert { 0, 0 }, 72*2b15cb3dSCy Schubert { 0, 0 }, 73*2b15cb3dSCy Schubert { 0, 0 }, 74*2b15cb3dSCy Schubert { 0, 0 }, 75*2b15cb3dSCy Schubert { 0, 0 }, 76*2b15cb3dSCy Schubert { 0, 0 } 77*2b15cb3dSCy Schubert }, 78*2b15cb3dSCy Schubert (const unsigned char *)"\x01 : : : : \x0d\x0a", 79*2b15cb3dSCy Schubert 0 80*2b15cb3dSCy Schubert }; 81*2b15cb3dSCy Schubert 82*2b15cb3dSCy Schubert // Structure desctibing the parser 83*2b15cb3dSCy Schubert clockformat_t clock_sel240x = 84*2b15cb3dSCy Schubert { 85*2b15cb3dSCy Schubert inp_sel240x, 86*2b15cb3dSCy Schubert cvt_sel240x, 87*2b15cb3dSCy Schubert pps_one, 88*2b15cb3dSCy Schubert (void*)&sel240x_fmt, 89*2b15cb3dSCy Schubert "SEL B8", 90*2b15cb3dSCy Schubert 25, 91*2b15cb3dSCy Schubert 0 92*2b15cb3dSCy Schubert }; 93*2b15cb3dSCy Schubert 94*2b15cb3dSCy Schubert ////////////////////////////////////////////////////////////////////////////// 95*2b15cb3dSCy Schubert static unsigned long 96*2b15cb3dSCy Schubert inp_sel240x( parse_t *parseio, 97*2b15cb3dSCy Schubert unsigned int ch, 98*2b15cb3dSCy Schubert timestamp_t *tstamp 99*2b15cb3dSCy Schubert ) 100*2b15cb3dSCy Schubert { 101*2b15cb3dSCy Schubert unsigned long rc; 102*2b15cb3dSCy Schubert 103*2b15cb3dSCy Schubert parseprintf( DD_PARSE, 104*2b15cb3dSCy Schubert ("inp_sel240x(0x%lx, 0x%x, ...)\n",(long)parseio, ch)); 105*2b15cb3dSCy Schubert 106*2b15cb3dSCy Schubert switch( ch ) 107*2b15cb3dSCy Schubert { 108*2b15cb3dSCy Schubert case '\x01': 109*2b15cb3dSCy Schubert parseio->parse_index = 1; 110*2b15cb3dSCy Schubert parseio->parse_data[0] = ch; 111*2b15cb3dSCy Schubert parseio->parse_dtime.parse_stime = *tstamp; 112*2b15cb3dSCy Schubert rc = PARSE_INP_SKIP; 113*2b15cb3dSCy Schubert break; 114*2b15cb3dSCy Schubert case '\n': 115*2b15cb3dSCy Schubert if( (rc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP ) 116*2b15cb3dSCy Schubert { 117*2b15cb3dSCy Schubert rc = parse_end( parseio ); 118*2b15cb3dSCy Schubert } 119*2b15cb3dSCy Schubert break; 120*2b15cb3dSCy Schubert default: 121*2b15cb3dSCy Schubert rc = parse_addchar( parseio, ch ); 122*2b15cb3dSCy Schubert } 123*2b15cb3dSCy Schubert 124*2b15cb3dSCy Schubert return rc; 125*2b15cb3dSCy Schubert } 126*2b15cb3dSCy Schubert 127*2b15cb3dSCy Schubert ////////////////////////////////////////////////////////////////////////////// 128*2b15cb3dSCy Schubert static unsigned long 129*2b15cb3dSCy Schubert cvt_sel240x( unsigned char *buffer, 130*2b15cb3dSCy Schubert int size, 131*2b15cb3dSCy Schubert struct format *format, 132*2b15cb3dSCy Schubert clocktime_t *clock_time, 133*2b15cb3dSCy Schubert void *local 134*2b15cb3dSCy Schubert ) 135*2b15cb3dSCy Schubert { 136*2b15cb3dSCy Schubert unsigned long rc = CVT_NONE; 137*2b15cb3dSCy Schubert 138*2b15cb3dSCy Schubert if( Strok(buffer, format->fixed_string) ) 139*2b15cb3dSCy Schubert { 140*2b15cb3dSCy Schubert struct tm ptime; 141*2b15cb3dSCy Schubert buffer++; 142*2b15cb3dSCy Schubert buffer = (unsigned char *) strptime( 143*2b15cb3dSCy Schubert (const char *)buffer, "%Y:%j:%H:%M:%S", &ptime ); 144*2b15cb3dSCy Schubert if( *(buffer+1) != '\x0d' ) 145*2b15cb3dSCy Schubert { 146*2b15cb3dSCy Schubert rc = CVT_FAIL | CVT_BADFMT; 147*2b15cb3dSCy Schubert } 148*2b15cb3dSCy Schubert else 149*2b15cb3dSCy Schubert { 150*2b15cb3dSCy Schubert clock_time->day = ptime.tm_mday; 151*2b15cb3dSCy Schubert clock_time->month = ptime.tm_mon + 1; 152*2b15cb3dSCy Schubert clock_time->year = ptime.tm_year + 1900; 153*2b15cb3dSCy Schubert clock_time->hour = ptime.tm_hour; 154*2b15cb3dSCy Schubert clock_time->minute = ptime.tm_min; 155*2b15cb3dSCy Schubert clock_time->second = ptime.tm_sec; 156*2b15cb3dSCy Schubert clock_time->usecond = 0; 157*2b15cb3dSCy Schubert clock_time->utcoffset = 0; 158*2b15cb3dSCy Schubert clock_time->flags = PARSEB_UTC; 159*2b15cb3dSCy Schubert 160*2b15cb3dSCy Schubert if( *buffer == '?' ) 161*2b15cb3dSCy Schubert { 162*2b15cb3dSCy Schubert clock_time->flags |= PARSEB_POWERUP; 163*2b15cb3dSCy Schubert } 164*2b15cb3dSCy Schubert else if( *buffer != ' ' ) 165*2b15cb3dSCy Schubert { 166*2b15cb3dSCy Schubert clock_time->flags |= PARSEB_NOSYNC; 167*2b15cb3dSCy Schubert } 168*2b15cb3dSCy Schubert 169*2b15cb3dSCy Schubert rc = CVT_OK; 170*2b15cb3dSCy Schubert } 171*2b15cb3dSCy Schubert } 172*2b15cb3dSCy Schubert 173*2b15cb3dSCy Schubert return rc; 174*2b15cb3dSCy Schubert } 175*2b15cb3dSCy Schubert 176*2b15cb3dSCy Schubert #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */ 177*2b15cb3dSCy Schubert int clk_sel240x_bs; 178*2b15cb3dSCy Schubert #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */ 179