# 2.11BSD#431 - /usr/src/usr.sbin/ntp/read_psti.c

##### Functions

    init_clock_psti   X
    main              X
    read_clock_psti   X

##### Variables

    debug             X

##### Macros

    CLOCKDEV          X
    DEBUG             X
    ERR_RATE          X
    MIN_READ          X

       1: #if defined(REFCLOCK) && defined(PSTI)
       2: #ifndef lint
       3: static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/read_psti.c,v 3.4.1.1 89/05/18 18:36:45 louie Exp Locker: louie $";
       4: static char *sccsid = "@(#)read_psti.c	1.1	MS/ACF	89/02/17";
       5: #endif	lint
       6:
       7: #define ERR_RATE    60  /* Repeat errors once an hour */
       8:
       9: /*
      10:  * read_psti.c
      11:  *     January 1988 -- orignal by Jeffrey I. Schiller <JIS@BITSY.MIT.EDU>
      12:  *     January 1989 -- QU version by Doug Kingston <DPK@Morgan.COM>
      13:  *
      14:  *   This module facilitates reading a Precision Time Standard, Inc.
      15:  *   WWV radio clock. We assume that clock is configured for 9600 baud,
      16:  *   no parity. Output is accepted in either 24 or 12 hour format.
      17:  *   Time is requested and processed in GMT.
      18:  *
      19:  *   This version is designed to make use of the QU command due to
      20:  *   additional information it provides (like date and flags).
      21:  *   Select is used to prevent hanging in a read when there are
      22:  *   no characters to read.  The line is run in cooked mode to
      23:  *   reduce overhead.
      24:  *
      25:  *   This requires a PSTI ROM revision later 4.01.000 or later.
      26:  *
      27:  *   Routines defined:
      28:  *	init_clock_psti(): Open the tty associated with the clock and
      29:  *			   set its tty mode bits. Returns fd on success
      30:  *			   and -1 on failure.
      31:  *	read_clock_psti(): Reads the clock and returns either 0 on success
      32:  *			   or non-zero on error.  On success, pointers are
      33:  *			   provided to the reference and local time.
      34:  */
      35: #include <stdio.h>
      36: #include <syslog.h>
      37: #include <sys/time.h>
      38: #include <sys/types.h>
      39: #include <sys/ioctl.h>
      40: #if defined(sun)
      41: #include <termio.h>
      42: #endif
      43:
      44: #ifdef  DEBUG
      45: extern int debug;
      46: #endif	DEBUG
      47:
      48: static int nerrors = 0;
      49: static char clockdata[32];
      50: #define MIN_READ 13     /* for Rev 4.01.001 */
      51:
      52: static double reltime();
      53:
      54: #ifdef STANDALONE
      55:
      56: #ifndef CLOCKDEV
      57: #define CLOCKDEV "/dev/radioclock"
      58: #endif
      59:
      60: #define DEBUG   1
      61: int debug = 1;
      62:
      63: main(argc, argv)
      64: int argc;
      65: char **argv;
      66: {
      67:     struct timeval *tvp, *otvp;
      68:
      69:     debug = argc;
      70:     if (openclock(CLOCKDEV))
      71:         do {
      72:             (void)readclock(&tvp, &otvp);
      73:             sleep(1);
      74:         } while (debug>1);
      75:     exit(0);
      76: }
      77: #endif STANDALONE
      78:
      79:
      80: init_clock_psti(timesource)
      81: char *timesource;
      82: {
      83:     int cfd;
      84: #ifdef TCSETA
      85:     struct termio tty;
      86: #else
      87:     struct sgttyb tty;
      88: #endif
      89:
      90:     if ((cfd = open(timesource, 2)) < 0) {
      91: #ifdef DEBUG
      92:         if (debug) perror(timesource); else
      93: #endif DEBUG
      94:         syslog(LOG_ERR, "can't open %s: %m", timesource);
      95:         return(-1);
      96:     }
      97:
      98:     if (ioctl(cfd, TIOCEXCL, 0) < 0) {
      99: #ifdef DEBUG
     100:         if (debug) perror("TIOCEXCL on radioclock failed"); else
     101: #endif DEBUG
     102:         syslog(LOG_ERR, "TIOCEXCL on %s failed: %m", timesource);
     103:         return(-1);
     104:     }
     105:
     106: #ifdef TCSETA
     107:     if (ioctl(cfd, TCGETA, &tty) < 0) {
     108: #ifdef DEBUG
     109:         if (debug) perror("ioctl on radioclock failed"); else
     110: #endif DEBUG
     111:         syslog(LOG_ERR, "ioctl on %s failed: %m", timesource);
     112:         return(-1);
     113:     }
     114:     tty.c_cflag = (B9600<<16)|B9600|CS8|CLOCAL|CREAD;
     115:     tty.c_iflag = ICRNL;
     116:     tty.c_oflag = 0;
     117:     tty.c_lflag = 0;
     118:     bzero((char *)tty.c_cc, sizeof tty.c_cc);
     119:     tty.c_cc[VMIN] = MIN_READ;
     120:     tty.c_cc[VTIME] = 0;
     121:     if (ioctl(cfd, TCSETA, &tty) < 0) {
     122: #else TCSETA    /* Use older Berkeley style IOCTL's */
     123:     bzero((char *)&tty, sizeof tty);
     124:     tty.sg_ispeed = tty.sg_ospeed = B9600;
     125:     tty.sg_flags = ANYP|CRMOD;
     126:     tty.sg_erase = tty.sg_kill = '\0';
     127:     if (ioctl(cfd, TIOCSETP, &tty) < 0) {
     128: #endif TCSETA
     129: #ifdef DEBUG
     130:         if (debug) perror("ioctl on radioclock failed"); else
     131: #endif DEBUG
     132:         syslog(LOG_ERR, "ioctl on %s failed: %m", timesource);
     133:         return(-1);
     134:     }
     135:     if (write(cfd, "xxxxxxsn\r", 9) != 9) {
     136: #ifdef DEBUG
     137:         if (debug) perror("init write to radioclock failed"); else
     138: #endif DEBUG
     139:         syslog(LOG_ERR, "init write to %s failed: %m", timesource);
     140:         return(-1);
     141:     }
     142:     return(cfd);            /* Succeeded in opening the clock */
     143: }
     144:
     145: /*
     146:  * read_clock_psti() -- Read the PSTI Radio Clock.
     147:  */
     148: read_clock_psti(cfd, tvpp, otvpp)
     149: int cfd;
     150: struct timeval **tvpp, **otvpp;
     151: {
     152:     static struct timeval radiotime;
     153:     static struct timeval mytime;
     154:     struct timeval timeout;
     155:     struct tm *mtm;
     156:     struct tm radio_tm, *rtm = &radio_tm;
     157:     register int i;
     158:     register int millis;
     159:     register double diff;
     160:     int stat1, stat2;
     161:     fd_set readfds;
     162:     char message[256];
     163: #ifndef TCSETA
     164:     register char *cp;
     165:     int  need;
     166: #endif TCSETA
     167:
     168:     FD_ZERO(&readfds);
     169:     FD_SET(cfd, &readfds);
     170:     timeout.tv_sec = 2;
     171:     timeout.tv_usec = 0;
     172:
     173:     (void) ioctl(cfd, TIOCFLUSH, 0);    /* scrap the I/O queues */
     174:
     175:     /* BEGIN TIME CRITICAL CODE SECTION!!!!!! */
     176:     /* EVERY CYCLE FROM THIS POINT OUT ADDS TO THE INACCURACY OF
     177: 	     THE READ CLOCK VALUE!!!!! */
     178:     if (write(cfd, "\003qu0000", 7) != 7) {
     179: #ifdef DEBUG
     180:         if (debug) printf("radioclock write failed\n"); else
     181: #endif DEBUG
     182:         if ((nerrors++%ERR_RATE) == 0)
     183:             syslog(LOG_ERR, "write to radioclock failed: %m");
     184:         return(1);
     185:     }
     186:     if(select(cfd+1, &readfds, 0, 0, &timeout) != 1) {
     187: #ifdef DEBUG
     188:         if (debug) printf("radioclock poll timed out\n"); else
     189: #endif DEBUG
     190:         if ((nerrors++%ERR_RATE) == 0)
     191:             syslog(LOG_ERR, "poll of radioclock failed: %m");
     192:         return(1);
     193:     }
     194:     if ((i = read(cfd, clockdata, sizeof clockdata)) < MIN_READ) {
     195: #ifdef DEBUG
     196:         if (debug) printf("radioclock read error (%d)\n", i); else
     197: #endif DEBUG
     198:         if ((nerrors++%ERR_RATE) == 0)
     199:             syslog(LOG_ERR, "radioclock read error (%d!=13): %m", i);
     200:         return(1);
     201:     }
     202:
     203:     (void) gettimeofday(&mytime, (struct timezone *)0);
     204:     /* END OF TIME CRITICAL CODE SECTION!!!! */
     205:
     206:     if (clockdata[i-1] != '\n') {
     207: #ifdef DEBUG
     208:         if (debug) printf("radioclock format error1 (%.12s)(0x%x)\n",
     209:             clockdata, clockdata[12]); else
     210: #endif DEBUG
     211:         if ((nerrors++%ERR_RATE) == 0)
     212:             syslog(LOG_ERR, "radioclock format error1 (%.12s)(0x%x)",
     213:                 clockdata, clockdata[12]);
     214:         return(1);
     215:     }
     216:     for (i = 0; i < 12; i++) {
     217:         if (clockdata[i] < '0' || clockdata[i] > 'o') {
     218: #ifdef DEBUG
     219:             if (debug) printf("radioclock format error2\n"); else
     220: #endif DEBUG
     221:             if ((nerrors++%ERR_RATE) == 0)
     222:                 syslog(LOG_ERR, "radioclock format error2\n");
     223:             return(1);
     224:         }
     225:     }
     226:     stat1 = clockdata[0]-'0';
     227:     stat2 = clockdata[1]-'0';
     228:     millis = ((clockdata[2]-'0')*64)+(clockdata[3]-'0');
     229:     rtm->tm_sec = (clockdata[4]-'0');
     230:     rtm->tm_min = (clockdata[5]-'0');
     231:     rtm->tm_hour = (clockdata[6]-'0');
     232:     rtm->tm_yday = ((clockdata[7]-'0')*64)+(clockdata[8]-'0')-1;
     233:     rtm->tm_year = 86+(clockdata[9]-'0');
     234:     /* byte 10 and 11 reserved */
     235:
     236:     /*
     237: 	 * Correct "hours" based on whether or not AM/PM mode is enabled.
     238: 	 * If clock is in 24 hour (military) mode then no correction is
     239: 	 * needed.
     240: 	 */
     241:     if(stat2&0x10) {        /* Map AM/PM time to Military */
     242:         if (stat2&0x8) {
     243:             if (rtm->tm_hour != 12) rtm->tm_hour += 12;
     244:         } else {
     245:             if (rtm->tm_hour == 12) rtm->tm_hour = 0;
     246:         }
     247:     }
     248:
     249:     if (stat1 != 0x4 && (nerrors++%ERR_RATE)==0) {
     250: #ifdef DEBUG
     251:         if (debug) printf("radioclock fault #%d 0x%x:%s%s%s%s%s%s\n",
     252:             nerrors, stat1,
     253:             stat1&0x20?" Out of Spec,":"",
     254:             stat1&0x10?" Hardware Fault,":"",
     255:             stat1&0x8?" Signal Fault,":"",
     256:             stat1&0x4?" Time Avail,":"",
     257:             stat1&0x2?" Year Mismatch,":"",
     258:             stat1&0x1?" Clock Reset,":"");
     259:         else {
     260: #endif DEBUG
     261:             sprintf(message, "radioclock fault #%d 0x%x:%s%s%s%s%s%s\n",
     262:                 nerrors, stat1,
     263:                 stat1&0x20?" Out of Spec,":"",
     264:                 stat1&0x10?" Hardware Fault,":"",
     265:                 stat1&0x8?" Signal Fault,":"",
     266:                 stat1&0x4?" Time Avail,":"",
     267:                 stat1&0x2?" Year Mismatch,":"",
     268:                 stat1&0x1?" Clock Reset,":"");
     269:             syslog(LOG_ERR, message);
     270:         }
     271:     }
     272:     if (stat1&0x38) /* Out of Spec, Hardware Fault, Signal Fault */
     273:         return(1);
     274:     if ((millis > 999 || rtm->tm_sec > 60 || rtm->tm_min > 60 ||
     275:          rtm->tm_hour > 23 || rtm->tm_yday > 365) && (nerrors++%ERR_RATE)==0) {
     276: #ifdef DEBUG
     277:         if (debug) printf("radioclock bogon #%d: %dd %dh %dm %ds %dms\n",
     278:             nerrors, rtm->tm_yday, rtm->tm_hour,
     279:             rtm->tm_min, rtm->tm_sec, millis);
     280:         else
     281: #endif DEBUG
     282:         sprintf(message, "radioclock bogon #%d: %dd %dh %dm %ds %dms\n",
     283:             nerrors, rtm->tm_yday, rtm->tm_hour,
     284:             rtm->tm_min, rtm->tm_sec, millis);
     285:         syslog(LOG_ERR, message);
     286:         return(1);
     287:     }
     288:
     289:     mtm = gmtime(&mytime.tv_sec);
     290:     diff =  reltime(rtm, millis*1000) - reltime(mtm, mytime.tv_usec);
     291: #ifdef DEBUG
     292:     if (debug > 1)
     293:         printf("Clock time:  19%d day %03d %02d:%02d:%02d.%03d diff %.3f\n",
     294:             rtm->tm_year, rtm->tm_yday, rtm->tm_hour,
     295:             rtm->tm_min, rtm->tm_sec, millis, diff);
     296: #endif DEBUG
     297:
     298:     if (diff > (90*24*60*60.0) && (nerrors++%ERR_RATE)==0) {
     299: #ifdef DEBUG
     300:         if (debug)
     301:             printf("offset excessive (system 19%d/%d, clock 19%d/%d)\n",
     302:                 mtm->tm_year, mtm->tm_yday,
     303:                 rtm->tm_year, mtm->tm_yday);
     304:         else
     305: #endif DEBUG
     306:         syslog(LOG_ERR, "offset excessive (system 19%d/%d, clock 19%d/%d)\n",
     307:                 mtm->tm_year, mtm->tm_yday,
     308:                 rtm->tm_year, mtm->tm_yday);
     309:         return(1);
     310:     }
     311:
     312:     diff += (double)mytime.tv_sec + ((double)mytime.tv_usec/1000000.0);
     313:     radiotime.tv_sec = diff;
     314:     radiotime.tv_usec = (diff - (double)radiotime.tv_sec) * 1000000;
     315: #ifdef DEBUG
     316:     if (debug > 1) {
     317:         printf("System time: 19%d day %03d %02d:%02d:%02d.%03d\n",
     318:             mtm->tm_year, mtm->tm_yday, mtm->tm_hour,
     319:             mtm->tm_min, mtm->tm_sec, mytime.tv_usec/1000);
     320:         printf("stat1 0%o, stat2 0%o: ", stat1, stat2);
     321:         if (stat1 || stat2)
     322:             printf("%s%s%s%s%s%s%s%s%s%s%s%s",
     323:                 stat1&0x20?" Out of Spec,":"",
     324:                 stat1&0x10?" Hardware Fault,":"",
     325:                 stat1&0x8?" Signal Fault,":"",
     326:                 stat1&0x4?" Time Avail,":"",
     327:                 stat1&0x2?" Year Mismatch,":"",
     328:                 stat1&0x1?" Clock Reset,":"",
     329:                 stat2&0x20?" DST on,":"",
     330:                 stat2&0x10?" 12hr mode,":"",
     331:                 stat2&0x8?" PM,":"",
     332:                 stat2&0x4?" Spare?,":"",
     333:                 stat2&0x2?" DST??? +1,":"",
     334:                 stat2&0x1?" DST??? -1,":"");
     335:         printf("\n");
     336:     }
     337: #endif DEBUG
     338:     /* If necessary, acknowledge "Clock Reset" flag bit */
     339:     if (stat1 & 0x1) {
     340:         if (write(cfd, "si0", 3) != 3) {
     341: #ifdef DEBUG
     342:             if (debug) printf("radioclock reset write failed\n"); else
     343: #endif DEBUG
     344:             syslog(LOG_ERR, "reset write to radioclock failed: %m");
     345:             return(1);
     346:         }
     347:     }
     348:     if (nerrors && stat1==0x4) {
     349:         syslog(LOG_ERR, "radioclock OK (after %d errors)", nerrors);
     350:         nerrors = 0;
     351:     }
     352:     *tvpp = &radiotime;
     353:     *otvpp = &mytime;
     354:     return(0);
     355: }
     356:
     357: static double
     358: reltime(tm, usec)
     359: register struct tm *tm;
     360: register int usec;
     361: {
     362:     return(tm->tm_year*(366.0*24.0*60.0*60.0) +
     363:            tm->tm_yday*(24.0*60.0*60.0) +
     364:            tm->tm_hour*(60.0*60.0) +
     365:            tm->tm_min*(60.0) +
     366:            tm->tm_sec +
     367:            usec/1000000.0);
     368: }
     369: #endif

#### Defined functions

init_clock_psti defined in line 80; used 2 times

- in /usr/src/usr.sbin/ntp/ntpd.c line 1306, 1323

main defined in line 63; never used
read_clock_psti defined in line 148; used 2 times

- in /usr/src/usr.sbin/ntp/ntpd.c line 1306, 1322

reltime defined in line 357; used 3 times

- in line 52, 290(2)

#### Defined variables

clockdata defined in line 49; used 19 times

- in line 194(2), 206-217(7), 226-233(10)

debug declared in line 45; defined in line 61; used 69 times

- in line 69-74(2), 92, 100, 109, 130, 137, 180, 188, 196, 208, 219, 251, 277, 292, 300, 316, 342
- in /usr/src/usr.sbin/ntp/ntp_adjust.c line 159, 281, 297
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 231, 267, 288, 344, 474, 492, 583, 628, 701, 713, 731, 743, 789, 847, 940, 977, 988, 994, 1029, 1038, 1047, 1057, 1081, 1118, 1132, 1139, 1156, 1205, 1220, 1264
- in /usr/src/usr.sbin/ntp/read_psti.c line 69-74(2), 92, 100, 109, 130, 137, 180, 188, 196, 208, 219, 251, 277, 292, 300, 316, 342

nerrors defined in line 48; used 15 times

- in line 182, 190, 198, 211, 221, 249-252(2), 262, 275-283(3), 298, 348-350(3)

rcsid defined in line 3; never used
sccsid defined in line 4; never used

#### Defined macros

CLOCKDEV defined in line 57; used 2 times

- in line 56, 70

DEBUG defined in line 60; used 17 times

- in line 44, 91, 99, 108, 129, 136, 179, 187, 195, 207, 218, 250, 276, 291, 299, 315, 341

ERR_RATE defined in line 7; used 8 times

- in line 182, 190, 198, 211, 221, 249, 275, 298

MIN_READ defined in line 50; used 2 times

- in line 119, 194

Last modified: 1989-05-19 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2031 |