diff options
Diffstat (limited to 'ntpd/refclock_jjy.c')
-rw-r--r-- | ntpd/refclock_jjy.c | 156 |
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 */ |