Annotation of embedaddon/ntp/libparse/clk_varitext.c, revision 1.1

1.1     ! misho       1: #ifdef HAVE_CONFIG_H
        !             2: # include <config.h>
        !             3: #endif
        !             4: 
        !             5: #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_VARITEXT)
        !             6: /*
        !             7:  * /src/NTP/ntp4-dev/libparse/clk_varitext.c,v 1.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
        !             8:  *
        !             9:  * clk_varitext.c,v 1.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
        !            10:  *
        !            11:  * Varitext code variant by A.McConnell 1997/01/19
        !            12:  * 
        !            13:  * Supports Varitext's Radio Clock
        !            14:  * 
        !            15:  * Used the Meinberg/Computime clock as a template for Varitext Radio Clock
        !            16:  *
        !            17:  * Codebase:
        !            18:  * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
        !            19:  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
        !            20:  *
        !            21:  * Redistribution and use in source and binary forms, with or without
        !            22:  * modification, are permitted provided that the following conditions
        !            23:  * are met:
        !            24:  * 1. Redistributions of source code must retain the above copyright
        !            25:  *    notice, this list of conditions and the following disclaimer.
        !            26:  * 2. Redistributions in binary form must reproduce the above copyright
        !            27:  *    notice, this list of conditions and the following disclaimer in the
        !            28:  *    documentation and/or other materials provided with the distribution.
        !            29:  * 3. Neither the name of the author nor the names of its contributors
        !            30:  *    may be used to endorse or promote products derived from this software
        !            31:  *    without specific prior written permission.
        !            32:  *
        !            33:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            34:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            35:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            36:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            37:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            38:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            39:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            40:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            41:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            42:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            43:  * SUCH DAMAGE.
        !            44:  *
        !            45:  */
        !            46: 
        !            47: #include "ntp_fp.h"
        !            48: #include "ntp_unixtime.h"
        !            49: #include "ntp_calendar.h"
        !            50: 
        !            51: #include "parse.h"
        !            52: 
        !            53: #ifndef PARSESTREAM
        !            54: # include "ntp_stdlib.h"
        !            55: # include <stdio.h>
        !            56: #else
        !            57: # include "sys/parsestreams.h"
        !            58: extern int printf (const char *, ...);
        !            59: #endif
        !            60: 
        !            61: static const u_char VT_INITIALISED      = 0x01;
        !            62: static const u_char VT_SYNCHRONISED     = 0x02;
        !            63: static const u_char VT_ALARM_STATE      = 0x04;
        !            64: static const u_char VT_BST              = 0x08;
        !            65: static const u_char VT_SEASON_CHANGE    = 0x10;
        !            66: static const u_char VT_LAST_TELEGRAM_OK = 0x20;
        !            67: 
        !            68: /*
        !            69:  * The Varitext receiver sends a datagram in the following format every minute
        !            70:  * 
        !            71:  * Timestamp   T:YY:MM:MD:WD:HH:MM:SSCRLFSTXXX 
        !            72:  * Pos          0123456789012345678901 2 3 4567
        !            73:  *              0000000000111111111122 2 2 2222
        !            74:  * Parse        T:  :  :  :  :  :  :  \r\n    
        !            75:  * 
        !            76:  * T   Startcharacter "T" specifies start of the timestamp 
        !            77:  * YY  Year MM Month 1-12 
        !            78:  * MD  Day of the month 
        !            79:  * WD  Day of week 
        !            80:  * HH  Hour 
        !            81:  * MM   Minute 
        !            82:  * SS   Second
        !            83:  * CR   Carriage return 
        !            84:  * LF   Linefeed
        !            85:  * ST  Status character
        !            86:  *     Bit 0 - Set= Initialised; Reset=Time Invalid (DO NOT USE)
        !            87:  *     Bit 1 - Set= Synchronised; Reset= Unsynchronised 
        !            88:  *     Bit 2 - Set= Alarm state; Reset= No alarm
        !            89:  *     Bit 3 - Set= BST; Reset= GMT
        !            90:  *     Bit 4 - Set= Seasonal change in approx hour; Reset= No seasonal change expected
        !            91:  *     Bit 5 - Set= Last MSF telegram was OK; Reset= Last telegram was in error;
        !            92:  *     Bit 6 - Always set
        !            93:  *     Bit 7 - Unused
        !            94:  * XXX Checksum calculated using Fletcher's method (ignored for now). 
        !            95:  */
        !            96: 
        !            97: static struct format varitext_fmt =
        !            98: {
        !            99:   {
        !           100:     {8, 2},  {5,  2}, {2,  2}, /* day, month, year */
        !           101:     {14, 2}, {17, 2}, {20, 2}, /* hour, minute, second */
        !           102:     {11, 2}, {24, 1}           /* dayofweek, status */
        !           103:   },
        !           104:   (const unsigned char*)"T:  :  :  :  :  :  :  \r\n    ",
        !           105:   0
        !           106: };
        !           107: 
        !           108: static u_long   cvt_varitext (unsigned char *, int, struct format *, clocktime_t *, void *);
        !           109: static u_long   inp_varitext (parse_t *, unsigned int, timestamp_t *);
        !           110: 
        !           111: struct varitext {
        !           112:   unsigned char start_found;
        !           113:   unsigned char end_found;
        !           114:   unsigned char end_count;
        !           115:   unsigned char previous_ch;
        !           116:   timestamp_t   tstamp;
        !           117: };
        !           118: 
        !           119: clockformat_t   clock_varitext =
        !           120: {
        !           121:   inp_varitext,                        /* Because of the strange format we need to parse it ourselves */
        !           122:   cvt_varitext,                        /* Varitext conversion */
        !           123:   0,                           /* no PPS monitoring */
        !           124:   (void *)&varitext_fmt,       /* conversion configuration */
        !           125:   "Varitext Radio Clock",      /* Varitext Radio Clock */
        !           126:   30,                          /* string buffer */
        !           127:   sizeof(struct varitext),     /* Private data size required to hold current parse state */
        !           128: };
        !           129: 
        !           130: /*
        !           131:  * cvt_varitext
        !           132:  * 
        !           133:  * convert simple type format
        !           134:  */
        !           135: static          u_long
        !           136: cvt_varitext(
        !           137:             unsigned char      *buffer,
        !           138:             int                size,
        !           139:             struct format      *format,
        !           140:             clocktime_t        *clock_time,
        !           141:             void               *local
        !           142:             )
        !           143: {
        !           144: 
        !           145:   if (!Strok(buffer, format->fixed_string)) { 
        !           146:     return CVT_NONE;
        !           147:   } else {
        !           148:     if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
        !           149:             format->field_offsets[O_DAY].length) ||
        !           150:        Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
        !           151:             format->field_offsets[O_MONTH].length) ||
        !           152:        Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
        !           153:             format->field_offsets[O_YEAR].length) ||
        !           154:        Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
        !           155:             format->field_offsets[O_HOUR].length) ||
        !           156:        Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
        !           157:             format->field_offsets[O_MIN].length) ||
        !           158:        Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
        !           159:             format->field_offsets[O_SEC].length)) { 
        !           160:       return CVT_FAIL | CVT_BADFMT;
        !           161:     } else {
        !           162:       u_char *f = (u_char*) &buffer[format->field_offsets[O_FLAGS].offset];
        !           163: 
        !           164:       clock_time->flags = 0;
        !           165:       clock_time->utcoffset = 0;
        !           166: 
        !           167:       if (((*f) & VT_BST))     /* BST flag is set so set to indicate daylight saving time is active and utc offset */
        !           168:        {
        !           169:          clock_time->utcoffset = -1*60*60;
        !           170:          clock_time->flags |= PARSEB_DST;
        !           171:        }
        !           172:       /*
        !           173:         if (!((*f) & VT_INITIALISED))  Clock not initialised 
        !           174:         clock_time->flags |= PARSEB_POWERUP;
        !           175:         
        !           176:         if (!((*f) & VT_SYNCHRONISED))   Clock not synchronised 
        !           177:         clock_time->flags |= PARSEB_NOSYNC;
        !           178:         
        !           179:         if (((*f) & VT_SEASON_CHANGE))  Seasonal change expected in the next hour 
        !           180:         clock_time->flags |= PARSEB_ANNOUNCE;
        !           181:         */
        !           182:       return CVT_OK; 
        !           183:     }
        !           184:   }
        !           185: }
        !           186: 
        !           187: static u_long 
        !           188: inp_varitext(
        !           189:             parse_t     *parseio,
        !           190:             unsigned int ch,
        !           191:             timestamp_t *tstamp
        !           192:             )
        !           193: {
        !           194:   struct varitext *t = (struct varitext *)parseio->parse_pdata;
        !           195:   int    rtc;
        !           196: 
        !           197:   parseprintf(DD_PARSE, ("inp_varitext(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
        !           198: 
        !           199:   if (!t) 
        !           200:     return PARSE_INP_SKIP;     /* local data not allocated - sigh! */
        !           201: 
        !           202:   if (ch == 'T') 
        !           203:     t->tstamp = *tstamp;
        !           204: 
        !           205:   if ((t->previous_ch == 'T') && (ch == ':'))
        !           206:     {
        !           207:       parseprintf(DD_PARSE, ("inp_varitext: START seen\n"));
        !           208: 
        !           209:       parseio->parse_data[0] = 'T';
        !           210:       parseio->parse_index=1;
        !           211:       parseio->parse_dtime.parse_stime = t->tstamp; /* Time stamp at packet start */
        !           212:       t->start_found = 1;
        !           213:       t->end_found = 0;
        !           214:       t->end_count = 0;
        !           215:     }
        !           216: 
        !           217:   if (t->start_found)
        !           218:     {
        !           219:       if ((rtc = parse_addchar(parseio, ch)) != PARSE_INP_SKIP)
        !           220:        {
        !           221:          parseprintf(DD_PARSE, ("inp_varitext: ABORTED due to too many characters\n"));
        !           222: 
        !           223:          memset(t, 0, sizeof(struct varitext));
        !           224:          return rtc;
        !           225:        }
        !           226: 
        !           227:       if (t->end_found) 
        !           228:        {
        !           229:          if (++(t->end_count) == 4) /* Finally found the end of the message */
        !           230:            {
        !           231:              parseprintf(DD_PARSE, ("inp_varitext: END seen\n"));
        !           232: 
        !           233:              memset(t, 0, sizeof(struct varitext));
        !           234:              if ((rtc = parse_addchar(parseio, 0)) == PARSE_INP_SKIP)
        !           235:                return parse_end(parseio);
        !           236:              else
        !           237:                return rtc;
        !           238:            }   
        !           239:        }
        !           240: 
        !           241:       if ((t->previous_ch == '\r') && (ch == '\n')) 
        !           242:        {
        !           243:          t->end_found = 1;
        !           244:        }
        !           245: 
        !           246:     }
        !           247:  
        !           248:   t->previous_ch = ch;
        !           249: 
        !           250:   return PARSE_INP_SKIP;
        !           251: }
        !           252: 
        !           253: #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_VARITEXT) */
        !           254: int clk_varitext_bs;
        !           255: #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_VARITEXT) */
        !           256: 
        !           257: /*
        !           258:  * History:
        !           259:  *
        !           260:  * clk_varitext.c,v
        !           261:  * Revision 1.5  2005/04/16 17:32:10  kardel
        !           262:  * update copyright
        !           263:  *
        !           264:  * Revision 1.4  2004/11/14 15:29:41  kardel
        !           265:  * support PPSAPI, upgrade Copyright to Berkeley style
        !           266:  *
        !           267:  *
        !           268:  * Revision 1.0  1997/06/02 13:16:30  McConnell
        !           269:  * File created
        !           270:  *
        !           271:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>