Deleted Added
full compact
refclock_jjy.c (182007) refclock_jjy.c (200576)
1/*
2 * refclock_jjy - clock driver for JJY receivers
3 */
4
5/**********************************************************************/
6/* */
7/* Copyright (C) 2001-2004, Takao Abe. All rights reserved. */
8/* */
9/* Permission to use, copy, modify, and distribute this software */
10/* and its documentation for any purpose is hereby granted */
11/* without fee, provided that the following conditions are met: */
12/* */
13/* One retains the entire copyright notice properly, and both the */
14/* copyright notice and this license. in the documentation and/or */
15/* other materials provided with the distribution. */
16/* */
17/* This software and the name of the author must not be used to */
18/* endorse or promote products derived from this software without */
19/* prior written permission. */
20/* */
21/* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESSED OR IMPLIED */
22/* WARRANTIES OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, THE */
23/* IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS FOR A */
24/* PARTICULAR PURPOSE. */
25/* IN NO EVENT SHALL THE AUTHOR TAKAO ABE BE LIABLE FOR ANY DIRECT, */
26/* INDIRECT, GENERAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
27/* ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */
28/* GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS */
29/* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */
30/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING */
31/* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF */
32/* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33/* */
34/* This driver is developed in my private time, and is opened as */
35/* voluntary contributions for the NTP. */
36/* The manufacturer of the JJY receiver has not participated in */
37/* a development of this driver. */
38/* The manufacturer does not warrant anything about this driver, */
39/* and is not liable for anything about this driver. */
40/* */
41/**********************************************************************/
42/* */
43/* Author Takao Abe */
44/* Email abetakao@bea.hi-ho.ne.jp */
45/* Homepage http://www.bea.hi-ho.ne.jp/abetakao/ */
46/* */
47/**********************************************************************/
48/* */
49/* History */
50/* */
51/* 2001/07/15 */
52/* [New] Support the Tristate Ltd. JJY receiver */
53/* */
54/* 2001/08/04 */
55/* [Change] Log to clockstats even if bad reply */
56/* [Fix] PRECISION = (-3) (about 100 ms) */
57/* [Add] Support the C-DEX Co.Ltd. JJY receiver */
58/* */
59/* 2001/12/04 */
60/* [Fix] C-DEX JST2000 ( fukusima@goto.info.waseda.ac.jp ) */
61/* */
62/* 2002/07/12 */
63/* [Fix] Portability for FreeBSD ( patched by the user ) */
64/* */
65/* 2004/10/31 */
66/* [Change] Command send timing for the Tristate Ltd. JJY receiver */
67/* JJY-01 ( Firmware version 2.01 ) */
68/* Thanks to Andy Taki for testing under FreeBSD */
69/* */
70/* 2004/11/28 */
71/* [Add] Support the Echo Keisokuki LT-2000 receiver */
72/* */
73/* 2006/11/04 */
74/* [Fix] C-DEX JST2000 */
75/* Thanks to Hideo Kuramatsu for the patch */
76/* */
1/*
2 * refclock_jjy - clock driver for JJY receivers
3 */
4
5/**********************************************************************/
6/* */
7/* Copyright (C) 2001-2004, Takao Abe. All rights reserved. */
8/* */
9/* Permission to use, copy, modify, and distribute this software */
10/* and its documentation for any purpose is hereby granted */
11/* without fee, provided that the following conditions are met: */
12/* */
13/* One retains the entire copyright notice properly, and both the */
14/* copyright notice and this license. in the documentation and/or */
15/* other materials provided with the distribution. */
16/* */
17/* This software and the name of the author must not be used to */
18/* endorse or promote products derived from this software without */
19/* prior written permission. */
20/* */
21/* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESSED OR IMPLIED */
22/* WARRANTIES OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, THE */
23/* IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS FOR A */
24/* PARTICULAR PURPOSE. */
25/* IN NO EVENT SHALL THE AUTHOR TAKAO ABE BE LIABLE FOR ANY DIRECT, */
26/* INDIRECT, GENERAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
27/* ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */
28/* GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS */
29/* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */
30/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING */
31/* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF */
32/* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33/* */
34/* This driver is developed in my private time, and is opened as */
35/* voluntary contributions for the NTP. */
36/* The manufacturer of the JJY receiver has not participated in */
37/* a development of this driver. */
38/* The manufacturer does not warrant anything about this driver, */
39/* and is not liable for anything about this driver. */
40/* */
41/**********************************************************************/
42/* */
43/* Author Takao Abe */
44/* Email abetakao@bea.hi-ho.ne.jp */
45/* Homepage http://www.bea.hi-ho.ne.jp/abetakao/ */
46/* */
47/**********************************************************************/
48/* */
49/* History */
50/* */
51/* 2001/07/15 */
52/* [New] Support the Tristate Ltd. JJY receiver */
53/* */
54/* 2001/08/04 */
55/* [Change] Log to clockstats even if bad reply */
56/* [Fix] PRECISION = (-3) (about 100 ms) */
57/* [Add] Support the C-DEX Co.Ltd. JJY receiver */
58/* */
59/* 2001/12/04 */
60/* [Fix] C-DEX JST2000 ( fukusima@goto.info.waseda.ac.jp ) */
61/* */
62/* 2002/07/12 */
63/* [Fix] Portability for FreeBSD ( patched by the user ) */
64/* */
65/* 2004/10/31 */
66/* [Change] Command send timing for the Tristate Ltd. JJY receiver */
67/* JJY-01 ( Firmware version 2.01 ) */
68/* Thanks to Andy Taki for testing under FreeBSD */
69/* */
70/* 2004/11/28 */
71/* [Add] Support the Echo Keisokuki LT-2000 receiver */
72/* */
73/* 2006/11/04 */
74/* [Fix] C-DEX JST2000 */
75/* Thanks to Hideo Kuramatsu for the patch */
76/* */
77/* 2009/04/05 */
78/* [Add] Support the CITIZEN T.I.C JJY-200 receiver */
79/* */
77/**********************************************************************/
78
79#ifdef HAVE_CONFIG_H
80#include <config.h>
81#endif
82
83#if defined(REFCLOCK) && defined(CLOCK_JJY)
84
85#include <stdio.h>
86#include <ctype.h>
87#include <string.h>
88#include <sys/time.h>
89#include <time.h>
90
91#include "ntpd.h"
92#include "ntp_io.h"
93#include "ntp_tty.h"
94#include "ntp_refclock.h"
95#include "ntp_calendar.h"
96#include "ntp_stdlib.h"
97
98/**********************************************************************/
99/* */
100/* The Tristate Ltd. JJY receiver JJY01 */
101/* */
102/* Command Response Remarks */
103/* ------------ ---------------------- --------------------- */
104/* date<CR><LF> YYYY/MM/DD XXX<CR><LF> */
105/* time<CR><LF> HH:MM:SS<CR><LF> */
106/* stim<CR><LF> HH:MM:SS<CR><LF> Reply at just second */
107/* */
108/* During synchronization after a receiver is turned on, */
109/* It replies the past time from 2000/01/01 00:00:00. */
110/* The function "refclock_process" checks the time and tells */
111/* as an insanity time. */
112/* */
113/**********************************************************************/
114/* */
115/* The C-DEX Co. Ltd. JJY receiver JST2000 */
116/* */
117/* Command Response Remarks */
118/* ------------ ---------------------- --------------------- */
119/* <ENQ>1J<ETX> <STX>JYYMMDD HHMMSSS<ETX> */
120/* */
121/**********************************************************************/
122/* */
123/* The Echo Keisokuki Co. Ltd. JJY receiver LT2000 */
124/* */
125/* Command Response Remarks */
126/* ------------ ---------------------- --------------------- */
127/* # Mode 1 (Request&Send) */
128/* T YYMMDDWHHMMSS<BCC1><BCC2><CR> */
129/* C Mode 2 (Continuous) */
130/* YYMMDDWHHMMSS<ST1><ST2><ST3><ST4><CR> */
131/* <SUB> Second signal */
132/* */
133/**********************************************************************/
80/**********************************************************************/
81
82#ifdef HAVE_CONFIG_H
83#include <config.h>
84#endif
85
86#if defined(REFCLOCK) && defined(CLOCK_JJY)
87
88#include <stdio.h>
89#include <ctype.h>
90#include <string.h>
91#include <sys/time.h>
92#include <time.h>
93
94#include "ntpd.h"
95#include "ntp_io.h"
96#include "ntp_tty.h"
97#include "ntp_refclock.h"
98#include "ntp_calendar.h"
99#include "ntp_stdlib.h"
100
101/**********************************************************************/
102/* */
103/* The Tristate Ltd. JJY receiver JJY01 */
104/* */
105/* Command Response Remarks */
106/* ------------ ---------------------- --------------------- */
107/* date<CR><LF> YYYY/MM/DD XXX<CR><LF> */
108/* time<CR><LF> HH:MM:SS<CR><LF> */
109/* stim<CR><LF> HH:MM:SS<CR><LF> Reply at just second */
110/* */
111/* During synchronization after a receiver is turned on, */
112/* It replies the past time from 2000/01/01 00:00:00. */
113/* The function "refclock_process" checks the time and tells */
114/* as an insanity time. */
115/* */
116/**********************************************************************/
117/* */
118/* The C-DEX Co. Ltd. JJY receiver JST2000 */
119/* */
120/* Command Response Remarks */
121/* ------------ ---------------------- --------------------- */
122/* <ENQ>1J<ETX> <STX>JYYMMDD HHMMSSS<ETX> */
123/* */
124/**********************************************************************/
125/* */
126/* The Echo Keisokuki Co. Ltd. JJY receiver LT2000 */
127/* */
128/* Command Response Remarks */
129/* ------------ ---------------------- --------------------- */
130/* # Mode 1 (Request&Send) */
131/* T YYMMDDWHHMMSS<BCC1><BCC2><CR> */
132/* C Mode 2 (Continuous) */
133/* YYMMDDWHHMMSS<ST1><ST2><ST3><ST4><CR> */
134/* <SUB> Second signal */
135/* */
136/**********************************************************************/
137/* */
138/* The CITIZEN T.I.C CO., LTD. JJY receiver JJY200 */
139/* */
140/* Command Response Remarks */
141/* ------------ ---------------------- --------------------- */
142/* 'XX YY/MM/DD W HH:MM:SS<CR> */
143/* XX: OK|NG|ER */
144/* W: 0(Monday)-6(Sunday) */
145/* */
146/**********************************************************************/
134
135/*
136 * Interface definitions
137 */
138#define DEVICE "/dev/jjy%d" /* device name and unit */
139#define SPEED232 B9600 /* uart speed (9600 baud) */
147
148/*
149 * Interface definitions
150 */
151#define DEVICE "/dev/jjy%d" /* device name and unit */
152#define SPEED232 B9600 /* uart speed (9600 baud) */
153#define SPEED232_TRISTATE_JJY01 B9600 /* UART speed (9600 baud) */
154#define SPEED232_CDEX_JST2000 B9600 /* UART speed (9600 baud) */
155#define SPEED232_ECHOKEISOKUKI_LT2000 B9600 /* UART speed (9600 baud) */
156#define SPEED232_CITIZENTIC_JJY200 B4800 /* UART speed (4800 baud) */
140#define REFID "JJY" /* reference ID */
141#define DESCRIPTION "JJY Receiver"
142#define PRECISION (-3) /* precision assumed (about 100 ms) */
143
144/*
145 * JJY unit control structure
146 */
147struct jjyunit {
148 char unittype ; /* UNITTYPE_XXXXXXXXXX */
149 short operationmode ; /* Echo Keisokuki LT-2000 : 1 or 2 */
150 short version ;
151 short linediscipline ; /* LDISC_CLK or LDISC_RAW */
157#define REFID "JJY" /* reference ID */
158#define DESCRIPTION "JJY Receiver"
159#define PRECISION (-3) /* precision assumed (about 100 ms) */
160
161/*
162 * JJY unit control structure
163 */
164struct jjyunit {
165 char unittype ; /* UNITTYPE_XXXXXXXXXX */
166 short operationmode ; /* Echo Keisokuki LT-2000 : 1 or 2 */
167 short version ;
168 short linediscipline ; /* LDISC_CLK or LDISC_RAW */
169 char bPollFlag ; /* Set by jjy_pool and Reset by jjy_receive */
152 int linecount ;
153 int lineerror ;
154 int year, month, day, hour, minute, second, msecond ;
155/* LDISC_RAW only */
156#define MAX_LINECOUNT 8
157#define MAX_RAWBUF 64
158 int lineexpect ;
159 int charexpect [ MAX_LINECOUNT ] ;
160 int charcount ;
161 char rawbuf [ MAX_RAWBUF ] ;
162};
163
164#define UNITTYPE_TRISTATE_JJY01 1
165#define UNITTYPE_CDEX_JST2000 2
166#define UNITTYPE_ECHOKEISOKUKI_LT2000 3
170 int linecount ;
171 int lineerror ;
172 int year, month, day, hour, minute, second, msecond ;
173/* LDISC_RAW only */
174#define MAX_LINECOUNT 8
175#define MAX_RAWBUF 64
176 int lineexpect ;
177 int charexpect [ MAX_LINECOUNT ] ;
178 int charcount ;
179 char rawbuf [ MAX_RAWBUF ] ;
180};
181
182#define UNITTYPE_TRISTATE_JJY01 1
183#define UNITTYPE_CDEX_JST2000 2
184#define UNITTYPE_ECHOKEISOKUKI_LT2000 3
185#define UNITTYPE_CITIZENTIC_JJY200 4
167
168/*
169 * Function prototypes
170 */
171static int jjy_start P((int, struct peer *));
172static void jjy_shutdown P((int, struct peer *));
173static void jjy_poll P((int, struct peer *));
174static void jjy_poll_tristate_jjy01 P((int, struct peer *));
175static void jjy_poll_cdex_jst2000 P((int, struct peer *));
176static void jjy_poll_echokeisokuki_lt2000 P((int, struct peer *));
186
187/*
188 * Function prototypes
189 */
190static int jjy_start P((int, struct peer *));
191static void jjy_shutdown P((int, struct peer *));
192static void jjy_poll P((int, struct peer *));
193static void jjy_poll_tristate_jjy01 P((int, struct peer *));
194static void jjy_poll_cdex_jst2000 P((int, struct peer *));
195static void jjy_poll_echokeisokuki_lt2000 P((int, struct peer *));
196static void jjy_poll_citizentic_jjy200 P((int, struct peer *));
177static void jjy_receive P((struct recvbuf *));
178static int jjy_receive_tristate_jjy01 P((struct recvbuf *));
179static int jjy_receive_cdex_jst2000 P((struct recvbuf *));
180static int jjy_receive_echokeisokuki_lt2000 P((struct recvbuf *));
197static void jjy_receive P((struct recvbuf *));
198static int jjy_receive_tristate_jjy01 P((struct recvbuf *));
199static int jjy_receive_cdex_jst2000 P((struct recvbuf *));
200static int jjy_receive_echokeisokuki_lt2000 P((struct recvbuf *));
201static int jjy_receive_citizentic_jjy200 P((struct recvbuf *));
181
182/*
183 * Transfer vector
184 */
185struct refclock refclock_jjy = {
186 jjy_start, /* start up driver */
187 jjy_shutdown, /* shutdown driver */
188 jjy_poll, /* transmit poll message */
189 noentry, /* not used */
190 noentry, /* not used */
191 noentry, /* not used */
192 NOFLAGS /* not used */
193};
194
195/*
196 * Start up driver return code
197 */
198#define RC_START_SUCCESS 1
199#define RC_START_ERROR 0
200
201/*
202 * Local constants definition
203 */
204
205#define MAX_LOGTEXT 64
206
207
208/**************************************************************************************************/
209/* jjy_start - open the devices and initialize data for processing */
210/**************************************************************************************************/
211static int
212jjy_start ( int unit, struct peer *peer )
213{
214
215 struct jjyunit *up ;
216 struct refclockproc *pp ;
217 int fd ;
218 char *pDeviceName ;
219 short iDiscipline ;
202
203/*
204 * Transfer vector
205 */
206struct refclock refclock_jjy = {
207 jjy_start, /* start up driver */
208 jjy_shutdown, /* shutdown driver */
209 jjy_poll, /* transmit poll message */
210 noentry, /* not used */
211 noentry, /* not used */
212 noentry, /* not used */
213 NOFLAGS /* not used */
214};
215
216/*
217 * Start up driver return code
218 */
219#define RC_START_SUCCESS 1
220#define RC_START_ERROR 0
221
222/*
223 * Local constants definition
224 */
225
226#define MAX_LOGTEXT 64
227
228
229/**************************************************************************************************/
230/* jjy_start - open the devices and initialize data for processing */
231/**************************************************************************************************/
232static int
233jjy_start ( int unit, struct peer *peer )
234{
235
236 struct jjyunit *up ;
237 struct refclockproc *pp ;
238 int fd ;
239 char *pDeviceName ;
240 short iDiscipline ;
241 int iSpeed232 ;
220
221#ifdef DEBUG
222 if ( debug ) {
223 printf ( "jjy_start (refclock_jjy.c) : %s mode=%d ", ntoa(&peer->srcadr), peer->ttl ) ;
224 printf ( DEVICE, unit ) ;
225 printf ( "\n" ) ;
226 }
227#endif
228 /*
229 * Open serial port
230 */
231 if ( ! ( pDeviceName = (char*) emalloc ( strlen(DEVICE) + 10 ) ) ) {
232 return RC_START_ERROR ;
233 }
234 sprintf ( pDeviceName, DEVICE, unit ) ;
235
236 /*
237 * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
238 */
239 switch ( peer->ttl ) {
240 case 0 :
242
243#ifdef DEBUG
244 if ( debug ) {
245 printf ( "jjy_start (refclock_jjy.c) : %s mode=%d ", ntoa(&peer->srcadr), peer->ttl ) ;
246 printf ( DEVICE, unit ) ;
247 printf ( "\n" ) ;
248 }
249#endif
250 /*
251 * Open serial port
252 */
253 if ( ! ( pDeviceName = (char*) emalloc ( strlen(DEVICE) + 10 ) ) ) {
254 return RC_START_ERROR ;
255 }
256 sprintf ( pDeviceName, DEVICE, unit ) ;
257
258 /*
259 * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
260 */
261 switch ( peer->ttl ) {
262 case 0 :
241 case 1 : iDiscipline = LDISC_CLK ; break ;
242 case 2 : iDiscipline = LDISC_RAW ; break ;
243 case 3 : iDiscipline = LDISC_CLK ; break ;
263 case 1 :
264 iDiscipline = LDISC_CLK ;
265 iSpeed232 = SPEED232_TRISTATE_JJY01 ;
266 break ;
267 case 2 :
268 iDiscipline = LDISC_RAW ;
269 iSpeed232 = SPEED232_CDEX_JST2000 ;
270 break ;
271 case 3 :
272 iDiscipline = LDISC_CLK ;
273 iSpeed232 = SPEED232_ECHOKEISOKUKI_LT2000 ;
274 break ;
275 case 4 :
276 iDiscipline = LDISC_CLK ;
277 iSpeed232 = SPEED232_CITIZENTIC_JJY200 ;
278 break ;
244 default :
245 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
246 ntoa(&peer->srcadr), peer->ttl ) ;
247 free ( (void*) pDeviceName ) ;
248 return RC_START_ERROR ;
249 }
250
279 default :
280 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
281 ntoa(&peer->srcadr), peer->ttl ) ;
282 free ( (void*) pDeviceName ) ;
283 return RC_START_ERROR ;
284 }
285
251 if ( ! ( fd = refclock_open ( pDeviceName, SPEED232, iDiscipline ) ) ) {
286 if ( ! ( fd = refclock_open ( pDeviceName, iSpeed232, iDiscipline ) ) ) {
252 free ( (void*) pDeviceName ) ;
253 return RC_START_ERROR ;
254 }
255 free ( (void*) pDeviceName ) ;
256
257 /*
258 * Allocate and initialize unit structure
259 */
260 if ( ! ( up = (struct jjyunit *) emalloc (sizeof(struct jjyunit)) ) ) {
261 close ( fd ) ;
262 return RC_START_ERROR ;
263 }
264
265 memset ( (char*)up, 0, sizeof(struct jjyunit) ) ;
266 up->linediscipline = iDiscipline ;
267
268 /*
269 * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
270 */
271 switch ( peer->ttl ) {
272 case 0 :
273 /*
274 * The mode 0 is a default clock type at this time.
275 * But this will be change to auto-detect mode in the future.
276 */
277 case 1 :
278 up->unittype = UNITTYPE_TRISTATE_JJY01 ;
279 up->version = 100 ;
280 up->lineexpect = 2 ;
281 up->charexpect[0] = 14 ; /* YYYY/MM/DD WWW<CR><LF> */
282 up->charexpect[1] = 8 ; /* HH:MM:SS<CR><LF> */
283 break ;
284 case 2 :
285 up->unittype = UNITTYPE_CDEX_JST2000 ;
286 up->lineexpect = 1 ;
287 up->charexpect[0] = 15 ; /* <STX>JYYMMDD HHMMSSS<ETX> */
288 break ;
289 case 3 :
290 up->unittype = UNITTYPE_ECHOKEISOKUKI_LT2000 ;
291 up->operationmode = 2 ; /* Mode 2 : Continuous mode */
292 up->lineexpect = 1 ;
293 switch ( up->operationmode ) {
294 case 1 :
295 up->charexpect[0] = 15 ; /* YYMMDDWHHMMSS<BCC1><BCC2><CR> */
296 break ;
297 case 2 :
298 up->charexpect[0] = 17 ; /* YYMMDDWHHMMSS<ST1><ST2><ST3><ST4><CR> */
299 break ;
300 }
301 break ;
287 free ( (void*) pDeviceName ) ;
288 return RC_START_ERROR ;
289 }
290 free ( (void*) pDeviceName ) ;
291
292 /*
293 * Allocate and initialize unit structure
294 */
295 if ( ! ( up = (struct jjyunit *) emalloc (sizeof(struct jjyunit)) ) ) {
296 close ( fd ) ;
297 return RC_START_ERROR ;
298 }
299
300 memset ( (char*)up, 0, sizeof(struct jjyunit) ) ;
301 up->linediscipline = iDiscipline ;
302
303 /*
304 * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf
305 */
306 switch ( peer->ttl ) {
307 case 0 :
308 /*
309 * The mode 0 is a default clock type at this time.
310 * But this will be change to auto-detect mode in the future.
311 */
312 case 1 :
313 up->unittype = UNITTYPE_TRISTATE_JJY01 ;
314 up->version = 100 ;
315 up->lineexpect = 2 ;
316 up->charexpect[0] = 14 ; /* YYYY/MM/DD WWW<CR><LF> */
317 up->charexpect[1] = 8 ; /* HH:MM:SS<CR><LF> */
318 break ;
319 case 2 :
320 up->unittype = UNITTYPE_CDEX_JST2000 ;
321 up->lineexpect = 1 ;
322 up->charexpect[0] = 15 ; /* <STX>JYYMMDD HHMMSSS<ETX> */
323 break ;
324 case 3 :
325 up->unittype = UNITTYPE_ECHOKEISOKUKI_LT2000 ;
326 up->operationmode = 2 ; /* Mode 2 : Continuous mode */
327 up->lineexpect = 1 ;
328 switch ( up->operationmode ) {
329 case 1 :
330 up->charexpect[0] = 15 ; /* YYMMDDWHHMMSS<BCC1><BCC2><CR> */
331 break ;
332 case 2 :
333 up->charexpect[0] = 17 ; /* YYMMDDWHHMMSS<ST1><ST2><ST3><ST4><CR> */
334 break ;
335 }
336 break ;
337 case 4 :
338 up->unittype = UNITTYPE_CITIZENTIC_JJY200 ;
339 up->lineexpect = 1 ;
340 up->charexpect[0] = 23 ; /* 'XX YY/MM/DD W HH:MM:SS<CR> */
341 break ;
302 default :
303 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
304 ntoa(&peer->srcadr), peer->ttl ) ;
305 close ( fd ) ;
306 free ( (void*) up ) ;
307 return RC_START_ERROR ;
308 }
309
310 pp = peer->procptr ;
311 pp->unitptr = (caddr_t) up ;
312 pp->io.clock_recv = jjy_receive ;
313 pp->io.srcclock = (caddr_t) peer ;
314 pp->io.datalen = 0 ;
315 pp->io.fd = fd ;
316 if ( ! io_addclock(&pp->io) ) {
317 close ( fd ) ;
318 free ( (void*) up ) ;
319 return RC_START_ERROR ;
320 }
321
322 /*
323 * Initialize miscellaneous variables
324 */
325 peer->precision = PRECISION ;
326 peer->burst = 1 ;
327 pp->clockdesc = DESCRIPTION ;
328 memcpy ( (char*)&pp->refid, REFID, strlen(REFID) ) ;
329
330 return RC_START_SUCCESS ;
331
332}
333
334
335/**************************************************************************************************/
336/* jjy_shutdown - shutdown the clock */
337/**************************************************************************************************/
338static void
339jjy_shutdown ( int unit, struct peer *peer )
340{
341
342 struct jjyunit *up;
343 struct refclockproc *pp;
344
345 pp = peer->procptr ;
346 up = (struct jjyunit *) pp->unitptr ;
347 io_closeclock ( &pp->io ) ;
348 free ( (void*) up ) ;
349
350}
351
352
353/**************************************************************************************************/
354/* jjy_receive - receive data from the serial interface */
355/**************************************************************************************************/
356static void
357jjy_receive ( struct recvbuf *rbufp )
358{
359
360 struct jjyunit *up ;
361 struct refclockproc *pp ;
362 struct peer *peer;
363
364 l_fp tRecvTimestamp; /* arrival timestamp */
365 int rc ;
366 char sLogText [ MAX_LOGTEXT ] ;
367 int i, bCntrlChar ;
368
369 /*
370 * Initialize pointers and read the timecode and timestamp
371 */
372 peer = (struct peer *) rbufp->recv_srcclock ;
373 pp = peer->procptr ;
374 up = (struct jjyunit *) pp->unitptr ;
375
376 /*
377 * Get next input line
378 */
379 pp->lencode = refclock_gtlin ( rbufp, pp->a_lastcode, BMAX, &tRecvTimestamp ) ;
380
381 if ( up->linediscipline == LDISC_RAW ) {
382 /*
383 * The reply with <STX> and <ETX> may give a blank line
384 */
385 if ( pp->lencode == 0 && up->charcount == 0 ) return ;
386 /*
387 * Copy received charaters to temporary buffer
388 */
389 for ( i = 0 ; i < pp->lencode && up->charcount < MAX_RAWBUF - 2 ; i ++ , up->charcount ++ ) {
390 up->rawbuf[up->charcount] = pp->a_lastcode[i] ;
391 }
392 while ( up->charcount > 0 && up->rawbuf[0] < ' ' ) {
393 for ( i = 0 ; i < up->charcount - 1 ; i ++ ) up->rawbuf[i] = up->rawbuf[i+1] ;
394 up->charcount -- ;
395 }
396 bCntrlChar = 0 ;
397 for ( i = 0 ; i < up->charcount ; i ++ ) {
398 if ( up->rawbuf[i] < ' ' ) {
399 bCntrlChar = 1 ;
400 break ;
401 }
402 }
403 if ( pp->lencode > 0 && up->linecount < up->lineexpect ) {
404 if ( bCntrlChar == 0 && up->charcount < up->charexpect[up->linecount] ) return ;
405 }
406 up->rawbuf[up->charcount] = 0 ;
407 } else {
408 /*
409 * The reply with <CR><LF> gives a blank line
410 */
411 if ( pp->lencode == 0 ) return ;
412 }
413 /*
414 * We get down to business
415 */
416
417 pp->lastrec = tRecvTimestamp ;
418
419 up->linecount ++ ;
420
421 if ( up->lineerror != 0 ) return ;
422
423 switch ( up->unittype ) {
424
425 case UNITTYPE_TRISTATE_JJY01 :
426 rc = jjy_receive_tristate_jjy01 ( rbufp ) ;
427 break ;
428
429 case UNITTYPE_CDEX_JST2000 :
430 rc = jjy_receive_cdex_jst2000 ( rbufp ) ;
431 break ;
432
433 case UNITTYPE_ECHOKEISOKUKI_LT2000 :
434 rc = jjy_receive_echokeisokuki_lt2000 ( rbufp ) ;
435 break ;
436
342 default :
343 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
344 ntoa(&peer->srcadr), peer->ttl ) ;
345 close ( fd ) ;
346 free ( (void*) up ) ;
347 return RC_START_ERROR ;
348 }
349
350 pp = peer->procptr ;
351 pp->unitptr = (caddr_t) up ;
352 pp->io.clock_recv = jjy_receive ;
353 pp->io.srcclock = (caddr_t) peer ;
354 pp->io.datalen = 0 ;
355 pp->io.fd = fd ;
356 if ( ! io_addclock(&pp->io) ) {
357 close ( fd ) ;
358 free ( (void*) up ) ;
359 return RC_START_ERROR ;
360 }
361
362 /*
363 * Initialize miscellaneous variables
364 */
365 peer->precision = PRECISION ;
366 peer->burst = 1 ;
367 pp->clockdesc = DESCRIPTION ;
368 memcpy ( (char*)&pp->refid, REFID, strlen(REFID) ) ;
369
370 return RC_START_SUCCESS ;
371
372}
373
374
375/**************************************************************************************************/
376/* jjy_shutdown - shutdown the clock */
377/**************************************************************************************************/
378static void
379jjy_shutdown ( int unit, struct peer *peer )
380{
381
382 struct jjyunit *up;
383 struct refclockproc *pp;
384
385 pp = peer->procptr ;
386 up = (struct jjyunit *) pp->unitptr ;
387 io_closeclock ( &pp->io ) ;
388 free ( (void*) up ) ;
389
390}
391
392
393/**************************************************************************************************/
394/* jjy_receive - receive data from the serial interface */
395/**************************************************************************************************/
396static void
397jjy_receive ( struct recvbuf *rbufp )
398{
399
400 struct jjyunit *up ;
401 struct refclockproc *pp ;
402 struct peer *peer;
403
404 l_fp tRecvTimestamp; /* arrival timestamp */
405 int rc ;
406 char sLogText [ MAX_LOGTEXT ] ;
407 int i, bCntrlChar ;
408
409 /*
410 * Initialize pointers and read the timecode and timestamp
411 */
412 peer = (struct peer *) rbufp->recv_srcclock ;
413 pp = peer->procptr ;
414 up = (struct jjyunit *) pp->unitptr ;
415
416 /*
417 * Get next input line
418 */
419 pp->lencode = refclock_gtlin ( rbufp, pp->a_lastcode, BMAX, &tRecvTimestamp ) ;
420
421 if ( up->linediscipline == LDISC_RAW ) {
422 /*
423 * The reply with <STX> and <ETX> may give a blank line
424 */
425 if ( pp->lencode == 0 && up->charcount == 0 ) return ;
426 /*
427 * Copy received charaters to temporary buffer
428 */
429 for ( i = 0 ; i < pp->lencode && up->charcount < MAX_RAWBUF - 2 ; i ++ , up->charcount ++ ) {
430 up->rawbuf[up->charcount] = pp->a_lastcode[i] ;
431 }
432 while ( up->charcount > 0 && up->rawbuf[0] < ' ' ) {
433 for ( i = 0 ; i < up->charcount - 1 ; i ++ ) up->rawbuf[i] = up->rawbuf[i+1] ;
434 up->charcount -- ;
435 }
436 bCntrlChar = 0 ;
437 for ( i = 0 ; i < up->charcount ; i ++ ) {
438 if ( up->rawbuf[i] < ' ' ) {
439 bCntrlChar = 1 ;
440 break ;
441 }
442 }
443 if ( pp->lencode > 0 && up->linecount < up->lineexpect ) {
444 if ( bCntrlChar == 0 && up->charcount < up->charexpect[up->linecount] ) return ;
445 }
446 up->rawbuf[up->charcount] = 0 ;
447 } else {
448 /*
449 * The reply with <CR><LF> gives a blank line
450 */
451 if ( pp->lencode == 0 ) return ;
452 }
453 /*
454 * We get down to business
455 */
456
457 pp->lastrec = tRecvTimestamp ;
458
459 up->linecount ++ ;
460
461 if ( up->lineerror != 0 ) return ;
462
463 switch ( up->unittype ) {
464
465 case UNITTYPE_TRISTATE_JJY01 :
466 rc = jjy_receive_tristate_jjy01 ( rbufp ) ;
467 break ;
468
469 case UNITTYPE_CDEX_JST2000 :
470 rc = jjy_receive_cdex_jst2000 ( rbufp ) ;
471 break ;
472
473 case UNITTYPE_ECHOKEISOKUKI_LT2000 :
474 rc = jjy_receive_echokeisokuki_lt2000 ( rbufp ) ;
475 break ;
476
477 case UNITTYPE_CITIZENTIC_JJY200 :
478 rc = jjy_receive_citizentic_jjy200 ( rbufp ) ;
479 break ;
480
437 default :
438 rc = 0 ;
439 break ;
440
441 }
442
443 if ( up->linediscipline == LDISC_RAW ) {
444 if ( up->linecount <= up->lineexpect && up->charcount > up->charexpect[up->linecount-1] ) {
445 for ( i = 0 ; i < up->charcount - up->charexpect[up->linecount-1] ; i ++ ) {
446 up->rawbuf[i] = up->rawbuf[i+up->charexpect[up->linecount-1]] ;
447 }
448 up->charcount -= up->charexpect[up->linecount-1] ;
449 } else {
450 up->charcount = 0 ;
451 }
452 }
453
454 if ( rc == 0 ) return ;
455
481 default :
482 rc = 0 ;
483 break ;
484
485 }
486
487 if ( up->linediscipline == LDISC_RAW ) {
488 if ( up->linecount <= up->lineexpect && up->charcount > up->charexpect[up->linecount-1] ) {
489 for ( i = 0 ; i < up->charcount - up->charexpect[up->linecount-1] ; i ++ ) {
490 up->rawbuf[i] = up->rawbuf[i+up->charexpect[up->linecount-1]] ;
491 }
492 up->charcount -= up->charexpect[up->linecount-1] ;
493 } else {
494 up->charcount = 0 ;
495 }
496 }
497
498 if ( rc == 0 ) return ;
499
500 up->bPollFlag = 0 ;
501
456 if ( up->lineerror != 0 ) {
457 refclock_report ( peer, CEVNT_BADREPLY ) ;
458 strcpy ( sLogText, "BAD REPLY [" ) ;
459 if ( up->linediscipline == LDISC_RAW ) {
460 strncat ( sLogText, up->rawbuf, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
461 } else {
462 strncat ( sLogText, pp->a_lastcode, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
463 }
464 sLogText[MAX_LOGTEXT-1] = 0 ;
465 if ( strlen ( sLogText ) < MAX_LOGTEXT - 2 ) strcat ( sLogText, "]" ) ;
466 record_clock_stats ( &peer->srcadr, sLogText ) ;
467 return ;
468 }
469
470 pp->year = up->year ;
471 pp->day = ymd2yd ( up->year, up->month, up->day ) ;
472 pp->hour = up->hour ;
473 pp->minute = up->minute ;
474 pp->second = up->second ;
475 pp->nsec = up->msecond * 1000000;
476
477 /*
478 * JST to UTC
479 */
480 pp->hour -= 9 ;
481 if ( pp->hour < 0 ) {
482 pp->hour += 24 ;
483 pp->day -- ;
484 if ( pp->day < 1 ) {
485 pp->year -- ;
486 pp->day = ymd2yd ( pp->year, 12, 31 ) ;
487 }
488 }
489#ifdef DEBUG
490 if ( debug ) {
491 printf ( "jjy_receive (refclock_jjy.c) : %04d/%02d/%02d %02d:%02d:%02d.%1d JST ",
492 up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond/100 ) ;
493 printf ( "( %04d/%03d %02d:%02d:%02d.%1d UTC )\n",
494 pp->year, pp->day, pp->hour, pp->minute, pp->second, (int)(pp->nsec/100000000) ) ;
495 }
496#endif
497
498 /*
499 * Process the new sample in the median filter and determine the
500 * timecode timestamp.
501 */
502
503 sprintf ( sLogText, "%04d/%02d/%02d %02d:%02d:%02d.%1d JST",
504 up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond/100 ) ;
505 record_clock_stats ( &peer->srcadr, sLogText ) ;
506
507 if ( ! refclock_process ( pp ) ) {
508 refclock_report(peer, CEVNT_BADTIME);
509 return ;
510 }
511
512 pp->lastref = pp->lastrec;
513 refclock_receive(peer);
514
515}
516
517/**************************************************************************************************/
518
519static int
520jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
521{
522
523 static char *sFunctionName = "jjy_receive_tristate_jjy01" ;
524
525 struct jjyunit *up ;
526 struct refclockproc *pp ;
527 struct peer *peer;
528
529 char *pBuf ;
530 int iLen ;
531 int rc ;
532
533 /*
534 * Initialize pointers and read the timecode and timestamp
535 */
536 peer = (struct peer *) rbufp->recv_srcclock ;
537 pp = peer->procptr ;
538 up = (struct jjyunit *) pp->unitptr ;
539
540 if ( up->linediscipline == LDISC_RAW ) {
541 pBuf = up->rawbuf ;
542 iLen = up->charcount ;
543 } else {
544 pBuf = pp->a_lastcode ;
545 iLen = pp->lencode ;
546 }
547
548 switch ( up->linecount ) {
549
550 case 1 : /* YYYY/MM/DD WWW */
551
552 if ( iLen != 14 ) {
553#ifdef DEBUG
554 if ( debug >= 2 ) {
555 printf ( "%s (refclock_jjy.c) : Reply length error ( up->linecount=%d iLen=%d )\n", sFunctionName, up->linecount, iLen ) ;
556 }
557#endif
558 up->lineerror = 1 ;
559 break ;
560 }
561 rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year, &up->month, &up->day ) ;
562 if ( rc != 3 || up->year < 2000 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31 ) {
563#ifdef DEBUG
564 if ( debug >= 2 ) {
565 printf ( "%s (refclock_jjy.c) : Date error ( up->linecount=%d )\n", sFunctionName, up->linecount ) ;
566 }
567#endif
568 up->lineerror = 1 ;
569 break ;
570 }
571
572 /*** Start of modification on 2004/10/31 */
573 /*
574 * Following codes are moved from the function jjy_poll_tristate_jjy01 in this source.
575 * The Tristate JJY-01 ( Firmware version 1.01 ) accepts "time" and "stim" commands without any delay.
576 * But the JJY-01 ( Firmware version 2.01 ) does not accept these commands continuously,
577 * so this driver issues the second command "stim" after the reply of the first command "date".
578 */
579
580 /*
581 * Send "stim<CR><LF>" or "time<CR><LF>" command
582 */
583
584
585 if ( up->version >= 100 ) {
586#ifdef DEBUG
587 if ( debug ) {
588 printf ( "%s (refclock_jjy.c) : send 'stim<CR><LF>'\n", sFunctionName ) ;
589 }
590#endif
591 if ( write ( pp->io.fd, "stim\r\n",6 ) != 6 ) {
592 refclock_report ( peer, CEVNT_FAULT ) ;
593 }
594 } else {
595#ifdef DEBUG
596 if ( debug ) {
597 printf ( "%s (refclock_jjy.c) : send 'time<CR><LF>'\n", sFunctionName ) ;
598 }
599#endif
600 if ( write ( pp->io.fd, "time\r\n",6 ) != 6 ) {
601 refclock_report ( peer, CEVNT_FAULT ) ;
602 }
603 }
604 /*** End of modification ***/
605
606 return 0 ;
607
608 case 2 : /* HH:MM:SS */
609
610 if ( iLen != 8 ) {
611#ifdef DEBUG
612 if ( debug >= 2 ) {
613 printf ( "%s (refclock_jjy.c) : Reply length error ( up->linecount=%d iLen=%d )\n", sFunctionName, up->linecount, iLen ) ;
614 }
615#endif
616 up->lineerror = 1 ;
617 break ;
618 }
619 rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour, &up->minute, &up->second ) ;
620 if ( rc != 3 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
621#ifdef DEBUG
622 if ( debug >= 2 ) {
623 printf ( "%s (refclock_jjy.c) : Time error ( up->linecount=%d )\n", sFunctionName, up->linecount ) ;
624 }
625#endif
626 up->lineerror = 1 ;
627 break ;
628 }
629 up->msecond = 0 ;
630 if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) {
631 /*
632 * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver continuously.
633 * But the JJY receiver replies a date and time separately.
634 * Just after midnight transitions, we ignore this time.
635 */
636 return 0 ;
637 }
638 break ;
639
640 default : /* Unexpected reply */
641
642 up->lineerror = 1 ;
643 break ;
644
645 }
646
647 return 1 ;
648
649}
650
651/**************************************************************************************************/
652
653static int
654jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
655{
656
657 static char *sFunctionName = "jjy_receive_cdex_jst2000" ;
658
659 struct jjyunit *up ;
660 struct refclockproc *pp ;
661 struct peer *peer;
662
663 char *pBuf ;
664 int iLen ;
665 int rc ;
666
667 /*
668 * Initialize pointers and read the timecode and timestamp
669 */
670 peer = (struct peer *) rbufp->recv_srcclock ;
671 pp = peer->procptr ;
672 up = (struct jjyunit *) pp->unitptr ;
673
674 if ( up->linediscipline == LDISC_RAW ) {
675 pBuf = up->rawbuf ;
676 iLen = up->charcount ;
677 } else {
678 pBuf = pp->a_lastcode ;
679 iLen = pp->lencode ;
680 }
681
682 switch ( up->linecount ) {
683
684 case 1 : /* JYYMMDD HHMMSSS */
685
686 if ( iLen != 15 ) {
687#ifdef DEBUG
688 if ( debug >= 2 ) {
689 printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
690 }
691#endif
692 up->lineerror = 1 ;
693 break ;
694 }
695 rc = sscanf ( pBuf, "J%2d%2d%2d%*1d%2d%2d%2d%1d",
696 &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second, &up->msecond ) ;
697 if ( rc != 7 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
698 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
699#ifdef DEBUG
700 if ( debug >= 2 ) {
701 printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d.%1d ]\n", sFunctionName,
702 rc, up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond ) ;
703 }
704#endif
705 up->lineerror = 1 ;
706 break ;
707 }
708 up->year += 2000 ;
709 up->msecond *= 100 ;
710 break ;
711
712 default : /* Unexpected reply */
713
714 up->lineerror = 1 ;
715 break ;
716
717 }
718
719 return 1 ;
720
721}
722
723/**************************************************************************************************/
724
725static int
726jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
727{
728
729 static char *sFunctionName = "jjy_receive_echokeisokuki_lt2000" ;
730
731 struct jjyunit *up ;
732 struct refclockproc *pp ;
733 struct peer *peer;
734
735 char *pBuf ;
736 int iLen ;
737 int rc ;
738 int i, ibcc, ibcc1, ibcc2 ;
739
740 /*
741 * Initialize pointers and read the timecode and timestamp
742 */
743 peer = (struct peer *) rbufp->recv_srcclock ;
744 pp = peer->procptr ;
745 up = (struct jjyunit *) pp->unitptr ;
746
747 if ( up->linediscipline == LDISC_RAW ) {
748 pBuf = up->rawbuf ;
749 iLen = up->charcount ;
750 } else {
751 pBuf = pp->a_lastcode ;
752 iLen = pp->lencode ;
753 }
754
755 switch ( up->linecount ) {
756
757 case 1 : /* YYMMDDWHHMMSS<BCC1><BCC2> or YYMMDDWHHMMSS<ST1><ST2><ST3><ST4> */
758
759 if ( ( up->operationmode == 1 && iLen != 15 ) || ( up->operationmode == 2 && iLen != 17 ) ) {
760#ifdef DEBUG
761 if ( debug >= 2 ) {
762 printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
763 }
764#endif
765 if ( up->operationmode == 1 ) {
766#ifdef DEBUG
767 if ( debug ) {
768 printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
769 }
770#endif
771 if ( write ( pp->io.fd, "#",1 ) != 1 ) {
772 refclock_report ( peer, CEVNT_FAULT ) ;
773 }
774 }
775 up->lineerror = 1 ;
776 break ;
777 }
778
779 if ( up->operationmode == 1 ) {
780
781 for ( i = ibcc = 0 ; i < 13 ; i ++ ) ibcc ^= pBuf[i] ;
782 ibcc1 = 0x30 | ( ( ibcc >> 4 ) & 0xF ) ;
783 ibcc2 = 0x30 | ( ( ibcc ) & 0xF ) ;
784 if ( pBuf[13] != ibcc1 || pBuf[14] != ibcc2 ) {
785#ifdef DEBUG
786 if ( debug >= 2 ) {
787 printf ( "%s (refclock_jjy.c) : BCC error ( Recv=%02X,%02X / Calc=%02X,%02X)\n", sFunctionName, pBuf[13]&0xFF, pBuf[14]&0xFF, ibcc1, ibcc2 ) ;
788 }
789#endif
790 up->lineerror = 1 ;
791 break ;
792 }
793
794 }
795
796 rc = sscanf ( pBuf, "%2d%2d%2d%*1d%2d%2d%2d",
797 &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second ) ;
798 if ( rc != 6 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
799 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
800#ifdef DEBUG
801 if ( debug >= 2 ) {
802 printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d ]\n", sFunctionName,
803 rc, up->year, up->month, up->day, up->hour, up->minute, up->second ) ;
804 }
805#endif
806 up->lineerror = 1 ;
807 break ;
808 }
809
810 up->year += 2000 ;
811
812 if ( up->operationmode == 2 ) {
813
814 /* A time stamp comes on every 0.5 seccond in the mode 2 of the LT-2000. */
815 up->msecond = 500 ;
816 pp->second -- ;
817 if ( pp->second < 0 ) {
818 pp->second = 59 ;
819 pp->minute -- ;
820 if ( pp->minute < 0 ) {
821 pp->minute = 59 ;
822 pp->hour -- ;
823 if ( pp->hour < 0 ) {
824 pp->hour = 23 ;
825 pp->day -- ;
826 if ( pp->day < 1 ) {
827 pp->year -- ;
828 pp->day = ymd2yd ( pp->year, 12, 31 ) ;
829 }
830 }
831 }
832 }
833
834 /* Switch from mode 2 to mode 1 in order to restraint of useless time stamp. */
835#ifdef DEBUG
836 if ( debug ) {
837 printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
838 }
839#endif
840 if ( write ( pp->io.fd, "#",1 ) != 1 ) {
841 refclock_report ( peer, CEVNT_FAULT ) ;
842 }
843
844 }
845
846 break ;
847
848 default : /* Unexpected reply */
849
850#ifdef DEBUG
851 if ( debug ) {
852 printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
853 }
854#endif
855 if ( write ( pp->io.fd, "#",1 ) != 1 ) {
856 refclock_report ( peer, CEVNT_FAULT ) ;
857 }
858
859 up->lineerror = 1 ;
860 break ;
861
862 }
863
864 return 1 ;
865
866}
867
868/**************************************************************************************************/
502 if ( up->lineerror != 0 ) {
503 refclock_report ( peer, CEVNT_BADREPLY ) ;
504 strcpy ( sLogText, "BAD REPLY [" ) ;
505 if ( up->linediscipline == LDISC_RAW ) {
506 strncat ( sLogText, up->rawbuf, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
507 } else {
508 strncat ( sLogText, pp->a_lastcode, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ;
509 }
510 sLogText[MAX_LOGTEXT-1] = 0 ;
511 if ( strlen ( sLogText ) < MAX_LOGTEXT - 2 ) strcat ( sLogText, "]" ) ;
512 record_clock_stats ( &peer->srcadr, sLogText ) ;
513 return ;
514 }
515
516 pp->year = up->year ;
517 pp->day = ymd2yd ( up->year, up->month, up->day ) ;
518 pp->hour = up->hour ;
519 pp->minute = up->minute ;
520 pp->second = up->second ;
521 pp->nsec = up->msecond * 1000000;
522
523 /*
524 * JST to UTC
525 */
526 pp->hour -= 9 ;
527 if ( pp->hour < 0 ) {
528 pp->hour += 24 ;
529 pp->day -- ;
530 if ( pp->day < 1 ) {
531 pp->year -- ;
532 pp->day = ymd2yd ( pp->year, 12, 31 ) ;
533 }
534 }
535#ifdef DEBUG
536 if ( debug ) {
537 printf ( "jjy_receive (refclock_jjy.c) : %04d/%02d/%02d %02d:%02d:%02d.%1d JST ",
538 up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond/100 ) ;
539 printf ( "( %04d/%03d %02d:%02d:%02d.%1d UTC )\n",
540 pp->year, pp->day, pp->hour, pp->minute, pp->second, (int)(pp->nsec/100000000) ) ;
541 }
542#endif
543
544 /*
545 * Process the new sample in the median filter and determine the
546 * timecode timestamp.
547 */
548
549 sprintf ( sLogText, "%04d/%02d/%02d %02d:%02d:%02d.%1d JST",
550 up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond/100 ) ;
551 record_clock_stats ( &peer->srcadr, sLogText ) ;
552
553 if ( ! refclock_process ( pp ) ) {
554 refclock_report(peer, CEVNT_BADTIME);
555 return ;
556 }
557
558 pp->lastref = pp->lastrec;
559 refclock_receive(peer);
560
561}
562
563/**************************************************************************************************/
564
565static int
566jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
567{
568
569 static char *sFunctionName = "jjy_receive_tristate_jjy01" ;
570
571 struct jjyunit *up ;
572 struct refclockproc *pp ;
573 struct peer *peer;
574
575 char *pBuf ;
576 int iLen ;
577 int rc ;
578
579 /*
580 * Initialize pointers and read the timecode and timestamp
581 */
582 peer = (struct peer *) rbufp->recv_srcclock ;
583 pp = peer->procptr ;
584 up = (struct jjyunit *) pp->unitptr ;
585
586 if ( up->linediscipline == LDISC_RAW ) {
587 pBuf = up->rawbuf ;
588 iLen = up->charcount ;
589 } else {
590 pBuf = pp->a_lastcode ;
591 iLen = pp->lencode ;
592 }
593
594 switch ( up->linecount ) {
595
596 case 1 : /* YYYY/MM/DD WWW */
597
598 if ( iLen != 14 ) {
599#ifdef DEBUG
600 if ( debug >= 2 ) {
601 printf ( "%s (refclock_jjy.c) : Reply length error ( up->linecount=%d iLen=%d )\n", sFunctionName, up->linecount, iLen ) ;
602 }
603#endif
604 up->lineerror = 1 ;
605 break ;
606 }
607 rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year, &up->month, &up->day ) ;
608 if ( rc != 3 || up->year < 2000 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31 ) {
609#ifdef DEBUG
610 if ( debug >= 2 ) {
611 printf ( "%s (refclock_jjy.c) : Date error ( up->linecount=%d )\n", sFunctionName, up->linecount ) ;
612 }
613#endif
614 up->lineerror = 1 ;
615 break ;
616 }
617
618 /*** Start of modification on 2004/10/31 */
619 /*
620 * Following codes are moved from the function jjy_poll_tristate_jjy01 in this source.
621 * The Tristate JJY-01 ( Firmware version 1.01 ) accepts "time" and "stim" commands without any delay.
622 * But the JJY-01 ( Firmware version 2.01 ) does not accept these commands continuously,
623 * so this driver issues the second command "stim" after the reply of the first command "date".
624 */
625
626 /*
627 * Send "stim<CR><LF>" or "time<CR><LF>" command
628 */
629
630
631 if ( up->version >= 100 ) {
632#ifdef DEBUG
633 if ( debug ) {
634 printf ( "%s (refclock_jjy.c) : send 'stim<CR><LF>'\n", sFunctionName ) ;
635 }
636#endif
637 if ( write ( pp->io.fd, "stim\r\n",6 ) != 6 ) {
638 refclock_report ( peer, CEVNT_FAULT ) ;
639 }
640 } else {
641#ifdef DEBUG
642 if ( debug ) {
643 printf ( "%s (refclock_jjy.c) : send 'time<CR><LF>'\n", sFunctionName ) ;
644 }
645#endif
646 if ( write ( pp->io.fd, "time\r\n",6 ) != 6 ) {
647 refclock_report ( peer, CEVNT_FAULT ) ;
648 }
649 }
650 /*** End of modification ***/
651
652 return 0 ;
653
654 case 2 : /* HH:MM:SS */
655
656 if ( iLen != 8 ) {
657#ifdef DEBUG
658 if ( debug >= 2 ) {
659 printf ( "%s (refclock_jjy.c) : Reply length error ( up->linecount=%d iLen=%d )\n", sFunctionName, up->linecount, iLen ) ;
660 }
661#endif
662 up->lineerror = 1 ;
663 break ;
664 }
665 rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour, &up->minute, &up->second ) ;
666 if ( rc != 3 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
667#ifdef DEBUG
668 if ( debug >= 2 ) {
669 printf ( "%s (refclock_jjy.c) : Time error ( up->linecount=%d )\n", sFunctionName, up->linecount ) ;
670 }
671#endif
672 up->lineerror = 1 ;
673 break ;
674 }
675 up->msecond = 0 ;
676 if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) {
677 /*
678 * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver continuously.
679 * But the JJY receiver replies a date and time separately.
680 * Just after midnight transitions, we ignore this time.
681 */
682 return 0 ;
683 }
684 break ;
685
686 default : /* Unexpected reply */
687
688 up->lineerror = 1 ;
689 break ;
690
691 }
692
693 return 1 ;
694
695}
696
697/**************************************************************************************************/
698
699static int
700jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
701{
702
703 static char *sFunctionName = "jjy_receive_cdex_jst2000" ;
704
705 struct jjyunit *up ;
706 struct refclockproc *pp ;
707 struct peer *peer;
708
709 char *pBuf ;
710 int iLen ;
711 int rc ;
712
713 /*
714 * Initialize pointers and read the timecode and timestamp
715 */
716 peer = (struct peer *) rbufp->recv_srcclock ;
717 pp = peer->procptr ;
718 up = (struct jjyunit *) pp->unitptr ;
719
720 if ( up->linediscipline == LDISC_RAW ) {
721 pBuf = up->rawbuf ;
722 iLen = up->charcount ;
723 } else {
724 pBuf = pp->a_lastcode ;
725 iLen = pp->lencode ;
726 }
727
728 switch ( up->linecount ) {
729
730 case 1 : /* JYYMMDD HHMMSSS */
731
732 if ( iLen != 15 ) {
733#ifdef DEBUG
734 if ( debug >= 2 ) {
735 printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
736 }
737#endif
738 up->lineerror = 1 ;
739 break ;
740 }
741 rc = sscanf ( pBuf, "J%2d%2d%2d%*1d%2d%2d%2d%1d",
742 &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second, &up->msecond ) ;
743 if ( rc != 7 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
744 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
745#ifdef DEBUG
746 if ( debug >= 2 ) {
747 printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d.%1d ]\n", sFunctionName,
748 rc, up->year, up->month, up->day, up->hour, up->minute, up->second, up->msecond ) ;
749 }
750#endif
751 up->lineerror = 1 ;
752 break ;
753 }
754 up->year += 2000 ;
755 up->msecond *= 100 ;
756 break ;
757
758 default : /* Unexpected reply */
759
760 up->lineerror = 1 ;
761 break ;
762
763 }
764
765 return 1 ;
766
767}
768
769/**************************************************************************************************/
770
771static int
772jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
773{
774
775 static char *sFunctionName = "jjy_receive_echokeisokuki_lt2000" ;
776
777 struct jjyunit *up ;
778 struct refclockproc *pp ;
779 struct peer *peer;
780
781 char *pBuf ;
782 int iLen ;
783 int rc ;
784 int i, ibcc, ibcc1, ibcc2 ;
785
786 /*
787 * Initialize pointers and read the timecode and timestamp
788 */
789 peer = (struct peer *) rbufp->recv_srcclock ;
790 pp = peer->procptr ;
791 up = (struct jjyunit *) pp->unitptr ;
792
793 if ( up->linediscipline == LDISC_RAW ) {
794 pBuf = up->rawbuf ;
795 iLen = up->charcount ;
796 } else {
797 pBuf = pp->a_lastcode ;
798 iLen = pp->lencode ;
799 }
800
801 switch ( up->linecount ) {
802
803 case 1 : /* YYMMDDWHHMMSS<BCC1><BCC2> or YYMMDDWHHMMSS<ST1><ST2><ST3><ST4> */
804
805 if ( ( up->operationmode == 1 && iLen != 15 ) || ( up->operationmode == 2 && iLen != 17 ) ) {
806#ifdef DEBUG
807 if ( debug >= 2 ) {
808 printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
809 }
810#endif
811 if ( up->operationmode == 1 ) {
812#ifdef DEBUG
813 if ( debug ) {
814 printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
815 }
816#endif
817 if ( write ( pp->io.fd, "#",1 ) != 1 ) {
818 refclock_report ( peer, CEVNT_FAULT ) ;
819 }
820 }
821 up->lineerror = 1 ;
822 break ;
823 }
824
825 if ( up->operationmode == 1 ) {
826
827 for ( i = ibcc = 0 ; i < 13 ; i ++ ) ibcc ^= pBuf[i] ;
828 ibcc1 = 0x30 | ( ( ibcc >> 4 ) & 0xF ) ;
829 ibcc2 = 0x30 | ( ( ibcc ) & 0xF ) ;
830 if ( pBuf[13] != ibcc1 || pBuf[14] != ibcc2 ) {
831#ifdef DEBUG
832 if ( debug >= 2 ) {
833 printf ( "%s (refclock_jjy.c) : BCC error ( Recv=%02X,%02X / Calc=%02X,%02X)\n", sFunctionName, pBuf[13]&0xFF, pBuf[14]&0xFF, ibcc1, ibcc2 ) ;
834 }
835#endif
836 up->lineerror = 1 ;
837 break ;
838 }
839
840 }
841
842 rc = sscanf ( pBuf, "%2d%2d%2d%*1d%2d%2d%2d",
843 &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second ) ;
844 if ( rc != 6 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
845 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
846#ifdef DEBUG
847 if ( debug >= 2 ) {
848 printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %02d %02d %02d * %02d %02d %02d ]\n", sFunctionName,
849 rc, up->year, up->month, up->day, up->hour, up->minute, up->second ) ;
850 }
851#endif
852 up->lineerror = 1 ;
853 break ;
854 }
855
856 up->year += 2000 ;
857
858 if ( up->operationmode == 2 ) {
859
860 /* A time stamp comes on every 0.5 seccond in the mode 2 of the LT-2000. */
861 up->msecond = 500 ;
862 pp->second -- ;
863 if ( pp->second < 0 ) {
864 pp->second = 59 ;
865 pp->minute -- ;
866 if ( pp->minute < 0 ) {
867 pp->minute = 59 ;
868 pp->hour -- ;
869 if ( pp->hour < 0 ) {
870 pp->hour = 23 ;
871 pp->day -- ;
872 if ( pp->day < 1 ) {
873 pp->year -- ;
874 pp->day = ymd2yd ( pp->year, 12, 31 ) ;
875 }
876 }
877 }
878 }
879
880 /* Switch from mode 2 to mode 1 in order to restraint of useless time stamp. */
881#ifdef DEBUG
882 if ( debug ) {
883 printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
884 }
885#endif
886 if ( write ( pp->io.fd, "#",1 ) != 1 ) {
887 refclock_report ( peer, CEVNT_FAULT ) ;
888 }
889
890 }
891
892 break ;
893
894 default : /* Unexpected reply */
895
896#ifdef DEBUG
897 if ( debug ) {
898 printf ( "%s (refclock_jjy.c) : send '#'\n", sFunctionName ) ;
899 }
900#endif
901 if ( write ( pp->io.fd, "#",1 ) != 1 ) {
902 refclock_report ( peer, CEVNT_FAULT ) ;
903 }
904
905 up->lineerror = 1 ;
906 break ;
907
908 }
909
910 return 1 ;
911
912}
913
914/**************************************************************************************************/
915
916static int
917jjy_receive_citizentic_jjy200 ( struct recvbuf *rbufp )
918{
919
920 static char *sFunctionName = "jjy_receive_citizentic_jjy200" ;
921
922 struct jjyunit *up ;
923 struct refclockproc *pp ;
924 struct peer *peer;
925
926 char *pBuf ;
927 int iLen ;
928 int rc ;
929 char cApostrophe, sStatus[3] ;
930 int iWeekday ;
931
932 /*
933 * Initialize pointers and read the timecode and timestamp
934 */
935 peer = (struct peer *) rbufp->recv_srcclock ;
936 pp = peer->procptr ;
937 up = (struct jjyunit *) pp->unitptr ;
938
939 if ( up->linediscipline == LDISC_RAW ) {
940 pBuf = up->rawbuf ;
941 iLen = up->charcount ;
942 } else {
943 pBuf = pp->a_lastcode ;
944 iLen = pp->lencode ;
945 }
946
947 /*
948 * JJY-200 sends a timestamp every second.
949 * So, a timestamp is ignored unless it is right after polled.
950 */
951 if ( ! up->bPollFlag ) return 0 ;
952
953 switch ( up->linecount ) {
954
955 case 1 : /* 'XX YY/MM/DD W HH:MM:SS<CR> */
956
957 if ( iLen != 23 ) {
958#ifdef DEBUG
959 if ( debug >= 2 ) {
960 printf ( "%s (refclock_jjy.c) : Reply length error ( iLen=%d )\n", sFunctionName, iLen ) ;
961 }
962#endif
963 up->lineerror = 1 ;
964 break ;
965 }
966
967 rc = sscanf ( pBuf, "%c%2s %2d/%2d/%2d %1d %2d:%2d:%2d",
968 &cApostrophe, sStatus,
969 &up->year, &up->month, &up->day, &iWeekday, &up->hour, &up->minute, &up->second ) ;
970 sStatus[2] = 0 ;
971 if ( rc != 9 || cApostrophe != '\'' || strcmp( sStatus, "OK" ) != 0
972 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31
973 || iWeekday > 6
974 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
975#ifdef DEBUG
976 if ( debug >= 2 ) {
977 printf ( "%s (refclock_jjy.c) : Time error (rc=%d) [ %c %2s %02d %02d %02d %d %02d %02d %02d ]\n", sFunctionName,
978 rc, cApostrophe, sStatus, up->year, up->month, up->day, iWeekday, up->hour, up->minute, up->second ) ;
979 }
980#endif
981 up->lineerror = 1 ;
982 break ;
983 }
984
985 up->year += 2000 ;
986 up->msecond = 0 ;
987
988 break ;
989
990 default : /* Unexpected reply */
991
992 up->lineerror = 1 ;
993 break ;
994
995 }
996
997 return 1 ;
998
999}
1000
1001/**************************************************************************************************/
869/* jjy_poll - called by the transmit procedure */
870/**************************************************************************************************/
871static void
872jjy_poll ( int unit, struct peer *peer )
873{
874
875 struct jjyunit *up;
876 struct refclockproc *pp;
877
878 pp = peer->procptr;
879 up = (struct jjyunit *) pp->unitptr ;
880
881 if ( pp->polls > 0 && up->linecount == 0 ) {
882 /*
883 * No reply for last command
884 */
885 refclock_report ( peer, CEVNT_TIMEOUT ) ;
886 }
887
888#ifdef DEBUG
889 if ( debug ) {
890 printf ( "jjy_poll (refclock_jjy.c) : %ld\n", pp->polls ) ;
891 }
892#endif
893
894 pp->polls ++ ;
895
1002/* jjy_poll - called by the transmit procedure */
1003/**************************************************************************************************/
1004static void
1005jjy_poll ( int unit, struct peer *peer )
1006{
1007
1008 struct jjyunit *up;
1009 struct refclockproc *pp;
1010
1011 pp = peer->procptr;
1012 up = (struct jjyunit *) pp->unitptr ;
1013
1014 if ( pp->polls > 0 && up->linecount == 0 ) {
1015 /*
1016 * No reply for last command
1017 */
1018 refclock_report ( peer, CEVNT_TIMEOUT ) ;
1019 }
1020
1021#ifdef DEBUG
1022 if ( debug ) {
1023 printf ( "jjy_poll (refclock_jjy.c) : %ld\n", pp->polls ) ;
1024 }
1025#endif
1026
1027 pp->polls ++ ;
1028
1029 up->bPollFlag = 1 ;
896 up->linecount = 0 ;
897 up->lineerror = 0 ;
898 up->charcount = 0 ;
899
900 switch ( up->unittype ) {
901
902 case UNITTYPE_TRISTATE_JJY01 :
903 jjy_poll_tristate_jjy01 ( unit, peer ) ;
904 break ;
905
906 case UNITTYPE_CDEX_JST2000 :
907 jjy_poll_cdex_jst2000 ( unit, peer ) ;
908 break ;
909
910 case UNITTYPE_ECHOKEISOKUKI_LT2000 :
911 jjy_poll_echokeisokuki_lt2000 ( unit, peer ) ;
912 break ;
913
1030 up->linecount = 0 ;
1031 up->lineerror = 0 ;
1032 up->charcount = 0 ;
1033
1034 switch ( up->unittype ) {
1035
1036 case UNITTYPE_TRISTATE_JJY01 :
1037 jjy_poll_tristate_jjy01 ( unit, peer ) ;
1038 break ;
1039
1040 case UNITTYPE_CDEX_JST2000 :
1041 jjy_poll_cdex_jst2000 ( unit, peer ) ;
1042 break ;
1043
1044 case UNITTYPE_ECHOKEISOKUKI_LT2000 :
1045 jjy_poll_echokeisokuki_lt2000 ( unit, peer ) ;
1046 break ;
1047
1048 case UNITTYPE_CITIZENTIC_JJY200 :
1049 jjy_poll_citizentic_jjy200 ( unit, peer ) ;
1050 break ;
1051
914 default :
915 break ;
916
917 }
918
919}
920
921/**************************************************************************************************/
922
923static void
924jjy_poll_tristate_jjy01 ( int unit, struct peer *peer )
925{
926
927 struct refclockproc *pp;
928
929 pp = peer->procptr;
930
931 /*
932 * Send "date<CR><LF>" command
933 */
934
935#ifdef DEBUG
936 if ( debug ) {
937 printf ( "jjy_poll_tristate_jjy01 (refclock_jjy.c) : send 'date<CR><LF>'\n" ) ;
938 }
939#endif
940
941 if ( write ( pp->io.fd, "date\r\n",6 ) != 6 ) {
942 refclock_report ( peer, CEVNT_FAULT ) ;
943 }
944
945}
946
947/**************************************************************************************************/
948
949static void
950jjy_poll_cdex_jst2000 ( int unit, struct peer *peer )
951{
952
953 struct refclockproc *pp;
954
955 pp = peer->procptr;
956
957 /*
958 * Send "<ENQ>1J<ETX>" command
959 */
960
961#ifdef DEBUG
962 if ( debug ) {
963 printf ( "jjy_poll_cdex_jst2000 (refclock_jjy.c) : send '<ENQ>1J<ETX>'\n" ) ;
964 }
965#endif
966
967 if ( write ( pp->io.fd, "\0051J\003", 4 ) != 4 ) {
968 refclock_report ( peer, CEVNT_FAULT ) ;
969 }
970
971}
972
973/**************************************************************************************************/
974
975static void
976jjy_poll_echokeisokuki_lt2000 ( int unit, struct peer *peer )
977{
978
979 struct jjyunit *up;
980 struct refclockproc *pp;
981
982 char sCmd[2] ;
983
984 pp = peer->procptr;
985 up = (struct jjyunit *) pp->unitptr ;
986
987 /*
988 * Send "T" or "C" command
989 */
990
991 switch ( up->operationmode ) {
992 case 1 : sCmd[0] = 'T' ; break ;
993 case 2 : sCmd[0] = 'C' ; break ;
994 }
995 sCmd[1] = 0 ;
996
997#ifdef DEBUG
998 if ( debug ) {
999 printf ( "jjy_poll_echokeisokuki_lt2000 (refclock_jjy.c) : send '%s'\n", sCmd ) ;
1000 }
1001#endif
1002
1003 if ( write ( pp->io.fd, sCmd, 1 ) != 1 ) {
1004 refclock_report ( peer, CEVNT_FAULT ) ;
1005 }
1006
1007}
1008
1052 default :
1053 break ;
1054
1055 }
1056
1057}
1058
1059/**************************************************************************************************/
1060
1061static void
1062jjy_poll_tristate_jjy01 ( int unit, struct peer *peer )
1063{
1064
1065 struct refclockproc *pp;
1066
1067 pp = peer->procptr;
1068
1069 /*
1070 * Send "date<CR><LF>" command
1071 */
1072
1073#ifdef DEBUG
1074 if ( debug ) {
1075 printf ( "jjy_poll_tristate_jjy01 (refclock_jjy.c) : send 'date<CR><LF>'\n" ) ;
1076 }
1077#endif
1078
1079 if ( write ( pp->io.fd, "date\r\n",6 ) != 6 ) {
1080 refclock_report ( peer, CEVNT_FAULT ) ;
1081 }
1082
1083}
1084
1085/**************************************************************************************************/
1086
1087static void
1088jjy_poll_cdex_jst2000 ( int unit, struct peer *peer )
1089{
1090
1091 struct refclockproc *pp;
1092
1093 pp = peer->procptr;
1094
1095 /*
1096 * Send "<ENQ>1J<ETX>" command
1097 */
1098
1099#ifdef DEBUG
1100 if ( debug ) {
1101 printf ( "jjy_poll_cdex_jst2000 (refclock_jjy.c) : send '<ENQ>1J<ETX>'\n" ) ;
1102 }
1103#endif
1104
1105 if ( write ( pp->io.fd, "\0051J\003", 4 ) != 4 ) {
1106 refclock_report ( peer, CEVNT_FAULT ) ;
1107 }
1108
1109}
1110
1111/**************************************************************************************************/
1112
1113static void
1114jjy_poll_echokeisokuki_lt2000 ( int unit, struct peer *peer )
1115{
1116
1117 struct jjyunit *up;
1118 struct refclockproc *pp;
1119
1120 char sCmd[2] ;
1121
1122 pp = peer->procptr;
1123 up = (struct jjyunit *) pp->unitptr ;
1124
1125 /*
1126 * Send "T" or "C" command
1127 */
1128
1129 switch ( up->operationmode ) {
1130 case 1 : sCmd[0] = 'T' ; break ;
1131 case 2 : sCmd[0] = 'C' ; break ;
1132 }
1133 sCmd[1] = 0 ;
1134
1135#ifdef DEBUG
1136 if ( debug ) {
1137 printf ( "jjy_poll_echokeisokuki_lt2000 (refclock_jjy.c) : send '%s'\n", sCmd ) ;
1138 }
1139#endif
1140
1141 if ( write ( pp->io.fd, sCmd, 1 ) != 1 ) {
1142 refclock_report ( peer, CEVNT_FAULT ) ;
1143 }
1144
1145}
1146
1147/**************************************************************************************************/
1148
1149static void
1150jjy_poll_citizentic_jjy200 ( int unit, struct peer *peer )
1151{
1152
1153 /* Do nothing ( up->bPollFlag is set by the jjy_poll ) */
1154
1155}
1156
1009#else
1010int refclock_jjy_bs ;
1011#endif /* REFCLOCK */
1157#else
1158int refclock_jjy_bs ;
1159#endif /* REFCLOCK */