FreeBSD/contrib/ntp/libparse/clk_meinberg.c
/*
 * parse_inp_fnc_t gps_input
 *
 * grep binary data from input stream
 */
parse_inp_fnc_t gps_input
grep binary data from input stream
parse_inp_fnc_t gps_input grep binary data from input stream
static u_long
gps_input(
	  parse_t      *parseio,
	  char ch,
	  timestamp_t  *tstamp
	  )
{
  CSUM calc_csum;                    
  GPS_MSG_HDR header;
  struct msg_buf *msg_buf;
  msg_buf = (struct msg_buf *)parseio->parse_pdata;
  parseprintf(DD_PARSE, ("gps_input(0x%p, 0x%x, ...)\n", (void*)parseio, ch));
  if (!msg_buf)
    return PARSE_INP_SKIP;
  if ( msg_buf->phase == MBG_NONE )
    {                  
      switch (ch)
	{
	case SOH:
	  parseprintf(DD_PARSE, ("gps_input: SOH seen\n"));
	  msg_buf->len = sizeof( header ); 
	  msg_buf->phase = MBG_HEADER; 
	  break;
	case STX:
	  parseprintf(DD_PARSE, ("gps_input: STX seen\n"));
	  msg_buf->len = 0;
	  msg_buf->phase = MBG_STRING; 
	  parseio->parse_index = 1;
	  parseio->parse_data[0] = ch;
	  break;
	default:
	  return PARSE_INP_SKIP;	
	}
      parseio->parse_dtime.parse_msglen = 1; 
      parseio->parse_dtime.parse_msg[0] = ch; 
      parseio->parse_dtime.parse_stime  = *tstamp; 
      return PARSE_INP_SKIP;
    }
  if ((msg_buf->phase == MBG_STRING) &&
      (parseio->parse_index < parseio->parse_dsize))
    parseio->parse_data[parseio->parse_index++] = ch;
  parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
  if (parseio->parse_dtime.parse_msglen > sizeof(parseio->parse_dtime.parse_msg))
    {
      msg_buf->phase = MBG_NONE; 
      parseio->parse_data[parseio->parse_index] = '\0';
      memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
      parseio->parse_ldsize = parseio->parse_index;
      return PARSE_INP_DATA;
    }
  switch (msg_buf->phase)
    {
    case MBG_HEADER:
    case MBG_DATA:
      msg_buf->len--;
      if ( msg_buf->len )               
	return PARSE_INP_SKIP;
      parseprintf(DD_PARSE, ("gps_input: %s complete\n", (msg_buf->phase == MBG_DATA) ? "data" : "header"));
      break;
    case MBG_STRING:
      if ((ch == ETX) || (parseio->parse_index >= parseio->parse_dsize))
	{
	  msg_buf->phase = MBG_NONE;
	  parseprintf(DD_PARSE, ("gps_input: string complete\n"));
	  parseio->parse_data[parseio->parse_index] = '\0';
	  memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
	  parseio->parse_ldsize = parseio->parse_index;
	  parseio->parse_index = 0;
	  return PARSE_INP_TIME;
	}
      else
	{
	  return PARSE_INP_SKIP;
	}
    }
  if ( msg_buf->phase == MBG_HEADER )
    {         
      unsigned char *datap = parseio->parse_dtime.parse_msg + 1;
      get_mbg_header(&datap, &header);
      parseprintf(DD_PARSE, ("gps_input: header: cmd 0x%x, len %d, dcsum 0x%x, hcsum 0x%x\n",
			     (int)header.cmd, (int)header.len, (int)header.data_csum,
			     (int)header.hdr_csum));
      calc_csum = mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg + 1, (unsigned short)6 );
      if ( calc_csum != header.hdr_csum )
	{
	  parseprintf(DD_PARSE, ("gps_input: header checksum mismatch expected 0x%x, got 0x%x\n",
				 (int)calc_csum, (int)mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg, (unsigned short)6 )));
	  msg_buf->phase = MBG_NONE;  
	  return PARSE_INP_DATA;      
	}
      if ((header.len == 0)  ||       
	  (header.len >= (sizeof (parseio->parse_dtime.parse_msg) - sizeof(header) - 1)))	
	{
	  msg_buf->phase = MBG_NONE;  
	  return (header.len == 0) ? PARSE_INP_DATA : PARSE_INP_SKIP; 
	}
      parseprintf(DD_PARSE, ("gps_input: expecting %d bytes of data message\n", (int)header.len));
      msg_buf->len   = header.len;
      msg_buf->phase = MBG_DATA;      
      return PARSE_INP_SKIP;
    }
  parseprintf(DD_PARSE, ("gps_input: message data complete\n"));
  msg_buf->phase = MBG_NONE;	      
  return PARSE_INP_DATA;              
}
static u_long gps_input ( parse_t * parseio , char ch , timestamp_t * tstamp ) { CSUM calc_csum ; GPS_MSG_HDR header ; struct msg_buf * msg_buf ; msg_buf = ( struct msg_buf * ) parseio -> parse_pdata ; parseprintf ( DD_PARSE , ( " \n " , ( void * ) parseio , ch ) ) ; if ( ! msg_buf ) return PARSE_INP_SKIP ; if ( msg_buf -> phase == MBG_NONE ) { switch ( ch ) { case SOH : parseprintf ( DD_PARSE , ( " \n " ) ) ; msg_buf -> len = sizeof ( header ) ; msg_buf -> phase = MBG_HEADER ; break ; case STX : parseprintf ( DD_PARSE , ( " \n " ) ) ; msg_buf -> len = 0 ; msg_buf -> phase = MBG_STRING ; parseio -> parse_index = 1 ; parseio -> parse_data [ 0 ] = ch ; break ; default : return PARSE_INP_SKIP ; } parseio -> parse_dtime . parse_msglen = 1 ; parseio -> parse_dtime . parse_msg [ 0 ] = ch ; parseio -> parse_dtime . parse_stime = * tstamp ; return PARSE_INP_SKIP ; } if ( ( msg_buf -> phase == MBG_STRING ) && ( parseio -> parse_index < parseio -> parse_dsize ) ) parseio -> parse_data [ parseio -> parse_index ++ ] = ch ; parseio -> parse_dtime . parse_msg [ parseio -> parse_dtime . parse_msglen ++ ] = ch ; if ( parseio -> parse_dtime . parse_msglen > sizeof ( parseio -> parse_dtime . parse_msg ) ) { msg_buf -> phase = MBG_NONE ; parseio -> parse_data [ parseio -> parse_index ] = ' \0 ' ; memcpy ( parseio -> parse_ldata , parseio -> parse_data , ( unsigned ) ( parseio -> parse_index + 1 ) ) ; parseio -> parse_ldsize = parseio -> parse_index ; return PARSE_INP_DATA ; } switch ( msg_buf -> phase ) { case MBG_HEADER : case MBG_DATA : msg_buf -> len -- ; if ( msg_buf -> len ) return PARSE_INP_SKIP ; parseprintf ( DD_PARSE , ( " \n " , ( msg_buf -> phase == MBG_DATA ) ? " " : " " ) ) ; break ; case MBG_STRING : if ( ( ch == ETX ) || ( parseio -> parse_index >= parseio -> parse_dsize ) ) { msg_buf -> phase = MBG_NONE ; parseprintf ( DD_PARSE , ( " \n " ) ) ; parseio -> parse_data [ parseio -> parse_index ] = ' \0 ' ; memcpy ( parseio -> parse_ldata , parseio -> parse_data , ( unsigned ) ( parseio -> parse_index + 1 ) ) ; parseio -> parse_ldsize = parseio -> parse_index ; parseio -> parse_index = 0 ; return PARSE_INP_TIME ; } else { return PARSE_INP_SKIP ; } } if ( msg_buf -> phase == MBG_HEADER ) { unsigned char * datap = parseio -> parse_dtime . parse_msg + 1 ; get_mbg_header ( & datap , & header ) ; parseprintf ( DD_PARSE , ( " \n " , ( int ) header . cmd , ( int ) header . len , ( int ) header . data_csum , ( int ) header . hdr_csum ) ) ; calc_csum = mbg_csum ( ( unsigned char * ) parseio -> parse_dtime . parse_msg + 1 , ( unsigned short ) 6 ) ; if ( calc_csum != header . hdr_csum ) { parseprintf ( DD_PARSE , ( " \n " , ( int ) calc_csum , ( int ) mbg_csum ( ( unsigned char * ) parseio -> parse_dtime . parse_msg , ( unsigned short ) 6 ) ) ) ; msg_buf -> phase = MBG_NONE ; return PARSE_INP_DATA ; } if ( ( header . len == 0 ) || ( header . len >= ( sizeof ( parseio -> parse_dtime . parse_msg ) - sizeof ( header ) - 1 ) ) ) { msg_buf -> phase = MBG_NONE ; return ( header . len == 0 ) ? PARSE_INP_DATA : PARSE_INP_SKIP ; } parseprintf ( DD_PARSE , ( " \n " , ( int ) header . len ) ) ; msg_buf -> len = header . len ; msg_buf -> phase = MBG_DATA ; return PARSE_INP_SKIP ; } parseprintf ( DD_PARSE , ( " \n " ) ) ; msg_buf -> phase = MBG_NONE ; return PARSE_INP_DATA ; }
parse_inp_fnc_t gps_input
 grep binary data from input stream
parse_inp_fnc_t gps_input grep binary data from input stream
/* used to compare the incoming csums */ /* not receiving yet */ /* prepare to receive msg header */ /* receiving header */ /* prepare to receive ASCII ETX delimited message */ /* keep searching */ /* reset buffer pointer */ /* fill in first character */ /* collect timestamp */ /* SOH/STX has already been received */ /* save incoming character in both buffers if needbe */ /* buffer overflow - discard */ /* transfer not complete */ /* cnt == 0, so the header or the whole message is complete */ /* header complete now */ /* back to hunting mode */ /* invalid header checksum received - pass up for detection */ /* no data to wait for */ /* blows anything we have space for */ /* back to hunting mode */ /* message complete/throwaway */ /* save number of bytes to wait for */ /* flag header already complete */ /* Header and data have been received. The header checksum has been */ /* checked */ /* back to hunting mode */ /* message complete, must be evaluated */