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