]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 1618] jjy_start() unreachable code.
authorDave Hart <hart@ntp.org>
Sun, 21 Nov 2010 23:03:15 +0000 (23:03 +0000)
committerDave Hart <hart@ntp.org>
Sun, 21 Nov 2010 23:03:15 +0000 (23:03 +0000)
refclock_jjy.c Tristate JJY01/02 improvements.

bk: 4ce9a533GRkfO8Kg2DjHQk6kbadLmw

html/copyright.html
ntpd/refclock_jjy.c

index 8dbf29956679f0e9e538bf52d0f4436aa87aef2e..09ca023f30dc512b8a6370c50cf13cee0e906106 100644 (file)
@@ -38,6 +38,7 @@
 </pre>
                <p>The following individuals contributed in part to the Network Time Protocol Distribution Version 4 and are acknowledged as authors of this work.</p>
                <ol>
+                       <li class="inline"><a href="mailto:%20takao_abe@xurb.jp">Takao Abe &lt;takao_abe@xurb.jp&gt;</a> Clock driver for JJY receivers
                        <li class="inline"><a href="mailto:%20mark_andrews@isc.org">Mark Andrews &lt;mark_andrews@isc.org&gt;</a> Leitch atomic clock controller
                        <li class="inline"><a href="mailto:%20altmeier@atlsoft.de">Bernd Altmeier &lt;altmeier@atlsoft.de&gt;</a> hopf Elektronik serial line and PCI-bus devices
                        <li class="inline"><a href="mailto:%20vbais@mailman1.intel.co">Viraj Bais &lt;vbais@mailman1.intel.com&gt;</a> and <a href="mailto:%20kirkwood@striderfm.intel.com">Clayton Kirkwood &lt;kirkwood@striderfm.intel.com&gt;</a> port to WindowsNT 3.5
index 13f56defdadaf9f820724fc1e2c43d1bbbb018d8..df7869dc987b0cdaf7a5db12d71c1dae50816509 100644 (file)
@@ -3,80 +3,95 @@
  */
 
 /**********************************************************************/
-/*                                                                    */
-/*  Copyright (C) 2001-2004, Takao Abe.  All rights reserved.         */
-/*                                                                    */
+/*                                                                   */
+/*  Copyright (C) 2001-2004, Takao Abe.  All rights reserved.        */
+/*                                                                   */
 /*  Permission to use, copy, modify, and distribute this software     */
-/*  and its documentation for any purpose is hereby granted           */
+/*  and its documentation for any purpose is hereby granted          */
 /*  without fee, provided that the following conditions are met:      */
-/*                                                                    */
+/*                                                                   */
 /*  One retains the entire copyright notice properly, and both the    */
 /*  copyright notice and this license. in the documentation and/or    */
-/*  other materials provided with the distribution.                   */
-/*                                                                    */
+/*  other materials provided with the distribution.                  */
+/*                                                                   */
 /*  This software and the name of the author must not be used to      */
 /*  endorse or promote products derived from this software without    */
-/*  prior written permission.                                         */
-/*                                                                    */
+/*  prior written permission.                                        */
+/*                                                                   */
 /*  THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESSED OR IMPLIED    */
-/*  WARRANTIES OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, THE        */
-/*  IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS FOR A          */
-/*  PARTICULAR PURPOSE.                                               */
+/*  WARRANTIES OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, THE       */
+/*  IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS FOR A         */
+/*  PARTICULAR PURPOSE.                                                      */
 /*  IN NO EVENT SHALL THE AUTHOR TAKAO ABE BE LIABLE FOR ANY DIRECT,  */
 /*  INDIRECT, GENERAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   */
-/*  ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE        */
+/*  ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE       */
 /*  GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS      */
 /*  INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     */
-/*  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING        */
+/*  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING       */
 /*  NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF    */
 /*  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-/*                                                                    */
+/*                                                                   */
 /*  This driver is developed in my private time, and is opened as     */
-/*  voluntary contributions for the NTP.                              */
+/*  voluntary contributions for the NTP.                             */
 /*  The manufacturer of the JJY receiver has not participated in      */
-/*  a development of this driver.                                     */
+/*  a development of this driver.                                    */
 /*  The manufacturer does not warrant anything about this driver,     */
-/*  and is not liable for anything about this driver.                 */
-/*                                                                    */
+/*  and is not liable for anything about this driver.                */
+/*                                                                   */
 /**********************************************************************/
-/*                                                                    */
-/*  Author     Takao Abe                                              */
-/*  Email      abetakao@bea.hi-ho.ne.jp                               */
-/*  Homepage   http://www.bea.hi-ho.ne.jp/abetakao/                   */
-/*                                                                    */
+/*                                                                   */
+/*  Author     Takao Abe                                             */
+/*  Email      takao_abe@xurb.jp                                     */
+/*  Homepage   http://www.bea.hi-ho.ne.jp/abetakao/                  */
+/*                                                                   */
+/*  The email address abetakao@bea.hi-ho.ne.jp is never read         */
+/*  from 2010, because a few filtering rule are provided by the              */
+/*  "hi-ho.ne.jp", and lots of spam mail are reached.                */
+/*  New email address for supporting the refclock_jjy is             */
+/*  takao_abe@xurb.jp                                                */
+/*                                                                   */
 /**********************************************************************/
-/*                                                                    */
-/*  History                                                           */
-/*                                                                    */
-/*  2001/07/15                                                        */
-/*    [New]    Support the Tristate Ltd. JJY receiver                 */
-/*                                                                    */
-/*  2001/08/04                                                        */
-/*    [Change] Log to clockstats even if bad reply                    */
-/*    [Fix]    PRECISION = (-3) (about 100 ms)                        */
-/*    [Add]    Support the C-DEX Co.Ltd. JJY receiver                 */
-/*                                                                    */
-/*  2001/12/04                                                        */
+/*                                                                   */
+/*  History                                                          */
+/*                                                                   */
+/*  2001/07/15                                                       */
+/*    [New]    Support the Tristate Ltd. JJY receiver                */
+/*                                                                   */
+/*  2001/08/04                                                       */
+/*    [Change] Log to clockstats even if bad reply                   */
+/*    [Fix]    PRECISION = (-3) (about 100 ms)                       */
+/*    [Add]    Support the C-DEX Co.Ltd. JJY receiver                */
+/*                                                                   */
+/*  2001/12/04                                                       */
 /*    [Fix]    C-DEX JST2000 ( fukusima@goto.info.waseda.ac.jp )      */
-/*                                                                    */
-/*  2002/07/12                                                        */
-/*    [Fix]    Portability for FreeBSD ( patched by the user )        */
-/*                                                                    */
-/*  2004/10/31                                                        */
+/*                                                                   */
+/*  2002/07/12                                                       */
+/*    [Fix]    Portability for FreeBSD ( patched by the user )       */
+/*                                                                   */
+/*  2004/10/31                                                       */
 /*    [Change] Command send timing for the Tristate Ltd. JJY receiver */
-/*             JJY-01 ( Firmware version 2.01 )                       */
-/*             Thanks to Andy Taki for testing under FreeBSD          */
-/*                                                                    */
-/*  2004/11/28                                                        */
-/*    [Add]    Support the Echo Keisokuki LT-2000 receiver            */
-/*                                                                    */
-/*  2006/11/04                                                        */
-/*    [Fix]    C-DEX JST2000                                          */
-/*             Thanks to Hideo Kuramatsu for the patch                */
-/*                                                                    */
-/*  2009/04/05                                                        */
-/*    [Add]    Support the CITIZEN T.I.C JJY-200 receiver             */
-/*                                                                    */
+/*            JJY-01 ( Firmware version 2.01 )                       */
+/*            Thanks to Andy Taki for testing under FreeBSD          */
+/*                                                                   */
+/*  2004/11/28                                                       */
+/*    [Add]    Support the Echo Keisokuki LT-2000 receiver           */
+/*                                                                   */
+/*  2006/11/04                                                       */
+/*    [Fix]    C-DEX JST2000                                         */
+/*            Thanks to Hideo Kuramatsu for the patch                */
+/*                                                                   */
+/*  2009/04/05                                                       */
+/*    [Add]    Support the CITIZEN T.I.C JJY-200 receiver            */
+/*                                                                   */
+/*  2010/11/20                                                       */
+/*    [Change] Bug 1618 ( Harmless )                                 */
+/*            Code clean up ( Remove unreachable codes ) in          */
+/*            jjy_start()                                            */
+/*    [Change] Change clockstats format of the Tristate JJY01/02      */
+/*            Issues more command to get the status of the receiver  */
+/*            when "fudge 127.127.40.X flag1 1" is specified         */
+/*            ( DATE,STIM -> DCST,STUS,DATE,STIM )                   */
+/*                                                                   */
 /**********************************************************************/
 
 #ifdef HAVE_CONFIG_H
 #include "ntp_stdlib.h"
 
 /**********************************************************************/
-/*                                                                    */
-/*  The Tristate Ltd. JJY receiver JJY01                              */
-/*                                                                    */
-/*  Command        Response                 Remarks                   */
+/*                                                                   */
+/*  The Tristate Ltd. JJY receiver JJY01                             */
+/*                                                                   */
+/*  Command       Response                 Remarks                   */
 /*  ------------   ----------------------   ---------------------     */
-/*  date<CR><LF>   YYYY/MM/DD XXX<CR><LF>                             */
-/*  time<CR><LF>   HH:MM:SS<CR><LF>                                   */
-/*  stim<CR><LF>   HH:MM:SS<CR><LF>         Reply at just second      */
-/*                                                                    */
-/*  During synchronization after a receiver is turned on,             */
-/*  It replies the past time from 2000/01/01 00:00:00.                */
-/*  The function "refclock_process" checks the time and tells         */
-/*  as an insanity time.                                              */
-/*                                                                    */
+/*  dcst<CR><LF>   VALID|INVALID<CR><LF>                             */
+/*  stus<CR><LF>   ADJUSTED|UNADJUSTED<CR><LF>                       */
+/*  date<CR><LF>   YYYY/MM/DD XXX<CR><LF>                            */
+/*  time<CR><LF>   HH:MM:SS<CR><LF>                                  */
+/*  stim<CR><LF>   HH:MM:SS<CR><LF>        Reply at just second      */
+/*                                                                   */
+/*  During synchronization after a receiver is turned on,            */
+/*  It replies the past time from 2000/01/01 00:00:00.               */
+/*  The function "refclock_process" checks the time and tells        */
+/*  as an insanity time.                                             */
+/*                                                                   */
 /**********************************************************************/
-/*                                                                    */
-/*  The C-DEX Co. Ltd. JJY receiver JST2000                           */
-/*                                                                    */
-/*  Command        Response                 Remarks                   */
+/*                                                                   */
+/*  The C-DEX Co. Ltd. JJY receiver JST2000                          */
+/*                                                                   */
+/*  Command       Response                 Remarks                   */
 /*  ------------   ----------------------   ---------------------     */
-/*  <ENQ>1J<ETX>   <STX>JYYMMDD HHMMSSS<ETX>                          */
-/*                                                                    */
+/*  <ENQ>1J<ETX>   <STX>JYYMMDD HHMMSSS<ETX>                         */
+/*                                                                   */
 /**********************************************************************/
-/*                                                                    */
-/*  The Echo Keisokuki Co. Ltd. JJY receiver LT2000                   */
-/*                                                                    */
-/*  Command        Response                 Remarks                   */
+/*                                                                   */
+/*  The Echo Keisokuki Co. Ltd. JJY receiver LT2000                  */
+/*                                                                   */
+/*  Command        Response                Remarks                   */
 /*  ------------   ----------------------   ---------------------     */
-/*  #                                       Mode 1 (Request&Send)     */
-/*  T              YYMMDDWHHMMSS<BCC1><BCC2><CR>                      */
-/*  C                                       Mode 2 (Continuous)       */
-/*                 YYMMDDWHHMMSS<ST1><ST2><ST3><ST4><CR>              */
-/*                 <SUB>                    Second signal             */
-/*                                                                    */
+/*  #                                      Mode 1 (Request&Send)     */
+/*  T             YYMMDDWHHMMSS<BCC1><BCC2><CR>                      */
+/*  C                                      Mode 2 (Continuous)       */
+/*                YYMMDDWHHMMSS<ST1><ST2><ST3><ST4><CR>              */
+/*                <SUB>                    Second signal             */
+/*                                                                   */
 /**********************************************************************/
-/*                                                                    */
-/*  The CITIZEN T.I.C CO., LTD. JJY receiver JJY200                   */
-/*                                                                    */
-/*  Command        Response                 Remarks                   */
+/*                                                                   */
+/*  The CITIZEN T.I.C CO., LTD. JJY receiver JJY200                  */
+/*                                                                   */
+/*  Command       Response                 Remarks                   */
 /*  ------------   ----------------------   ---------------------     */
-/*                 'XX YY/MM/DD W HH:MM:SS<CR>                        */
-/*                                          XX: OK|NG|ER              */
-/*                                          W:  0(Monday)-6(Sunday)   */
-/*                                                                    */
+/*                'XX YY/MM/DD W HH:MM:SS<CR>                        */
+/*                                         XX: OK|NG|ER              */
+/*                                         W:  0(Monday)-6(Sunday)   */
+/*                                                                   */
 /**********************************************************************/
 
 /*
  * Interface definitions
  */
-#define        DEVICE          "/dev/jjy%d"    /* device name and unit */
-#define        SPEED232        B9600           /* uart speed (9600 baud) */
-#define        SPEED232_TRISTATE_JJY01         B9600   /* UART speed (9600 baud) */
-#define        SPEED232_CDEX_JST2000           B9600   /* UART speed (9600 baud) */
-#define        SPEED232_ECHOKEISOKUKI_LT2000   B9600   /* UART speed (9600 baud) */
-#define        SPEED232_CITIZENTIC_JJY200      B4800   /* UART speed (4800 baud) */
-#define        REFID           "JJY"           /* reference ID */
+#define        DEVICE          "/dev/jjy%d"    /* device name and unit */
+#define        SPEED232        B9600           /* uart speed (9600 baud) */
+#define        SPEED232_TRISTATE_JJY01         B9600   /* UART speed (9600 baud) */
+#define        SPEED232_CDEX_JST2000           B9600   /* UART speed (9600 baud) */
+#define        SPEED232_ECHOKEISOKUKI_LT2000   B9600   /* UART speed (9600 baud) */
+#define        SPEED232_CITIZENTIC_JJY200      B4800   /* UART speed (4800 baud) */
+#define        REFID           "JJY"           /* reference ID */
 #define        DESCRIPTION     "JJY Receiver"
-#define        PRECISION       (-3)           /* precision assumed (about 100 ms) */
+#define        PRECISION       (-3)            /* precision assumed (about 100 ms) */
 
 /*
  * JJY unit control structure
  */
 struct jjyunit {
-       char    unittype ;          /* UNITTYPE_XXXXXXXXXX */
-    short   operationmode ;     /* Echo Keisokuki LT-2000 : 1 or 2 */
+       char    unittype ;          /* UNITTYPE_XXXXXXXXXX */
+       short   operationmode ;     /* Echo Keisokuki LT-2000 : 1 or 2 */
        short   version ;
-       short   linediscipline ;        /* LDISC_CLK or LDISC_RAW */
-    char    bPollFlag ;         /* Set by jjy_pool and Reset by jjy_receive */
+       short   linediscipline ;    /* LDISC_CLK or LDISC_RAW */
+       char    bPollFlag ;         /* Set by jjy_pool and Reset by jjy_receive */
        int     linecount ;
        int     lineerror ;
        int     year, month, day, hour, minute, second, msecond ;
@@ -187,37 +204,39 @@ struct jjyunit {
 /*
  * Function prototypes
  */
-static int     jjy_start                   (int, struct peer *);
-static void    jjy_shutdown                (int, struct peer *);
-static void    jjy_poll                    (int, struct peer *);
-static void    jjy_poll_tristate_jjy01     (int, struct peer *);
-static void    jjy_poll_cdex_jst2000       (int, struct peer *);
-static void    jjy_poll_echokeisokuki_lt2000    (int, struct peer *);
-static  void    jjy_poll_citizentic_jjy200          (int, struct peer *);
-static void    jjy_receive                 (struct recvbuf *);
-static int     jjy_receive_tristate_jjy01  (struct recvbuf *);
-static int     jjy_receive_cdex_jst2000    (struct recvbuf *);
-static int     jjy_receive_echokeisokuki_lt2000 (struct recvbuf *);
-static  int     jjy_receive_citizentic_jjy200 (struct recvbuf *);
+static int     jjy_start                   (int, struct peer *);
+static void    jjy_shutdown                (int, struct peer *);
+static void    jjy_poll                    (int, struct peer *);
+static void    jjy_poll_tristate_jjy01     (int, struct peer *);
+static void    jjy_poll_cdex_jst2000       (int, struct peer *);
+static void    jjy_poll_echokeisokuki_lt2000(int, struct peer *);
+static void    jjy_poll_citizentic_jjy200  (int, struct peer *);
+static void    jjy_receive                 (struct recvbuf *);
+static int     jjy_receive_tristate_jjy01  (struct recvbuf *);
+static int     jjy_receive_cdex_jst2000    (struct recvbuf *);
+static int     jjy_receive_echokeisokuki_lt2000 (struct recvbuf *);
+static  int    jjy_receive_citizentic_jjy200 (struct recvbuf *);
+
+static void    printableString ( char*, int, char*, int ) ;
 
 /*
  * Transfer vector
  */
 struct refclock refclock_jjy = {
-       jjy_start,      /* start up driver */
-       jjy_shutdown,   /* shutdown driver */
-       jjy_poll,       /* transmit poll message */
-       noentry,        /* not used */
-       noentry,        /* not used */
-       noentry,        /* not used */
-       NOFLAGS         /* not used */
+       jjy_start,      /* start up driver */
+       jjy_shutdown,   /* shutdown driver */
+       jjy_poll,       /* transmit poll message */
+       noentry,        /* not used */
+       noentry,        /* not used */
+       noentry,        /* not used */
+       NOFLAGS         /* not used */
 };
 
 /*
  * Start up driver return code
  */
 #define        RC_START_SUCCESS        1
-#define        RC_START_ERROR          0
+#define        RC_START_ERROR          0
 
 /*
  * Local constants definition
@@ -225,6 +244,49 @@ struct     refclock refclock_jjy = {
 
 #define        MAX_LOGTEXT     64
 
+/*
+ * Tristate JJY01/JJY02 constants definition
+ */
+
+#define        TS_JJY01_COMMAND_NUMBER_DATE    1
+#define        TS_JJY01_COMMAND_NUMBER_TIME    2
+#define        TS_JJY01_COMMAND_NUMBER_STIM    3
+#define        TS_JJY01_COMMAND_NUMBER_STUS    4
+#define        TS_JJY01_COMMAND_NUMBER_DCST    5
+
+#define        TS_JJY01_REPLY_DATE             "yyyy/mm/dd www\r\n"
+#define        TS_JJY01_REPLY_STIM             "hh:mm:ss\r\n"
+#define        TS_JJY01_REPLY_STUS_YES         "adjusted\r\n"
+#define        TS_JJY01_REPLY_STUS_NO          "unadjusted\r\n"
+#define        TS_JJY01_REPLY_DCST_VALID       "valid\r\n"
+#define        TS_JJY01_REPLY_DCST_INVALID     "invalid\r\n"
+
+#define        TS_JJY01_REPLY_LENGTH_DATE          14  /* Length without <CR><LF> */
+#define        TS_JJY01_REPLY_LENGTH_STIM          8   /* Length without <CR><LF> */
+#define        TS_JJY01_REPLY_LENGTH_STUS_YES      8   /* Length without <CR><LF> */
+#define        TS_JJY01_REPLY_LENGTH_STUS_NO       10  /* Length without <CR><LF> */
+#define        TS_JJY01_REPLY_LENGTH_DCST_VALID    5   /* Length without <CR><LF> */
+#define        TS_JJY01_REPLY_LENGTH_DCST_INVALID  7   /* Length without <CR><LF> */
+
+static  struct
+{
+       char    commandNumber ;
+       char    *commandLog ;
+       char    *command ;
+       int     commandLength ;
+} tristate_jjy01_command_sequence[] =
+{
+       /* dcst<CR><LF> -> VALID<CR><LF> or INVALID<CR><LF> */
+       { TS_JJY01_COMMAND_NUMBER_DCST, "dcst", "dcst\r\n", 6 },
+       /* stus<CR><LF> -> ADJUSTED<CR><LF> or UNADJUSTED<CR><LF> */
+       { TS_JJY01_COMMAND_NUMBER_STUS, "stus", "stus\r\n", 6 },
+       /* date<CR><LF> -> YYYY/MM/DD WWW<CR><LF> */
+       { TS_JJY01_COMMAND_NUMBER_DATE, "date", "date\r\n", 6 },
+       /* stim<CR><LF> -> HH:MM:SS<CR><LF> */
+       { TS_JJY01_COMMAND_NUMBER_STIM, "stim", "stim\r\n", 6 },
+       { 0                           , NULL  , NULL      , 0 }
+} ;
+
 
 /**************************************************************************************************/
 /*  jjy_start - open the devices and initialize data for processing                               */
@@ -233,7 +295,7 @@ static int
 jjy_start ( int unit, struct peer *peer )
 {
 
-       struct jjyunit      *up ;
+       struct jjyunit      *up ;
        struct refclockproc *pp ;
        int     fd ;
        char    *pDeviceName ;
@@ -258,25 +320,25 @@ jjy_start ( int unit, struct peer *peer )
         */
        switch ( peer->ttl ) {
        case 0 :
-    case 1 :
-        iDiscipline = LDISC_CLK ;
-        iSpeed232   = SPEED232_TRISTATE_JJY01 ;
-        break ;
-    case 2 :
-        iDiscipline = LDISC_RAW ;
-        iSpeed232   = SPEED232_CDEX_JST2000   ;
-        break ;
-    case 3 :
-        iDiscipline = LDISC_CLK ;
-        iSpeed232   = SPEED232_ECHOKEISOKUKI_LT2000 ;
-        break ;
-    case 4 :
-        iDiscipline = LDISC_CLK ;
-        iSpeed232   = SPEED232_CITIZENTIC_JJY200 ;
-        break ;
+       case 1 :
+               iDiscipline = LDISC_CLK ;
+               iSpeed232   = SPEED232_TRISTATE_JJY01 ;
+               break ;
+       case 2 :
+               iDiscipline = LDISC_RAW ;
+               iSpeed232   = SPEED232_CDEX_JST2000   ;
+               break ;
+       case 3 :
+               iDiscipline = LDISC_CLK ;
+               iSpeed232   = SPEED232_ECHOKEISOKUKI_LT2000 ;
+               break ;
+       case 4 :
+               iDiscipline = LDISC_CLK ;
+               iSpeed232   = SPEED232_CITIZENTIC_JJY200 ;
+               break ;
        default :
                msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
-                         ntoa(&peer->srcadr), peer->ttl ) ;
+                         ntoa(&peer->srcadr), peer->ttl ) ;
                free ( (void*) pDeviceName ) ;
                return RC_START_ERROR ;
        }
@@ -306,9 +368,12 @@ jjy_start ( int unit, struct peer *peer )
        case 1 :
                up->unittype = UNITTYPE_TRISTATE_JJY01 ;
                up->version  = 100 ;
-               up->lineexpect = 2 ;
-               up->charexpect[0] = 14 ; /* YYYY/MM/DD WWW<CR><LF> */
-               up->charexpect[1] =  8 ; /* HH:MM:SS<CR><LF> */
+               /* 2010/11/20 */
+               /* Command sequence is defined by the struct tristate_jjy01_command_sequence, */
+               /* and the following 3 lines are not used in the mode LDISC_CLK. */
+               /* up->lineexpect = 2 ; */
+               /* up->charexpect[0] = 14 ; */ /* YYYY/MM/DD WWW<CR><LF> */
+               /* up->charexpect[1] =  8 ; */ /* HH:MM:SS<CR><LF> */
                break ;
        case 2 :
                up->unittype = UNITTYPE_CDEX_JST2000 ;
@@ -333,20 +398,21 @@ jjy_start ( int unit, struct peer *peer )
                up->lineexpect = 1 ;
                up->charexpect[0] = 23 ; /* 'XX YY/MM/DD W HH:MM:SS<CR> */
                break ;
-       default :
-               msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
-                         ntoa(&peer->srcadr), peer->ttl ) ;
-               close ( fd ) ;
-               free ( (void*) up ) ;
-               return RC_START_ERROR ;
+
+       /* 2010/11/20 */
+       /* The "default:" section of this switch block is never executed,     */
+       /* because the former switch block traps the same "default:" case.    */
+       /* This "default:" section codes are removed to avoid spending time   */
+       /* in the future looking, though the codes are functionally harmless. */
+
        }
 
        pp = peer->procptr ;
        pp->unitptr       = (caddr_t) up ;
        pp->io.clock_recv = jjy_receive ;
        pp->io.srcclock   = (caddr_t) peer ;
-       pp->io.datalen    = 0 ;
-       pp->io.fd         = fd ;
+       pp->io.datalen    = 0 ;
+       pp->io.fd         = fd ;
        if ( ! io_addclock(&pp->io) ) {
                close ( fd ) ;
                pp->io.fd = -1 ;
@@ -359,8 +425,8 @@ jjy_start ( int unit, struct peer *peer )
         * Initialize miscellaneous variables
         */
        peer->precision = PRECISION ;
-       peer->burst     = 1 ;
-       pp->clockdesc   = DESCRIPTION ;
+       peer->burst     = 1 ;
+       pp->clockdesc   = DESCRIPTION ;
        memcpy ( (char*)&pp->refid, REFID, strlen(REFID) ) ;
 
        return RC_START_SUCCESS ;
@@ -375,7 +441,7 @@ static void
 jjy_shutdown ( int unit, struct peer *peer )
 {
 
-       struct jjyunit      *up;
+       struct jjyunit      *up;
        struct refclockproc *pp;
 
        pp = peer->procptr ;
@@ -395,9 +461,9 @@ static void
 jjy_receive ( struct recvbuf *rbufp )
 {
 
-       struct jjyunit      *up ;
+       struct jjyunit      *up ;
        struct refclockproc *pp ;
-       struct peer         *peer;
+       struct peer         *peer;
 
        l_fp    tRecvTimestamp;         /* arrival timestamp */
        int     rc ;
@@ -424,11 +490,14 @@ jjy_receive ( struct recvbuf *rbufp )
                /*
                 * Copy received charaters to temporary buffer 
                 */
-               for ( i = 0 ; i < pp->lencode && up->charcount < MAX_RAWBUF - 2 ; i ++ , up->charcount ++ ) {
+               for ( i = 0 ;
+                     i < pp->lencode && up->charcount < MAX_RAWBUF - 2 ;
+                     i ++ , up->charcount ++ ) {
                        up->rawbuf[up->charcount] = pp->a_lastcode[i] ;
                }
                while ( up->charcount > 0 && up->rawbuf[0] < ' ' ) {
-                       for ( i = 0 ; i < up->charcount - 1 ; i ++ ) up->rawbuf[i] = up->rawbuf[i+1] ;
+                       for ( i = 0 ; i < up->charcount - 1 ; i ++ )
+                               up->rawbuf[i] = up->rawbuf[i+1] ;
                        up->charcount -- ;
                }
                bCntrlChar = 0 ;
@@ -439,7 +508,9 @@ jjy_receive ( struct recvbuf *rbufp )
                        }
                }
                if ( pp->lencode > 0  &&  up->linecount < up->lineexpect ) {
-                       if ( bCntrlChar == 0  &&  up->charcount < up->charexpect[up->linecount] ) return ;
+                       if ( bCntrlChar == 0  &&
+                            up->charcount < up->charexpect[up->linecount] )
+                               return ;
                }
                up->rawbuf[up->charcount] = 0 ;
        } else {
@@ -472,9 +543,9 @@ jjy_receive ( struct recvbuf *rbufp )
                rc = jjy_receive_echokeisokuki_lt2000 ( rbufp ) ;
                break ;
 
-    case UNITTYPE_CITIZENTIC_JJY200 :
-        rc = jjy_receive_citizentic_jjy200 ( rbufp ) ;
-        break ;
+       case UNITTYPE_CITIZENTIC_JJY200 :
+               rc = jjy_receive_citizentic_jjy200 ( rbufp ) ;
+               break ;
 
        default :
                rc = 0 ;
@@ -483,8 +554,11 @@ jjy_receive ( struct recvbuf *rbufp )
        }
 
        if ( up->linediscipline == LDISC_RAW ) {
-               if ( up->linecount <= up->lineexpect  &&  up->charcount > up->charexpect[up->linecount-1] ) {
-                       for ( i = 0 ; i < up->charcount - up->charexpect[up->linecount-1] ; i ++ ) {
+               if ( up->linecount <= up->lineexpect  &&
+                    up->charcount > up->charexpect[up->linecount-1] ) {
+                       for ( i = 0 ;
+                             i < up->charcount - up->charexpect[up->linecount-1] ;
+                             i ++ ) {
                                up->rawbuf[i] = up->rawbuf[i+up->charexpect[up->linecount-1]] ;
                        }
                        up->charcount -= up->charexpect[up->linecount-1] ;
@@ -493,20 +567,29 @@ jjy_receive ( struct recvbuf *rbufp )
                }
        }
 
-       if ( rc == 0 ) return ;
+       if ( rc == 0 ) 
+               return ;
 
-    up->bPollFlag = 0 ;
+       up->bPollFlag = 0 ;
 
        if ( up->lineerror != 0 ) {
                refclock_report ( peer, CEVNT_BADREPLY ) ;
-               strcpy  ( sLogText, "BAD REPLY [" ) ;
+               strncpy  ( sLogText, "BAD REPLY [",
+                          sizeof( sLogText ) ) ;
                if ( up->linediscipline == LDISC_RAW ) {
-                       strncat ( sLogText, up->rawbuf, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
+                       strncat ( sLogText, up->rawbuf,
+                                 sizeof( sLogText ) -
+                                     strlen ( sLogText ) - 1 ) ;
                } else {
-                       strncat ( sLogText, pp->a_lastcode, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
+                       strncat ( sLogText, pp->a_lastcode,
+                                 sizeof( sLogText ) -
+                                     strlen ( sLogText ) - 1 ) ;
                }
                sLogText[MAX_LOGTEXT-1] = 0 ;
-               if ( strlen ( sLogText ) < MAX_LOGTEXT - 2 ) strcat ( sLogText, "]" ) ;
+               if ( strlen ( sLogText ) < MAX_LOGTEXT - 2 )
+                       strncat ( sLogText, "]",
+                                 sizeof( sLogText ) -
+                                     strlen ( sLogText ) - 1 ) ;
                record_clock_stats ( &peer->srcadr, sLogText ) ;
                return ;
        }
@@ -533,9 +616,11 @@ jjy_receive ( struct recvbuf *rbufp )
 #ifdef DEBUG
        if ( debug ) {
                printf ( "jjy_receive (refclock_jjy.c) : %04d/%02d/%02d %02d:%02d:%02d.%1d JST   ", 
-                         up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond/100 ) ;
+                         up->year, up->month, up->day, up->hour,
+                         up->minute, up->second, up->msecond/100 ) ;
                printf ( "( %04d/%03d %02d:%02d:%02d.%1d UTC )\n",
-                         pp->year, pp->day, pp->hour, pp->minute, pp->second, (int)(pp->nsec/100000000) ) ;
+                         pp->year, pp->day, pp->hour, pp->minute,
+                         pp->second, (int)(pp->nsec/100000000) ) ;
        }
 #endif
 
@@ -546,7 +631,7 @@ jjy_receive ( struct recvbuf *rbufp )
 
        snprintf ( sLogText, sizeof(sLogText),
                   "%04d/%02d/%02d %02d:%02d:%02d.%1d JST",
-                  up->year, up->month, up->day,
+                  up->year, up->month, up->day,
                   up->hour, up->minute, up->second, up->msecond/100 ) ;
        record_clock_stats ( &peer->srcadr, sLogText ) ;
 
@@ -568,14 +653,21 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
 
        static  char    *sFunctionName = "jjy_receive_tristate_jjy01" ;
 
-       struct jjyunit      *up ;
+       struct jjyunit      *up ;
        struct refclockproc *pp ;
-       struct peer         *peer;
+       struct peer         *peer;
 
        char    *pBuf ;
        int     iLen ;
        int     rc ;
 
+       int     bOverMidnight = 0 ;
+
+       char    sLogText [ MAX_LOGTEXT ], sReplyText  [ MAX_LOGTEXT ] ;
+
+       char    *pCmd ;
+       int     iCmdLen ;
+
        /*
         * Initialize pointers and read the timecode and timestamp
         */
@@ -587,35 +679,28 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
                pBuf = up->rawbuf ;
                iLen = up->charcount ;
        } else {
-           pBuf = pp->a_lastcode ;
-           iLen = pp->lencode ;
+               pBuf = pp->a_lastcode ;
+               iLen = pp->lencode ;
        }
 
-       switch ( up->linecount ) {
+       switch ( tristate_jjy01_command_sequence[up->linecount-1].commandNumber ) {
 
-       case 1 : /* YYYY/MM/DD WWW */
+       case TS_JJY01_COMMAND_NUMBER_DATE : /* YYYY/MM/DD WWW */
 
-               if ( iLen != 14 ) {
-#ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Reply length error ( up->linecount=%d  iLen=%d )\n", sFunctionName, up->linecount, iLen ) ;
-               }
-#endif
+               if ( iLen != TS_JJY01_REPLY_LENGTH_DATE ) {
                        up->lineerror = 1 ;
                        break ;
                }
-               rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year, &up->month, &up->day ) ;
-               if ( rc != 3 || up->year < 2000 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31 ) {
-#ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Date error ( up->linecount=%d )\n", sFunctionName, up->linecount ) ;
-               }
-#endif
+
+               rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year,
+                             &up->month, &up->day ) ;
+               if ( rc != 3 || up->year < 2000 || up->month < 1 ||
+                    up->month > 12 || up->day < 1 || up->day > 31 ) {
                        up->lineerror = 1 ;
                        break ;
                }
 
-               /*** Start of modification on 2004/10/31 */
+               /*** Start of modification on 2004/10/31 ***/
                /*
                 * Following codes are moved from the function jjy_poll_tristate_jjy01 in this source.
                 * The Tristate JJY-01 ( Firmware version 1.01 ) accepts "time" and "stim" commands without any delay.
@@ -623,64 +708,73 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
                 * so this driver issues the second command "stim" after the reply of the first command "date".
                 */
 
+               /*** 2010/11/20 ***/
                /*
-                * Send "stim<CR><LF>" or "time<CR><LF>" command
+                * Codes of a next command issue are moved to the end of this function.
                 */
-                
 
-               if ( up->version >= 100 ) {
-#ifdef DEBUG
-                       if ( debug ) {
-                               printf ( "%s (refclock_jjy.c) : send 'stim<CR><LF>'\n", sFunctionName ) ;
-                       }
-#endif
-                       if ( write ( pp->io.fd, "stim\r\n",6 ) != 6  ) {
-                               refclock_report ( peer, CEVNT_FAULT ) ;
-                       }
-               } else {
-#ifdef DEBUG
-                       if ( debug ) {
-                               printf ( "%s (refclock_jjy.c) : send 'time<CR><LF>'\n", sFunctionName ) ;
-                       }
-#endif
-                       if ( write ( pp->io.fd, "time\r\n",6 ) != 6  ) {
-                               refclock_report ( peer, CEVNT_FAULT ) ;
-                       }
-               }
                /*** End of modification ***/
 
-               return 0 ;
+               break ;
 
-       case 2 : /* HH:MM:SS */
+       case TS_JJY01_COMMAND_NUMBER_TIME : /* HH:MM:SS */
+       case TS_JJY01_COMMAND_NUMBER_STIM : /* HH:MM:SS */
 
-               if ( iLen != 8 ) {
-#ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Reply length error ( up->linecount=%d  iLen=%d )\n", sFunctionName, up->linecount, iLen ) ;
-               }
-#endif
+               if ( iLen != TS_JJY01_REPLY_LENGTH_STIM ) {
                        up->lineerror = 1 ;
                        break ;
                }
-               rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour, &up->minute, &up->second ) ;
-               if ( rc != 3 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
-#ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Time error ( up->linecount=%d )\n", sFunctionName, up->linecount ) ;
-               }
-#endif
+
+               rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour,
+                             &up->minute, &up->second ) ;
+               if ( rc != 3 || up->hour > 23 || up->minute > 59 ||
+                    up->second > 60 ) {
                        up->lineerror = 1 ;
                        break ;
                }
+
                up->msecond = 0 ;
-               if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) {
+               if ( up->hour == 0 && up->minute == 0 &&
+                    up->second <= 2 ) {
                        /*
-                        * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver continuously.
-                        * But the JJY receiver replies a date and time separately.
+                        * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver separately,
+                        * and the JJY receiver replies a date and time separately.
                         * Just after midnight transitions, we ignore this time.
                         */
-                       return 0 ;
+                       bOverMidnight = 1 ;
+               }
+               break ;
+
+       case TS_JJY01_COMMAND_NUMBER_STUS :
+
+               if ( ( iLen == TS_JJY01_REPLY_LENGTH_STUS_YES
+                   && strncmp( pBuf, TS_JJY01_REPLY_STUS_YES,
+                               TS_JJY01_REPLY_LENGTH_STUS_YES ) == 0 )
+                 || ( iLen == TS_JJY01_REPLY_LENGTH_STUS_NO
+                   && strncmp( pBuf, TS_JJY01_REPLY_STUS_NO,
+                               TS_JJY01_REPLY_LENGTH_STUS_NO ) == 0 ) ) {
+                       /* Good */
+               } else {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               break ;
+
+       case TS_JJY01_COMMAND_NUMBER_DCST :
+
+               if ( ( iLen == TS_JJY01_REPLY_LENGTH_DCST_VALID
+                   && strncmp( pBuf, TS_JJY01_REPLY_DCST_VALID,
+                               TS_JJY01_REPLY_LENGTH_DCST_VALID ) == 0 )
+                 || ( iLen == TS_JJY01_REPLY_LENGTH_DCST_INVALID
+                   && strncmp( pBuf, TS_JJY01_REPLY_DCST_INVALID,
+                               TS_JJY01_REPLY_LENGTH_DCST_INVALID ) == 0 ) ) {
+                       /* Good */
+               } else {
+                       up->lineerror = 1 ;
+                       break ;
                }
+
                break ;
 
        default : /*  Unexpected reply */
@@ -690,7 +784,53 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
 
        }
 
-       return 1 ;
+       /* Clockstats Log */
+
+       printableString( sReplyText, sizeof(sReplyText), pBuf, iLen ) ;
+       snprintf ( sLogText, sizeof(sLogText), "%d: %s -> %c: %s",
+                  up->linecount,
+                  tristate_jjy01_command_sequence[up->linecount-1].commandLog,
+                  ( up->lineerror == 0 ) 
+                       ? ( ( bOverMidnight == 0 )
+                               ? 'O' 
+                               : 'S' ) 
+                       : 'X',
+                  sReplyText ) ;
+       record_clock_stats ( &peer->srcadr, sLogText ) ;
+
+       /* Check before issue next command */
+
+       if ( up->lineerror != 0 ) {
+               /* Do not issue next command */
+               return 0 ;
+       }
+
+       if ( bOverMidnight != 0 ) {
+               /* Do not issue next command */
+               return 0 ;
+       }
+
+       if ( tristate_jjy01_command_sequence[up->linecount].command == NULL ) {
+               /* Command sequence completed */
+               return 1 ;
+       }
+
+       /* Issue next command */
+
+#ifdef DEBUG
+       if ( debug ) {
+               printf ( "%s (refclock_jjy.c) : send '%s'\n",
+                       sFunctionName, tristate_jjy01_command_sequence[up->linecount].commandLog ) ;
+       }
+#endif
+
+       pCmd =  tristate_jjy01_command_sequence[up->linecount].command ;
+       iCmdLen = tristate_jjy01_command_sequence[up->linecount].commandLength ;
+       if ( write ( pp->io.fd, pCmd, iCmdLen ) != iCmdLen ) {
+               refclock_report ( peer, CEVNT_FAULT ) ;
+       }
+
+       return 0 ;
 
 }
 
@@ -721,8 +861,8 @@ jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
                pBuf = up->rawbuf ;
                iLen = up->charcount ;
        } else {
-           pBuf = pp->a_lastcode ;
-           iLen = pp->lencode ;
+               pBuf = pp->a_lastcode ;
+               iLen = pp->lencode ;
        }
 
        switch ( up->linecount ) {
@@ -731,22 +871,29 @@ jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
 
                if ( iLen != 15 ) {
 #ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
-               }
+                       if ( debug >= 2 ) {
+                               printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n",
+                                        sFunctionName, iLen ) ;
+                       }
 #endif
                        up->lineerror = 1 ;
                        break ;
                }
                rc = sscanf ( pBuf, "J%2d%2d%2d%*1d%2d%2d%2d%1d",
-                             &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second, &up->msecond ) ;
-               if ( rc != 7 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
-                 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
+                             &up->year, &up->month, &up->day,
+                             &up->hour, &up->minute, &up->second,
+                             &up->msecond ) ;
+               if ( rc != 7 || up->month < 1 || up->month > 12 ||
+                    up->day < 1 || up->day > 31 || up->hour > 23 ||
+                    up->minute > 59 || up->second > 60 ) {
 #ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d.%1d ]\n", sFunctionName,
-                                                rc, up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond ) ;
-               }
+                       if ( debug >= 2 ) {
+                               printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d.%1d ]\n",
+                                        sFunctionName, rc, up->year,
+                                        up->month, up->day, up->hour,
+                                        up->minute, up->second,
+                                        up->msecond ) ;
+                       }
 #endif
                        up->lineerror = 1 ;
                        break ;
@@ -776,12 +923,12 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
 
        struct jjyunit      *up ;
        struct refclockproc *pp ;
-       struct peer         *peer;
+       struct peer         *peer;
 
        char    *pBuf ;
        int     iLen ;
        int     rc ;
-    int     i, ibcc, ibcc1, ibcc2 ;
+       int     i, ibcc, ibcc1, ibcc2 ;
 
        /*
         * Initialize pointers and read the timecode and timestamp
@@ -794,19 +941,21 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
                pBuf = up->rawbuf ;
                iLen = up->charcount ;
        } else {
-           pBuf = pp->a_lastcode ;
-           iLen = pp->lencode ;
+               pBuf = pp->a_lastcode ;
+               iLen = pp->lencode ;
        }
 
        switch ( up->linecount ) {
 
        case 1 : /* YYMMDDWHHMMSS<BCC1><BCC2> or YYMMDDWHHMMSS<ST1><ST2><ST3><ST4> */
 
-               if ( ( up->operationmode == 1 && iLen != 15 ) || ( up->operationmode == 2 && iLen != 17 ) ) {
+               if ( ( up->operationmode == 1 && iLen != 15 ) ||
+                    ( up->operationmode == 2 && iLen != 17 ) ) {
 #ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
-               }
+                       if ( debug >= 2 ) {
+                               printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n",
+                                        sFunctionName, iLen ) ;
+                       }
 #endif
                        if ( up->operationmode == 1 ) {
 #ifdef DEBUG
@@ -824,30 +973,39 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
 
                if ( up->operationmode == 1 ) {
 
-               for ( i = ibcc = 0 ; i < 13 ; i ++ ) ibcc ^= pBuf[i] ;
-               ibcc1 = 0x30 | ( ( ibcc >> 4 ) & 0xF ) ;
-               ibcc2 = 0x30 | ( ( ibcc      ) & 0xF ) ;
-               if ( pBuf[13] != ibcc1 || pBuf[14] != ibcc2 ) {
+                       for ( i = ibcc = 0 ; i < 13 ; i ++ )
+                               ibcc ^= pBuf[i] ;
+                       ibcc1 = 0x30 | ( ( ibcc >> 4 ) & 0xF ) ;
+                       ibcc2 = 0x30 | ( ( ibcc      ) & 0xF ) ;
+                       if ( pBuf[13] != ibcc1 || pBuf[14] != ibcc2 ) {
 #ifdef DEBUG
-                       if ( debug >= 2 ) {
-                               printf ( "%s (refclock_jjy.c) : BCC error ( Recv=%02X,%02X / Calc=%02X,%02X)\n", sFunctionName, pBuf[13]&0xFF, pBuf[14]&0xFF, ibcc1, ibcc2 ) ;
-                       }
+                               if ( debug >= 2 ) {
+                                       printf ( "%s (refclock_jjy.c) : BCC error ( Recv=%02X,%02X / Calc=%02X,%02X)\n",
+                                                sFunctionName,
+                                                pBuf[13] & 0xFF,
+                                                pBuf[14] & 0xFF,
+                                                ibcc1, ibcc2 ) ;
+                               }
 #endif
                                up->lineerror = 1 ;
                                break ;
                        }
 
-        }
+               }
 
                rc = sscanf ( pBuf, "%2d%2d%2d%*1d%2d%2d%2d",
-                      &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second ) ;
-               if ( rc != 6 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
-                 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
+                             &up->year, &up->month, &up->day,
+                             &up->hour, &up->minute, &up->second ) ;
+               if ( rc != 6 || up->month < 1 || up->month > 12 ||
+                    up->day < 1 || up->day > 31 || up->hour > 23 ||
+                    up->minute > 59 || up->second > 60 ) {
 #ifdef DEBUG
-               if ( debug >= 2 ) {
-                       printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d ]\n", sFunctionName,
-                                                rc, up->year, up->month, up->day, up->hour, up->minute, up->second ) ;
-               }
+                       if ( debug >= 2 ) {
+                               printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d ]\n",
+                                        sFunctionName, rc, up->year,
+                                        up->month, up->day, up->hour,
+                                        up->minute, up->second ) ;
+                       }
 #endif
                        up->lineerror = 1 ;
                        break ;
@@ -880,7 +1038,8 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
                        /* Switch from mode 2 to mode 1 in order to restraint of useless time stamp. */
 #ifdef DEBUG
                        if ( debug ) {
-                               printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
+                               printf ( "%s (refclock_jjy.c) : send '#'\n",
+                                        sFunctionName ) ;
                        }
 #endif
                        if ( write ( pp->io.fd, "#",1 ) != 1  ) {
@@ -895,7 +1054,8 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
 
 #ifdef DEBUG
                if ( debug ) {
-                       printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
+                       printf ( "%s (refclock_jjy.c) : send '#'\n",
+                                sFunctionName ) ;
                }
 #endif
                if ( write ( pp->io.fd, "#",1 ) != 1  ) {
@@ -917,84 +1077,91 @@ static int
 jjy_receive_citizentic_jjy200 ( struct recvbuf *rbufp )
 {
 
-    static  char    *sFunctionName = "jjy_receive_citizentic_jjy200" ;
+       static char *sFunctionName = "jjy_receive_citizentic_jjy200" ;
 
-    struct jjyunit      *up ;
-    struct refclockproc *pp ;
-    struct peer         *peer;
+       struct jjyunit          *up ;
+       struct refclockproc     *pp ;
+       struct peer             *peer;
 
-    char    *pBuf ;
-    int     iLen ;
-    int     rc ;
-    char    cApostrophe, sStatus[3] ;
-    int     iWeekday ;
+       char    *pBuf ;
+       int     iLen ;
+       int     rc ;
+       char    cApostrophe, sStatus[3] ;
+       int     iWeekday ;
 
-    /*
-     * Initialize pointers and read the timecode and timestamp
-     */
-    peer = (struct peer *) rbufp->recv_srcclock ;
-    pp = peer->procptr ;
-    up = (struct jjyunit *) pp->unitptr ;
+       /*
+       * Initialize pointers and read the timecode and timestamp
+       */
+       peer = (struct peer *) rbufp->recv_srcclock ;
+       pp = peer->procptr ;
+       up = (struct jjyunit *) pp->unitptr ;
 
-    if ( up->linediscipline == LDISC_RAW ) {
-        pBuf = up->rawbuf ;
-        iLen = up->charcount ;
-    } else {
-        pBuf = pp->a_lastcode ;
-        iLen = pp->lencode ;
-    }
+       if ( up->linediscipline == LDISC_RAW ) {
+               pBuf = up->rawbuf ;
+               iLen = up->charcount ;
+       } else {
+               pBuf = pp->a_lastcode ;
+               iLen = pp->lencode ;
+       }
 
-    /*
-     * JJY-200 sends a timestamp every second.
-     * So, a timestamp is ignored unless it is right after polled.
-     */
-    if ( ! up->bPollFlag ) return 0 ;
+       /*
+       * JJY-200 sends a timestamp every second.
+       * So, a timestamp is ignored unless it is right after polled.
+       */
+       if ( ! up->bPollFlag )
+               return 0 ;
 
-    switch ( up->linecount ) {
+       switch ( up->linecount ) {
 
-    case 1 : /* 'XX YY/MM/DD W HH:MM:SS<CR> */
+       case 1 : /* 'XX YY/MM/DD W HH:MM:SS<CR> */
 
-        if ( iLen != 23 ) {
+               if ( iLen != 23 ) {
 #ifdef DEBUG
-            if ( debug >= 2 ) {
-                printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
-            }
+                       if ( debug >= 2 ) {
+                               printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n",
+                                        sFunctionName, iLen ) ;
+                       }
 #endif
-            up->lineerror = 1 ;
-            break ;
-        }
-
-        rc = sscanf ( pBuf, "%c%2s %2d/%2d/%2d %1d %2d:%2d:%2d",
-                      &cApostrophe, sStatus, 
-                      &up->year, &up->month, &up->day, &iWeekday, &up->hour, &up->minute, &up->second ) ;
-        sStatus[2] = 0 ;
-        if ( rc != 9 || cApostrophe != '\'' || strcmp( sStatus, "OK" ) != 0
-          || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
-          || iWeekday > 6
-          || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               rc = sscanf ( pBuf, "%c%2s %2d/%2d/%2d %1d %2d:%2d:%2d",
+                             &cApostrophe, sStatus, &up->year,
+                             &up->month, &up->day, &iWeekday,
+                             &up->hour, &up->minute, &up->second ) ;
+               sStatus[2] = 0 ;
+               if ( rc != 9 || cApostrophe != '\'' ||
+                    strcmp( sStatus, "OK" ) != 0 || up->month < 1 ||
+                    up->month > 12 || up->day < 1 || up->day > 31 ||
+                    iWeekday > 6 || up->hour > 23 || up->minute > 59 ||
+                    up->second > 60 ) {
 #ifdef DEBUG
-            if ( debug >= 2 ) {
-                printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %c %2s %02d %02d %02d %d %02d %02d %02d ]\n", sFunctionName,
-                         rc, cApostrophe, sStatus, up->year, up->month, up->day, iWeekday, up->hour, up->minute, up->second ) ;
-            }
+                       if ( debug >= 2 ) {
+                               printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %c %2s %02d %02d %02d %d %02d %02d %02d ]\n",
+                                        sFunctionName, rc, cApostrophe,
+                                        sStatus, up->year, up->month,
+                                        up->day, iWeekday, up->hour,
+                                        up->minute, up->second ) ;
+                       }
 #endif
-            up->lineerror = 1 ;
-            break ;
-        }
+                       up->lineerror = 1 ;
+                       break ;
+               }
 
-        up->year += 2000 ;
-        up->msecond = 0 ;
+               up->year += 2000 ;
+               up->msecond = 0 ;
 
-        break ;
+               break ;
 
-    default : /* Unexpected reply */
+       default : /* Unexpected reply */
 
-        up->lineerror = 1 ;
-        break ;
+               up->lineerror = 1 ;
+               break ;
 
-    }
+       }
 
-    return 1 ;
+       return 1 ;
 
 }
 
@@ -1026,7 +1193,7 @@ jjy_poll ( int unit, struct peer *peer )
 
        pp->polls ++ ;
 
-    up->bPollFlag = 1 ;
+       up->bPollFlag = 1 ;
        up->linecount = 0 ;
        up->lineerror = 0 ;
        up->charcount = 0 ;
@@ -1045,9 +1212,9 @@ jjy_poll ( int unit, struct peer *peer )
                jjy_poll_echokeisokuki_lt2000 ( unit, peer ) ;
                break ;
 
-    case UNITTYPE_CITIZENTIC_JJY200 :
-        jjy_poll_citizentic_jjy200 ( unit, peer ) ;
-        break ;
+       case UNITTYPE_CITIZENTIC_JJY200 :
+               jjy_poll_citizentic_jjy200 ( unit, peer ) ;
+               break ;
 
        default :
                break ;
@@ -1062,21 +1229,44 @@ static void
 jjy_poll_tristate_jjy01  ( int unit, struct peer *peer )
 {
 
+       static char *sFunctionName = "jjy_poll_tristate_jjy01" ;
+
+       struct jjyunit      *up;
        struct refclockproc *pp;
 
+       char    *pCmd ;
+       int     iCmdLen ;
+
        pp = peer->procptr;
+       up = (struct jjyunit *) pp->unitptr ;
+
+       if ( ( pp->sloppyclockflag & CLK_FLAG1 ) == 0 ) {
+               up->linecount = 2 ;
+       }
+
+#ifdef DEBUG
+       if ( debug ) {
+               printf ( "%s (refclock_jjy.c) : flag1=%X CLK_FLAG1=%X up->linecount=%d\n",
+                       sFunctionName, pp->sloppyclockflag, CLK_FLAG1,
+                       up->linecount ) ;
+       }
+#endif
 
        /*
-        * Send "date<CR><LF>" command
+        * Send a first command
         */
 
 #ifdef DEBUG
        if ( debug ) {
-               printf ( "jjy_poll_tristate_jjy01 (refclock_jjy.c) : send 'date<CR><LF>'\n" ) ;
+               printf ( "%s (refclock_jjy.c) : send '%s'\n",
+                        sFunctionName,
+                        tristate_jjy01_command_sequence[up->linecount].commandLog ) ;
        }
 #endif
 
-       if ( write ( pp->io.fd, "date\r\n",6 ) != 6  ) {
+       pCmd =  tristate_jjy01_command_sequence[up->linecount].command ;
+       iCmdLen = tristate_jjy01_command_sequence[up->linecount].commandLength ;
+       if ( write ( pp->io.fd, pCmd, iCmdLen ) != iCmdLen ) {
                refclock_report ( peer, CEVNT_FAULT ) ;
        }
 
@@ -1150,10 +1340,58 @@ static void
 jjy_poll_citizentic_jjy200 ( int unit, struct peer *peer )
 {
 
-    /* Do nothing ( up->bPollFlag is set by the jjy_poll ) */
+       /* Do nothing ( up->bPollFlag is set by the jjy_poll ) */
+
+}
+
+/**************************************************************************************************/
+
+static void
+printableString ( char *sOutput, int iOutputLen, char *sInput, int iInputLen )
+{
+
+       char    *printableControlChar[] = {
+                       "<NUL>", "<SOH>", "<STX>", "<ETX>",
+                       "<EOT>", "<ENQ>", "<ACK>", "<BEL>",
+                       "<BS>" , "<HT>" , "<LF>" , "<VT>" ,
+                       "<FF>" , "<CR>" , "<SO>" , "<SI>" ,
+                       "<DLE>", "<DC1>", "<DC2>", "<DC3>",
+                       "<DC4>", "<NAK>", "<SYN>", "<ETB>",
+                       "<CAN>", "<EM>" , "<SUB>", "<ESC>",
+                       "<FS>" , "<GS>" , "<RS>" , "<US>" ,
+                       " " } ;
+
+       int     i, j, n ;
+
+       for ( i = j = 0 ; i < iInputLen && j < iOutputLen ; i ++ ) {
+               if ( isprint( sInput[i] ) ) {
+                       n = 1 ;
+                       if ( j + 1 >= iOutputLen )
+                               break ;
+                       sOutput[j] = sInput[i] ;
+               } else if ( ( sInput[i] & 0xFF ) < 
+                           COUNTOF(printableControlChar) ) {
+                       n = strlen( printableControlChar[sInput[i] & 0xFF] ) ;
+                       if ( j + n + 1 >= iOutputLen )
+                               break ;
+                       strncpy( sOutput + j,
+                                printableControlChar[sInput[i] & 0xFF],
+                                (size_t)iOutputLen - j ) ;
+               } else {
+                       n = 5 ;
+                       if ( j + n + 1 >= iOutputLen ) break ;
+                       snprintf( sOutput + j, (size_t)iOutputLen - j,
+                                 "<x%X>", sInput[i] & 0xFF ) ;
+               }
+               j += n ;
+       }
+
+       sOutput[min(j, iOutputLen - 1)] = '\0' ;
 
 }
 
+/**************************************************************************************************/
+
 #else
 int refclock_jjy_bs ;
 #endif /* REFCLOCK */