1 /* 2 * This software was developed by the Software and Component Technologies 3 * group of Trimble Navigation, Ltd. 4 * 5 * Copyright (c) 1997, 1998, 1999, 2000 Trimble Navigation Ltd. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Trimble Navigation, Ltd. 19 * 4. The name of Trimble Navigation Ltd. may not be used to endorse or 20 * promote products derived from this software without specific prior 21 * written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY TRIMBLE NAVIGATION LTD. ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL TRIMBLE NAVIGATION LTD. BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 /* 37 * refclock_palisade - clock driver for the Trimble Palisade GPS 38 * timing receiver 39 * 40 * For detailed information on this program, please refer to the html 41 * Refclock 29 page accompanying the NTP distribution. 42 * 43 * for questions / bugs / comments, contact: 44 * sven_dietrich@trimble.com 45 * 46 * Sven-Thorsten Dietrich 47 * 645 North Mary Avenue 48 * Post Office Box 3642 49 * Sunnyvale, CA 94088-3642 50 * 51 * Version 2.45; July 14, 1999 52 * 53 */ 54 55 #ifdef HAVE_CONFIG_H 56 #include "config.h" 57 #endif 58 59 #if defined(REFCLOCK) && (defined(PALISADE) || defined(CLOCK_PALISADE)) 60 61 #include "refclock_palisade.h" 62 /* Table to get from month to day of the year */ 63 const int days_of_year [12] = { 64 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 65 }; 66 67 #ifdef DEBUG 68 const char * Tracking_Status[15][15] = { 69 { "Doing Fixes\0" }, { "Good 1SV\0" }, { "Approx. 1SV\0" }, 70 {"Need Time\0" }, { "Need INIT\0" }, { "PDOP too High\0" }, 71 { "Bad 1SV\0" }, { "0SV Usable\0" }, { "1SV Usable\0" }, 72 { "2SV Usable\0" }, { "3SV Usable\0" }, { "No Integrity\0" }, 73 { "Diff Corr\0" }, { "Overdet Clock\0" }, { "Invalid\0" } }; 74 #endif 75 76 /* 77 * Transfer vector 78 */ 79 struct refclock refclock_palisade = { 80 palisade_start, /* start up driver */ 81 palisade_shutdown, /* shut down driver */ 82 palisade_poll, /* transmit poll message */ 83 noentry, /* not used */ 84 noentry, /* initialize driver (not used) */ 85 noentry, /* not used */ 86 NOFLAGS /* not used */ 87 }; 88 89 int day_of_year P((char *dt)); 90 91 /* 92 * palisade_start - open the devices and initialize data for processing 93 */ 94 static int 95 palisade_start ( 96 #ifdef PALISADE 97 unit, peer 98 ) 99 int unit; 100 struct peer *peer; 101 #else /* ANSI */ 102 int unit, 103 struct peer *peer 104 ) 105 #endif 106 { 107 struct palisade_unit *up; 108 struct refclockproc *pp; 109 int fd; 110 char gpsdev[20]; 111 112 struct termios tio; 113 #ifdef SYS_WINNT 114 (void) sprintf(gpsdev, "COM%d:", unit); 115 #else 116 (void) sprintf(gpsdev, DEVICE, unit); 117 #endif 118 /* 119 * Open serial port. 120 */ 121 #if defined PALISADE 122 fd = open(gpsdev, O_RDWR 123 #ifdef O_NONBLOCK 124 | O_NONBLOCK 125 #endif 126 ); 127 #else /* NTP 4.x */ 128 fd = refclock_open(gpsdev, SPEED232, LDISC_RAW); 129 #endif 130 if (fd <= 0) { 131 #ifdef DEBUG 132 printf("Palisade(%d) start: open %s failed\n", unit, gpsdev); 133 #endif 134 return 0; 135 } 136 137 msyslog(LOG_NOTICE, "Palisade(%d) fd: %d dev: %s", unit, fd, 138 gpsdev); 139 140 #if defined PALISADE 141 tio.c_cflag = (CS8|CLOCAL|CREAD|PARENB|PARODD); 142 tio.c_iflag = (IGNBRK); 143 tio.c_oflag = (0); 144 tio.c_lflag = (0); 145 146 if (cfsetispeed(&tio, SPEED232) == -1) { 147 msyslog(LOG_ERR,"Palisade(%d) cfsetispeed(fd, &tio): %m",unit); 148 #ifdef DEBUG 149 printf("Palisade(%d) cfsetispeed(fd, &tio)\n",unit); 150 #endif 151 return 0; 152 } 153 if (cfsetospeed(&tio, SPEED232) == -1) { 154 #ifdef DEBUG 155 printf("Palisade(%d) cfsetospeed(fd, &tio)\n",unit); 156 #endif 157 msyslog(LOG_ERR,"Palisade(%d) cfsetospeed(fd, &tio): %m",unit); 158 return 0; 159 } 160 #else /* NTP 4.x */ 161 if (tcgetattr(fd, &tio) < 0) { 162 msyslog(LOG_ERR, 163 "Palisade(%d) tcgetattr(fd, &tio): %m",unit); 164 #ifdef DEBUG 165 printf("Palisade(%d) tcgetattr(fd, &tio)\n",unit); 166 #endif 167 return (0); 168 } 169 170 tio.c_cflag |= (PARENB|PARODD); 171 tio.c_iflag &= ~ICRNL; 172 #endif /* NTP 4.x */ 173 174 if (tcsetattr(fd, TCSANOW, &tio) == -1) { 175 msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit); 176 #ifdef DEBUG 177 printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit); 178 #endif 179 return 0; 180 } 181 182 /* 183 * Allocate and initialize unit structure 184 */ 185 up = (struct palisade_unit *) emalloc(sizeof(struct palisade_unit)); 186 187 if (!(up)) { 188 msyslog(LOG_ERR, "Palisade(%d) emalloc: %m",unit); 189 #ifdef DEBUG 190 printf("Palisade(%d) emalloc\n",unit); 191 #endif 192 (void) close(fd); 193 return (0); 194 } 195 196 memset((char *)up, 0, sizeof(struct palisade_unit)); 197 198 pp = peer->procptr; 199 pp->io.clock_recv = palisade_io; 200 pp->io.srcclock = (caddr_t)peer; 201 pp->io.datalen = 0; 202 pp->io.fd = fd; 203 if (!io_addclock(&pp->io)) { 204 #ifdef DEBUG 205 printf("Palisade(%d) io_addclock\n",unit); 206 #endif 207 (void) close(fd); 208 free(up); 209 return (0); 210 } 211 212 /* 213 * Initialize miscellaneous variables 214 */ 215 pp->unitptr = (caddr_t)up; 216 pp->clockdesc = DESCRIPTION; 217 218 peer->precision = PRECISION; 219 peer->sstclktype = CTL_SST_TS_UHF; 220 peer->minpoll = TRMB_MINPOLL; 221 peer->maxpoll = TRMB_MAXPOLL; 222 memcpy((char *)&pp->refid, REFID, 4); 223 224 up->leap_status = 0; 225 up->unit = (short) unit; 226 up->rpt_status = TSIP_PARSED_EMPTY; 227 up->rpt_cnt = 0; 228 229 return 1; 230 } 231 232 233 /* 234 * palisade_shutdown - shut down the clock 235 */ 236 static void 237 palisade_shutdown ( 238 #ifdef PALISADE 239 unit, peer 240 ) 241 int unit; 242 struct peer *peer; 243 #else /* ANSI */ 244 int unit, 245 struct peer *peer 246 ) 247 #endif 248 { 249 struct palisade_unit *up; 250 struct refclockproc *pp; 251 pp = peer->procptr; 252 up = (struct palisade_unit *)pp->unitptr; 253 io_closeclock(&pp->io); 254 free(up); 255 } 256 257 258 259 /* 260 * unpack_date - get day and year from date 261 */ 262 int 263 day_of_year ( 264 #ifdef PALISADE 265 dt 266 ) 267 char * dt; 268 #else 269 char * dt 270 ) 271 #endif 272 { 273 int day, mon, year; 274 275 mon = dt[1]; 276 /* Check month is inside array bounds */ 277 if ((mon < 1) || (mon > 12)) 278 return -1; 279 280 day = dt[0] + days_of_year[mon - 1]; 281 year = getint((u_char *) (dt + 2)); 282 283 if ( !(year % 4) && ((year % 100) || 284 (!(year % 100) && !(year%400))) 285 &&(mon > 2)) 286 day ++; /* leap year and March or later */ 287 288 return day; 289 } 290 291 292 /* 293 * TSIP_decode - decode the TSIP data packets 294 */ 295 int 296 TSIP_decode ( 297 #ifdef PALISADE 298 peer 299 ) 300 struct peer *peer; 301 #else 302 struct peer *peer 303 ) 304 #endif 305 { 306 int st; 307 long secint; 308 double secs; 309 double secfrac; 310 unsigned short event = 0; 311 312 struct palisade_unit *up; 313 struct refclockproc *pp; 314 315 pp = peer->procptr; 316 up = (struct palisade_unit *)pp->unitptr; 317 318 /* 319 * Check the time packet, decode its contents. 320 * If the timecode has invalid length or is not in 321 * proper format, declare bad format and exit. 322 */ 323 324 if ((up->rpt_buf[0] == (char) 0x41) || 325 (up->rpt_buf[0] == (char) 0x46) || 326 (up->rpt_buf[0] == (char) 0x54) || 327 (up->rpt_buf[0] == (char) 0x4B) || 328 (up->rpt_buf[0] == (char) 0x6D)) { 329 330 /* standard time packet - GPS time and GPS week number */ 331 #ifdef DEBUG 332 printf("Palisade Port B packets detected. Connect to Port A\n"); 333 #endif 334 335 return 0; 336 } 337 338 if (up->rpt_buf[0] == (char) 0x8f) { 339 /* 340 * Superpackets 341 */ 342 event = (unsigned short) (getint((u_char *) &mb(1)) & 0xffff); 343 if (!((pp->sloppyclockflag & CLK_FLAG2) || event)) 344 /* Ignore Packet */ 345 return 0; 346 347 switch (mb(0) & 0xff) { 348 int GPS_UTC_Offset; 349 case PACKET_8F0B: 350 351 if (up->polled <= 0) 352 return 0; 353 354 if (up->rpt_cnt != LENCODE_8F0B) /* check length */ 355 break; 356 357 #ifdef DEBUG 358 if (debug > 1) { 359 int ts; 360 double lat, lon, alt; 361 lat = getdbl((u_char *) &mb(42)) * R2D; 362 lon = getdbl((u_char *) &mb(50)) * R2D; 363 alt = getdbl((u_char *) &mb(58)); 364 365 printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n", 366 up->unit, lat,lon,alt); 367 printf("TSIP_decode: unit %d: Sats:", up->unit); 368 for (st = 66, ts = 0; st <= 73; st++) if (mb(st)) { 369 if (mb(st) > 0) ts++; 370 printf(" %02d", mb(st)); 371 } 372 printf(" : Tracking %d\n", ts); 373 } 374 #endif 375 376 GPS_UTC_Offset = getint((u_char *) &mb(16)); 377 if (GPS_UTC_Offset == 0) { /* Check UTC offset */ 378 #ifdef DEBUG 379 printf("TSIP_decode: UTC Offset Unknown\n"); 380 #endif 381 break; 382 } 383 384 secs = getdbl((u_char *) &mb(3)); 385 secint = (long) secs; 386 secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */ 387 388 pp->usec = (long) (secfrac * 1000000); 389 390 secint %= 86400; /* Only care about today */ 391 pp->hour = secint / 3600; 392 secint %= 3600; 393 pp->minute = secint / 60; 394 secint %= 60; 395 pp->second = secint % 60; 396 397 if ((pp->day = day_of_year(&mb(11))) < 0) break; 398 399 pp->year = getint((u_char *) &mb(13)); 400 401 #ifdef DEBUG 402 if (debug > 1) 403 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02d\n", 404 up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, 405 pp->second, pp->usec, mb(12), mb(11), pp->year, GPS_UTC_Offset); 406 #endif 407 /* Only use this packet when no 408 * 8F-AD's are being received 409 */ 410 411 if (up->leap_status) { 412 up->leap_status = 0; 413 return 0; 414 } 415 416 return 2; 417 break; 418 419 case PACKET_NTP: 420 /* Palisade-NTP Packet */ 421 422 if (up->rpt_cnt != LENCODE_NTP) /* check length */ 423 break; 424 425 up->leap_status = mb(19); 426 427 if (up->polled <= 0) 428 return 0; 429 430 /* Check Tracking Status */ 431 st = mb(18); 432 if (st < 0 || st > 14) st = 14; 433 if ((st >= 2 && st <= 7) || st == 11 || st == 12) { 434 #ifdef DEBUG 435 printf("TSIP_decode: Not Tracking Sats : %s\n", 436 *Tracking_Status[st]); 437 #endif 438 refclock_report(peer, CEVNT_BADTIME); 439 up->polled = -1; 440 return 0; 441 break; 442 } 443 444 if (up->leap_status & PALISADE_LEAP_PENDING) { 445 if (up->leap_status & PALISADE_UTC_TIME) 446 pp->leap = LEAP_ADDSECOND; 447 else 448 pp->leap = LEAP_DELSECOND; 449 } 450 else if (up->leap_status) 451 pp->leap = LEAP_NOWARNING; 452 453 else { /* UTC flag is not set: 454 * Receiver may have been reset, and lost 455 * its UTC almanac data */ 456 pp->leap = LEAP_NOTINSYNC; 457 #ifdef DEBUG 458 printf("TSIP_decode: UTC Almanac unavailable: %d\n", 459 mb(19)); 460 #endif 461 refclock_report(peer, CEVNT_BADTIME); 462 up->polled = -1; 463 return 0; 464 } 465 466 pp->usec = (long) (getdbl((u_char *) &mb(3)) * 1000000); 467 468 if ((pp->day = day_of_year(&mb(14))) < 0) 469 break; 470 pp->year = getint((u_char *) &mb(16)); 471 pp->hour = mb(11); 472 pp->minute = mb(12); 473 pp->second = mb(13); 474 475 #ifdef DEBUG 476 if (debug > 1) 477 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02x %s\n", 478 up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, 479 pp->second, pp->usec, mb(15), mb(14), pp->year, 480 mb(19), *Tracking_Status[st]); 481 #endif 482 return 1; 483 break; 484 485 default: 486 /* Ignore Packet */ 487 return 0; 488 } /* switch */ 489 }/* if 8F packets */ 490 491 refclock_report(peer, CEVNT_BADREPLY); 492 up->polled = -1; 493 #ifdef DEBUG 494 printf("TSIP_decode: unit %d: bad packet %02x-%02x event %d len %d\n", 495 up->unit, up->rpt_buf[0] & 0xff, mb(0) & 0xff, 496 event, up->rpt_cnt); 497 #endif 498 return 0; 499 } 500 501 /* 502 * palisade__receive - receive data from the serial interface 503 */ 504 505 static void 506 palisade_receive ( 507 #ifdef PALISADE 508 peer 509 ) 510 struct peer * peer; 511 #else /* ANSI */ 512 struct peer * peer 513 ) 514 #endif 515 { 516 struct palisade_unit *up; 517 struct refclockproc *pp; 518 519 /* 520 * Initialize pointers and read the timecode and timestamp. 521 */ 522 pp = peer->procptr; 523 up = (struct palisade_unit *)pp->unitptr; 524 525 if (! TSIP_decode(peer)) return; 526 527 if (up->polled <= 0) 528 return; /* no poll pending, already received or timeout */ 529 530 up->polled = 0; /* Poll reply received */ 531 pp->lencode = 0; /* clear time code */ 532 #ifdef DEBUG 533 if (debug) 534 printf( 535 "palisade_receive: unit %d: %4d %03d %02d:%02d:%02d.%06ld\n", 536 up->unit, pp->year, pp->day, pp->hour, pp->minute, 537 pp->second, pp->usec); 538 #endif 539 540 /* 541 * Process the sample 542 * Generate timecode: YYYY DoY HH:MM:SS.microsec 543 * report and process 544 */ 545 546 (void) sprintf(pp->a_lastcode,"%4d %03d %02d:%02d:%02d.%06ld", 547 pp->year,pp->day,pp->hour,pp->minute, pp->second,pp->usec); 548 pp->lencode = 24; 549 550 #ifdef PALISADE 551 pp->lasttime = current_time; 552 #endif 553 if (!refclock_process(pp 554 #ifdef PALISADE 555 , PALISADE_SAMPLES, PALISADE_SAMPLES * 3 / 5 556 #endif 557 )) { 558 refclock_report(peer, CEVNT_BADTIME); 559 560 #ifdef DEBUG 561 printf("palisade_receive: unit %d: refclock_process failed!\n", 562 up->unit); 563 #endif 564 return; 565 } 566 567 record_clock_stats(&peer->srcadr, pp->a_lastcode); 568 569 #ifdef DEBUG 570 if (debug) 571 printf("palisade_receive: unit %d: %s\n", 572 up->unit, prettydate(&pp->lastrec)); 573 #endif 574 575 refclock_receive(peer 576 #ifdef PALISADE 577 , &pp->offset, 0, pp->dispersion, 578 &pp->lastrec, &pp->lastrec, pp->leap 579 #endif 580 ); 581 } 582 583 584 /* 585 * palisade_poll - called by the transmit procedure 586 * 587 */ 588 static void 589 palisade_poll ( 590 #ifdef PALISADE 591 unit, peer 592 ) 593 int unit; 594 struct peer *peer; 595 #else 596 int unit, 597 struct peer *peer 598 ) 599 #endif 600 { 601 struct palisade_unit *up; 602 struct refclockproc *pp; 603 604 pp = peer->procptr; 605 up = (struct palisade_unit *)pp->unitptr; 606 607 pp->polls++; 608 if (up->polled > 0) /* last reply never arrived or error */ 609 refclock_report(peer, CEVNT_TIMEOUT); 610 611 up->polled = 2; /* synchronous packet + 1 event */ 612 613 #ifdef DEBUG 614 if (debug) 615 printf("palisade_poll: unit %d: polling %s\n", unit, 616 (pp->sloppyclockflag & CLK_FLAG2) ? 617 "synchronous packet" : "event"); 618 #endif 619 620 if (pp->sloppyclockflag & CLK_FLAG2) 621 return; /* using synchronous packet input */ 622 623 if (HW_poll(pp) < 0) 624 refclock_report(peer, CEVNT_FAULT); 625 } 626 627 628 static void 629 palisade_io ( 630 #ifdef PALISADE 631 rbufp 632 ) 633 struct recvbuf *rbufp; 634 #else /* ANSI */ 635 struct recvbuf *rbufp 636 ) 637 #endif 638 { 639 /* 640 * Initialize pointers and read the timecode and timestamp. 641 */ 642 struct palisade_unit *up; 643 struct refclockproc *pp; 644 struct peer *peer; 645 646 char * c, * d; 647 648 peer = (struct peer *)rbufp->recv_srcclock; 649 pp = peer->procptr; 650 up = (struct palisade_unit *)pp->unitptr; 651 652 c = (char *) &rbufp->recv_space; 653 d = c + rbufp->recv_length; 654 655 while (c != d) { 656 657 /* Build time packet */ 658 switch (up->rpt_status) { 659 660 case TSIP_PARSED_DLE_1: 661 switch (*c) 662 { 663 case 0: 664 case DLE: 665 case ETX: 666 up->rpt_status = TSIP_PARSED_EMPTY; 667 break; 668 669 default: 670 up->rpt_status = TSIP_PARSED_DATA; 671 /* save packet ID */ 672 up->rpt_buf[0] = *c; 673 break; 674 } 675 break; 676 677 case TSIP_PARSED_DATA: 678 if (*c == DLE) 679 up->rpt_status = TSIP_PARSED_DLE_2; 680 else 681 mb(up->rpt_cnt++) = *c; 682 break; 683 684 case TSIP_PARSED_DLE_2: 685 if (*c == DLE) { 686 up->rpt_status = TSIP_PARSED_DATA; 687 mb(up->rpt_cnt++) = 688 *c; 689 } 690 else if (*c == ETX) 691 up->rpt_status = TSIP_PARSED_FULL; 692 else { 693 /* error: start new report packet */ 694 up->rpt_status = TSIP_PARSED_DLE_1; 695 up->rpt_buf[0] = *c; 696 } 697 break; 698 699 case TSIP_PARSED_FULL: 700 case TSIP_PARSED_EMPTY: 701 default: 702 if ( *c != DLE) 703 up->rpt_status = TSIP_PARSED_EMPTY; 704 else 705 up->rpt_status = TSIP_PARSED_DLE_1; 706 break; 707 } 708 709 c++; 710 711 if (up->rpt_status == TSIP_PARSED_DLE_1) { 712 up->rpt_cnt = 0; 713 if (pp->sloppyclockflag & CLK_FLAG2) 714 /* stamp it */ 715 get_systime(&pp->lastrec); 716 } 717 else if (up->rpt_status == TSIP_PARSED_EMPTY) 718 up->rpt_cnt = 0; 719 720 else if (up->rpt_cnt > BMAX) 721 up->rpt_status =TSIP_PARSED_EMPTY; 722 723 if (up->rpt_status == TSIP_PARSED_FULL) 724 palisade_receive(peer); 725 726 } /* while chars in buffer */ 727 } 728 729 730 /* 731 * Trigger the Palisade's event input, which is driven off the RTS 732 * 733 * Take a system time stamp to match the GPS time stamp. 734 * 735 */ 736 long 737 HW_poll ( 738 #ifdef PALISADE 739 pp /* pointer to unit structure */ 740 ) 741 struct refclockproc * pp; /* pointer to unit structure */ 742 #else 743 struct refclockproc * pp /* pointer to unit structure */ 744 ) 745 #endif 746 { 747 int x; /* state before & after RTS set */ 748 struct palisade_unit *up; 749 750 up = (struct palisade_unit *) pp->unitptr; 751 752 /* read the current status, so we put things back right */ 753 if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) { 754 #ifdef DEBUG 755 if (debug) 756 printf("Palisade HW_poll: unit %d: GET %s\n", up->unit, strerror(errno)); 757 #endif 758 msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m", 759 up->unit); 760 return -1; 761 } 762 763 x |= TIOCM_RTS; /* turn on RTS */ 764 765 /* Edge trigger */ 766 if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) { 767 #ifdef DEBUG 768 if (debug) 769 printf("Palisade HW_poll: unit %d: SET \n", up->unit); 770 #endif 771 msyslog(LOG_ERR, 772 "Palisade(%d) HW_poll: ioctl(fd, SET, RTS_on): %m", 773 up->unit); 774 return -1; 775 } 776 777 x &= ~TIOCM_RTS; /* turn off RTS */ 778 779 /* poll timestamp */ 780 get_systime(&pp->lastrec); 781 782 if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) { 783 #ifdef DEBUG 784 if (debug) 785 printf("Palisade HW_poll: unit %d: UNSET \n", up->unit); 786 #endif 787 msyslog(LOG_ERR, 788 "Palisade(%d) HW_poll: ioctl(fd, UNSET, RTS_off): %m", 789 up->unit); 790 return -1; 791 } 792 793 return 0; 794 } 795 796 #if 0 /* unused */ 797 /* 798 * this 'casts' a character array into a float 799 */ 800 float 801 getfloat ( 802 #ifdef PALISADE 803 bp 804 ) 805 u_char *bp; 806 #else 807 u_char *bp 808 ) 809 #endif 810 { 811 float sval; 812 #ifdef WORDS_BIGENDIAN 813 ((char *) &sval)[0] = *bp++; 814 ((char *) &sval)[1] = *bp++; 815 ((char *) &sval)[2] = *bp++; 816 ((char *) &sval)[3] = *bp++; 817 #else 818 ((char *) &sval)[3] = *bp++; 819 ((char *) &sval)[2] = *bp++; 820 ((char *) &sval)[1] = *bp++; 821 ((char *) &sval)[0] = *bp; 822 #endif /* ! XNTP_BIG_ENDIAN */ 823 return sval; 824 } 825 #endif 826 827 /* 828 * this 'casts' a character array into a double 829 */ 830 double 831 getdbl ( 832 #ifdef PALISADE 833 bp 834 ) 835 u_char *bp; 836 #else 837 u_char *bp 838 ) 839 #endif 840 { 841 double dval; 842 #ifdef WORDS_BIGENDIAN 843 ((char *) &dval)[0] = *bp++; 844 ((char *) &dval)[1] = *bp++; 845 ((char *) &dval)[2] = *bp++; 846 ((char *) &dval)[3] = *bp++; 847 ((char *) &dval)[4] = *bp++; 848 ((char *) &dval)[5] = *bp++; 849 ((char *) &dval)[6] = *bp++; 850 ((char *) &dval)[7] = *bp; 851 #else 852 ((char *) &dval)[7] = *bp++; 853 ((char *) &dval)[6] = *bp++; 854 ((char *) &dval)[5] = *bp++; 855 ((char *) &dval)[4] = *bp++; 856 ((char *) &dval)[3] = *bp++; 857 ((char *) &dval)[2] = *bp++; 858 ((char *) &dval)[1] = *bp++; 859 ((char *) &dval)[0] = *bp; 860 #endif /* ! XNTP_BIG_ENDIAN */ 861 return dval; 862 } 863 864 /* 865 * cast a 16 bit character array into a short (16 bit) int 866 */ 867 short 868 getint ( 869 #ifdef PALISADE 870 bp 871 ) 872 u_char *bp; 873 #else 874 u_char *bp 875 ) 876 #endif 877 { 878 return (short) (bp[1] + (bp[0] << 8)); 879 } 880 881 #endif /* REFCLOCK */ 882