File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / libparse / parse.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, 4 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    1: /*
    2:  * /src/NTP/ntp4-dev/libparse/parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A
    3:  *  
    4:  * parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A
    5:  *
    6:  * Parser module for reference clock
    7:  *
    8:  * PARSEKERNEL define switches between two personalities of the module
    9:  * if PARSEKERNEL is defined this module can be used
   10:  * as kernel module. In this case the time stamps will be
   11:  * a struct timeval.
   12:  * when PARSEKERNEL is not defined NTP time stamps will be used.
   13:  *
   14:  * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
   15:  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
   16:  *
   17:  * Redistribution and use in source and binary forms, with or without
   18:  * modification, are permitted provided that the following conditions
   19:  * are met:
   20:  * 1. Redistributions of source code must retain the above copyright
   21:  *    notice, this list of conditions and the following disclaimer.
   22:  * 2. Redistributions in binary form must reproduce the above copyright
   23:  *    notice, this list of conditions and the following disclaimer in the
   24:  *    documentation and/or other materials provided with the distribution.
   25:  * 3. Neither the name of the author nor the names of its contributors
   26:  *    may be used to endorse or promote products derived from this software
   27:  *    without specific prior written permission.
   28:  *
   29:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   30:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   33:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39:  * SUCH DAMAGE.
   40:  *
   41:  */
   42: 
   43: #ifdef HAVE_CONFIG_H
   44: # include <config.h>
   45: #endif
   46: 
   47: #if defined(REFCLOCK) && defined(CLOCK_PARSE)
   48: 
   49: #if	!(defined(lint) || defined(__GNUC__))
   50: static char rcsid[] = "parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A";
   51: #endif
   52: 
   53: #include "ntp_fp.h"
   54: #include "ntp_unixtime.h"
   55: #include "ntp_calendar.h"
   56: #include "ntp_stdlib.h"
   57: #include "ntp_machine.h"
   58: #include "ntp.h"		/* (get Y2KFixes definitions) 	Y2KFixes */
   59: 
   60: #include "parse.h"
   61: 
   62: #ifndef PARSESTREAM
   63: # include <stdio.h>
   64: #else
   65: # include "sys/parsestreams.h"
   66: #endif
   67: 
   68: extern clockformat_t *clockformats[];
   69: extern unsigned short nformats;
   70: 
   71: static u_long timepacket (parse_t *);
   72: 
   73: /*
   74:  * strings support usually not in kernel - duplicated, but what the heck
   75:  */
   76: static int
   77: Strlen(
   78: 	register const char *s
   79: 	)
   80: {
   81: 	register int c;
   82: 
   83: 	c = 0;
   84: 	if (s)
   85: 	{
   86: 		while (*s++)
   87: 		{
   88: 			c++;
   89: 		}
   90: 	}
   91: 	return c;
   92: }
   93: 
   94: static int
   95: Strcmp(
   96: 	register const char *s,
   97: 	register const char *t
   98: 	)
   99: {
  100: 	register int c = 0;
  101: 
  102: 	if (!s || !t || (s == t))
  103: 	{
  104: 		return 0;
  105: 	}
  106: 
  107: 	while (!(c = *s++ - *t++) && *s && *t)
  108: 	    /* empty loop */;
  109:   
  110: 	return c;
  111: }
  112: 
  113: int
  114: parse_timedout(
  115: 	       parse_t *parseio,
  116: 	       timestamp_t *tstamp,
  117: 	       struct timeval *del
  118: 	       )
  119: {
  120: 	struct timeval delta;
  121: 
  122: #ifdef PARSEKERNEL
  123: 	delta.tv_sec = tstamp->tv.tv_sec - parseio->parse_lastchar.tv.tv_sec;
  124: 	delta.tv_usec = tstamp->tv.tv_usec - parseio->parse_lastchar.tv.tv_usec;
  125: 	if (delta.tv_usec < 0)
  126: 	{
  127: 		delta.tv_sec  -= 1;
  128: 		delta.tv_usec += 1000000;
  129: 	}
  130: #else
  131: 	extern long tstouslo[];
  132: 	extern long tstousmid[];
  133: 	extern long tstoushi[];
  134: 
  135: 	l_fp delt;
  136: 
  137: 	delt = tstamp->fp;
  138: 	L_SUB(&delt, &parseio->parse_lastchar.fp);
  139: 	TSTOTV(&delt, &delta);
  140: #endif
  141: 
  142: 	if (timercmp(&delta, del, >))
  143: 	{
  144: 		parseprintf(DD_PARSE, ("parse: timedout: TRUE\n"));
  145: 		return 1;
  146: 	}
  147: 	else
  148: 	{
  149: 		parseprintf(DD_PARSE, ("parse: timedout: FALSE\n"));
  150: 		return 0;
  151: 	}
  152: }
  153: 
  154: /*ARGSUSED*/
  155: int
  156: parse_ioinit(
  157: 	register parse_t *parseio
  158: 	)
  159: {
  160: 	parseprintf(DD_PARSE, ("parse_iostart\n"));
  161:   
  162: 	parseio->parse_plen = 0;
  163: 	parseio->parse_pdata = (void *)0;
  164:   
  165: 	parseio->parse_data = 0;
  166: 	parseio->parse_ldata = 0;
  167: 	parseio->parse_dsize = 0;
  168: 
  169: 	parseio->parse_badformat = 0;
  170: 	parseio->parse_ioflags   = PARSE_IO_CS7;	/* usual unix default */
  171: 	parseio->parse_index     = 0;
  172: 	parseio->parse_ldsize    = 0;
  173:   
  174: 	return 1;
  175: }
  176: 
  177: /*ARGSUSED*/
  178: void
  179: parse_ioend(
  180: 	register parse_t *parseio
  181: 	)
  182: {
  183: 	parseprintf(DD_PARSE, ("parse_ioend\n"));
  184: 
  185: 	if (parseio->parse_pdata)
  186: 	    FREE(parseio->parse_pdata, parseio->parse_plen);
  187: 
  188: 	if (parseio->parse_data)
  189: 	    FREE(parseio->parse_data, (unsigned)(parseio->parse_dsize * 2 + 2));
  190: }
  191: 
  192: unsigned int
  193: parse_restart(
  194: 	      parse_t *parseio,
  195: 	      unsigned int ch
  196: 	      )
  197: {
  198: 	unsigned int updated = PARSE_INP_SKIP;
  199: 	
  200: 	/*
  201: 	 * re-start packet - timeout - overflow - start symbol
  202: 	 */
  203: 	
  204: 	if (parseio->parse_index)
  205: 	{
  206: 		/*
  207: 		 * filled buffer - thus not end character found
  208: 		 * do processing now
  209: 		 */
  210: 		parseio->parse_data[parseio->parse_index] = '\0';
  211: 		memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
  212: 		parseio->parse_ldsize = parseio->parse_index;
  213: 		updated = PARSE_INP_TIME;
  214: 	}
  215: 		
  216: 	parseio->parse_index = 1;
  217: 	parseio->parse_data[0] = ch;
  218: 	parseprintf(DD_PARSE, ("parse: parse_restart: buffer start (updated = %x)\n", updated));
  219: 	return updated;
  220: }
  221: 	
  222: unsigned int
  223: parse_addchar(
  224: 	      parse_t *parseio,
  225: 	      unsigned int ch
  226: 	      )
  227: {
  228: 	/*
  229: 	 * add to buffer
  230: 	 */
  231: 	if (parseio->parse_index < parseio->parse_dsize)
  232: 	{
  233: 		/*
  234: 		 * collect into buffer
  235: 		 */
  236: 		parseprintf(DD_PARSE, ("parse: parse_addchar: buffer[%d] = 0x%x\n", parseio->parse_index, ch));
  237: 		parseio->parse_data[parseio->parse_index++] = (char)ch;
  238: 		return PARSE_INP_SKIP;
  239: 	}
  240: 	else
  241: 		/*
  242: 		 * buffer overflow - attempt to make the best of it
  243: 		 */
  244: 		return parse_restart(parseio, ch);
  245: }
  246: 	
  247: unsigned int
  248: parse_end(
  249: 	  parse_t *parseio
  250: 	  )
  251: {
  252: 	/*
  253: 	 * message complete processing
  254: 	 */
  255: 	parseio->parse_data[parseio->parse_index] = '\0';
  256: 	memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
  257: 	parseio->parse_ldsize = parseio->parse_index;
  258: 	parseio->parse_index = 0;
  259: 	parseprintf(DD_PARSE, ("parse: parse_end: buffer end\n"));
  260: 	return PARSE_INP_TIME;
  261: }
  262: 
  263: /*ARGSUSED*/
  264: int
  265: parse_ioread(
  266: 	register parse_t *parseio,
  267: 	register unsigned int ch,
  268: 	register timestamp_t *tstamp
  269: 	)
  270: {
  271: 	register unsigned updated = CVT_NONE;
  272: 	/*
  273: 	 * within STREAMS CSx (x < 8) chars still have the upper bits set
  274: 	 * so we normalize the characters by masking unecessary bits off.
  275: 	 */
  276: 	switch (parseio->parse_ioflags & PARSE_IO_CSIZE)
  277: 	{
  278: 	    case PARSE_IO_CS5:
  279: 		ch &= 0x1F;
  280: 		break;
  281: 
  282: 	    case PARSE_IO_CS6:
  283: 		ch &= 0x3F;
  284: 		break;
  285: 
  286: 	    case PARSE_IO_CS7:
  287: 		ch &= 0x7F;
  288: 		break;
  289:       
  290: 	    case PARSE_IO_CS8:
  291: 		ch &= 0xFF;
  292: 		break;
  293: 	}
  294: 
  295: 	parseprintf(DD_PARSE, ("parse_ioread(0x%lx, char=0x%x, ..., ...)\n", (unsigned long)parseio, ch & 0xFF));
  296: 
  297: 	if (!clockformats[parseio->parse_lformat]->convert)
  298: 	{
  299: 		parseprintf(DD_PARSE, ("parse_ioread: input dropped.\n"));
  300: 		return CVT_NONE;
  301: 	}
  302: 
  303: 	if (clockformats[parseio->parse_lformat]->input)
  304: 	{
  305: 		unsigned long input_status;
  306: 
  307: 		input_status = clockformats[parseio->parse_lformat]->input(parseio, ch, tstamp);
  308: 
  309: 		if (input_status & PARSE_INP_SYNTH)
  310: 		{
  311: 			updated = CVT_OK;
  312: 		}
  313: 		
  314: 		if (input_status & PARSE_INP_TIME)	/* time sample is available */
  315: 		{
  316: 			updated = timepacket(parseio);
  317: 		}
  318: 		  
  319: 		if (input_status & PARSE_INP_DATA) /* got additional data */
  320: 		{
  321: 			updated |= CVT_ADDITIONAL;
  322: 		}
  323: 	}
  324: 	
  325: 
  326: 	/*
  327: 	 * remember last character time
  328: 	 */
  329: 	parseio->parse_lastchar = *tstamp;
  330: 
  331: #ifdef DEBUG
  332: 	if ((updated & CVT_MASK) != CVT_NONE)
  333: 	{
  334: 		parseprintf(DD_PARSE, ("parse_ioread: time sample accumulated (status=0x%x)\n", updated));
  335: 	}
  336: #endif
  337: 
  338: 	parseio->parse_dtime.parse_status = updated;
  339: 
  340: 	return (((updated & CVT_MASK) != CVT_NONE) ||
  341: 		((updated & CVT_ADDITIONAL) != 0));
  342: }
  343: 
  344: /*
  345:  * parse_iopps
  346:  *
  347:  * take status line indication and derive synchronisation information
  348:  * from it.
  349:  * It can also be used to decode a serial serial data format (such as the
  350:  * ONE, ZERO, MINUTE sync data stream from DCF77)
  351:  */
  352: /*ARGSUSED*/
  353: int
  354: parse_iopps(
  355: 	register parse_t *parseio,
  356: 	register int status,
  357: 	register timestamp_t *ptime
  358: 	)
  359: {
  360: 	register unsigned updated = CVT_NONE;
  361: 
  362: 	/*
  363: 	 * PPS pulse information will only be delivered to ONE clock format
  364: 	 * this is either the last successful conversion module with a ppssync
  365: 	 * routine, or a fixed format with a ppssync routine
  366: 	 */
  367: 	parseprintf(DD_PARSE, ("parse_iopps: STATUS %s\n", (status == SYNC_ONE) ? "ONE" : "ZERO"));
  368: 
  369: 	if (clockformats[parseio->parse_lformat]->syncpps)
  370: 	{
  371: 		updated = clockformats[parseio->parse_lformat]->syncpps(parseio, status == SYNC_ONE, ptime);
  372: 		parseprintf(DD_PARSE, ("parse_iopps: updated = 0x%x\n", updated));
  373: 	}
  374: 
  375: 	return (updated & CVT_MASK) != CVT_NONE;
  376: }
  377: 
  378: /*
  379:  * parse_iodone
  380:  *
  381:  * clean up internal status for new round
  382:  */
  383: /*ARGSUSED*/
  384: void
  385: parse_iodone(
  386: 	register parse_t *parseio
  387: 	)
  388: {
  389: 	/*
  390: 	 * we need to clean up certain flags for the next round
  391: 	 */
  392: 	parseprintf(DD_PARSE, ("parse_iodone: DONE\n"));
  393: 	parseio->parse_dtime.parse_state = 0; /* no problems with ISRs */
  394: }
  395: 
  396: /*---------- conversion implementation --------------------*/
  397: 
  398: /*
  399:  * convert a struct clock to UTC since Jan, 1st 1970 0:00 (the UNIX EPOCH)
  400:  */
  401: #define days_per_year(x)	((x) % 4 ? 365 : ((x % 400) ? ((x % 100) ? 366 : 365) : 366))
  402: 
  403: time_t
  404: parse_to_unixtime(
  405: 	register clocktime_t   *clock_time,
  406: 	register u_long *cvtrtc
  407: 	)
  408: {
  409: #define SETRTC(_X_)	{ if (cvtrtc) *cvtrtc = (_X_); }
  410: 	static int days_of_month[] = 
  411: 	{
  412: 		0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  413: 	};
  414: 	register int i;
  415: 	time_t t;
  416:   
  417: 	if (clock_time->utctime)
  418: 	    return clock_time->utctime;	/* if the conversion routine gets it right away - why not */
  419: 
  420: 	if ( clock_time->year < YEAR_PIVOT )			/* Y2KFixes [ */
  421: 	    clock_time->year += 100;	/* convert 20xx%100 to 20xx-1900 */
  422: 	if ( clock_time->year < YEAR_BREAK )	/* expand to full four-digits */
  423: 	    clock_time->year += 1900;
  424: 
  425: 	if (clock_time->year < 1970 )				/* Y2KFixes ] */
  426: 	{
  427: 		SETRTC(CVT_FAIL|CVT_BADDATE);
  428: 		return -1;
  429: 	}
  430:   
  431: 	/*
  432: 	 * sorry, slow section here - but it's not time critical anyway
  433: 	 */
  434: 	t = julian0(clock_time->year) - julian0(1970);		/* Y2kFixes */
  435:   				/* month */
  436: 	if (clock_time->month <= 0 || clock_time->month > 12)
  437: 	{
  438: 		SETRTC(CVT_FAIL|CVT_BADDATE);
  439: 		return -1;		/* bad month */
  440: 	}
  441: 
  442: #if 0								/* Y2KFixes */
  443: 				/* adjust leap year */
  444: 	if (clock_time->month < 3 && days_per_year(clock_time->year) == 366)
  445: 	    t--;
  446: #else								/* Y2KFixes [ */
  447: 	if ( clock_time->month >= 3  &&  isleap_4(clock_time->year) )
  448: 	    t++;		/* add one more if within leap year */
  449: #endif								/* Y2KFixes ] */
  450: 
  451: 	for (i = 1; i < clock_time->month; i++)
  452: 	{
  453: 		t += days_of_month[i];
  454: 	}
  455: 				/* day */
  456: 	if (clock_time->day < 1 || ((clock_time->month == 2 && days_per_year(clock_time->year) == 366) ?
  457: 			       clock_time->day > 29 : clock_time->day > days_of_month[clock_time->month]))
  458: 	{
  459: 		SETRTC(CVT_FAIL|CVT_BADDATE);
  460: 		return -1;		/* bad day */
  461: 	}
  462: 
  463: 	t += clock_time->day - 1;
  464: 				/* hour */
  465: 	if (clock_time->hour < 0 || clock_time->hour >= 24)
  466: 	{
  467: 		SETRTC(CVT_FAIL|CVT_BADTIME);
  468: 		return -1;		/* bad hour */
  469: 	}
  470: 
  471: 	t = TIMES24(t) + clock_time->hour;
  472: 
  473:   				/* min */
  474: 	if (clock_time->minute < 0 || clock_time->minute > 59)
  475: 	{
  476: 		SETRTC(CVT_FAIL|CVT_BADTIME);
  477: 		return -1;		/* bad min */
  478: 	}
  479: 
  480: 	t = TIMES60(t) + clock_time->minute;
  481: 				/* sec */
  482:   
  483: 	if (clock_time->second < 0 || clock_time->second > 60)	/* allow for LEAPs */
  484: 	{
  485: 		SETRTC(CVT_FAIL|CVT_BADTIME);
  486: 		return -1;		/* bad sec */
  487: 	}
  488: 
  489: 	t  = TIMES60(t) + clock_time->second;
  490: 
  491: 	t += clock_time->utcoffset;	/* warp to UTC */
  492: 
  493: 				/* done */
  494: 
  495: 	clock_time->utctime = t;		/* documentray only */
  496: 
  497: 	return t;
  498: }
  499: 
  500: /*--------------- format conversion -----------------------------------*/
  501: 
  502: int
  503: Stoi(
  504: 	const unsigned char *s,
  505: 	long *zp,
  506: 	int cnt
  507: 	)
  508: {
  509: 	char unsigned const *b = s;
  510: 	int f,z,v;
  511: 	char unsigned c;
  512: 
  513: 	f=z=v=0;
  514: 
  515: 	while(*s == ' ')
  516: 	    s++;
  517:   
  518: 	if (*s == '-')
  519: 	{
  520: 		s++;
  521: 		v = 1;
  522: 	}
  523: 	else
  524: 	    if (*s == '+')
  525: 		s++;
  526:   
  527: 	for(;;)
  528: 	{
  529: 		c = *s++;
  530: 		if (c == '\0' || c < '0' || c > '9' || (cnt && ((s-b) > cnt)))
  531: 		{
  532: 			if (f == 0)
  533: 			{
  534: 				return(-1);
  535: 			}
  536: 			if (v)
  537: 			    z = -z;
  538: 			*zp = z;
  539: 			return(0);
  540: 		}
  541: 		z = (z << 3) + (z << 1) + ( c - '0' );
  542: 		f=1;
  543: 	}
  544: }
  545: 
  546: int
  547: Strok(
  548: 	const unsigned char *s,
  549: 	const unsigned char *m
  550: 	)
  551: {
  552: 	if (!s || !m)
  553: 	    return 0;
  554: 
  555: 	while(*s && *m)
  556: 	{
  557: 		if ((*m == ' ') ? 1 : (*s == *m))
  558: 		{
  559: 			s++;
  560: 			m++;
  561: 		}
  562: 		else
  563: 		{
  564: 			return 0;
  565: 		}
  566: 	}
  567: 	return !*m;
  568: }
  569: 
  570: u_long
  571: updatetimeinfo(
  572: 	       register parse_t *parseio,
  573: 	       register u_long   flags
  574: 	       )
  575: {
  576: #ifdef PARSEKERNEL
  577: 	{
  578: 		int s = splhigh();
  579: #endif
  580:   
  581: 		parseio->parse_lstate          = parseio->parse_dtime.parse_state | flags | PARSEB_TIMECODE;
  582:     
  583: 		parseio->parse_dtime.parse_state = parseio->parse_lstate;
  584: 
  585: #ifdef PARSEKERNEL
  586: 		(void)splx((unsigned int)s);
  587: 	}
  588: #endif
  589:   
  590: 
  591: #ifdef PARSEKERNEL
  592: 	parseprintf(DD_PARSE, ("updatetimeinfo status=0x%x, time=%x\n", parseio->parse_dtime.parse_state,
  593: 			       parseio->parse_dtime.parse_time.tv.tv_sec));
  594: #else
  595: 	parseprintf(DD_PARSE, ("updatetimeinfo status=0x%lx, time=%x\n", (long)parseio->parse_dtime.parse_state,
  596: 	                       parseio->parse_dtime.parse_time.fp.l_ui));
  597: #endif
  598: 	
  599: 	return CVT_OK;		/* everything fine and dandy... */
  600: }
  601: 
  602: 
  603: /*
  604:  * syn_simple
  605:  *
  606:  * handle a sync time stamp
  607:  */
  608: /*ARGSUSED*/
  609: void
  610: syn_simple(
  611: 	register parse_t *parseio,
  612: 	register timestamp_t *ts,
  613: 	register struct format *format,
  614: 	register u_long why
  615: 	)
  616: {
  617: 	parseio->parse_dtime.parse_stime = *ts;
  618: }
  619: 
  620: /*
  621:  * pps_simple
  622:  *
  623:  * handle a pps time stamp
  624:  */
  625: /*ARGSUSED*/
  626: u_long
  627: pps_simple(
  628: 	register parse_t *parseio,
  629: 	register int status,
  630: 	register timestamp_t *ptime
  631: 	)
  632: {
  633: 	parseio->parse_dtime.parse_ptime  = *ptime;
  634: 	parseio->parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
  635:   
  636: 	return CVT_NONE;
  637: }
  638: 
  639: /*
  640:  * pps_one
  641:  *
  642:  * handle a pps time stamp in ONE edge
  643:  */
  644: /*ARGSUSED*/
  645: u_long
  646: pps_one(
  647: 	register parse_t *parseio,
  648: 	register int status,
  649: 	register timestamp_t *ptime
  650: 	)
  651: {
  652: 	if (status)
  653: 		return pps_simple(parseio, status, ptime);
  654: 	
  655: 	return CVT_NONE;
  656: }
  657: 
  658: /*
  659:  * pps_zero
  660:  *
  661:  * handle a pps time stamp in ZERO edge
  662:  */
  663: /*ARGSUSED*/
  664: u_long
  665: pps_zero(
  666: 	register parse_t *parseio,
  667: 	register int status,
  668: 	register timestamp_t *ptime
  669: 	)
  670: {
  671: 	if (!status)
  672: 		return pps_simple(parseio, status, ptime);
  673: 	
  674: 	return CVT_NONE;
  675: }
  676: 
  677: /*
  678:  * timepacket
  679:  *
  680:  * process a data packet
  681:  */
  682: static u_long
  683: timepacket(
  684: 	register parse_t *parseio
  685: 	)
  686: {
  687: 	register unsigned short format;
  688: 	register time_t t;
  689: 	u_long cvtrtc;		/* current conversion result */
  690: 	clocktime_t clock_time;
  691:   
  692: 	memset((char *)&clock_time, 0, sizeof clock_time);
  693: 	format = parseio->parse_lformat;
  694: 
  695: 	if (format == (unsigned short)~0)
  696: 		return CVT_NONE;
  697: 	
  698: 	switch ((cvtrtc = clockformats[format]->convert ?
  699: 		 clockformats[format]->convert((unsigned char *)parseio->parse_ldata, parseio->parse_ldsize, (struct format *)(clockformats[format]->data), &clock_time, parseio->parse_pdata) :
  700: 		 CVT_NONE) & CVT_MASK)
  701: 	{
  702: 	case CVT_FAIL:
  703: 		parseio->parse_badformat++;
  704: 		break;
  705: 		
  706: 	case CVT_NONE:
  707: 		/*
  708: 		 * too bad - pretend bad format
  709: 		 */
  710: 		parseio->parse_badformat++;
  711: 		break;
  712: 		
  713: 	case CVT_OK:
  714: 		break;
  715: 		
  716: 	case CVT_SKIP:
  717: 		return CVT_NONE;
  718: 
  719: 	default:
  720: 		/* shouldn't happen */
  721: #ifndef PARSEKERNEL
  722: 		msyslog(LOG_WARNING, "parse: INTERNAL error: bad return code of convert routine \"%s\"\n", clockformats[format]->name);
  723: #endif	  
  724: 		return CVT_FAIL|cvtrtc;
  725: 	}
  726: 
  727: 	if ((t = parse_to_unixtime(&clock_time, &cvtrtc)) == -1)
  728: 	{
  729: 		return CVT_FAIL|cvtrtc;
  730: 	}
  731:   
  732: 	/*
  733: 	 * time stamp
  734: 	 */
  735: #ifdef PARSEKERNEL
  736: 	parseio->parse_dtime.parse_time.tv.tv_sec  = t;
  737: 	parseio->parse_dtime.parse_time.tv.tv_usec = clock_time.usecond;
  738: #else
  739: 	parseio->parse_dtime.parse_time.fp.l_ui = t + JAN_1970;
  740: 	TVUTOTSF(clock_time.usecond, parseio->parse_dtime.parse_time.fp.l_uf);
  741: #endif
  742: 
  743: 	parseio->parse_dtime.parse_format       = format;
  744: 
  745: 	return updatetimeinfo(parseio, clock_time.flags);
  746: }
  747: 
  748: /*ARGSUSED*/
  749: int
  750: parse_timecode(
  751: 	parsectl_t *dct,
  752: 	parse_t    *parse
  753: 	)
  754: {
  755: 	dct->parsegettc.parse_state  = parse->parse_lstate;
  756: 	dct->parsegettc.parse_format = parse->parse_lformat;
  757: 	/*
  758: 	 * move out current bad packet count
  759: 	 * user program is expected to sum these up
  760: 	 * this is not a problem, as "parse" module are
  761: 	 * exclusive open only
  762: 	 */
  763: 	dct->parsegettc.parse_badformat = parse->parse_badformat;
  764: 	parse->parse_badformat = 0;
  765: 		  
  766: 	if (parse->parse_ldsize <= PARSE_TCMAX)
  767: 	{
  768: 		dct->parsegettc.parse_count = parse->parse_ldsize;
  769: 		memcpy(dct->parsegettc.parse_buffer, parse->parse_ldata, dct->parsegettc.parse_count);
  770: 		return 1;
  771: 	}
  772: 	else
  773: 	{
  774: 		return 0;
  775: 	}
  776: }
  777: 
  778: 		  
  779: /*ARGSUSED*/
  780: int
  781: parse_setfmt(
  782: 	parsectl_t *dct,
  783: 	parse_t    *parse
  784: 	)
  785: {
  786: 	if (dct->parseformat.parse_count <= PARSE_TCMAX)
  787: 	{
  788: 		if (dct->parseformat.parse_count)
  789: 		{
  790: 			register unsigned short i;
  791: 
  792: 			for (i = 0; i < nformats; i++)
  793: 			{
  794: 				if (!Strcmp(dct->parseformat.parse_buffer, clockformats[i]->name))
  795: 				{
  796: 					if (parse->parse_pdata)
  797: 						FREE(parse->parse_pdata, parse->parse_plen);
  798: 					parse->parse_pdata = 0;
  799: 					
  800: 					parse->parse_plen = clockformats[i]->plen;
  801: 
  802: 					if (parse->parse_plen)
  803: 					{
  804: 						parse->parse_pdata = MALLOC(parse->parse_plen);
  805: 						if (!parse->parse_pdata)
  806: 						{
  807: 							parseprintf(DD_PARSE, ("set format failed: malloc for private data area failed\n"));
  808: 							return 0;
  809: 						}
  810: 						memset((char *)parse->parse_pdata, 0, parse->parse_plen);
  811: 					}
  812: 
  813: 					if (parse->parse_data)
  814: 						FREE(parse->parse_data, (unsigned)(parse->parse_dsize * 2 + 2));
  815: 					parse->parse_ldata = parse->parse_data = 0;
  816: 					
  817: 					parse->parse_dsize = clockformats[i]->length;
  818: 					
  819: 					if (parse->parse_dsize)
  820: 					{
  821: 						parse->parse_data = (char*)MALLOC((unsigned)(parse->parse_dsize * 2 + 2));
  822: 						if (!parse->parse_data)
  823: 						{
  824: 							if (parse->parse_pdata)
  825: 								FREE(parse->parse_pdata, parse->parse_plen);
  826: 							parse->parse_pdata = 0;
  827: 							
  828: 							parseprintf(DD_PARSE, ("init failed: malloc for data area failed\n"));
  829: 							return 0;
  830: 						}
  831: 					}
  832: 					
  833: 
  834: 					/*
  835: 					 * leave room for '\0'
  836: 					 */
  837: 					parse->parse_ldata     = parse->parse_data + parse->parse_dsize + 1;
  838: 					
  839: 					parse->parse_lformat  = i;
  840: 					
  841: 					return 1;
  842: 				}
  843: 			}
  844: 		}
  845: 	}
  846: 	return 0;
  847: }
  848: 
  849: /*ARGSUSED*/
  850: int
  851: parse_getfmt(
  852: 	parsectl_t *dct,
  853: 	parse_t    *parse
  854: 	)
  855: {
  856: 	if (dct->parseformat.parse_format < nformats &&
  857: 	    Strlen(clockformats[dct->parseformat.parse_format]->name) <= PARSE_TCMAX)
  858: 	{
  859: 		dct->parseformat.parse_count = Strlen(clockformats[dct->parseformat.parse_format]->name)+1;
  860: 		memcpy(dct->parseformat.parse_buffer, clockformats[dct->parseformat.parse_format]->name, dct->parseformat.parse_count);
  861: 		return 1;
  862: 	}
  863: 	else
  864: 	{
  865: 		return 0;
  866: 	}
  867: }
  868: 
  869: /*ARGSUSED*/
  870: int
  871: parse_setcs(
  872: 	parsectl_t *dct,
  873: 	parse_t    *parse
  874: 	)
  875: {
  876: 	parse->parse_ioflags &= ~PARSE_IO_CSIZE;
  877: 	parse->parse_ioflags |= dct->parsesetcs.parse_cs & PARSE_IO_CSIZE;
  878: 	return 1;
  879: }
  880: 
  881: #else /* not (REFCLOCK && CLOCK_PARSE) */
  882: int parse_bs;
  883: #endif /* not (REFCLOCK && CLOCK_PARSE) */
  884: 
  885: /*
  886:  * History:
  887:  *
  888:  * parse.c,v
  889:  * Revision 4.20  2005/08/06 17:39:40  kardel
  890:  * cleanup size handling wrt/ to buffer boundaries
  891:  *
  892:  * Revision 4.19  2005/04/16 17:32:10  kardel
  893:  * update copyright
  894:  *
  895:  * Revision 4.18  2004/11/14 16:11:05  kardel
  896:  * update Id tags
  897:  *
  898:  * Revision 4.17  2004/11/14 15:29:41  kardel
  899:  * support PPSAPI, upgrade Copyright to Berkeley style
  900:  *
  901:  * Revision 4.14  1999/11/28 09:13:52  kardel
  902:  * RECON_4_0_98F
  903:  *
  904:  * Revision 4.13  1999/02/28 11:50:20  kardel
  905:  * (timepacket): removed unecessary code
  906:  *
  907:  * Revision 4.12  1999/02/21 12:17:44  kardel
  908:  * 4.91f reconcilation
  909:  *
  910:  * Revision 4.11  1999/02/21 11:09:47  kardel
  911:  * unified debug output
  912:  *
  913:  * Revision 4.10  1998/12/20 23:45:30  kardel
  914:  * fix types and warnings
  915:  *
  916:  * Revision 4.9  1998/08/09 22:26:06  kardel
  917:  * Trimble TSIP support
  918:  *
  919:  * Revision 4.8  1998/06/14 21:09:39  kardel
  920:  * Sun acc cleanup
  921:  *
  922:  * Revision 4.7  1998/06/13 15:19:13  kardel
  923:  * fix mem*() to b*() function macro emulation
  924:  *
  925:  * Revision 4.6  1998/06/13 13:24:13  kardel
  926:  * printf fmt
  927:  *
  928:  * Revision 4.5  1998/06/13 13:01:10  kardel
  929:  * printf fmt
  930:  *
  931:  * Revision 4.4  1998/06/13 12:12:10  kardel
  932:  * bcopy/memcpy cleanup
  933:  * fix SVSV name clash
  934:  *
  935:  * Revision 4.3  1998/06/12 15:22:30  kardel
  936:  * fix prototypes
  937:  *
  938:  * Revision 4.2  1998/06/12 09:13:27  kardel
  939:  * conditional compile macros fixed
  940:  * printf prototype
  941:  *
  942:  * Revision 4.1  1998/05/24 09:39:55  kardel
  943:  * implementation of the new IO handling model
  944:  *
  945:  * Revision 4.0  1998/04/10 19:45:36  kardel
  946:  * Start 4.0 release version numbering
  947:  *
  948:  * from V3 3.46 log info deleted 1998/04/11 kardel
  949:  */

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