Ejemplo n.º 1
0
/*
 * cvt_dcf7000
 *
 * convert dcf7000 type format
 */
static u_long
cvt_dcf7000(
	    unsigned char *buffer,
	    int            size,
	    struct format *format,
	    clocktime_t   *clock_time,
	    void          *local
	    )
{
	if (!Strok(buffer, format->fixed_string))
	{
		return CVT_NONE;
	}
	else
	{
		if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
			 format->field_offsets[O_DAY].length) ||
		    Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
			 format->field_offsets[O_MONTH].length) ||
		    Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
			 format->field_offsets[O_YEAR].length) ||
		    Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
			 format->field_offsets[O_HOUR].length) ||
		    Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
			 format->field_offsets[O_MIN].length) ||
		    Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
			 format->field_offsets[O_SEC].length))
		{
			return CVT_FAIL|CVT_BADFMT;
		}
		else
		{
			unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
			long flags;
	  
			clock_time->flags = 0;
			clock_time->usecond = 0;

			if (Stoi(f, &flags, format->field_offsets[O_FLAGS].length))
			{
				return CVT_FAIL|CVT_BADFMT;
			}
			else
			{
				if (flags & 0x1)
				    clock_time->utcoffset = -2*60*60;
				else
				    clock_time->utcoffset = -1*60*60;

				if (flags & 0x2)
				    clock_time->flags |= PARSEB_ANNOUNCE;

				if (flags & 0x4)
				    clock_time->flags |= PARSEB_NOSYNC;
			}
			return CVT_OK;
		}
	}
}
Ejemplo n.º 2
0
/* parse_cvt_fnc_t cvt_rcc8000 */
static u_long
cvt_rcc8000(
	    unsigned char *buffer,
	    int            size,
	    struct format *format,
	    clocktime_t   *clock_time,
	    void          *local
	    )
{
	if (!Strok(buffer, format->fixed_string)) return CVT_NONE;
#define	OFFS(x) format->field_offsets[(x)].offset
#define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length)
	if (	STOI(O_DAY,	&clock_time->day)	||
		STOI(O_MONTH,	&clock_time->month)	||
		STOI(O_YEAR,	&clock_time->year)	||
		STOI(O_HOUR,	&clock_time->hour)	||
		STOI(O_MIN,	&clock_time->minute)	||
		STOI(O_SEC,	&clock_time->second)	||
		STOI(O_USEC,	&clock_time->usecond)
		) return CVT_FAIL|CVT_BADFMT;
	clock_time->usecond *= 1000;

	clock_time->utcoffset = 0;

#define RCCP buffer[28]
	/*
	 * buffer[28] is the ASCII representation of a hex character ( 0 through F )
	 *      The four bits correspond to:
	 *      8 - Valid Time
	 *      4 - Reject Code
	 *      2 - British Summer Time (receiver set to emit GMT all year.)
	 *      1 - Leap year
	 */
#define RCC8000_VALID  0x8
#define RCC8000_REJECT 0x4
#define RCC8000_BST    0x2
#define RCC8000_LEAPY  0x1

	clock_time->flags = 0;

	if ( (RCCP >= '0' && RCCP <= '9') || (RCCP >= 'A' && RCCP <= 'F') )
	{
		register int flag;

		flag = (RCCP >= '0' && RCCP <= '9' ) ?  RCCP - '0' : RCCP - 'A' + 10;

		if (!(flag & RCC8000_VALID))
		    clock_time->flags |= PARSEB_POWERUP;

		clock_time->flags |= PARSEB_UTC; /* British special - guess why 8-) */

		/* other flags not used */
	}
	return CVT_OK;
}
Ejemplo n.º 3
0
/*
 * cvt_varitext
 * 
 * convert simple type format
 */
static          u_long
cvt_varitext(
	     unsigned char	*buffer,
	     int    		size,
	     struct format	*format,
	     clocktime_t	*clock_time,
	     void		*local
	     )
{

  if (!Strok(buffer, format->fixed_string)) { 
    return CVT_NONE;
  } else {
    if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
	     format->field_offsets[O_DAY].length) ||
	Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
	     format->field_offsets[O_MONTH].length) ||
	Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
	     format->field_offsets[O_YEAR].length) ||
	Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
	     format->field_offsets[O_HOUR].length) ||
	Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
	     format->field_offsets[O_MIN].length) ||
	Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
	     format->field_offsets[O_SEC].length)) { 
      return CVT_FAIL | CVT_BADFMT;
    } else {
      u_char *f = (u_char*) &buffer[format->field_offsets[O_FLAGS].offset];

      clock_time->flags = 0;
      clock_time->utcoffset = 0;

      if (((*f) & VT_BST))	/* BST flag is set so set to indicate daylight saving time is active and utc offset */
	{
	  clock_time->utcoffset = -1*60*60;
	  clock_time->flags |= PARSEB_DST;
	}
      /*
	 if (!((*f) & VT_INITIALISED))  Clock not initialised 
	 clock_time->flags |= PARSEB_POWERUP;
	 
	 if (!((*f) & VT_SYNCHRONISED))   Clock not synchronised 
	 clock_time->flags |= PARSEB_NOSYNC;
	 
	 if (((*f) & VT_SEASON_CHANGE))  Seasonal change expected in the next hour 
	 clock_time->flags |= PARSEB_ANNOUNCE;
	 */
      return CVT_OK; 
    }
  }
}
Ejemplo n.º 4
0
static unsigned long
cvt_sel240x( unsigned char *buffer,
	     int            size,
	     struct format *format,
	     clocktime_t   *clock_time,
	     void          *local
	   )
{
	unsigned long rc = CVT_NONE;

	UNUSED_ARG(size);
	UNUSED_ARG(local);

	if( Strok(buffer, format->fixed_string) )
	{
		struct tm ptime;
		buffer++;
		buffer = (unsigned char *)strptime(
			(const char *)buffer, "%Y:%j:%H:%M:%S", &ptime );
		if( *(buffer+1) != '\x0d' )
		{
			rc = CVT_FAIL | CVT_BADFMT;
		}
		else
		{
			clock_time->day = ptime.tm_mday;
			clock_time->month = ptime.tm_mon + 1;
			clock_time->year = ptime.tm_year + 1900;
			clock_time->hour = ptime.tm_hour;
			clock_time->minute = ptime.tm_min;
			clock_time->second = ptime.tm_sec;
			clock_time->usecond = 0;
			clock_time->utcoffset = 0;
			clock_time->flags = PARSEB_UTC;

			if( *buffer == '?' )
			{
				clock_time->flags |= PARSEB_POWERUP;
			}
			else if( *buffer != ' ' )
			{
				clock_time->flags |= PARSEB_NOSYNC;
			}

			rc = CVT_OK;
		}
	}

	return rc;
}
Ejemplo n.º 5
0
/* parse_cvt_fnc_t cvt_trimtaip */
static u_long
cvt_trimtaip(
	     unsigned char *buffer,
	     int            size,
	     struct format *format,
	     clocktime_t   *clock_time,
	     void          *local
	     )
{
	long gpsfix;
	u_char calc_csum = 0;
	long   recv_csum;
	int	 i;

	if (!Strok(buffer, format->fixed_string)) return CVT_NONE;
#define	OFFS(x) format->field_offsets[(x)].offset
#define	STOI(x, y) \
	Stoi(&buffer[OFFS(x)], y, \
	     format->field_offsets[(x)].length)
		if (	STOI(O_DAY,	&clock_time->day)	||
			STOI(O_MONTH,	&clock_time->month)	||
			STOI(O_YEAR,	&clock_time->year)	||
			STOI(O_HOUR,	&clock_time->hour)	||
			STOI(O_MIN,	&clock_time->minute)	||
			STOI(O_SEC,	&clock_time->second)	||
			STOI(O_USEC,	&clock_time->usecond)||
			STOI(O_GPSFIX,	&gpsfix)
			) return CVT_FAIL|CVT_BADFMT;

	clock_time->usecond *= 1000;
	/* Check that the checksum is right */
	for (i=OFFS(O_CHKSUM)-1; i >= 0; i--) calc_csum ^= buffer[i];
	recv_csum =	(hexval(buffer[OFFS(O_CHKSUM)]) << 4) |
		hexval(buffer[OFFS(O_CHKSUM)+1]);
	if (recv_csum < 0) return CVT_FAIL|CVT_BADTIME;
	if (((u_char) recv_csum) != calc_csum) return CVT_FAIL|CVT_BADTIME;

	clock_time->utcoffset = 0;

	/* What should flags be set to ? */
	clock_time->flags = PARSEB_UTC;

	/* if the current GPS fix is 9 (unknown), reject */
	if (0 > gpsfix || gpsfix > 9) clock_time->flags |= PARSEB_POWERUP;

	return CVT_OK;
}
Ejemplo n.º 6
0
/* parse_cvt_fnc_t cvt_hopf6021 */
static u_long
cvt_hopf6021(
	     unsigned char *buffer,
	     int            size,
	     struct format *format,
	     clocktime_t   *clock_time,
	     void          *local
	     )
{
	unsigned char status,weekday;

	if (!Strok(buffer, format->fixed_string))
	{
		return CVT_NONE;
	}

	if (  STOI(O_DAY,   &clock_time->day)    ||
	      STOI(O_MONTH, &clock_time->month)  ||
	      STOI(O_YEAR,  &clock_time->year)   ||
	      STOI(O_HOUR,  &clock_time->hour)   ||
	      STOI(O_MIN,   &clock_time->minute) ||
	      STOI(O_SEC,   &clock_time->second)
	      )
	{
		return CVT_FAIL|CVT_BADFMT;
	}

	clock_time->usecond   = 0;
	clock_time->utcoffset = 0;

	status = (u_char) hexval(buffer[OFFS(O_FLAGS)]);
	weekday= (u_char) hexval(buffer[OFFS(O_WDAY)]);

	if ((status == 0xFF) || (weekday == 0xFF))
	{
		return CVT_FAIL|CVT_BADFMT;
	}

	clock_time->flags  = 0;

	if (weekday & HOPF_UTC)
	{
		clock_time->flags |= PARSEB_UTC;
	}
	else
	{
		if (status & HOPF_DST)
		{
			clock_time->flags     |= PARSEB_DST;
			clock_time->utcoffset  = -2*60*60; /* MET DST */
		}
		else
		{
			clock_time->utcoffset  = -1*60*60; /* MET */
		}
	}

	clock_time->flags |= (status & HOPF_DSTWARN)  ? PARSEB_ANNOUNCE : 0;

	switch (status & HOPF_MODE)
	{
	    case HOPF_INVALID:  /* Time/Date invalid */
		clock_time->flags |= PARSEB_POWERUP;
		break;

	    case HOPF_INTERNAL: /* internal clock */
		clock_time->flags |= PARSEB_NOSYNC;
		break;

	    case HOPF_RADIO:    /* Radio clock */
	    case HOPF_RADIOHP:  /* Radio clock high precision */
		break;

	    default:
		return CVT_FAIL|CVT_BADFMT;
	}

	return CVT_OK;
}
Ejemplo n.º 7
0
/*
 * parse_cvt_fnc_t cvt_mgps
 *
 * convert Meinberg GPS format
 */
static u_long
cvt_mgps(
	 unsigned char *buffer,
	 int            size,
	 struct format *format,
	 clocktime_t   *clock_time,
	 void          *local
	)
{
	if (!Strok(buffer, format->fixed_string))
	{
		return cvt_meinberg(buffer, size, format, clock_time, local);
	}
	else
	{
		if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
			 format->field_offsets[O_DAY].length) ||
		    Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
			 format->field_offsets[O_MONTH].length) ||
		    Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
			 format->field_offsets[O_YEAR].length) ||
		    Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
			 format->field_offsets[O_HOUR].length) ||
		    Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
			 format->field_offsets[O_MIN].length) ||
		    Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
			 format->field_offsets[O_SEC].length))
		{
			return CVT_FAIL|CVT_BADFMT;
		}
		else
		{
			long h;
			unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];

			clock_time->flags = PARSEB_S_LEAP|PARSEB_S_POSITION;

			clock_time->usecond = 0;

			/*
			 * calculate UTC offset
			 */
			if (Stoi(&buffer[format->field_offsets[O_UTCHOFFSET].offset], &h,
				 format->field_offsets[O_UTCHOFFSET].length))
			{
				return CVT_FAIL|CVT_BADFMT;
			}
			else
			{
				if (Stoi(&buffer[format->field_offsets[O_UTCMOFFSET].offset], &clock_time->utcoffset,
					 format->field_offsets[O_UTCMOFFSET].length))
				{
					return CVT_FAIL|CVT_BADFMT;
				}

				clock_time->utcoffset += TIMES60(h);
				clock_time->utcoffset  = TIMES60(clock_time->utcoffset);

				if (buffer[format->field_offsets[O_UTCSOFFSET].offset] != '-')
				{
					clock_time->utcoffset = -clock_time->utcoffset;
				}
			}

			/*
			 * gather status flags
			 */
			if (buffer[format->field_offsets[O_ZONE].offset] == 'S')
			    clock_time->flags    |= PARSEB_DST;

			if (clock_time->utcoffset == 0)
			    clock_time->flags |= PARSEB_UTC;

			/*
			 * no sv's seen - no time & position
			 */
			if (f[0] == '#')
			    clock_time->flags |= PARSEB_POWERUP;

			/*
			 * at least one sv seen - time (for last position)
			 */
			if (f[1] == '*')
			    clock_time->flags |= PARSEB_NOSYNC;
			else
			    if (!(clock_time->flags & PARSEB_POWERUP))
				clock_time->flags |= PARSEB_POSITION;

			/*
			 * oncoming zone switch
			 */
			if (f[3] == '!')
			    clock_time->flags |= PARSEB_ANNOUNCE;

			/*
			 * oncoming leap second
			 * 'a' code not confirmed - earth is not
			 * expected to speed up
			 */
			if (f[4] == 'A')
			    clock_time->flags |= PARSEB_LEAPADD;

			if (f[4] == 'a')
			    clock_time->flags |= PARSEB_LEAPDEL;

			/*
			 * f[5] == ' '
			 */

			/*
			 * this is the leap second
			 */
			if ((f[6] == 'L') || (clock_time->second == 60))
			    clock_time->flags |= PARSEB_LEAPSECOND;

			return CVT_OK;
		}
	}
}
Ejemplo n.º 8
0
/*
 * parse_cvt_fnc_t cvt_meinberg
 *
 * convert simple type format
 */
static u_long
cvt_meinberg(
	     unsigned char *buffer,
	     int            size,
	     struct format *unused,
	     clocktime_t   *clock_time,
	     void          *local
	     )
{
	struct format *format;

	/*
	 * select automagically correct data format
	 */
	if (Strok(buffer, meinberg_fmt[0].fixed_string))
	{
		format = &meinberg_fmt[0];
	}
	else
	{
		if (Strok(buffer, meinberg_fmt[1].fixed_string))
		{
			format = &meinberg_fmt[1];
		}
		else
		{
			return CVT_FAIL|CVT_BADFMT;
		}
	}

	/*
	 * collect data
	 */
	if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
		 format->field_offsets[O_DAY].length) ||
	    Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
		 format->field_offsets[O_MONTH].length) ||
	    Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
		 format->field_offsets[O_YEAR].length) ||
	    Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
		 format->field_offsets[O_HOUR].length) ||
	    Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
		 format->field_offsets[O_MIN].length) ||
	    Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
		 format->field_offsets[O_SEC].length))
	{
		return CVT_FAIL|CVT_BADFMT;
	}
	else
	{
		unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];

		clock_time->usecond = 0;
		clock_time->flags   = PARSEB_S_LEAP;

		if (clock_time->second == 60)
			clock_time->flags |= PARSEB_LEAPSECOND;

		/*
		 * in the extended timecode format we have also the
		 * indication that the timecode is in UTC
		 * for compatibilty reasons we start at the USUAL
		 * offset (POWERUP flag) and know that the UTC indication
		 * is the character before the powerup flag
		 */
		if ((format->flags & MBG_EXTENDED) && (f[-1] == 'U'))
		{
			/*
			 * timecode is in UTC
			 */
			clock_time->utcoffset = 0; /* UTC */
			clock_time->flags    |= PARSEB_UTC;
		}
		else
		{
			/*
			 * only calculate UTC offset if MET/MED is in time code
			 * or we have the old time code format, where we do not
			 * know whether it is UTC time or MET/MED
			 * pray that nobody switches to UTC in the *old* standard time code
			 * ROMS !!!! The new ROMS have 'U' at the ZONE field - good.
			 */
			switch (buffer[format->field_offsets[O_ZONE].offset])
			{
			case ' ':
				clock_time->utcoffset = -1*60*60; /* MET */
				break;

			case 'S':
				clock_time->utcoffset = -2*60*60; /* MED */
				break;

			case 'U':
				/*
				 * timecode is in UTC
				 */
				clock_time->utcoffset = 0;        /* UTC */
				clock_time->flags    |= PARSEB_UTC;
				break;

			default:
				return CVT_FAIL|CVT_BADFMT;
			}
		}

		/*
		 * gather status flags
		 */
		if (buffer[format->field_offsets[O_ZONE].offset] == 'S')
			clock_time->flags    |= PARSEB_DST;

		if (f[0] == '#')
			clock_time->flags |= PARSEB_POWERUP;

		if (f[1] == '*')
			clock_time->flags |= PARSEB_NOSYNC;

		if (f[3] == '!')
			clock_time->flags |= PARSEB_ANNOUNCE;

		/*
		 * oncoming leap second
		 * 'a' code not confirmed - earth is not
		 * expected to speed up
		 */
		if (f[3] == 'A')
			clock_time->flags |= PARSEB_LEAPADD;

		if (f[3] == 'a')
			clock_time->flags |= PARSEB_LEAPDEL;


		if (format->flags & MBG_EXTENDED)
		{
			clock_time->flags |= PARSEB_S_CALLBIT;

			/*
			 * DCF77 does not encode the direction -
			 * so we take the current default -
			 * earth slowing down
			 */
			clock_time->flags &= ~PARSEB_LEAPDEL;

			if (f[4] == 'A')
				clock_time->flags |= PARSEB_LEAPADD;

			if (f[5] == 'R')
				clock_time->flags |= PARSEB_CALLBIT;
		}
		return CVT_OK;
	}
}