]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ntp/ntpd/refclock_jjy.c
This commit was generated by cvs2svn to compensate for changes in r171577,
[FreeBSD/FreeBSD.git] / contrib / ntp / ntpd / refclock_jjy.c
1 /*
2  * refclock_jjy - clock driver for JJY receivers
3  */
4
5 /**********************************************************************/
6 /*                                                                    */
7 /*  Copyright (C) 2001, Takao Abe.  All rights reserved.              */
8 /*                                                                    */
9 /*  Permission to use, copy, modify, and distribute this software     */
10 /*  and its documentation for any purpose is hereby granted           */
11 /*  without fee, provided that the following conditions are met:      */
12 /*                                                                    */
13 /*  One retains the entire copyright notice properly, and both the    */
14 /*  copyright notice and this license. in the documentation and/or    */
15 /*  other materials provided with the distribution.                   */
16 /*                                                                    */
17 /*  This software and the name of the author must not be used to      */
18 /*  endorse or promote products derived from this software without    */
19 /*  prior written permission.                                         */
20 /*                                                                    */
21 /*  THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESSED OR IMPLIED    */
22 /*  WARRANTIES OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, THE        */
23 /*  IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS FOR A          */
24 /*  PARTICULAR PURPOSE.                                               */
25 /*  IN NO EVENT SHALL THE AUTHOR TAKAO ABE BE LIABLE FOR ANY DIRECT,  */
26 /*  INDIRECT, GENERAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   */
27 /*  ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE        */
28 /*  GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS      */
29 /*  INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     */
30 /*  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING        */
31 /*  NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF    */
32 /*  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33 /*                                                                    */
34 /*  This driver is developed in my private time, and is opened as     */
35 /*  voluntary contributions for the NTP.                              */
36 /*  The manufacturer of the JJY receiver has not participated in      */
37 /*  a development of this driver.                                     */
38 /*  The manufacturer does not warrant anything about this driver,     */
39 /*  and is not liable for anything about this driver.                 */
40 /*                                                                    */
41 /**********************************************************************/
42 /*                                                                    */
43 /*  Author     Takao Abe                                              */
44 /*  Email      abetakao@bea.hi-ho.ne.jp                               */
45 /*  Homepage   http://www.bea.hi-ho.ne.jp/abetakao/                   */
46 /*                                                                    */
47 /**********************************************************************/
48 /*                                                                    */
49 /*  History                                                           */
50 /*                                                                    */
51 /*  2001/07/15                                                        */
52 /*    [New]    Support the Tristate Ltd. JJY receiver                 */
53 /*                                                                    */
54 /*  2001/08/04                                                        */
55 /*    [Change] Log to clockstats even if bad reply                    */
56 /*    [Fix]    PRECISION = (-3) (about 100 ms)                        */
57 /*    [Add]    Support the C-DEX Co.Ltd. JJY receiver                 */
58 /*  2001/12/04                                                        */
59 /*    [Fix]    C-DEX JST2000 ( fukusima@goto.info.waseda.ac.jp )      */
60 /*                                                                    */
61 /**********************************************************************/
62
63 #ifdef HAVE_CONFIG_H
64 #include <config.h>
65 #endif
66
67 #if defined(REFCLOCK) && defined(CLOCK_JJY)
68
69 #include <stdio.h>
70 #include <ctype.h>
71 #include <string.h>
72 #include <sys/time.h>
73 #include <time.h>
74
75 #include "ntpd.h"
76 #include "ntp_io.h"
77 #include "ntp_tty.h"
78 #include "ntp_refclock.h"
79 #include "ntp_calendar.h"
80 #include "ntp_stdlib.h"
81
82 /**********************************************************************/
83 /*                                                                    */
84 /*  The Tristate Ltd. JJY receiver JJY01                              */
85 /*                                                                    */
86 /*  Command        Response                 Remarks                   */
87 /*  ------------   ----------------------   ---------------------     */
88 /*  date<CR><LF>   YYYY/MM/DD XXX<CR><LF>                             */
89 /*  time<CR><LF>   HH:MM:SS<CR><LF>                                   */
90 /*  stim<CR><LF>   HH:MM:SS<CR><LF>         Reply at just second      */
91 /*                                                                    */
92 /*  During synchronization after a receiver is turned on,             */
93 /*  It replies the past time from 2000/01/01 00:00:00.                */
94 /*  The function "refclock_process" checks the time and tells         */
95 /*  as an insanity time.                                              */
96 /*                                                                    */
97 /**********************************************************************/
98 /*                                                                    */
99 /*  The C-DEX Co. Ltd. JJY receiver JST2000                           */
100 /*                                                                    */
101 /*  Command        Response                 Remarks                   */
102 /*  ------------   ----------------------   ---------------------     */
103 /*  <ENQ>1J<ETX>   <STX>JYYMMDD HHMMSSS<ETX>                          */
104 /*                                                                    */
105 /**********************************************************************/
106
107 /*
108  * Interface definitions
109  */
110 #define DEVICE          "/dev/jjy%d"    /* device name and unit */
111 #define SPEED232        B9600           /* uart speed (9600 baud) */
112 #define REFID           "JJY"           /* reference ID */
113 #define DESCRIPTION     "JJY Receiver"
114 #define PRECISION       (-3)           /* precision assumed (about 100 ms) */
115
116 /*
117  * JJY unit control structure
118  */
119 struct jjyunit {
120         char    unittype ;      /* UNITTYPE_XXXXXXXXXX */
121         short   version ;
122         short   linediscipline ;        /* LDISC_CLK or LDISC_RAW */
123         int     linecount ;
124         int     lineerror ;
125         int     year, month, day, hour, minute, second, msecond ;
126 /* LDISC_RAW only */
127 #define MAX_LINECOUNT   8
128 #define MAX_RAWBUF      64
129         int     lineexpect ;
130         int     charexpect [ MAX_LINECOUNT ] ;
131         int     charcount ;
132         char    rawbuf [ MAX_RAWBUF ] ;
133 };
134
135 #define UNITTYPE_TRISTATE_JJY01 1
136 #define UNITTYPE_CDEX_JST2000   2
137
138 /*
139  * Function prototypes
140  */
141 static  int     jjy_start                   P((int, struct peer *));
142 static  void    jjy_shutdown                P((int, struct peer *));
143 static  void    jjy_poll                    P((int, struct peer *));
144 static  void    jjy_poll_tristate_jjy01     P((int, struct peer *));
145 static  void    jjy_poll_cdex_jst2000       P((int, struct peer *));
146 static  void    jjy_receive                 P((struct recvbuf *));
147 static  int     jjy_receive_tristate_jjy01  P((struct recvbuf *));
148 static  int     jjy_receive_cdex_jst2000    P((struct recvbuf *));
149
150 /*
151  * Transfer vector
152  */
153 struct  refclock refclock_jjy = {
154         jjy_start,      /* start up driver */
155         jjy_shutdown,   /* shutdown driver */
156         jjy_poll,       /* transmit poll message */
157         noentry,        /* not used */
158         noentry,        /* not used */
159         noentry,        /* not used */
160         NOFLAGS         /* not used */
161 };
162
163 /*
164  * Start up driver return code
165  */
166 #define RC_START_SUCCESS        1
167 #define RC_START_ERROR          0
168
169 /*
170  * Local constants definition
171  */
172
173 #define MAX_LOGTEXT     64
174
175
176 /**************************************************************************************************/
177 /*  jjy_start - open the devices and initialize data for processing                               */
178 /**************************************************************************************************/
179 static int
180 jjy_start ( int unit, struct peer *peer )
181 {
182
183         struct jjyunit      *up ;
184         struct refclockproc *pp ;
185         int     fd ;
186         char    *pDeviceName ;
187         short   iDiscipline ;
188
189 #ifdef DEBUG
190         if ( debug ) {
191                 printf ( "jjy_start (refclock_jjy.c) : %s  mode=%d  ", ntoa(&peer->srcadr), peer->ttl ) ;
192                 printf ( DEVICE, unit ) ;
193                 printf ( "\n" ) ;
194         }
195 #endif
196         /*
197          * Open serial port
198          */
199         if ( ! ( pDeviceName = (char*) emalloc ( strlen(DEVICE) + 10 ) ) ) {
200                 return RC_START_ERROR ;
201         }
202         sprintf ( pDeviceName, DEVICE, unit ) ;
203
204         /*
205          * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
206          */
207         switch ( peer->ttl ) {
208         case 0 :
209         case 1 : iDiscipline = LDISC_CLK ; break ;
210         case 2 : iDiscipline = LDISC_RAW ; break ;
211         default :
212                 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
213                           ntoa(&peer->srcadr), peer->ttl ) ;
214                 free ( (void*) pDeviceName ) ;
215                 return RC_START_ERROR ;
216         }
217
218         if ( ! ( fd = refclock_open ( pDeviceName, SPEED232, iDiscipline ) ) ) {
219                 free ( (void*) pDeviceName ) ;
220                 return RC_START_ERROR ;
221         }
222         free ( (void*) pDeviceName ) ;
223
224         /*
225          * Allocate and initialize unit structure
226          */
227         if ( ! ( up = (struct jjyunit *) emalloc (sizeof(struct jjyunit)) ) ) {
228                 close ( fd ) ;
229                 return RC_START_ERROR ;
230         }
231
232         memset ( (char*)up, 0, sizeof(struct jjyunit) ) ;
233         up->linediscipline = iDiscipline ;
234
235         /*
236          * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
237          */
238         switch ( peer->ttl ) {
239         case 0 :
240                 /*
241                  * The mode 0 is a default clock type at this time.
242                  * But this will be change to auto-detect mode in the future.
243                  */
244         case 1 :
245                 up->unittype = UNITTYPE_TRISTATE_JJY01 ;
246                 up->version  = 100 ;
247                 up->lineexpect = 2 ;
248                 up->charexpect[0] = 14 ; /* YYYY/MM/DD WWW<CR><LF> */
249                 up->charexpect[1] =  8 ; /* HH:MM:SS<CR><LF> */
250                 break ;
251         case 2 :
252                 up->unittype = UNITTYPE_CDEX_JST2000 ;
253                 up->lineexpect = 1 ;
254                 up->charexpect[0] = 15 ; /* <STX>JYYMMDD HHMMSSS<ETX> */
255                 break ;
256         default :
257                 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
258                           ntoa(&peer->srcadr), peer->ttl ) ;
259                 close ( fd ) ;
260                 free ( (void*) up ) ;
261                 return RC_START_ERROR ;
262         }
263
264         pp = peer->procptr ;
265         pp->unitptr       = (caddr_t) up ;
266         pp->io.clock_recv = jjy_receive ;
267         pp->io.srcclock   = (caddr_t) peer ;
268         pp->io.datalen    = 0 ;
269         pp->io.fd         = fd ;
270         if ( ! io_addclock(&pp->io) ) {
271                 close ( fd ) ;
272                 free ( (void*) up ) ;
273                 return RC_START_ERROR ;
274         }
275
276         /*
277          * Initialize miscellaneous variables
278          */
279         peer->precision = PRECISION ;
280         peer->burst     = 1 ;
281         pp->clockdesc   = DESCRIPTION ;
282         memcpy ( (char*)&pp->refid, REFID, strlen(REFID) ) ;
283
284         return RC_START_SUCCESS ;
285
286 }
287
288
289 /**************************************************************************************************/
290 /*  jjy_shutdown - shutdown the clock                                                             */
291 /**************************************************************************************************/
292 static void
293 jjy_shutdown ( int unit, struct peer *peer )
294 {
295
296         struct jjyunit      *up;
297         struct refclockproc *pp;
298
299         pp = peer->procptr ;
300         up = (struct jjyunit *) pp->unitptr ;
301         io_closeclock ( &pp->io ) ;
302         free ( (void*) up ) ;
303
304 }
305
306
307 /**************************************************************************************************/
308 /*  jjy_receive - receive data from the serial interface                                          */
309 /**************************************************************************************************/
310 static void
311 jjy_receive ( struct recvbuf *rbufp )
312 {
313
314         struct jjyunit      *up ;
315         struct refclockproc *pp ;
316         struct peer         *peer;
317
318         l_fp    tRecvTimestamp;         /* arrival timestamp */
319         int     rc ;
320         char    sLogText [ MAX_LOGTEXT ] ;
321         int     i, bCntrlChar ;
322
323         /*
324          * Initialize pointers and read the timecode and timestamp
325          */
326         peer = (struct peer *) rbufp->recv_srcclock ;
327         pp = peer->procptr ;
328         up = (struct jjyunit *) pp->unitptr ;
329
330         /*
331          * Get next input line
332          */
333         pp->lencode  = refclock_gtlin ( rbufp, pp->a_lastcode, BMAX, &tRecvTimestamp ) ;
334
335         if ( up->linediscipline == LDISC_RAW ) {
336                 /*
337                  * The reply with <STX> and <ETX> may give a blank line
338                  */
339                 if ( pp->lencode == 0  &&  up->charcount == 0 ) return ;
340                 /*
341                  * Copy received charaters to temporary buffer 
342                  */
343                 for ( i = 0 ; i < pp->lencode && up->charcount < MAX_RAWBUF - 2 ; i ++ , up->charcount ++ ) {
344                         up->rawbuf[up->charcount] = pp->a_lastcode[i] ;
345                 }
346                 while ( up->charcount > 0 && up->rawbuf[0] < ' ' ) {
347                         for ( i = 0 ; i < up->charcount - 1 ; i ++ ) up->rawbuf[i] = up->rawbuf[i+1] ;
348                         up->charcount -- ;
349                 }
350                 bCntrlChar = 0 ;
351                 for ( i = 0 ; i < up->charcount ; i ++ ) {
352                         if ( up->rawbuf[i] < ' ' ) {
353                                 bCntrlChar = 1 ;
354                                 break ;
355                         }
356                 }
357                 if ( pp->lencode > 0  &&  up->linecount < up->lineexpect ) {
358                         if ( bCntrlChar == 0  &&  up->charcount < up->charexpect[up->linecount] ) return ;
359                 }
360                 up->rawbuf[up->charcount] = 0 ;
361         } else {
362                 /*
363                  * The reply with <CR><LF> gives a blank line
364                  */
365                 if ( pp->lencode == 0 ) return ;
366         }
367         /*
368          * We get down to business
369          */
370
371         pp->lastrec = tRecvTimestamp ;
372
373         up->linecount ++ ;
374
375         if ( up->lineerror != 0 ) return ;
376
377         switch ( up->unittype ) {
378         
379         case UNITTYPE_TRISTATE_JJY01 :
380                 rc = jjy_receive_tristate_jjy01  ( rbufp ) ;
381                 break ;
382
383         case UNITTYPE_CDEX_JST2000 :
384                 rc = jjy_receive_cdex_jst2000 ( rbufp ) ;
385                 break ;
386
387         default :
388                 rc = 0 ;
389                 break ;
390
391         }
392
393         if ( up->linediscipline == LDISC_RAW ) {
394                 if ( up->linecount <= up->lineexpect  &&  up->charcount > up->charexpect[up->linecount-1] ) {
395                         for ( i = 0 ; i < up->charcount - up->charexpect[up->linecount-1] ; i ++ ) {
396                                 up->rawbuf[i] = up->rawbuf[i+up->charexpect[up->linecount-1]] ;
397                         }
398                         up->charcount -= up->charexpect[up->linecount-1] ;
399                 } else {
400                         up->charcount = 0 ;
401                 }
402         }
403
404         if ( rc == 0 ) return ;
405
406         if ( up->lineerror != 0 ) {
407                 refclock_report ( peer, CEVNT_BADREPLY ) ;
408                 strcpy  ( sLogText, "BAD REPLY [" ) ;
409                 if ( up->linediscipline == LDISC_RAW ) {
410                         strncat ( sLogText, up->rawbuf, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
411                 } else {
412                         strncat ( sLogText, pp->a_lastcode, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
413                 }
414                 sLogText[MAX_LOGTEXT-1] = 0 ;
415                 if ( strlen ( sLogText ) < MAX_LOGTEXT - 2 ) strcat ( sLogText, "]" ) ;
416                 record_clock_stats ( &peer->srcadr, sLogText ) ;
417                 return ;
418         }
419
420         pp->year   = up->year ;
421         pp->day    = ymd2yd ( up->year, up->month, up->day ) ;
422         pp->hour   = up->hour ;
423         pp->minute = up->minute ;
424         pp->second = up->second ;
425         pp->nsec   = up->msecond * 1000000;
426
427         /* 
428          * JST to UTC 
429          */
430         pp->hour -= 9 ;
431         if ( pp->hour < 0 ) {
432                 pp->hour += 24 ;
433                 pp->day -- ;
434                 if ( pp->day < 1 ) {
435                         pp->year -- ;
436                         pp->day  = ymd2yd ( pp->year, 12, 31 ) ;
437                 }
438         }
439 #ifdef DEBUG
440         if ( debug ) {
441                 printf ( "jjy_receive (refclock_jjy.c) : %04d/%02d/%02d %02d:%02d:%02d JST   ", 
442                           up->year, up->month, up->day, up->hour, up->minute, up->second ) ;
443                 printf ( "( %04d/%03d %02d:%02d:%02d UTC )\n",
444                           pp->year, pp->day, pp->hour, pp->minute, pp->second ) ;
445         }
446 #endif
447
448         /*
449          * Process the new sample in the median filter and determine the
450          * timecode timestamp.
451          */
452         if ( ! refclock_process ( pp ) ) {
453                 refclock_report(peer, CEVNT_BADTIME);
454                 sprintf ( sLogText, "BAD TIME %04d/%02d/%02d %02d:%02d:%02d JST",
455                           up->year, up->month, up->day, up->hour, up->minute, up->second ) ;
456                 record_clock_stats ( &peer->srcadr, sLogText ) ;
457                 return ;
458         }
459
460         sprintf ( sLogText, "%04d/%02d/%02d %02d:%02d:%02d JST",
461                   up->year, up->month, up->day, up->hour, up->minute, up->second ) ;
462         pp->lastref = pp->lastrec;
463         refclock_receive(peer);
464         record_clock_stats ( &peer->srcadr, sLogText ) ;
465 }
466
467 /**************************************************************************************************/
468
469 static int
470 jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
471 {
472
473         struct jjyunit      *up ;
474         struct refclockproc *pp ;
475         struct peer         *peer;
476
477         char    *pBuf ;
478         int     iLen ;
479         int     rc ;
480
481         /*
482          * Initialize pointers and read the timecode and timestamp
483          */
484         peer = (struct peer *) rbufp->recv_srcclock ;
485         pp = peer->procptr ;
486         up = (struct jjyunit *) pp->unitptr ;
487
488         if ( up->linediscipline == LDISC_RAW ) {
489                 pBuf = up->rawbuf ;
490                 iLen = up->charcount ;
491         } else {
492             pBuf = pp->a_lastcode ;
493             iLen = pp->lencode ;
494         }
495
496         switch ( up->linecount ) {
497
498         case 1 : /* YYYY/MM/DD */
499
500                 if ( iLen < 10 ) {
501                         up->lineerror = 1 ;
502                         break ;
503                 }
504                 rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year, &up->month, &up->day ) ;
505                 if ( rc != 3 || up->year < 2000 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31 ) {
506                         up->lineerror = 1 ;
507                         break ;
508                 }
509                 return 0 ;
510
511         case 2 : /* HH:MM:SS */
512
513                 if ( iLen < 8 ) {
514                         up->lineerror = 1 ;
515                         break ;
516                 }
517                 rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour, &up->minute, &up->second ) ;
518                 if ( rc != 3 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
519                         up->lineerror = 1 ;
520                         break ;
521                 }
522                 up->msecond = 0 ;
523                 if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) {
524                         /*
525                          * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver continuously.
526                          * But the JJY receiver replies a date and time separately.
527                          * Just after midnight transtions, we ignore this time.
528                          */
529                         return 0 ;
530                 }
531                 break ;
532
533         default : /*  Unexpected reply */
534
535                 up->lineerror = 1 ;
536                 break ;
537
538         }
539
540         return 1 ;
541
542 }
543
544 /**************************************************************************************************/
545
546 static int
547 jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
548 {
549
550         struct jjyunit      *up ;
551         struct refclockproc *pp ;
552         struct peer         *peer;
553
554         char    *pBuf ;
555         int     iLen ;
556         int     rc ;
557
558         /*
559          * Initialize pointers and read the timecode and timestamp
560          */
561         peer = (struct peer *) rbufp->recv_srcclock ;
562         pp = peer->procptr ;
563         up = (struct jjyunit *) pp->unitptr ;
564
565         if ( up->linediscipline == LDISC_RAW ) {
566                 pBuf = up->rawbuf ;
567                 iLen = up->charcount ;
568         } else {
569             pBuf = pp->a_lastcode ;
570             iLen = pp->lencode ;
571         }
572
573         switch ( up->linecount ) {
574
575         case 1 : /* JYYMMDD HHMMSSS */
576
577                 if ( iLen < 15 ) {
578                         up->lineerror = 1 ;
579                         break ;
580                 }
581                 rc = sscanf ( pBuf, "J%2d%2d%2d%*1d%2d%2d%2d%1d",
582                               &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second, &up->msecond ) ;
583                 if ( rc != 7 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
584                   || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
585                         up->lineerror = 1 ;
586                         break ;
587                 }
588                 up->year    += 2000 ;
589                 up->msecond *= 100 ;
590                 break ;
591
592         default : /*  Unexpected reply */
593
594                 up->lineerror = 1 ;
595                 break ;
596
597         }
598
599         return 1 ;
600
601 }
602
603 /**************************************************************************************************/
604 /*  jjy_poll - called by the transmit procedure                                                   */
605 /**************************************************************************************************/
606 static void
607 jjy_poll ( int unit, struct peer *peer )
608 {
609
610         struct jjyunit      *up;
611         struct refclockproc *pp;
612
613         pp = peer->procptr;
614         up = (struct jjyunit *) pp->unitptr ;
615
616         if ( pp->polls > 0  &&  up->linecount == 0 ) {
617                 /*
618                  * No reply for last command
619                  */
620                 refclock_report ( peer, CEVNT_TIMEOUT ) ;
621         }
622
623 #ifdef DEBUG
624         if ( debug ) {
625                 printf ( "jjy_poll (refclock_jjy.c) : %ld\n", pp->polls ) ;
626         }
627 #endif
628
629         pp->polls ++ ;
630
631         up->linecount = 0 ;
632         up->lineerror = 0 ;
633         up->charcount = 0 ;
634
635         switch ( up->unittype ) {
636         
637         case UNITTYPE_TRISTATE_JJY01 :
638                 jjy_poll_tristate_jjy01  ( unit, peer ) ;
639                 break ;
640
641         case UNITTYPE_CDEX_JST2000 :
642                 jjy_poll_cdex_jst2000 ( unit, peer ) ;
643                 break ;
644
645         default :
646                 break ;
647
648         }
649
650 }
651
652 /**************************************************************************************************/
653
654 static void
655 jjy_poll_tristate_jjy01  ( int unit, struct peer *peer )
656 {
657
658         struct jjyunit      *up;
659         struct refclockproc *pp;
660
661         pp = peer->procptr;
662         up = (struct jjyunit *) pp->unitptr ;
663
664         /*
665          * Send "date<CR><LF>" command
666          */
667
668         if ( write ( pp->io.fd, "date\r\n",6 ) != 6  ) {
669                 refclock_report ( peer, CEVNT_FAULT ) ;
670         }
671
672         /*
673          * Send "stim<CR><LF>" or "time<CR><LF>" command
674          */
675
676         if ( up->version >= 100 ) {
677                 if ( write ( pp->io.fd, "stim\r\n",6 ) != 6  ) {
678                         refclock_report ( peer, CEVNT_FAULT ) ;
679                 }
680         } else {
681                 if ( write ( pp->io.fd, "time\r\n",6 ) != 6  ) {
682                         refclock_report ( peer, CEVNT_FAULT ) ;
683                 }
684         }
685
686 }
687
688 /**************************************************************************************************/
689
690 static void
691 jjy_poll_cdex_jst2000 ( int unit, struct peer *peer )
692 {
693
694         struct refclockproc *pp;
695
696         pp = peer->procptr;
697
698         /*
699          * Send "<ENQ>1J<ETX>" command
700          */
701
702         if ( write ( pp->io.fd, "\0051J\003", 4 ) != 4  ) {
703                 refclock_report ( peer, CEVNT_FAULT ) ;
704         }
705
706 }
707
708 #else
709 int refclock_jjy_bs ;
710 #endif /* REFCLOCK */