refclock_palisade.c revision 200576
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 62extern 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 */ 69const int days_of_year [12] = { 70 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 71}; 72 73#ifdef DEBUG 74const 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 */ 85struct 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 95int 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 104int praecis_msg; 105static void praecis_parse(struct recvbuf *rbufp, struct peer *peer); 106 107/* 108 * palisade_start - open the devices and initialize data for processing 109 */ 110static int 111palisade_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 */ 265static void 266palisade_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 */ 291int 292day_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 */ 324int 325TSIP_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 390if (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) 509printf("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 537static void 538palisade_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 */ 620static void 621palisade_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 668static void 669praecis_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 693static void 694palisade_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 */ 808long 809HW_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 */ 872float 873getfloat ( 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 */ 902double 903getdbl ( 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 */ 939short 940getint ( 941#ifdef PALISADE 942 bp 943 ) 944 u_char *bp; 945#else 946 u_char *bp 947 ) 948#endif 949{ 950return (short) (bp[1] + (bp[0] << 8)); 951} 952 953#else 954int refclock_palisade_bs; 955#endif /* REFCLOCK */ 956