1 /* 2 * refclock_jjy - clock driver for JJY receivers 3 */ 4 5 /**********************************************************************/ 6 /* */ 7 /* Copyright (C) 2001, 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 /* 2001/12/04 */ 59 /* [Fix] C-DEX JST2000 ( fukusima@goto.info.waseda.ac.jp ) */ 60 /* */ 61 /**********************************************************************/ 62 63 #ifdef HAVE_CONFIG_H 64 #include <config.h> 65 #endif 66 67 #if defined(REFCLOCK) && defined(CLOCK_JJY) 68 69 #include <stdio.h> 70 #include <ctype.h> 71 #include <string.h> 72 #include <sys/time.h> 73 #include <time.h> 74 75 #include "ntpd.h" 76 #include "ntp_io.h" 77 #include "ntp_tty.h" 78 #include "ntp_refclock.h" 79 #include "ntp_calendar.h" 80 #include "ntp_stdlib.h" 81 82 /**********************************************************************/ 83 /* */ 84 /* The Tristate Ltd. JJY receiver JJY01 */ 85 /* */ 86 /* Command Response Remarks */ 87 /* ------------ ---------------------- --------------------- */ 88 /* date<CR><LF> YYYY/MM/DD XXX<CR><LF> */ 89 /* time<CR><LF> HH:MM:SS<CR><LF> */ 90 /* stim<CR><LF> HH:MM:SS<CR><LF> Reply at just second */ 91 /* */ 92 /* During synchronization after a receiver is turned on, */ 93 /* It replies the past time from 2000/01/01 00:00:00. */ 94 /* The function "refclock_process" checks the time and tells */ 95 /* as an insanity time. */ 96 /* */ 97 /**********************************************************************/ 98 /* */ 99 /* The C-DEX Co. Ltd. JJY receiver JST2000 */ 100 /* */ 101 /* Command Response Remarks */ 102 /* ------------ ---------------------- --------------------- */ 103 /* <ENQ>1J<ETX> <STX>JYYMMDD HHMMSSS<ETX> */ 104 /* */ 105 /**********************************************************************/ 106 107 /* 108 * Interface definitions 109 */ 110 #define DEVICE "/dev/jjy%d" /* device name and unit */ 111 #define SPEED232 B9600 /* uart speed (9600 baud) */ 112 #define REFID "JJY" /* reference ID */ 113 #define DESCRIPTION "JJY Receiver" 114 #define PRECISION (-3) /* precision assumed (about 100 ms) */ 115 116 /* 117 * JJY unit control structure 118 */ 119 struct jjyunit { 120 char unittype ; /* UNITTYPE_XXXXXXXXXX */ 121 short version ; 122 short linediscipline ; /* LDISC_CLK or LDISC_RAW */ 123 int linecount ; 124 int lineerror ; 125 int year, month, day, hour, minute, second, msecond ; 126 /* LDISC_RAW only */ 127 #define MAX_LINECOUNT 8 128 #define MAX_RAWBUF 64 129 int lineexpect ; 130 int charexpect [ MAX_LINECOUNT ] ; 131 int charcount ; 132 char rawbuf [ MAX_RAWBUF ] ; 133 }; 134 135 #define UNITTYPE_TRISTATE_JJY01 1 136 #define UNITTYPE_CDEX_JST2000 2 137 138 /* 139 * Function prototypes 140 */ 141 static int jjy_start P((int, struct peer *)); 142 static void jjy_shutdown P((int, struct peer *)); 143 static void jjy_poll P((int, struct peer *)); 144 static void jjy_poll_tristate_jjy01 P((int, struct peer *)); 145 static void jjy_poll_cdex_jst2000 P((int, struct peer *)); 146 static void jjy_receive P((struct recvbuf *)); 147 static int jjy_receive_tristate_jjy01 P((struct recvbuf *)); 148 static int jjy_receive_cdex_jst2000 P((struct recvbuf *)); 149 150 /* 151 * Transfer vector 152 */ 153 struct refclock refclock_jjy = { 154 jjy_start, /* start up driver */ 155 jjy_shutdown, /* shutdown driver */ 156 jjy_poll, /* transmit poll message */ 157 noentry, /* not used */ 158 noentry, /* not used */ 159 noentry, /* not used */ 160 NOFLAGS /* not used */ 161 }; 162 163 /* 164 * Start up driver return code 165 */ 166 #define RC_START_SUCCESS 1 167 #define RC_START_ERROR 0 168 169 /* 170 * Local constants definition 171 */ 172 173 #define MAX_LOGTEXT 64 174 175 176 /**************************************************************************************************/ 177 /* jjy_start - open the devices and initialize data for processing */ 178 /**************************************************************************************************/ 179 static int 180 jjy_start ( int unit, struct peer *peer ) 181 { 182 183 struct jjyunit *up ; 184 struct refclockproc *pp ; 185 int fd ; 186 char *pDeviceName ; 187 short iDiscipline ; 188 189 #ifdef DEBUG 190 if ( debug ) { 191 printf ( "jjy_start (refclock_jjy.c) : %s mode=%d ", ntoa(&peer->srcadr), peer->ttl ) ; 192 printf ( DEVICE, unit ) ; 193 printf ( "\n" ) ; 194 } 195 #endif 196 /* 197 * Open serial port 198 */ 199 if ( ! ( pDeviceName = (char*) emalloc ( strlen(DEVICE) + 10 ) ) ) { 200 return RC_START_ERROR ; 201 } 202 sprintf ( pDeviceName, DEVICE, unit ) ; 203 204 /* 205 * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf 206 */ 207 switch ( peer->ttl ) { 208 case 0 : 209 case 1 : iDiscipline = LDISC_CLK ; break ; 210 case 2 : iDiscipline = LDISC_RAW ; break ; 211 default : 212 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode", 213 ntoa(&peer->srcadr), peer->ttl ) ; 214 free ( (void*) pDeviceName ) ; 215 return RC_START_ERROR ; 216 } 217 218 if ( ! ( fd = refclock_open ( pDeviceName, SPEED232, iDiscipline ) ) ) { 219 free ( (void*) pDeviceName ) ; 220 return RC_START_ERROR ; 221 } 222 free ( (void*) pDeviceName ) ; 223 224 /* 225 * Allocate and initialize unit structure 226 */ 227 if ( ! ( up = (struct jjyunit *) emalloc (sizeof(struct jjyunit)) ) ) { 228 close ( fd ) ; 229 return RC_START_ERROR ; 230 } 231 232 memset ( (char*)up, 0, sizeof(struct jjyunit) ) ; 233 up->linediscipline = iDiscipline ; 234 235 /* 236 * peer->ttl is a mode number specified by "127.127.40.X mode N" in the ntp.conf 237 */ 238 switch ( peer->ttl ) { 239 case 0 : 240 /* 241 * The mode 0 is a default clock type at this time. 242 * But this will be change to auto-detect mode in the future. 243 */ 244 case 1 : 245 up->unittype = UNITTYPE_TRISTATE_JJY01 ; 246 up->version = 100 ; 247 up->lineexpect = 2 ; 248 up->charexpect[0] = 14 ; /* YYYY/MM/DD WWW<CR><LF> */ 249 up->charexpect[1] = 8 ; /* HH:MM:SS<CR><LF> */ 250 break ; 251 case 2 : 252 up->unittype = UNITTYPE_CDEX_JST2000 ; 253 up->lineexpect = 1 ; 254 up->charexpect[0] = 15 ; /* <STX>JYYMMDD HHMMSSS<ETX> */ 255 break ; 256 default : 257 msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode", 258 ntoa(&peer->srcadr), peer->ttl ) ; 259 close ( fd ) ; 260 free ( (void*) up ) ; 261 return RC_START_ERROR ; 262 } 263 264 pp = peer->procptr ; 265 pp->unitptr = (caddr_t) up ; 266 pp->io.clock_recv = jjy_receive ; 267 pp->io.srcclock = (caddr_t) peer ; 268 pp->io.datalen = 0 ; 269 pp->io.fd = fd ; 270 if ( ! io_addclock(&pp->io) ) { 271 close ( fd ) ; 272 free ( (void*) up ) ; 273 return RC_START_ERROR ; 274 } 275 276 /* 277 * Initialize miscellaneous variables 278 */ 279 peer->precision = PRECISION ; 280 peer->burst = 1 ; 281 pp->clockdesc = DESCRIPTION ; 282 memcpy ( (char*)&pp->refid, REFID, strlen(REFID) ) ; 283 284 return RC_START_SUCCESS ; 285 286 } 287 288 289 /**************************************************************************************************/ 290 /* jjy_shutdown - shutdown the clock */ 291 /**************************************************************************************************/ 292 static void 293 jjy_shutdown ( int unit, struct peer *peer ) 294 { 295 296 struct jjyunit *up; 297 struct refclockproc *pp; 298 299 pp = peer->procptr ; 300 up = (struct jjyunit *) pp->unitptr ; 301 io_closeclock ( &pp->io ) ; 302 free ( (void*) up ) ; 303 304 } 305 306 307 /**************************************************************************************************/ 308 /* jjy_receive - receive data from the serial interface */ 309 /**************************************************************************************************/ 310 static void 311 jjy_receive ( struct recvbuf *rbufp ) 312 { 313 314 struct jjyunit *up ; 315 struct refclockproc *pp ; 316 struct peer *peer; 317 318 l_fp tRecvTimestamp; /* arrival timestamp */ 319 int rc ; 320 char sLogText [ MAX_LOGTEXT ] ; 321 int i, bCntrlChar ; 322 323 /* 324 * Initialize pointers and read the timecode and timestamp 325 */ 326 peer = (struct peer *) rbufp->recv_srcclock ; 327 pp = peer->procptr ; 328 up = (struct jjyunit *) pp->unitptr ; 329 330 /* 331 * Get next input line 332 */ 333 pp->lencode = refclock_gtlin ( rbufp, pp->a_lastcode, BMAX, &tRecvTimestamp ) ; 334 335 if ( up->linediscipline == LDISC_RAW ) { 336 /* 337 * The reply with <STX> and <ETX> may give a blank line 338 */ 339 if ( pp->lencode == 0 && up->charcount == 0 ) return ; 340 /* 341 * Copy received charaters to temporary buffer 342 */ 343 for ( i = 0 ; i < pp->lencode && up->charcount < MAX_RAWBUF - 2 ; i ++ , up->charcount ++ ) { 344 up->rawbuf[up->charcount] = pp->a_lastcode[i] ; 345 } 346 while ( up->charcount > 0 && up->rawbuf[0] < ' ' ) { 347 for ( i = 0 ; i < up->charcount - 1 ; i ++ ) up->rawbuf[i] = up->rawbuf[i+1] ; 348 up->charcount -- ; 349 } 350 bCntrlChar = 0 ; 351 for ( i = 0 ; i < up->charcount ; i ++ ) { 352 if ( up->rawbuf[i] < ' ' ) { 353 bCntrlChar = 1 ; 354 break ; 355 } 356 } 357 if ( pp->lencode > 0 && up->linecount < up->lineexpect ) { 358 if ( bCntrlChar == 0 && up->charcount < up->charexpect[up->linecount] ) return ; 359 } 360 up->rawbuf[up->charcount] = 0 ; 361 } else { 362 /* 363 * The reply with <CR><LF> gives a blank line 364 */ 365 if ( pp->lencode == 0 ) return ; 366 } 367 /* 368 * We get down to business 369 */ 370 371 pp->lastrec = tRecvTimestamp ; 372 373 up->linecount ++ ; 374 375 if ( up->lineerror != 0 ) return ; 376 377 switch ( up->unittype ) { 378 379 case UNITTYPE_TRISTATE_JJY01 : 380 rc = jjy_receive_tristate_jjy01 ( rbufp ) ; 381 break ; 382 383 case UNITTYPE_CDEX_JST2000 : 384 rc = jjy_receive_cdex_jst2000 ( rbufp ) ; 385 break ; 386 387 default : 388 rc = 0 ; 389 break ; 390 391 } 392 393 if ( up->linediscipline == LDISC_RAW ) { 394 if ( up->linecount <= up->lineexpect && up->charcount > up->charexpect[up->linecount-1] ) { 395 for ( i = 0 ; i < up->charcount - up->charexpect[up->linecount-1] ; i ++ ) { 396 up->rawbuf[i] = up->rawbuf[i+up->charexpect[up->linecount-1]] ; 397 } 398 up->charcount -= up->charexpect[up->linecount-1] ; 399 } else { 400 up->charcount = 0 ; 401 } 402 } 403 404 if ( rc == 0 ) return ; 405 406 if ( up->lineerror != 0 ) { 407 refclock_report ( peer, CEVNT_BADREPLY ) ; 408 strcpy ( sLogText, "BAD REPLY [" ) ; 409 if ( up->linediscipline == LDISC_RAW ) { 410 strncat ( sLogText, up->rawbuf, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ; 411 } else { 412 strncat ( sLogText, pp->a_lastcode, MAX_LOGTEXT - strlen ( sLogText ) - 1 ) ; 413 } 414 sLogText[MAX_LOGTEXT-1] = 0 ; 415 if ( strlen ( sLogText ) < MAX_LOGTEXT - 2 ) strcat ( sLogText, "]" ) ; 416 record_clock_stats ( &peer->srcadr, sLogText ) ; 417 return ; 418 } 419 420 pp->year = up->year ; 421 pp->day = ymd2yd ( up->year, up->month, up->day ) ; 422 pp->hour = up->hour ; 423 pp->minute = up->minute ; 424 pp->second = up->second ; 425 pp->nsec = up->msecond * 1000000; 426 427 /* 428 * JST to UTC 429 */ 430 pp->hour -= 9 ; 431 if ( pp->hour < 0 ) { 432 pp->hour += 24 ; 433 pp->day -- ; 434 if ( pp->day < 1 ) { 435 pp->year -- ; 436 pp->day = ymd2yd ( pp->year, 12, 31 ) ; 437 } 438 } 439 #ifdef DEBUG 440 if ( debug ) { 441 printf ( "jjy_receive (refclock_jjy.c) : %04d/%02d/%02d %02d:%02d:%02d JST ", 442 up->year, up->month, up->day, up->hour, up->minute, up->second ) ; 443 printf ( "( %04d/%03d %02d:%02d:%02d UTC )\n", 444 pp->year, pp->day, pp->hour, pp->minute, pp->second ) ; 445 } 446 #endif 447 448 /* 449 * Process the new sample in the median filter and determine the 450 * timecode timestamp. 451 */ 452 if ( ! refclock_process ( pp ) ) { 453 refclock_report(peer, CEVNT_BADTIME); 454 sprintf ( sLogText, "BAD TIME %04d/%02d/%02d %02d:%02d:%02d JST", 455 up->year, up->month, up->day, up->hour, up->minute, up->second ) ; 456 record_clock_stats ( &peer->srcadr, sLogText ) ; 457 return ; 458 } 459 460 sprintf ( sLogText, "%04d/%02d/%02d %02d:%02d:%02d JST", 461 up->year, up->month, up->day, up->hour, up->minute, up->second ) ; 462 pp->lastref = pp->lastrec; 463 refclock_receive(peer); 464 record_clock_stats ( &peer->srcadr, sLogText ) ; 465 } 466 467 /**************************************************************************************************/ 468 469 static int 470 jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp ) 471 { 472 473 struct jjyunit *up ; 474 struct refclockproc *pp ; 475 struct peer *peer; 476 477 char *pBuf ; 478 int iLen ; 479 int rc ; 480 481 /* 482 * Initialize pointers and read the timecode and timestamp 483 */ 484 peer = (struct peer *) rbufp->recv_srcclock ; 485 pp = peer->procptr ; 486 up = (struct jjyunit *) pp->unitptr ; 487 488 if ( up->linediscipline == LDISC_RAW ) { 489 pBuf = up->rawbuf ; 490 iLen = up->charcount ; 491 } else { 492 pBuf = pp->a_lastcode ; 493 iLen = pp->lencode ; 494 } 495 496 switch ( up->linecount ) { 497 498 case 1 : /* YYYY/MM/DD */ 499 500 if ( iLen < 10 ) { 501 up->lineerror = 1 ; 502 break ; 503 } 504 rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year, &up->month, &up->day ) ; 505 if ( rc != 3 || up->year < 2000 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31 ) { 506 up->lineerror = 1 ; 507 break ; 508 } 509 return 0 ; 510 511 case 2 : /* HH:MM:SS */ 512 513 if ( iLen < 8 ) { 514 up->lineerror = 1 ; 515 break ; 516 } 517 rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour, &up->minute, &up->second ) ; 518 if ( rc != 3 || up->hour > 23 || up->minute > 59 || up->second > 60 ) { 519 up->lineerror = 1 ; 520 break ; 521 } 522 up->msecond = 0 ; 523 if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) { 524 /* 525 * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver continuously. 526 * But the JJY receiver replies a date and time separately. 527 * Just after midnight transtions, we ignore this time. 528 */ 529 return 0 ; 530 } 531 break ; 532 533 default : /* Unexpected reply */ 534 535 up->lineerror = 1 ; 536 break ; 537 538 } 539 540 return 1 ; 541 542 } 543 544 /**************************************************************************************************/ 545 546 static int 547 jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp ) 548 { 549 550 struct jjyunit *up ; 551 struct refclockproc *pp ; 552 struct peer *peer; 553 554 char *pBuf ; 555 int iLen ; 556 int rc ; 557 558 /* 559 * Initialize pointers and read the timecode and timestamp 560 */ 561 peer = (struct peer *) rbufp->recv_srcclock ; 562 pp = peer->procptr ; 563 up = (struct jjyunit *) pp->unitptr ; 564 565 if ( up->linediscipline == LDISC_RAW ) { 566 pBuf = up->rawbuf ; 567 iLen = up->charcount ; 568 } else { 569 pBuf = pp->a_lastcode ; 570 iLen = pp->lencode ; 571 } 572 573 switch ( up->linecount ) { 574 575 case 1 : /* JYYMMDD HHMMSSS */ 576 577 if ( iLen < 15 ) { 578 up->lineerror = 1 ; 579 break ; 580 } 581 rc = sscanf ( pBuf, "J%2d%2d%2d%*1d%2d%2d%2d%1d", 582 &up->year, &up->month, &up->day, &up->hour, &up->minute, &up->second, &up->msecond ) ; 583 if ( rc != 7 || up->month < 1 || up->month > 12 || up->day < 1 || up->day > 31 584 || up->hour > 23 || up->minute > 59 || up->second > 60 ) { 585 up->lineerror = 1 ; 586 break ; 587 } 588 up->year += 2000 ; 589 up->msecond *= 100 ; 590 break ; 591 592 default : /* Unexpected reply */ 593 594 up->lineerror = 1 ; 595 break ; 596 597 } 598 599 return 1 ; 600 601 } 602 603 /**************************************************************************************************/ 604 /* jjy_poll - called by the transmit procedure */ 605 /**************************************************************************************************/ 606 static void 607 jjy_poll ( int unit, struct peer *peer ) 608 { 609 610 struct jjyunit *up; 611 struct refclockproc *pp; 612 613 pp = peer->procptr; 614 up = (struct jjyunit *) pp->unitptr ; 615 616 if ( pp->polls > 0 && up->linecount == 0 ) { 617 /* 618 * No reply for last command 619 */ 620 refclock_report ( peer, CEVNT_TIMEOUT ) ; 621 } 622 623 #ifdef DEBUG 624 if ( debug ) { 625 printf ( "jjy_poll (refclock_jjy.c) : %ld\n", pp->polls ) ; 626 } 627 #endif 628 629 pp->polls ++ ; 630 631 up->linecount = 0 ; 632 up->lineerror = 0 ; 633 up->charcount = 0 ; 634 635 switch ( up->unittype ) { 636 637 case UNITTYPE_TRISTATE_JJY01 : 638 jjy_poll_tristate_jjy01 ( unit, peer ) ; 639 break ; 640 641 case UNITTYPE_CDEX_JST2000 : 642 jjy_poll_cdex_jst2000 ( unit, peer ) ; 643 break ; 644 645 default : 646 break ; 647 648 } 649 650 } 651 652 /**************************************************************************************************/ 653 654 static void 655 jjy_poll_tristate_jjy01 ( int unit, struct peer *peer ) 656 { 657 658 struct jjyunit *up; 659 struct refclockproc *pp; 660 661 pp = peer->procptr; 662 up = (struct jjyunit *) pp->unitptr ; 663 664 /* 665 * Send "date<CR><LF>" command 666 */ 667 668 if ( write ( pp->io.fd, "date\r\n",6 ) != 6 ) { 669 refclock_report ( peer, CEVNT_FAULT ) ; 670 } 671 672 /* 673 * Send "stim<CR><LF>" or "time<CR><LF>" command 674 */ 675 676 if ( up->version >= 100 ) { 677 if ( write ( pp->io.fd, "stim\r\n",6 ) != 6 ) { 678 refclock_report ( peer, CEVNT_FAULT ) ; 679 } 680 } else { 681 if ( write ( pp->io.fd, "time\r\n",6 ) != 6 ) { 682 refclock_report ( peer, CEVNT_FAULT ) ; 683 } 684 } 685 686 } 687 688 /**************************************************************************************************/ 689 690 static void 691 jjy_poll_cdex_jst2000 ( int unit, struct peer *peer ) 692 { 693 694 struct refclockproc *pp; 695 696 pp = peer->procptr; 697 698 /* 699 * Send "<ENQ>1J<ETX>" command 700 */ 701 702 if ( write ( pp->io.fd, "\0051J\003", 4 ) != 4 ) { 703 refclock_report ( peer, CEVNT_FAULT ) ; 704 } 705 706 } 707 708 #else 709 int refclock_jjy_bs ; 710 #endif /* REFCLOCK */ 711