/*
 * /src/NTP/REPOSITORY/v3/kernel/parsetest.c,v 3.4 1993/03/17 17:16:57 kardel Exp
 *
 * parsetest.c,v 3.4 1993/03/17 17:16:57 kardel Exp
 *
 * Copyright (c) 1989,1990,1991,1992,1993
 * Frank Kardel Friedrich-Alexander Universitaet Erlangen-Nuernberg
 *                                    
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * parsetest.c,v
 * Revision 3.4  1993/03/17  17:16:57  kardel
 * DEC OSF/1 ALPHA Integration - 930314
 *
 * Revision 3.3  1993/01/18  09:24:33  kardel
 * updated copyright conditions in conjunction with
 * conditions set up in the COPYRIGHT file
 *
 * Revision 3.2  1993/01/17  13:43:00  kardel
 * 1993 initial update
 *
 */

#define STREAM			/* there is no other choice - TEST HACK */

#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/errno.h>
#include <sundev/mbvar.h>
#include <sun/autoconf.h>
#include <sys/time.h>
#ifdef u3b2
#include <sys/psw.h>
#include <sys/pcb.h>
#endif
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/dir.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <sys/errno.h>
#include <fcntl.h>

#define P(X) ()

#include "parse.h"

static char *strstatus(buffer, state)
  char *buffer;
  unsigned LONG state;
{
  static struct bits
    {
      unsigned LONG bit;
      char         *name;
    } flagstrings[] =
    {
      { PARSEB_ANNOUNCE, "DST SWITCH WARNING" },
      { PARSEB_POWERUP,  "NOT SYNCHRONIZED" },
      { PARSEB_NOSYNC,   "TIME CODE NOT CONFIRMED" },
      { PARSEB_DST,      "DST" },
      { PARSEB_UTC,      "UTC DISPLAY" },
      { PARSEB_LEAP,     "LEAP WARNING" },
      { PARSEB_LEAPSECOND, "LEAP SECOND" },
      { PARSEB_ALTERNATE,"ALTERNATE ANTENNA" },
      { PARSEB_TIMECODE, "TIME CODE" },
      { PARSEB_PPS,      "PPS" },
      { PARSEB_POSITION, "POSITION" },
      { 0 }
    };

  static struct sbits
    {
      unsigned LONG bit;
      char         *name;
    } sflagstrings[] =
    {
      { PARSEB_S_LEAP,     "LEAP INDICATION" },
      { PARSEB_S_PPS,      "PPS SIGNAL" },
      { PARSEB_S_ANTENNA,  "ANTENNA" },
      { PARSEB_S_POSITION, "POSITION" },
      { 0 }
    };
  int i;

  *buffer = '\0';
  
  i = 0;
  while (flagstrings[i].bit)
    {
      if (flagstrings[i].bit & state)
	{
	  if (buffer[0])
	    strcat(buffer, "; ");
	  strcat(buffer, flagstrings[i].name);
	}
      i++;
    }
  
  if (state & (PARSEB_S_LEAP|PARSEB_S_ANTENNA|PARSEB_S_PPS|PARSEB_S_POSITION))
    {
      register char *s, *t;
      
      if (buffer[0])
	strcat(buffer, "; ");

      strcat(buffer, "(");

      t = s = buffer + strlen(buffer);
      
      i = 0;
      while (sflagstrings[i].bit)
	{
	  if (sflagstrings[i].bit & state)
	    {
	      if (t != s)
		{
		  strcpy(t, "; ");
		  t += 2;
		}
	      
	      strcpy(t, sflagstrings[i].name);
	      t += strlen(t);
	    }
	  i++;
	}
      strcpy(t, ")");
    }
  return buffer;
}

/*--------------------------------------------------
 * convert a status flag field to a string
 */
static char *parsestatus(state, buffer)
  unsigned LONG state;
  char *buffer;
{
  static struct bits
    {
      unsigned LONG bit;
      char         *name;
    } flagstrings[] =
    {
      { CVT_OK,      "CONVERSION SUCCESSFUL" },
      { CVT_NONE,    "NO CONVERSION" },
      { CVT_FAIL,    "CONVERSION FAILED" },
      { CVT_BADFMT,  "ILLEGAL FORMAT" },
      { CVT_BADDATE, "DATE ILLEGAL" },
      { CVT_BADTIME, "TIME ILLEGAL" },
      { 0 }
    };
  int i;

  *buffer = '\0';
  
  i = 0;
  while (flagstrings[i].bit)
    {
      if (flagstrings[i].bit & state)
	{
	  if (buffer[0])
	    strcat(buffer, "; ");
	  strcat(buffer, flagstrings[i].name);
	}
      i++;
    }
  
  return buffer;
}

main(argc, argv)
  int argc;
  char **argv;
{
  if (argc != 2)
    {
      fprintf(stderr,"usage: %s <parse-device>\n", argv[0]);
      exit(1);
    }
  else
    {
      int fd;
      
      fd = open(argv[1], O_RDWR);
      if (fd == -1)
	{
	  perror(argv[1]);
	  exit(1);
	}
      else
	{
	  parsectl_t  dct;
	  parsetime_t parsetime;
	  struct strioctl strioc;
	  
	  char ch;
	  
	  printf("parsetest parsetest.c,v 3.4 1993/03/17 17:16:57 kardel Exp\n");
	  
	  while (ioctl(fd, I_POP, 0) == 0)
	    ;

	  if (ioctl(fd, I_PUSH, "parse") == -1)
	    {
	      perror("ioctl(I_PUSH,\"parse\")");
	      exit(1);
	    }

	  strioc.ic_cmd = PARSEIOC_GETSTAT;
	  strioc.ic_timout = 0;
	  strioc.ic_dp = (char *)&dct;
	  strioc.ic_len = sizeof(parsectl_t);

	  if (ioctl(fd, I_STR, &strioc) == -1)
	    {
	      perror("ioctl(fd, I_STR(PARSEIOC_GETSTAT))");
	      exit(1);
	    }
	  printf("parse status: %04x\n", dct.parsestatus.flags);

	  dct.parsestatus.flags |= PARSE_STAT_FILTER;
	  strioc.ic_cmd = PARSEIOC_SETSTAT;
	  
	  if (ioctl(fd, I_STR, &strioc) == -1)
	    {
	      perror("ioctl(fd, I_STR(PARSEIOC_SETSTAT))");
	      exit(1);
	    }
	  printf("PARSE clock FILTERMODE\n");
	  
	  if (ioctl(fd, I_STR, &strioc) == -1)
	    {
	      perror("ioctl(fd, I_STR(PARSEIOC_GETSTAT))");
	      exit(1);
	    }
	  printf("parse status: %04x\n", dct.parsestatus.flags);

	  while (read(fd, &parsetime, sizeof(parsetime)) == sizeof(parsetime))
	    {
	      char tmp[200], tmp1[200], tmp2[60];

	      strncpy(tmp, asctime(localtime(&parsetime.parse_time.tv_sec)), 30);
              strncpy(tmp1,asctime(localtime(&parsetime.parse_stime.tv_sec)), 30);
              strncpy(tmp2,asctime(localtime(&parsetime.parse_ptime.tv_sec)), 30);
	      tmp[24]  = '\0';
	      tmp1[24] = '\0';
	      tmp2[24] = '\0';

	      printf("%s (+%06dus) %s PPS: %s (+%06dus), ", tmp1, parsetime.parse_stime.tv_usec, tmp, tmp2, parsetime.parse_ptime.tv_usec);

	      strstatus(tmp, parsetime.parse_state);
	      printf("state: 0x%x (%s) error: %dus, dispersion: %dus, Status: 0x%x (%s)\n",
		     parsetime.parse_state,
		     tmp,
		     parsetime.parse_usecerror,
		     parsetime.parse_usecdisp,
		     parsetime.parse_status,
		     parsestatus(parsetime.parse_status, tmp1));
	    }
	  
	  close(fd);
	}
    }
}
