aboutsummaryrefslogtreecommitdiff
path: root/ntpd/refclock_jjy.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/refclock_jjy.c')
-rw-r--r--ntpd/refclock_jjy.c960
1 files changed, 599 insertions, 361 deletions
diff --git a/ntpd/refclock_jjy.c b/ntpd/refclock_jjy.c
index d1707ced0f21..df7869dc987b 100644
--- a/ntpd/refclock_jjy.c
+++ b/ntpd/refclock_jjy.c
@@ -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
@@ -99,74 +114,76 @@
#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 P((int, struct peer *));
-static void jjy_shutdown P((int, struct peer *));
-static void jjy_poll P((int, struct peer *));
-static void jjy_poll_tristate_jjy01 P((int, struct peer *));
-static void jjy_poll_cdex_jst2000 P((int, struct peer *));
-static void jjy_poll_echokeisokuki_lt2000 P((int, struct peer *));
-static void jjy_poll_citizentic_jjy200 P((int, struct peer *));
-static void jjy_receive P((struct recvbuf *));
-static int jjy_receive_tristate_jjy01 P((struct recvbuf *));
-static int jjy_receive_cdex_jst2000 P((struct recvbuf *));
-static int jjy_receive_echokeisokuki_lt2000 P((struct recvbuf *));
-static int jjy_receive_citizentic_jjy200 P((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 ;
@@ -250,35 +312,33 @@ jjy_start ( int unit, struct peer *peer )
/*
* Open serial port
*/
- if ( ! ( pDeviceName = (char*) emalloc ( strlen(DEVICE) + 10 ) ) ) {
- return RC_START_ERROR ;
- }
- sprintf ( pDeviceName, DEVICE, unit ) ;
+ pDeviceName = emalloc ( strlen(DEVICE) + 10 );
+ snprintf ( pDeviceName, strlen(DEVICE) + 10, DEVICE, unit ) ;
/*
* peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
*/
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 ;
}
@@ -292,12 +352,8 @@ jjy_start ( int unit, struct peer *peer )
/*
* Allocate and initialize unit structure
*/
- if ( ! ( up = (struct jjyunit *) emalloc (sizeof(struct jjyunit)) ) ) {
- close ( fd ) ;
- return RC_START_ERROR ;
- }
-
- memset ( (char*)up, 0, sizeof(struct jjyunit) ) ;
+ up = emalloc (sizeof(*up));
+ memset ( up, 0, sizeof(*up) ) ;
up->linediscipline = iDiscipline ;
/*
@@ -312,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 ;
@@ -325,8 +384,8 @@ jjy_start ( int unit, struct peer *peer )
up->unittype = UNITTYPE_ECHOKEISOKUKI_LT2000 ;
up->operationmode = 2 ; /* Mode 2 : Continuous mode */
up->lineexpect = 1 ;
- switch ( up->operationmode ) {
- case 1 :
+ switch ( up->operationmode ) {
+ case 1 :
up->charexpect[0] = 15 ; /* YYMMDDWHHMMSS<BCC1><BCC2><CR> */
break ;
case 2 :
@@ -334,28 +393,31 @@ jjy_start ( int unit, struct peer *peer )
break ;
}
break ;
- case 4 :
- up->unittype = UNITTYPE_CITIZENTIC_JJY200 ;
- 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 ;
+ case 4 :
+ up->unittype = UNITTYPE_CITIZENTIC_JJY200 ;
+ up->lineexpect = 1 ;
+ up->charexpect[0] = 23 ; /* 'XX YY/MM/DD W HH:MM:SS<CR> */
+ break ;
+
+ /* 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 ) ;
- free ( (void*) up ) ;
+ pp->io.fd = -1 ;
+ free ( up ) ;
+ pp->unitptr = NULL ;
return RC_START_ERROR ;
}
@@ -363,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 ;
@@ -379,13 +441,15 @@ static void
jjy_shutdown ( int unit, struct peer *peer )
{
- struct jjyunit *up;
+ struct jjyunit *up;
struct refclockproc *pp;
pp = peer->procptr ;
up = (struct jjyunit *) pp->unitptr ;
- io_closeclock ( &pp->io ) ;
- free ( (void*) up ) ;
+ if ( -1 != pp->io.fd )
+ io_closeclock ( &pp->io ) ;
+ if ( NULL != up )
+ free ( up ) ;
}
@@ -397,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 ;
@@ -426,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 ;
@@ -441,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 {
@@ -474,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 ;
@@ -485,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] ;
@@ -495,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 ;
}
@@ -535,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,8 +629,10 @@ jjy_receive ( struct recvbuf *rbufp )
* timecode timestamp.
*/
- sprintf ( sLogText, "%04d/%02d/%02d %02d:%02d:%02d.%1d JST",
- up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond/100 ) ;
+ snprintf ( sLogText, sizeof(sLogText),
+ "%04d/%02d/%02d %02d:%02d:%02d.%1d JST",
+ up->year, up->month, up->day,
+ up->hour, up->minute, up->second, up->msecond/100 ) ;
record_clock_stats ( &peer->srcadr, sLogText ) ;
if ( ! refclock_process ( pp ) ) {
@@ -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,66 +708,75 @@ 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 */
up->lineerror = 1 ;
@@ -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 */