File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / libparse / clk_varitext.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>