1c0b746e5SOllivier Robert /* 22b15cb3dSCy Schubert * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_trimtsip.c,v 4.19 2009/11/01 10:47:49 kardel RELEASE_20091101_A 3c0b746e5SOllivier Robert * 42b15cb3dSCy Schubert * clk_trimtsip.c,v 4.19 2009/11/01 10:47:49 kardel RELEASE_20091101_A 5c0b746e5SOllivier Robert * 6ea906c41SOllivier Robert * Trimble TSIP support 7ea906c41SOllivier Robert * Thanks to Sven Dietrich for providing test hardware 8ea906c41SOllivier Robert * 92b15cb3dSCy Schubert * Copyright (c) 1995-2009 by Frank Kardel <kardel <AT> ntp.org> 10a25439b6SCy Schubert * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany 11ea906c41SOllivier Robert * 12ea906c41SOllivier Robert * Redistribution and use in source and binary forms, with or without 13ea906c41SOllivier Robert * modification, are permitted provided that the following conditions 14ea906c41SOllivier Robert * are met: 15ea906c41SOllivier Robert * 1. Redistributions of source code must retain the above copyright 16ea906c41SOllivier Robert * notice, this list of conditions and the following disclaimer. 17ea906c41SOllivier Robert * 2. Redistributions in binary form must reproduce the above copyright 18ea906c41SOllivier Robert * notice, this list of conditions and the following disclaimer in the 19ea906c41SOllivier Robert * documentation and/or other materials provided with the distribution. 20ea906c41SOllivier Robert * 3. Neither the name of the author nor the names of its contributors 21ea906c41SOllivier Robert * may be used to endorse or promote products derived from this software 22ea906c41SOllivier Robert * without specific prior written permission. 23ea906c41SOllivier Robert * 24ea906c41SOllivier Robert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25ea906c41SOllivier Robert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26ea906c41SOllivier Robert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27ea906c41SOllivier Robert * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28ea906c41SOllivier Robert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29ea906c41SOllivier Robert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30ea906c41SOllivier Robert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31ea906c41SOllivier Robert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32ea906c41SOllivier Robert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33ea906c41SOllivier Robert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34ea906c41SOllivier Robert * SUCH DAMAGE. 35ea906c41SOllivier Robert * 36c0b746e5SOllivier Robert */ 37c0b746e5SOllivier Robert 38c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 39c0b746e5SOllivier Robert # include <config.h> 40c0b746e5SOllivier Robert #endif 41c0b746e5SOllivier Robert 42c0b746e5SOllivier Robert #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_TRIMTSIP) 43c0b746e5SOllivier Robert 44c0b746e5SOllivier Robert #include "ntp_syslog.h" 45c0b746e5SOllivier Robert #include "ntp_types.h" 46c0b746e5SOllivier Robert #include "ntp_fp.h" 472b15cb3dSCy Schubert #include "timevalops.h" 48c0b746e5SOllivier Robert #include "ntp_calendar.h" 49c0b746e5SOllivier Robert #include "ntp_machine.h" 50c0b746e5SOllivier Robert #include "ntp_stdlib.h" 51c0b746e5SOllivier Robert 52c0b746e5SOllivier Robert #include "parse.h" 53c0b746e5SOllivier Robert 54c0b746e5SOllivier Robert #ifndef PARSESTREAM 55c0b746e5SOllivier Robert # include <stdio.h> 56c0b746e5SOllivier Robert #else 57c0b746e5SOllivier Robert # include "sys/parsestreams.h" 58c0b746e5SOllivier Robert #endif 59c0b746e5SOllivier Robert 60c0b746e5SOllivier Robert #include "ascii.h" 61c0b746e5SOllivier Robert #include "binio.h" 62c0b746e5SOllivier Robert #include "ieee754io.h" 63c0b746e5SOllivier Robert #include "trimble.h" 64c0b746e5SOllivier Robert 65c0b746e5SOllivier Robert /* 66c0b746e5SOllivier Robert * Trimble low level TSIP parser / time converter 67c0b746e5SOllivier Robert * 68c0b746e5SOllivier Robert * The receiver uses a serial message protocol called Trimble Standard 69c0b746e5SOllivier Robert * Interface Protocol (it can support others but this driver only supports 70c0b746e5SOllivier Robert * TSIP). Messages in this protocol have the following form: 71c0b746e5SOllivier Robert * 72c0b746e5SOllivier Robert * <DLE><id> ... <data> ... <DLE><ETX> 73c0b746e5SOllivier Robert * 74c0b746e5SOllivier Robert * Any bytes within the <data> portion of value 10 hex (<DLE>) are doubled 75c0b746e5SOllivier Robert * on transmission and compressed back to one on reception. Otherwise 76c0b746e5SOllivier Robert * the values of data bytes can be anything. The serial interface is RS-422 77c0b746e5SOllivier Robert * asynchronous using 9600 baud, 8 data bits with odd party (**note** 9 bits 78c0b746e5SOllivier Robert * in total!), and 1 stop bit. The protocol supports byte, integer, single, 79c0b746e5SOllivier Robert * and double datatypes. Integers are two bytes, sent most significant first. 80c0b746e5SOllivier Robert * Singles are IEEE754 single precision floating point numbers (4 byte) sent 81c0b746e5SOllivier Robert * sign & exponent first. Doubles are IEEE754 double precision floating point 82c0b746e5SOllivier Robert * numbers (8 byte) sent sign & exponent first. 83c0b746e5SOllivier Robert * The receiver supports a large set of messages, only a very small subset of 84c0b746e5SOllivier Robert * which is used here. 85c0b746e5SOllivier Robert * 86c0b746e5SOllivier Robert * From this module the following are recognised: 87c0b746e5SOllivier Robert * 88c0b746e5SOllivier Robert * ID Description 89c0b746e5SOllivier Robert * 90c0b746e5SOllivier Robert * 41 GPS Time 91c0b746e5SOllivier Robert * 46 Receiver health 92c0b746e5SOllivier Robert * 4F UTC correction data (used to get leap second warnings) 93c0b746e5SOllivier Robert * 94c0b746e5SOllivier Robert * All others are accepted but ignored for time conversion - they are passed up to higher layers. 95c0b746e5SOllivier Robert * 96c0b746e5SOllivier Robert */ 97c0b746e5SOllivier Robert 98c0b746e5SOllivier Robert static offsets_t trim_offsets = { 0, 1, 2, 3, 4, 5, 6, 7 }; 99c0b746e5SOllivier Robert 100c0b746e5SOllivier Robert struct trimble 101c0b746e5SOllivier Robert { 102c0b746e5SOllivier Robert u_char t_in_pkt; /* first DLE received */ 103c0b746e5SOllivier Robert u_char t_dle; /* subsequent DLE received */ 104c0b746e5SOllivier Robert u_short t_week; /* GPS week */ 105c0b746e5SOllivier Robert u_short t_weekleap; /* GPS week of next/last week */ 106c0b746e5SOllivier Robert u_short t_dayleap; /* day in week */ 107c0b746e5SOllivier Robert u_short t_gpsutc; /* GPS - UTC offset */ 108c0b746e5SOllivier Robert u_short t_gpsutcleap; /* offset at next/last leap */ 109c0b746e5SOllivier Robert u_char t_operable; /* receiver feels OK */ 110c0b746e5SOllivier Robert u_char t_mode; /* actual operating mode */ 111c0b746e5SOllivier Robert u_char t_leap; /* possible leap warning */ 112c0b746e5SOllivier Robert u_char t_utcknown; /* utc offset known */ 113c0b746e5SOllivier Robert }; 114c0b746e5SOllivier Robert 115c0b746e5SOllivier Robert #define STATUS_BAD 0 /* BAD or UNINITIALIZED receiver status */ 116c0b746e5SOllivier Robert #define STATUS_UNSAFE 1 /* not enough receivers for full precision */ 117c0b746e5SOllivier Robert #define STATUS_SYNC 2 /* enough information for good operation */ 118c0b746e5SOllivier Robert 119a25439b6SCy Schubert static unsigned long inp_tsip (parse_t *, char, timestamp_t *); 1202b15cb3dSCy Schubert static unsigned long cvt_trimtsip (unsigned char *, int, struct format *, clocktime_t *, void *); 121c0b746e5SOllivier Robert 122c0b746e5SOllivier Robert struct clockformat clock_trimtsip = 123c0b746e5SOllivier Robert { 124c0b746e5SOllivier Robert inp_tsip, /* Trimble TSIP input handler */ 125c0b746e5SOllivier Robert cvt_trimtsip, /* Trimble TSIP conversion */ 126c0b746e5SOllivier Robert pps_one, /* easy PPS monitoring */ 127c0b746e5SOllivier Robert 0, /* no configuration data */ 128c0b746e5SOllivier Robert "Trimble TSIP", 129c0b746e5SOllivier Robert 400, /* input buffer */ 130c0b746e5SOllivier Robert sizeof(struct trimble) /* private data */ 131c0b746e5SOllivier Robert }; 132c0b746e5SOllivier Robert 133c0b746e5SOllivier Robert #define ADDSECOND 0x01 134c0b746e5SOllivier Robert #define DELSECOND 0x02 135c0b746e5SOllivier Robert 136c0b746e5SOllivier Robert static unsigned long 137c0b746e5SOllivier Robert inp_tsip( 138c0b746e5SOllivier Robert parse_t *parseio, 139a25439b6SCy Schubert char ch, 140c0b746e5SOllivier Robert timestamp_t *tstamp 141c0b746e5SOllivier Robert ) 142c0b746e5SOllivier Robert { 143c0b746e5SOllivier Robert struct trimble *t = (struct trimble *)parseio->parse_pdata; 144c0b746e5SOllivier Robert 145c0b746e5SOllivier Robert if (!t) 146c0b746e5SOllivier Robert return PARSE_INP_SKIP; /* local data not allocated - sigh! */ 147c0b746e5SOllivier Robert 148c0b746e5SOllivier Robert if (!t->t_in_pkt && ch != DLE) { 149c0b746e5SOllivier Robert /* wait for start of packet */ 150c0b746e5SOllivier Robert return PARSE_INP_SKIP; 151c0b746e5SOllivier Robert } 152c0b746e5SOllivier Robert 153c0b746e5SOllivier Robert if ((parseio->parse_index >= (parseio->parse_dsize - 2)) || 154c0b746e5SOllivier Robert (parseio->parse_dtime.parse_msglen >= (sizeof(parseio->parse_dtime.parse_msg) - 2))) 155c0b746e5SOllivier Robert { /* OVERFLOW - DROP! */ 156c0b746e5SOllivier Robert t->t_in_pkt = t->t_dle = 0; 157c0b746e5SOllivier Robert parseio->parse_index = 0; 158c0b746e5SOllivier Robert parseio->parse_dtime.parse_msglen = 0; 159c0b746e5SOllivier Robert return PARSE_INP_SKIP; 160c0b746e5SOllivier Robert } 161c0b746e5SOllivier Robert 162c0b746e5SOllivier Robert switch (ch) { 163c0b746e5SOllivier Robert case DLE: 164c0b746e5SOllivier Robert if (!t->t_in_pkt) { 165c0b746e5SOllivier Robert t->t_dle = 0; 166c0b746e5SOllivier Robert t->t_in_pkt = 1; 167c0b746e5SOllivier Robert parseio->parse_index = 0; 168c0b746e5SOllivier Robert parseio->parse_data[parseio->parse_index++] = ch; 169c0b746e5SOllivier Robert parseio->parse_dtime.parse_msglen = 0; 170c0b746e5SOllivier Robert parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch; 171c0b746e5SOllivier Robert parseio->parse_dtime.parse_stime = *tstamp; /* pick up time stamp at packet start */ 172c0b746e5SOllivier Robert } else if (t->t_dle) { 173c0b746e5SOllivier Robert /* Double DLE -> insert a DLE */ 174c0b746e5SOllivier Robert t->t_dle = 0; 175c0b746e5SOllivier Robert parseio->parse_data[parseio->parse_index++] = DLE; 176c0b746e5SOllivier Robert parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = DLE; 177c0b746e5SOllivier Robert } else 178c0b746e5SOllivier Robert t->t_dle = 1; 179c0b746e5SOllivier Robert break; 180c0b746e5SOllivier Robert 181c0b746e5SOllivier Robert case ETX: 182c0b746e5SOllivier Robert if (t->t_dle) { 183c0b746e5SOllivier Robert /* DLE,ETX -> end of packet */ 184c0b746e5SOllivier Robert parseio->parse_data[parseio->parse_index++] = DLE; 185c0b746e5SOllivier Robert parseio->parse_data[parseio->parse_index] = ch; 186a25439b6SCy Schubert parseio->parse_ldsize = (u_short) (parseio->parse_index + 1); 187c0b746e5SOllivier Robert memcpy(parseio->parse_ldata, parseio->parse_data, parseio->parse_ldsize); 188c0b746e5SOllivier Robert parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = DLE; 189c0b746e5SOllivier Robert parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch; 190c0b746e5SOllivier Robert t->t_in_pkt = t->t_dle = 0; 191c0b746e5SOllivier Robert return PARSE_INP_TIME|PARSE_INP_DATA; 192c0b746e5SOllivier Robert } 1932b15cb3dSCy Schubert /*FALLTHROUGH*/ 194c0b746e5SOllivier Robert 195c0b746e5SOllivier Robert default: /* collect data */ 196c0b746e5SOllivier Robert t->t_dle = 0; 197c0b746e5SOllivier Robert parseio->parse_data[parseio->parse_index++] = ch; 198c0b746e5SOllivier Robert parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch; 199c0b746e5SOllivier Robert } 200c0b746e5SOllivier Robert 201c0b746e5SOllivier Robert return PARSE_INP_SKIP; 202c0b746e5SOllivier Robert } 203c0b746e5SOllivier Robert 204a25439b6SCy Schubert static short 205c0b746e5SOllivier Robert getshort( 206c0b746e5SOllivier Robert unsigned char *p 207c0b746e5SOllivier Robert ) 208c0b746e5SOllivier Robert { 209a25439b6SCy Schubert return (short) get_msb_short(&p); 210c0b746e5SOllivier Robert } 211c0b746e5SOllivier Robert 212c0b746e5SOllivier Robert /* 213c0b746e5SOllivier Robert * cvt_trimtsip 214c0b746e5SOllivier Robert * 215c0b746e5SOllivier Robert * convert TSIP type format 216c0b746e5SOllivier Robert */ 217c0b746e5SOllivier Robert static unsigned long 218c0b746e5SOllivier Robert cvt_trimtsip( 219c0b746e5SOllivier Robert unsigned char *buffer, 220c0b746e5SOllivier Robert int size, 221c0b746e5SOllivier Robert struct format *format, 222c0b746e5SOllivier Robert clocktime_t *clock_time, 223c0b746e5SOllivier Robert void *local 224c0b746e5SOllivier Robert ) 225c0b746e5SOllivier Robert { 226c0b746e5SOllivier Robert register struct trimble *t = (struct trimble *)local; /* get local data space */ 227c0b746e5SOllivier Robert #define mb(_X_) (buffer[2+(_X_)]) /* shortcut for buffer access */ 228c0b746e5SOllivier Robert register u_char cmd; 229c0b746e5SOllivier Robert 230c0b746e5SOllivier Robert clock_time->flags = 0; 231c0b746e5SOllivier Robert 232c0b746e5SOllivier Robert if (!t) { 233c0b746e5SOllivier Robert return CVT_NONE; /* local data not allocated - sigh! */ 234c0b746e5SOllivier Robert } 235c0b746e5SOllivier Robert 236c0b746e5SOllivier Robert if ((size < 4) || 237c0b746e5SOllivier Robert (buffer[0] != DLE) || 238c0b746e5SOllivier Robert (buffer[size-1] != ETX) || 239c0b746e5SOllivier Robert (buffer[size-2] != DLE)) 240c0b746e5SOllivier Robert { 241c0b746e5SOllivier Robert printf("TRIMBLE BAD packet, size %d:\n", size); 242c0b746e5SOllivier Robert return CVT_NONE; 243c0b746e5SOllivier Robert } 244c0b746e5SOllivier Robert else 245c0b746e5SOllivier Robert { 246c0b746e5SOllivier Robert unsigned char *bp; 247c0b746e5SOllivier Robert cmd = buffer[1]; 248c0b746e5SOllivier Robert 249c0b746e5SOllivier Robert switch(cmd) 250c0b746e5SOllivier Robert { 251c0b746e5SOllivier Robert case CMD_RCURTIME: 252c0b746e5SOllivier Robert { /* GPS time */ 253c0b746e5SOllivier Robert l_fp secs; 254f0574f5cSXin LI u_int week = getshort((unsigned char *)&mb(4)); 255c0b746e5SOllivier Robert l_fp utcoffset; 256c0b746e5SOllivier Robert l_fp gpstime; 257c0b746e5SOllivier Robert 258c0b746e5SOllivier Robert bp = &mb(0); 259c0b746e5SOllivier Robert if (fetch_ieee754(&bp, IEEE_SINGLE, &secs, trim_offsets) != IEEE_OK) 260c0b746e5SOllivier Robert return CVT_FAIL|CVT_BADFMT; 261c0b746e5SOllivier Robert 262c0b746e5SOllivier Robert if ((secs.l_i <= 0) || 263c0b746e5SOllivier Robert (t->t_utcknown == 0)) 264c0b746e5SOllivier Robert { 265c0b746e5SOllivier Robert clock_time->flags = PARSEB_POWERUP; 266c0b746e5SOllivier Robert return CVT_OK; 267c0b746e5SOllivier Robert } 268052d159aSCy Schubert week = basedate_expand_gpsweek(week); 269c0b746e5SOllivier Robert 270c0b746e5SOllivier Robert /* time OK */ 271c0b746e5SOllivier Robert 272c0b746e5SOllivier Robert /* fetch UTC offset */ 273c0b746e5SOllivier Robert bp = &mb(6); 274c0b746e5SOllivier Robert if (fetch_ieee754(&bp, IEEE_SINGLE, &utcoffset, trim_offsets) != IEEE_OK) 275c0b746e5SOllivier Robert return CVT_FAIL|CVT_BADFMT; 276c0b746e5SOllivier Robert 277c0b746e5SOllivier Robert L_SUB(&secs, &utcoffset); /* adjust GPS time to UTC time */ 278c0b746e5SOllivier Robert 279c0b746e5SOllivier Robert gpstolfp((unsigned short)week, (unsigned short)0, 280c0b746e5SOllivier Robert secs.l_ui, &gpstime); 281c0b746e5SOllivier Robert 282c0b746e5SOllivier Robert gpstime.l_uf = secs.l_uf; 283c0b746e5SOllivier Robert 284c0b746e5SOllivier Robert clock_time->utctime = gpstime.l_ui - JAN_1970; 285c0b746e5SOllivier Robert 286c0b746e5SOllivier Robert TSFTOTVU(gpstime.l_uf, clock_time->usecond); 287c0b746e5SOllivier Robert 288c0b746e5SOllivier Robert if (t->t_leap == ADDSECOND) 289c0b746e5SOllivier Robert clock_time->flags |= PARSEB_LEAPADD; 290c0b746e5SOllivier Robert 291c0b746e5SOllivier Robert if (t->t_leap == DELSECOND) 292c0b746e5SOllivier Robert clock_time->flags |= PARSEB_LEAPDEL; 293c0b746e5SOllivier Robert 294c0b746e5SOllivier Robert switch (t->t_operable) 295c0b746e5SOllivier Robert { 296c0b746e5SOllivier Robert case STATUS_SYNC: 297c0b746e5SOllivier Robert clock_time->flags &= ~(PARSEB_POWERUP|PARSEB_NOSYNC); 298c0b746e5SOllivier Robert break; 299c0b746e5SOllivier Robert 300c0b746e5SOllivier Robert case STATUS_UNSAFE: 301c0b746e5SOllivier Robert clock_time->flags |= PARSEB_NOSYNC; 302c0b746e5SOllivier Robert break; 303c0b746e5SOllivier Robert 304c0b746e5SOllivier Robert case STATUS_BAD: 305c0b746e5SOllivier Robert clock_time->flags |= PARSEB_NOSYNC|PARSEB_POWERUP; 306c0b746e5SOllivier Robert break; 307c0b746e5SOllivier Robert } 308c0b746e5SOllivier Robert 309c0b746e5SOllivier Robert if (t->t_mode == 0) 310c0b746e5SOllivier Robert clock_time->flags |= PARSEB_POSITION; 311c0b746e5SOllivier Robert 312c0b746e5SOllivier Robert clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_POSITION; 313c0b746e5SOllivier Robert 314c0b746e5SOllivier Robert return CVT_OK; 315c0b746e5SOllivier Robert 316c0b746e5SOllivier Robert } /* case 0x41 */ 317c0b746e5SOllivier Robert 318c0b746e5SOllivier Robert case CMD_RRECVHEALTH: 319c0b746e5SOllivier Robert { 320c0b746e5SOllivier Robert /* TRIMBLE health */ 321c0b746e5SOllivier Robert u_char status = mb(0); 322c0b746e5SOllivier Robert 323c0b746e5SOllivier Robert switch (status) 324c0b746e5SOllivier Robert { 325c0b746e5SOllivier Robert case 0x00: /* position fixes */ 326c0b746e5SOllivier Robert t->t_operable = STATUS_SYNC; 327c0b746e5SOllivier Robert break; 328c0b746e5SOllivier Robert 329c0b746e5SOllivier Robert case 0x09: /* 1 satellite */ 330c0b746e5SOllivier Robert case 0x0A: /* 2 satellites */ 331c0b746e5SOllivier Robert case 0x0B: /* 3 satellites */ 332c0b746e5SOllivier Robert t->t_operable = STATUS_UNSAFE; 333c0b746e5SOllivier Robert break; 334c0b746e5SOllivier Robert 335c0b746e5SOllivier Robert default: 336c0b746e5SOllivier Robert t->t_operable = STATUS_BAD; 337c0b746e5SOllivier Robert break; 338c0b746e5SOllivier Robert } 339c0b746e5SOllivier Robert t->t_mode = status; 340c0b746e5SOllivier Robert } 341c0b746e5SOllivier Robert break; 342c0b746e5SOllivier Robert 343c0b746e5SOllivier Robert case CMD_RUTCPARAM: 344c0b746e5SOllivier Robert { 345c0b746e5SOllivier Robert l_fp t0t; 346c0b746e5SOllivier Robert unsigned char *lbp; 347c0b746e5SOllivier Robert 348c0b746e5SOllivier Robert /* UTC correction data - derive a leap warning */ 349a25439b6SCy Schubert int tls = t->t_gpsutc = (u_short) getshort((unsigned char *)&mb(12)); /* current leap correction (GPS-UTC) */ 350a25439b6SCy Schubert int tlsf = t->t_gpsutcleap = (u_short) getshort((unsigned char *)&mb(24)); /* new leap correction */ 351c0b746e5SOllivier Robert 352052d159aSCy Schubert t->t_weekleap = basedate_expand_gpsweek( 353052d159aSCy Schubert (u_short) getshort((unsigned char *)&mb(20))); /* week no of leap correction */ 354c0b746e5SOllivier Robert 355a25439b6SCy Schubert t->t_dayleap = (u_short) getshort((unsigned char *)&mb(22)); /* day in week of leap correction */ 356052d159aSCy Schubert t->t_week = basedate_expand_gpsweek( 357052d159aSCy Schubert (u_short) getshort((unsigned char *)&mb(18))); /* current week no */ 358c0b746e5SOllivier Robert 359c0b746e5SOllivier Robert lbp = (unsigned char *)&mb(14); /* last update time */ 360c0b746e5SOllivier Robert if (fetch_ieee754(&lbp, IEEE_SINGLE, &t0t, trim_offsets) != IEEE_OK) 361c0b746e5SOllivier Robert return CVT_FAIL|CVT_BADFMT; 362c0b746e5SOllivier Robert 363c0b746e5SOllivier Robert t->t_utcknown = t0t.l_ui != 0; 364c0b746e5SOllivier Robert 365c0b746e5SOllivier Robert if ((t->t_utcknown) && /* got UTC information */ 366c0b746e5SOllivier Robert (tlsf != tls) && /* something will change */ 367c0b746e5SOllivier Robert ((t->t_weekleap - t->t_week) < 5)) /* and close in the future */ 368c0b746e5SOllivier Robert { 369c0b746e5SOllivier Robert /* generate a leap warning */ 370c0b746e5SOllivier Robert if (tlsf > tls) 371c0b746e5SOllivier Robert t->t_leap = ADDSECOND; 372c0b746e5SOllivier Robert else 373c0b746e5SOllivier Robert t->t_leap = DELSECOND; 374c0b746e5SOllivier Robert } 375c0b746e5SOllivier Robert else 376c0b746e5SOllivier Robert { 377c0b746e5SOllivier Robert t->t_leap = 0; 378c0b746e5SOllivier Robert } 379c0b746e5SOllivier Robert } 380c0b746e5SOllivier Robert break; 381c0b746e5SOllivier Robert 382c0b746e5SOllivier Robert default: 383c0b746e5SOllivier Robert /* it's validly formed, but we don't care about it! */ 384c0b746e5SOllivier Robert break; 385c0b746e5SOllivier Robert } 386c0b746e5SOllivier Robert } 387c0b746e5SOllivier Robert return CVT_SKIP; 388c0b746e5SOllivier Robert } 389c0b746e5SOllivier Robert 390c0b746e5SOllivier Robert #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTSIP && !PARSESTREAM) */ 391*f5f40dd6SCy Schubert NONEMPTY_TRANSLATION_UNIT 392c0b746e5SOllivier Robert #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTSIP && !PARSESTREAM) */ 393c0b746e5SOllivier Robert 394c0b746e5SOllivier Robert /* 395c0b746e5SOllivier Robert * History: 396c0b746e5SOllivier Robert * 397c0b746e5SOllivier Robert * clk_trimtsip.c,v 3982b15cb3dSCy Schubert * Revision 4.19 2009/11/01 10:47:49 kardel 3992b15cb3dSCy Schubert * de-P() 4002b15cb3dSCy Schubert * 4012b15cb3dSCy Schubert * Revision 4.18 2009/11/01 08:46:46 kardel 4022b15cb3dSCy Schubert * clarify case FALLTHROUGH 4032b15cb3dSCy Schubert * 404ea906c41SOllivier Robert * Revision 4.17 2005/04/16 17:32:10 kardel 405ea906c41SOllivier Robert * update copyright 406ea906c41SOllivier Robert * 407ea906c41SOllivier Robert * Revision 4.16 2004/11/14 15:29:41 kardel 408ea906c41SOllivier Robert * support PPSAPI, upgrade Copyright to Berkeley style 409ea906c41SOllivier Robert * 410a151a66cSOllivier Robert * Revision 4.13 1999/11/28 09:13:51 kardel 411a151a66cSOllivier Robert * RECON_4_0_98F 412a151a66cSOllivier Robert * 413c0b746e5SOllivier Robert * Revision 4.12 1999/02/28 13:00:08 kardel 414c0b746e5SOllivier Robert * *** empty log message *** 415c0b746e5SOllivier Robert * 416c0b746e5SOllivier Robert * Revision 4.11 1999/02/28 11:47:54 kardel 417c0b746e5SOllivier Robert * (struct trimble): new member t_utcknown 418c0b746e5SOllivier Robert * (cvt_trimtsip): fixed status monitoring, bad receiver states are 419c0b746e5SOllivier Robert * now recognized 420c0b746e5SOllivier Robert * 421c0b746e5SOllivier Robert * Revision 4.10 1999/02/27 15:57:15 kardel 422c0b746e5SOllivier Robert * use mmemcpy instead of bcopy 423c0b746e5SOllivier Robert * 424c0b746e5SOllivier Robert * Revision 4.9 1999/02/21 12:17:42 kardel 425c0b746e5SOllivier Robert * 4.91f reconcilation 426c0b746e5SOllivier Robert * 427c0b746e5SOllivier Robert * Revision 4.8 1998/11/15 20:27:58 kardel 428c0b746e5SOllivier Robert * Release 4.0.73e13 reconcilation 429c0b746e5SOllivier Robert * 430c0b746e5SOllivier Robert * Revision 4.7 1998/08/16 18:49:20 kardel 431c0b746e5SOllivier Robert * (cvt_trimtsip): initial kernel capable version (no more floats) 432c0b746e5SOllivier Robert * (clock_trimtsip =): new format name 433c0b746e5SOllivier Robert * 434c0b746e5SOllivier Robert * Revision 4.6 1998/08/09 22:26:05 kardel 435c0b746e5SOllivier Robert * Trimble TSIP support 436c0b746e5SOllivier Robert * 437c0b746e5SOllivier Robert * Revision 4.5 1998/08/02 10:37:05 kardel 438c0b746e5SOllivier Robert * working TSIP parser 439c0b746e5SOllivier Robert * 440c0b746e5SOllivier Robert * Revision 4.4 1998/06/28 16:50:40 kardel 441c0b746e5SOllivier Robert * (getflt): fixed ENDIAN issue 442c0b746e5SOllivier Robert * (getdbl): fixed ENDIAN issue 443c0b746e5SOllivier Robert * (getint): use get_msb_short() 444c0b746e5SOllivier Robert * (cvt_trimtsip): use gpstolfp() for conversion 445c0b746e5SOllivier Robert * 446c0b746e5SOllivier Robert * Revision 4.3 1998/06/13 12:07:31 kardel 447c0b746e5SOllivier Robert * fix SYSV clock name clash 448c0b746e5SOllivier Robert * 449c0b746e5SOllivier Robert * Revision 4.2 1998/06/12 15:22:30 kardel 450c0b746e5SOllivier Robert * fix prototypes 451c0b746e5SOllivier Robert * 452c0b746e5SOllivier Robert * Revision 4.1 1998/05/24 09:39:54 kardel 453c0b746e5SOllivier Robert * implementation of the new IO handling model 454c0b746e5SOllivier Robert * 455c0b746e5SOllivier Robert * Revision 4.0 1998/04/10 19:45:32 kardel 456c0b746e5SOllivier Robert * Start 4.0 release version numbering 457c0b746e5SOllivier Robert * 458c0b746e5SOllivier Robert * from V3 1.8 loginfo deleted 1998/04/11 kardel 459c0b746e5SOllivier Robert */ 460