summaryrefslogtreecommitdiffstats
path: root/ntpd/refclock_jjy.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/refclock_jjy.c')
-rw-r--r--ntpd/refclock_jjy.c156
1 files changed, 152 insertions, 4 deletions
diff --git a/ntpd/refclock_jjy.c b/ntpd/refclock_jjy.c
index 9d1419a..d1707ce 100644
--- a/ntpd/refclock_jjy.c
+++ b/ntpd/refclock_jjy.c
@@ -74,6 +74,9 @@
/* [Fix] C-DEX JST2000 */
/* Thanks to Hideo Kuramatsu for the patch */
/* */
+/* 2009/04/05 */
+/* [Add] Support the CITIZEN T.I.C JJY-200 receiver */
+/* */
/**********************************************************************/
#ifdef HAVE_CONFIG_H
@@ -131,12 +134,26 @@
/* <SUB> Second signal */
/* */
/**********************************************************************/
+/* */
+/* 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) */
+/* */
+/**********************************************************************/
/*
* 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 DESCRIPTION "JJY Receiver"
#define PRECISION (-3) /* precision assumed (about 100 ms) */
@@ -149,6 +166,7 @@ struct jjyunit {
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 */
int linecount ;
int lineerror ;
int year, month, day, hour, minute, second, msecond ;
@@ -164,6 +182,7 @@ struct jjyunit {
#define UNITTYPE_TRISTATE_JJY01 1
#define UNITTYPE_CDEX_JST2000 2
#define UNITTYPE_ECHOKEISOKUKI_LT2000 3
+#define UNITTYPE_CITIZENTIC_JJY200 4
/*
* Function prototypes
@@ -174,10 +193,12 @@ 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 *));
/*
* Transfer vector
@@ -217,6 +238,7 @@ jjy_start ( int unit, struct peer *peer )
int fd ;
char *pDeviceName ;
short iDiscipline ;
+ int iSpeed232 ;
#ifdef DEBUG
if ( debug ) {
@@ -238,9 +260,22 @@ jjy_start ( int unit, struct peer *peer )
*/
switch ( peer->ttl ) {
case 0 :
- case 1 : iDiscipline = LDISC_CLK ; break ;
- case 2 : iDiscipline = LDISC_RAW ; break ;
- case 3 : iDiscipline = LDISC_CLK ; 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 ) ;
@@ -248,7 +283,7 @@ jjy_start ( int unit, struct peer *peer )
return RC_START_ERROR ;
}
- if ( ! ( fd = refclock_open ( pDeviceName, SPEED232, iDiscipline ) ) ) {
+ if ( ! ( fd = refclock_open ( pDeviceName, iSpeed232, iDiscipline ) ) ) {
free ( (void*) pDeviceName ) ;
return RC_START_ERROR ;
}
@@ -299,6 +334,11 @@ 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 ) ;
@@ -434,6 +474,10 @@ jjy_receive ( struct recvbuf *rbufp )
rc = jjy_receive_echokeisokuki_lt2000 ( rbufp ) ;
break ;
+ case UNITTYPE_CITIZENTIC_JJY200 :
+ rc = jjy_receive_citizentic_jjy200 ( rbufp ) ;
+ break ;
+
default :
rc = 0 ;
break ;
@@ -453,6 +497,8 @@ jjy_receive ( struct recvbuf *rbufp )
if ( rc == 0 ) return ;
+ up->bPollFlag = 0 ;
+
if ( up->lineerror != 0 ) {
refclock_report ( peer, CEVNT_BADREPLY ) ;
strcpy ( sLogText, "BAD REPLY [" ) ;
@@ -866,6 +912,93 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
}
/**************************************************************************************************/
+
+static int
+jjy_receive_citizentic_jjy200 ( struct recvbuf *rbufp )
+{
+
+ static char *sFunctionName = "jjy_receive_citizentic_jjy200" ;
+
+ struct jjyunit *up ;
+ struct refclockproc *pp ;
+ struct peer *peer;
+
+ 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 ;
+
+ 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 ;
+
+ switch ( up->linecount ) {
+
+ case 1 : /* 'XX YY/MM/DD W HH:MM:SS<CR> */
+
+ if ( iLen != 23 ) {
+#ifdef DEBUG
+ 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 ) {
+#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 ) ;
+ }
+#endif
+ up->lineerror = 1 ;
+ break ;
+ }
+
+ up->year += 2000 ;
+ up->msecond = 0 ;
+
+ break ;
+
+ default : /* Unexpected reply */
+
+ up->lineerror = 1 ;
+ break ;
+
+ }
+
+ return 1 ;
+
+}
+
+/**************************************************************************************************/
/* jjy_poll - called by the transmit procedure */
/**************************************************************************************************/
static void
@@ -893,6 +1026,7 @@ jjy_poll ( int unit, struct peer *peer )
pp->polls ++ ;
+ up->bPollFlag = 1 ;
up->linecount = 0 ;
up->lineerror = 0 ;
up->charcount = 0 ;
@@ -911,6 +1045,10 @@ 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 ;
+
default :
break ;
@@ -1006,6 +1144,16 @@ jjy_poll_echokeisokuki_lt2000 ( int unit, struct peer *peer )
}
+/**************************************************************************************************/
+
+static void
+jjy_poll_citizentic_jjy200 ( int unit, struct peer *peer )
+{
+
+ /* Do nothing ( up->bPollFlag is set by the jjy_poll ) */
+
+}
+
#else
int refclock_jjy_bs ;
#endif /* REFCLOCK */
OpenPOWER on IntegriCloud