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