1106424Sroberto/* 2106424Sroberto * $Id: refclock_ripencc.c,v 1.13 2002/06/18 14:20:55 marks Exp marks $ 3106424Sroberto * 4106424Sroberto * Copyright (c) 2002 RIPE NCC 5106424Sroberto * 6106424Sroberto * All Rights Reserved 7106424Sroberto * 8106424Sroberto * Permission to use, copy, modify, and distribute this software and its 9106424Sroberto * documentation for any purpose and without fee is hereby granted, 10106424Sroberto * provided that the above copyright notice appear in all copies and that 11106424Sroberto * both that copyright notice and this permission notice appear in 12106424Sroberto * supporting documentation, and that the name of the author not be 13106424Sroberto * used in advertising or publicity pertaining to distribution of the 14106424Sroberto * software without specific, written prior permission. 15106424Sroberto * 16106424Sroberto * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 17106424Sroberto * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 18106424Sroberto * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 19106424Sroberto * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 20106424Sroberto * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21106424Sroberto * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22106424Sroberto * 23106424Sroberto * 24106424Sroberto * 25106424Sroberto * This driver was developed for use with the RIPE NCC TTM project. 26106424Sroberto * 27106424Sroberto * 28106424Sroberto * The initial driver was developed by Daniel Karrenberg <dfk@ripe.net> 29106424Sroberto * using the code made available by Trimble. This was for xntpd-3.x.x 30106424Sroberto * 31106424Sroberto * Rewrite of the driver for ntpd-4.x.x by Mark Santcroos <marks@ripe.net> 32106424Sroberto * 33106424Sroberto */ 34106424Sroberto 35106424Sroberto#ifdef HAVE_CONFIG_H 36106424Sroberto#include <config.h> 37106424Sroberto#endif /* HAVE_CONFIG_H */ 38106424Sroberto 39106424Sroberto#if defined(REFCLOCK) && defined(CLOCK_RIPENCC) 40106424Sroberto 41106424Sroberto#include "ntp_stdlib.h" 42106424Sroberto#include "ntpd.h" 43106424Sroberto#include "ntp_refclock.h" 44106424Sroberto#include "ntp_unixtime.h" 45106424Sroberto#include "ntp_io.h" 46106424Sroberto 47182007Sroberto#ifdef HAVE_PPSAPI 48182007Sroberto# include "ppsapi_timepps.h" 49182007Sroberto#endif 50106424Sroberto 51106424Sroberto/* 52106424Sroberto * Definitions 53106424Sroberto */ 54106424Sroberto 55106424Sroberto/* we are on little endian */ 56106424Sroberto#define BYTESWAP 57106424Sroberto 58106424Sroberto/* 59106424Sroberto * DEBUG statements: uncomment if necessary 60106424Sroberto */ 61106424Sroberto/* #define DEBUG_NCC */ /* general debug statements */ 62106424Sroberto/* #define DEBUG_PPS */ /* debug pps */ 63106424Sroberto/* #define DEBUG_RAW */ /* print raw packets */ 64106424Sroberto 65106424Sroberto#define TRIMBLE_OUTPUT_FUNC 66106424Sroberto#define TSIP_VERNUM "7.12a" 67106424Sroberto 68106424Sroberto#ifndef FALSE 69106424Sroberto#define FALSE (0) 70106424Sroberto#define TRUE (!FALSE) 71106424Sroberto#endif /* FALSE */ 72106424Sroberto 73106424Sroberto#define GPS_PI (3.1415926535898) 74106424Sroberto#define GPS_C (299792458.) 75106424Sroberto#define D2R (GPS_PI/180.0) 76106424Sroberto#define R2D (180.0/GPS_PI) 77106424Sroberto#define WEEK (604800.) 78106424Sroberto#define MAXCHAN (8) 79106424Sroberto 80106424Sroberto/* control characters for TSIP packets */ 81106424Sroberto#define DLE (0x10) 82106424Sroberto#define ETX (0x03) 83106424Sroberto 84106424Sroberto#define MAX_RPTBUF (256) 85106424Sroberto 86106424Sroberto/* values of TSIPPKT.status */ 87106424Sroberto#define TSIP_PARSED_EMPTY 0 88106424Sroberto#define TSIP_PARSED_FULL 1 89106424Sroberto#define TSIP_PARSED_DLE_1 2 90106424Sroberto#define TSIP_PARSED_DATA 3 91106424Sroberto#define TSIP_PARSED_DLE_2 4 92106424Sroberto 93285612Sdelphij#define UTCF_UTC_AVAIL (unsigned char) (1) /* UTC available */ 94106424Sroberto#define UTCF_LEAP_SCHD (unsigned char) (1<<4) /* Leap scheduled */ 95106424Sroberto#define UTCF_LEAP_PNDG (unsigned char) (1<<5) /* Leap pending, will occur at end of day */ 96106424Sroberto 97106424Sroberto#define DEVICE "/dev/gps%d" /* name of radio device */ 98106424Sroberto#define PRECISION (-9) /* precision assumed (about 2 ms) */ 99106424Sroberto#define PPS_PRECISION (-20) /* precision assumed (about 1 us) */ 100106424Sroberto#define REFID "GPS\0" /* reference id */ 101106424Sroberto#define REFID_LEN 4 102106424Sroberto#define DESCRIPTION "RIPE NCC GPS (Palisade)" /* Description */ 103106424Sroberto#define SPEED232 B9600 /* 9600 baud */ 104106424Sroberto 105106424Sroberto#define NSAMPLES 3 /* stages of median filter */ 106106424Sroberto 107106424Sroberto/* Structures */ 108106424Sroberto 109106424Sroberto/* TSIP packets have the following structure, whether report or command. */ 110106424Srobertotypedef struct { 111106424Sroberto short 112285612Sdelphij counter, /* counter */ 113285612Sdelphij len; /* size of buf; < MAX_RPTBUF unsigned chars */ 114106424Sroberto unsigned char 115285612Sdelphij status, /* TSIP packet format/parse status */ 116285612Sdelphij code, /* TSIP code */ 117285612Sdelphij buf[MAX_RPTBUF]; /* report or command string */ 118106424Sroberto} TSIPPKT; 119106424Sroberto 120106424Sroberto/* TSIP binary data structures */ 121106424Srobertotypedef struct { 122106424Sroberto unsigned char 123285612Sdelphij t_oa_raw, SV_health; 124106424Sroberto float 125285612Sdelphij e, t_oa, i_0, OMEGADOT, sqrt_A, 126285612Sdelphij OMEGA_0, omega, M_0, a_f0, a_f1, 127285612Sdelphij Axis, n, OMEGA_n, ODOT_n, t_zc; 128106424Sroberto short 129285612Sdelphij weeknum, wn_oa; 130106424Sroberto} ALM_INFO; 131106424Sroberto 132285612Sdelphijtypedef struct { /* Almanac health page (25) parameters */ 133106424Sroberto unsigned char 134285612Sdelphij WN_a, SV_health[32], t_oa; 135106424Sroberto} ALH_PARMS; 136106424Sroberto 137285612Sdelphijtypedef struct { /* Universal Coordinated Time (UTC) parms */ 138106424Sroberto double 139285612Sdelphij A_0; 140106424Sroberto float 141285612Sdelphij A_1; 142106424Sroberto short 143285612Sdelphij delta_t_LS; 144106424Sroberto float 145285612Sdelphij t_ot; 146106424Sroberto short 147285612Sdelphij WN_t, WN_LSF, DN, delta_t_LSF; 148106424Sroberto} UTC_INFO; 149106424Sroberto 150285612Sdelphijtypedef struct { /* Ionospheric info (float) */ 151106424Sroberto float 152285612Sdelphij alpha_0, alpha_1, alpha_2, alpha_3, 153285612Sdelphij beta_0, beta_1, beta_2, beta_3; 154106424Sroberto} ION_INFO; 155106424Sroberto 156285612Sdelphijtypedef struct { /* Subframe 1 info (float) */ 157106424Sroberto short 158285612Sdelphij weeknum; 159106424Sroberto unsigned char 160285612Sdelphij codeL2, L2Pdata, SVacc_raw, SV_health; 161106424Sroberto short 162285612Sdelphij IODC; 163106424Sroberto float 164285612Sdelphij T_GD, t_oc, a_f2, a_f1, a_f0, SVacc; 165106424Sroberto} EPHEM_CLOCK; 166106424Sroberto 167285612Sdelphijtypedef struct { /* Ephemeris info (float) */ 168106424Sroberto unsigned char 169285612Sdelphij IODE, fit_interval; 170106424Sroberto float 171285612Sdelphij C_rs, delta_n; 172106424Sroberto double 173285612Sdelphij M_0; 174106424Sroberto float 175285612Sdelphij C_uc; 176106424Sroberto double 177285612Sdelphij e; 178106424Sroberto float 179285612Sdelphij C_us; 180106424Sroberto double 181285612Sdelphij sqrt_A; 182106424Sroberto float 183285612Sdelphij t_oe, C_ic; 184106424Sroberto double 185285612Sdelphij OMEGA_0; 186106424Sroberto float 187285612Sdelphij C_is; 188106424Sroberto double 189285612Sdelphij i_0; 190106424Sroberto float 191285612Sdelphij C_rc; 192106424Sroberto double 193285612Sdelphij omega; 194106424Sroberto float 195285612Sdelphij OMEGADOT, IDOT; 196106424Sroberto double 197285612Sdelphij Axis, n, r1me2, OMEGA_n, ODOT_n; 198106424Sroberto} EPHEM_ORBIT; 199106424Sroberto 200285612Sdelphijtypedef struct { /* Navigation data structure */ 201106424Sroberto short 202285612Sdelphij sv_number; /* SV number (0 = no entry) */ 203106424Sroberto float 204285612Sdelphij t_ephem; /* time of ephemeris collection */ 205106424Sroberto EPHEM_CLOCK 206285612Sdelphij ephclk; /* subframe 1 data */ 207106424Sroberto EPHEM_ORBIT 208285612Sdelphij ephorb; /* ephemeris data */ 209106424Sroberto} NAV_INFO; 210106424Sroberto 211106424Srobertotypedef struct { 212106424Sroberto unsigned char 213285612Sdelphij bSubcode, 214285612Sdelphij operating_mode, 215285612Sdelphij dgps_mode, 216285612Sdelphij dyn_code, 217285612Sdelphij trackmode; 218106424Sroberto float 219285612Sdelphij elev_mask, 220285612Sdelphij cno_mask, 221285612Sdelphij dop_mask, 222285612Sdelphij dop_switch; 223106424Sroberto unsigned char 224285612Sdelphij dgps_age_limit; 225106424Sroberto} TSIP_RCVR_CFG; 226106424Sroberto 227106424Sroberto 228106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 229106424Srobertostatic char 230285612Sdelphij *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, 231106424Sroberto old_baudnum[] = {0, 1, 4, 5, 6, 8, 9, 11, 28, 12}, 232106424Sroberto *st_baud_text_app [] = {"", "", " 300", " 600", " 1200", " 2400", 233285612Sdelphij " 4800", " 9600", "19200", "38400"}, 234106424Sroberto *old_parity_text[] = {"EVEN", "ODD", "", "", "NONE"}, 235106424Sroberto *parity_text [] = {"NONE", "ODD", "EVEN"}, 236106424Sroberto *old_input_ch[] = { "TSIP", "RTCM (6 of 8 bits)"}, 237106424Sroberto *old_output_ch[] = { "TSIP", "No output", "", "", "", "NMEA 0183"}, 238106424Sroberto *protocols_in_text[] = { "", "TSIP", "", ""}, 239106424Sroberto *protocols_out_text[] = { "", "TSIP", "NMEA"}, 240106424Sroberto *rcvr_port_text [] = { "Port A ", "Port B ", "Current Port"}, 241106424Sroberto *dyn_text [] = {"Unchanged", "Land", "Sea", "Air", "Static"}, 242106424Sroberto *NavModeText0xBB[] = {"automatic", "time only (0-D)", "", "2-D", 243285612Sdelphij "3-D", "", "", "OverDetermined Time"}, 244106424Sroberto *PPSTimeBaseText[] = {"GPS", "UTC", "USER"}, 245106424Sroberto *PPSPolarityText[] = {"Positive", "Negative"}, 246106424Sroberto *MaskText[] = { "Almanac ", "Ephemeris", "UTC ", "Iono ", 247285612Sdelphij "GPS Msg ", "Alm Hlth ", "Time Fix ", "SV Select", 248285612Sdelphij "Ext Event", "Pos Fix ", "Raw Meas "}; 249106424Sroberto 250106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 251106424Sroberto 252106424Sroberto/* 253106424Sroberto * Unit control structure 254106424Sroberto */ 255106424Srobertostruct ripencc_unit { 256106424Sroberto int unit; /* unit number */ 257106424Sroberto int pollcnt; /* poll message counter */ 258106424Sroberto int polled; /* Hand in a sample? */ 259106424Sroberto char leapdelta; /* delta of next leap event */ 260106424Sroberto unsigned char utcflags; /* delta of next leap event */ 261106424Sroberto l_fp tstamp; /* timestamp of last poll */ 262106424Sroberto 263106424Sroberto struct timespec ts; /* last timestamp */ 264106424Sroberto pps_params_t pps_params; /* pps parameters */ 265106424Sroberto pps_info_t pps_info; /* last pps data */ 266106424Sroberto pps_handle_t handle; /* pps handlebars */ 267106424Sroberto 268106424Sroberto}; 269106424Sroberto 270106424Sroberto 271106424Sroberto/******************* PROTOYPES *****************/ 272106424Sroberto 273106424Sroberto/* prototypes for report parsing primitives */ 274106424Srobertoshort rpt_0x3D (TSIPPKT *rpt, unsigned char *tx_baud_index, 275285612Sdelphij unsigned char *rx_baud_index, unsigned char *char_format_index, 276285612Sdelphij unsigned char *stop_bits, unsigned char *tx_mode_index, 277285612Sdelphij unsigned char *rx_mode_index); 278106424Srobertoshort rpt_0x40 (TSIPPKT *rpt, unsigned char *sv_prn, short *week_num, 279285612Sdelphij float *t_zc, float *eccentricity, float *t_oa, float *i_0, 280285612Sdelphij float *OMEGA_dot, float *sqrt_A, float *OMEGA_0, float *omega, 281285612Sdelphij float *M_0); 282106424Srobertoshort rpt_0x41 (TSIPPKT *rpt, float *time_of_week, float *UTC_offset, 283285612Sdelphij short *week_num); 284106424Srobertoshort rpt_0x42 (TSIPPKT *rpt, float ECEF_pos[3], float *time_of_fix); 285106424Srobertoshort rpt_0x43 (TSIPPKT *rpt, float ECEF_vel[3], float *freq_offset, 286285612Sdelphij float *time_of_fix); 287106424Srobertoshort rpt_0x45 (TSIPPKT *rpt, unsigned char *major_nav_version, 288285612Sdelphij unsigned char *minor_nav_version, unsigned char *nav_day, 289285612Sdelphij unsigned char *nav_month, unsigned char *nav_year, 290285612Sdelphij unsigned char *major_dsp_version, unsigned char *minor_dsp_version, 291285612Sdelphij unsigned char *dsp_day, unsigned char *dsp_month, 292285612Sdelphij unsigned char *dsp_year); 293106424Srobertoshort rpt_0x46 (TSIPPKT *rpt, unsigned char *status1, unsigned char *status2); 294106424Srobertoshort rpt_0x47 (TSIPPKT *rpt, unsigned char *nsvs, unsigned char *sv_prn, 295285612Sdelphij float *snr); 296106424Srobertoshort rpt_0x48 (TSIPPKT *rpt, unsigned char *message); 297106424Srobertoshort rpt_0x49 (TSIPPKT *rpt, unsigned char *sv_health); 298106424Srobertoshort rpt_0x4A (TSIPPKT *rpt, float *lat, float *lon, float *alt, 299285612Sdelphij float *clock_bias, float *time_of_fix); 300106424Srobertoshort rpt_0x4A_2 (TSIPPKT *rpt, float *alt, float *dummy, 301285612Sdelphij unsigned char *alt_flag); 302106424Srobertoshort rpt_0x4B (TSIPPKT *rpt, unsigned char *machine_id, 303285612Sdelphij unsigned char *status3, unsigned char *status4); 304106424Srobertoshort rpt_0x4C (TSIPPKT *rpt, unsigned char *dyn_code, float *el_mask, 305285612Sdelphij float *snr_mask, float *dop_mask, float *dop_switch); 306106424Srobertoshort rpt_0x4D (TSIPPKT *rpt, float *osc_offset); 307106424Srobertoshort rpt_0x4E (TSIPPKT *rpt, unsigned char *response); 308106424Srobertoshort rpt_0x4F (TSIPPKT *rpt, double *a0, float *a1, float *time_of_data, 309285612Sdelphij short *dt_ls, short *wn_t, short *wn_lsf, short *dn, short *dt_lsf); 310106424Srobertoshort rpt_0x54 (TSIPPKT *rpt, float *clock_bias, float *freq_offset, 311285612Sdelphij float *time_of_fix); 312106424Srobertoshort rpt_0x55 (TSIPPKT *rpt, unsigned char *pos_code, unsigned char *vel_code, 313285612Sdelphij unsigned char *time_code, unsigned char *aux_code); 314106424Srobertoshort rpt_0x56 (TSIPPKT *rpt, float vel_ENU[3], float *freq_offset, 315285612Sdelphij float *time_of_fix); 316106424Srobertoshort rpt_0x57 (TSIPPKT *rpt, unsigned char *source_code, 317285612Sdelphij unsigned char *diag_code, short *week_num, float *time_of_fix); 318106424Srobertoshort rpt_0x58 (TSIPPKT *rpt, unsigned char *op_code, unsigned char *data_type, 319285612Sdelphij unsigned char *sv_prn, unsigned char *data_length, 320285612Sdelphij unsigned char *data_packet); 321106424Srobertoshort rpt_0x59 (TSIPPKT *rpt, unsigned char *code_type, 322285612Sdelphij unsigned char status_code[32]); 323106424Srobertoshort rpt_0x5A (TSIPPKT *rpt, unsigned char *sv_prn, float *sample_length, 324285612Sdelphij float *signal_level, float *code_phase, float *Doppler, 325285612Sdelphij double *time_of_fix); 326106424Srobertoshort rpt_0x5B (TSIPPKT *rpt, unsigned char *sv_prn, unsigned char *sv_health, 327285612Sdelphij unsigned char *sv_iode, unsigned char *fit_interval_flag, 328285612Sdelphij float *time_of_collection, float *time_of_eph, float *sv_accy); 329106424Srobertoshort rpt_0x5C (TSIPPKT *rpt, unsigned char *sv_prn, unsigned char *slot, 330285612Sdelphij unsigned char *chan, unsigned char *acq_flag, unsigned char *eph_flag, 331285612Sdelphij float *signal_level, float *time_of_last_msmt, float *elev, 332285612Sdelphij float *azim, unsigned char *old_msmt_flag, 333285612Sdelphij unsigned char *integer_msec_flag, unsigned char *bad_data_flag, 334285612Sdelphij unsigned char *data_collect_flag); 335106424Srobertoshort rpt_0x6D (TSIPPKT *rpt, unsigned char *manual_mode, unsigned char *nsvs, 336285612Sdelphij unsigned char *ndim, unsigned char sv_prn[], float *pdop, 337285612Sdelphij float *hdop, float *vdop, float *tdop); 338106424Srobertoshort rpt_0x82 (TSIPPKT *rpt, unsigned char *diff_mode); 339106424Srobertoshort rpt_0x83 (TSIPPKT *rpt, double ECEF_pos[3], double *clock_bias, 340285612Sdelphij float *time_of_fix); 341106424Srobertoshort rpt_0x84 (TSIPPKT *rpt, double *lat, double *lon, double *alt, 342285612Sdelphij double *clock_bias, float *time_of_fix); 343106424Srobertoshort rpt_Paly0xBB(TSIPPKT *rpt, TSIP_RCVR_CFG *TsipxBB); 344106424Srobertoshort rpt_0xBC (TSIPPKT *rpt, unsigned char *port_num, 345285612Sdelphij unsigned char *in_baud, unsigned char *out_baud, 346285612Sdelphij unsigned char *data_bits, unsigned char *parity, 347285612Sdelphij unsigned char *stop_bits, unsigned char *flow_control, 348285612Sdelphij unsigned char *protocols_in, unsigned char *protocols_out, 349285612Sdelphij unsigned char *reserved); 350106424Sroberto 351106424Sroberto/* prototypes for superpacket parsers */ 352106424Sroberto 353106424Srobertoshort rpt_0x8F0B (TSIPPKT *rpt, unsigned short *event, double *tow, 354285612Sdelphij unsigned char *date, unsigned char *month, short *year, 355285612Sdelphij unsigned char *dim_mode, short *utc_offset, double *bias, double *drift, 356285612Sdelphij float *bias_unc, float *dr_unc, double *lat, double *lon, double *alt, 357285612Sdelphij char sv_id[8]); 358106424Srobertoshort rpt_0x8F14 (TSIPPKT *rpt, short *datum_idx, double datum_coeffs[5]); 359106424Srobertoshort rpt_0x8F15 (TSIPPKT *rpt, short *datum_idx, double datum_coeffs[5]); 360106424Srobertoshort rpt_0x8F20 (TSIPPKT *rpt, unsigned char *info, double *lat, 361285612Sdelphij double *lon, double *alt, double vel_enu[], double *time_of_fix, 362285612Sdelphij short *week_num, unsigned char *nsvs, unsigned char sv_prn[], 363285612Sdelphij short sv_IODC[], short *datum_index); 364106424Srobertoshort rpt_0x8F41 (TSIPPKT *rpt, unsigned char *bSearchRange, 365285612Sdelphij unsigned char *bBoardOptions, unsigned long *iiSerialNumber, 366285612Sdelphij unsigned char *bBuildYear, unsigned char *bBuildMonth, 367285612Sdelphij unsigned char *bBuildDay, unsigned char *bBuildHour, 368285612Sdelphij float *fOscOffset, unsigned short *iTestCodeId); 369106424Srobertoshort rpt_0x8F42 (TSIPPKT *rpt, unsigned char *bProdOptionsPre, 370285612Sdelphij unsigned char *bProdNumberExt, unsigned short *iCaseSerialNumberPre, 371285612Sdelphij unsigned long *iiCaseSerialNumber, unsigned long *iiProdNumber, 372285612Sdelphij unsigned short *iPremiumOptions, unsigned short *iMachineID, 373285612Sdelphij unsigned short *iKey); 374106424Srobertoshort rpt_0x8F45 (TSIPPKT *rpt, unsigned char *bSegMask); 375106424Srobertoshort rpt_0x8F4A_16 (TSIPPKT *rpt, unsigned char *pps_enabled, 376285612Sdelphij unsigned char *pps_timebase, unsigned char *pos_polarity, 377285612Sdelphij double *pps_offset, float *bias_unc_threshold); 378106424Srobertoshort rpt_0x8F4B (TSIPPKT *rpt, unsigned long *decorr_max); 379106424Srobertoshort rpt_0x8F4D (TSIPPKT *rpt, unsigned long *event_mask); 380106424Srobertoshort rpt_0x8FA5 (TSIPPKT *rpt, unsigned char *spktmask); 381106424Srobertoshort rpt_0x8FAD (TSIPPKT *rpt, unsigned short *COUNT, double *FracSec, 382285612Sdelphij unsigned char *Hour, unsigned char *Minute, unsigned char *Second, 383285612Sdelphij unsigned char *Day, unsigned char *Month, unsigned short *Year, 384285612Sdelphij unsigned char *Status, unsigned char *Flags); 385106424Sroberto 386106424Sroberto/**/ 387106424Sroberto/* prototypes for command-encode primitives with suffix convention: */ 388106424Sroberto/* c = clear, s = set, q = query, e = enable, d = disable */ 389106424Srobertovoid cmd_0x1F (TSIPPKT *cmd); 390106424Srobertovoid cmd_0x26 (TSIPPKT *cmd); 391106424Srobertovoid cmd_0x2F (TSIPPKT *cmd); 392106424Srobertovoid cmd_0x35s (TSIPPKT *cmd, unsigned char pos_code, unsigned char vel_code, 393285612Sdelphij unsigned char time_code, unsigned char opts_code); 394106424Srobertovoid cmd_0x3C (TSIPPKT *cmd, unsigned char sv_prn); 395106424Srobertovoid cmd_0x3Ds (TSIPPKT *cmd, unsigned char baud_out, unsigned char baud_inp, 396285612Sdelphij unsigned char char_code, unsigned char stopbitcode, 397285612Sdelphij unsigned char output_mode, unsigned char input_mode); 398106424Srobertovoid cmd_0xBBq (TSIPPKT *cmd, unsigned char subcode) ; 399106424Sroberto 400106424Sroberto/* prototypes 8E commands */ 401106424Srobertovoid cmd_0x8E0Bq (TSIPPKT *cmd); 402106424Srobertovoid cmd_0x8E41q (TSIPPKT *cmd); 403106424Srobertovoid cmd_0x8E42q (TSIPPKT *cmd); 404106424Srobertovoid cmd_0x8E4Aq (TSIPPKT *cmd); 405106424Srobertovoid cmd_0x8E4As (TSIPPKT *cmd, unsigned char PPSOnOff, unsigned char TimeBase, 406285612Sdelphij unsigned char Polarity, double PPSOffset, float Uncertainty); 407106424Srobertovoid cmd_0x8E4Bq (TSIPPKT *cmd); 408106424Srobertovoid cmd_0x8E4Ds (TSIPPKT *cmd, unsigned long AutoOutputMask); 409106424Srobertovoid cmd_0x8EADq (TSIPPKT *cmd); 410106424Sroberto 411106424Sroberto/* header/source border XXXXXXXXXXXXXXXXXXXXXXXXXX */ 412106424Sroberto 413106424Sroberto/* Trimble parse functions */ 414285612Sdelphijstatic int parse0x8FAD (TSIPPKT *, struct peer *); 415285612Sdelphijstatic int parse0x8F0B (TSIPPKT *, struct peer *); 416106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 417285612Sdelphijstatic int parseany (TSIPPKT *, struct peer *); 418285612Sdelphijstatic void TranslateTSIPReportToText (TSIPPKT *, char *); 419106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 420285612Sdelphijstatic int parse0x5C (TSIPPKT *, struct peer *); 421285612Sdelphijstatic int parse0x4F (TSIPPKT *, struct peer *); 422285612Sdelphijstatic void tsip_input_proc (TSIPPKT *, int); 423106424Sroberto 424106424Sroberto/* Trimble helper functions */ 425285612Sdelphijstatic void bPutFloat (float *, unsigned char *); 426285612Sdelphijstatic void bPutDouble (double *, unsigned char *); 427285612Sdelphijstatic void bPutULong (unsigned long *, unsigned char *); 428285612Sdelphijstatic int print_msg_table_header (int rptcode, char *HdrStr, int force); 429285612Sdelphijstatic char * show_time (float time_of_week); 430106424Sroberto 431106424Sroberto/* RIPE NCC functions */ 432285612Sdelphijstatic void ripencc_control (int, const struct refclockstat *, 433285612Sdelphij struct refclockstat *, struct peer *); 434285612Sdelphijstatic int ripencc_ppsapi (struct peer *, int, int); 435285612Sdelphijstatic int ripencc_get_pps_ts (struct ripencc_unit *, l_fp *); 436285612Sdelphijstatic int ripencc_start (int, struct peer *); 437285612Sdelphijstatic void ripencc_shutdown (int, struct peer *); 438285612Sdelphijstatic void ripencc_poll (int, struct peer *); 439285612Sdelphijstatic void ripencc_send (struct peer *, TSIPPKT spt); 440285612Sdelphijstatic void ripencc_receive (struct recvbuf *); 441106424Sroberto 442106424Sroberto/* fill in reflock structure for our clock */ 443106424Srobertostruct refclock refclock_ripencc = { 444106424Sroberto ripencc_start, /* start up driver */ 445106424Sroberto ripencc_shutdown, /* shut down driver */ 446106424Sroberto ripencc_poll, /* transmit poll message */ 447106424Sroberto ripencc_control, /* control function */ 448106424Sroberto noentry, /* initialize driver */ 449106424Sroberto noentry, /* debug info */ 450106424Sroberto NOFLAGS /* clock flags */ 451106424Sroberto}; 452106424Sroberto 453106424Sroberto/* 454106424Sroberto * Tables to compute the ddd of year form icky dd/mm timecode. Viva la 455106424Sroberto * leap. 456106424Sroberto */ 457106424Srobertostatic int day1tab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 458106424Srobertostatic int day2tab[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 459106424Sroberto 460106424Sroberto 461106424Sroberto/* 462106424Sroberto * ripencc_start - open the GPS devices and initialize data for processing 463106424Sroberto */ 464106424Srobertostatic int 465106424Srobertoripencc_start(int unit, struct peer *peer) 466106424Sroberto{ 467106424Sroberto register struct ripencc_unit *up; 468106424Sroberto struct refclockproc *pp; 469106424Sroberto char device[40]; 470106424Sroberto int fd; 471106424Sroberto struct termios tio; 472106424Sroberto TSIPPKT spt; 473106424Sroberto 474285612Sdelphij pp = peer->procptr; 475285612Sdelphij 476106424Sroberto /* 477106424Sroberto * Open serial port 478106424Sroberto */ 479106424Sroberto (void)snprintf(device, sizeof(device), DEVICE, unit); 480285612Sdelphij fd = refclock_open(device, SPEED232, LDISC_RAW); 481285612Sdelphij if (fd <= 0) { 482285612Sdelphij pp->io.fd = -1; 483106424Sroberto return (0); 484285612Sdelphij } 485106424Sroberto 486285612Sdelphij pp->io.fd = fd; 487285612Sdelphij 488106424Sroberto /* from refclock_palisade.c */ 489106424Sroberto if (tcgetattr(fd, &tio) < 0) { 490106424Sroberto msyslog(LOG_ERR, "Palisade(%d) tcgetattr(fd, &tio): %m",unit); 491106424Sroberto return (0); 492106424Sroberto } 493106424Sroberto 494106424Sroberto /* 495106424Sroberto * set flags 496106424Sroberto */ 497106424Sroberto tio.c_cflag |= (PARENB|PARODD); 498106424Sroberto tio.c_iflag &= ~ICRNL; 499106424Sroberto if (tcsetattr(fd, TCSANOW, &tio) == -1) { 500106424Sroberto msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit); 501106424Sroberto return (0); 502106424Sroberto } 503106424Sroberto 504106424Sroberto /* 505106424Sroberto * Allocate and initialize unit structure 506106424Sroberto */ 507285612Sdelphij up = emalloc_zero(sizeof(*up)); 508285612Sdelphij 509106424Sroberto pp->io.clock_recv = ripencc_receive; 510285612Sdelphij pp->io.srcclock = peer; 511106424Sroberto pp->io.datalen = 0; 512106424Sroberto if (!io_addclock(&pp->io)) { 513285612Sdelphij pp->io.fd = -1; 514285612Sdelphij close(fd); 515106424Sroberto free(up); 516106424Sroberto return (0); 517106424Sroberto } 518285612Sdelphij pp->unitptr = up; 519106424Sroberto 520106424Sroberto /* 521106424Sroberto * Initialize miscellaneous variables 522106424Sroberto */ 523106424Sroberto peer->precision = PRECISION; 524106424Sroberto pp->clockdesc = DESCRIPTION; 525106424Sroberto memcpy((char *)&pp->refid, REFID, REFID_LEN); 526106424Sroberto up->pollcnt = 2; 527106424Sroberto up->unit = unit; 528106424Sroberto up->leapdelta = 0; 529106424Sroberto up->utcflags = 0; 530106424Sroberto 531106424Sroberto /* 532106424Sroberto * Initialize the Clock 533106424Sroberto */ 534106424Sroberto 535106424Sroberto /* query software versions */ 536106424Sroberto cmd_0x1F(&spt); 537106424Sroberto ripencc_send(peer, spt); 538106424Sroberto 539106424Sroberto /* query receiver health */ 540106424Sroberto cmd_0x26(&spt); 541106424Sroberto ripencc_send(peer, spt); 542106424Sroberto 543106424Sroberto /* query serial numbers */ 544106424Sroberto cmd_0x8E42q(&spt); 545106424Sroberto ripencc_send(peer, spt); 546106424Sroberto 547106424Sroberto /* query manuf params */ 548106424Sroberto cmd_0x8E41q(&spt); 549106424Sroberto ripencc_send(peer, spt); 550106424Sroberto 551106424Sroberto /* i/o opts */ /* trimble manual page A30 */ 552106424Sroberto cmd_0x35s(&spt, 553285612Sdelphij 0x1C, /* position */ 554285612Sdelphij 0x00, /* velocity */ 555285612Sdelphij 0x05, /* timing */ 556285612Sdelphij 0x0a); /* auxilary */ 557106424Sroberto ripencc_send(peer, spt); 558106424Sroberto 559106424Sroberto /* turn off port A */ 560106424Sroberto cmd_0x3Ds (&spt, 561285612Sdelphij 0x0B, /* baud_out */ 562285612Sdelphij 0x0B, /* baud_inp */ 563285612Sdelphij 0x07, /* char_code */ 564285612Sdelphij 0x07, /* stopbitcode */ 565285612Sdelphij 0x01, /* output_mode */ 566285612Sdelphij 0x00); /* input_mode */ 567106424Sroberto ripencc_send(peer, spt); 568106424Sroberto 569106424Sroberto /* set i/o options */ 570106424Sroberto cmd_0x8E4As (&spt, 571285612Sdelphij 0x01, /* PPS on */ 572285612Sdelphij 0x01, /* Timebase UTC */ 573285612Sdelphij 0x00, /* polarity positive */ 574285612Sdelphij 0., /* 100 ft. cable XXX make flag */ 575285612Sdelphij 1e-6 * GPS_C); /* turn of biasuncert. > (1us) */ 576106424Sroberto ripencc_send(peer,spt); 577106424Sroberto 578106424Sroberto /* all outomatic packet output off */ 579106424Sroberto cmd_0x8E4Ds(&spt, 580285612Sdelphij 0x00000000); /* AutoOutputMask */ 581106424Sroberto ripencc_send(peer, spt); 582106424Sroberto 583106424Sroberto cmd_0xBBq (&spt, 584285612Sdelphij 0x00); /* query primary configuration */ 585106424Sroberto ripencc_send(peer,spt); 586106424Sroberto 587106424Sroberto 588106424Sroberto /* query PPS parameters */ 589285612Sdelphij cmd_0x8E4Aq (&spt); /* query PPS params */ 590106424Sroberto ripencc_send(peer,spt); 591106424Sroberto 592106424Sroberto /* query survey limit */ 593285612Sdelphij cmd_0x8E4Bq (&spt); /* query survey limit */ 594106424Sroberto ripencc_send(peer,spt); 595106424Sroberto 596106424Sroberto#ifdef DEBUG_NCC 597106424Sroberto if (debug) 598106424Sroberto printf("ripencc_start: success\n"); 599106424Sroberto#endif /* DEBUG_NCC */ 600106424Sroberto 601106424Sroberto /* 602106424Sroberto * Start the PPSAPI interface if it is there. Default to use 603106424Sroberto * the assert edge and do not enable the kernel hardpps. 604106424Sroberto */ 605106424Sroberto if (time_pps_create(fd, &up->handle) < 0) { 606106424Sroberto up->handle = 0; 607106424Sroberto msyslog(LOG_ERR, "refclock_ripencc: time_pps_create failed: %m"); 608106424Sroberto return (1); 609106424Sroberto } 610106424Sroberto 611132451Sroberto return(ripencc_ppsapi(peer, 0, 0)); 612106424Sroberto} 613106424Sroberto 614106424Sroberto/* 615106424Sroberto * ripencc_control - fudge control 616106424Sroberto */ 617106424Srobertostatic void 618106424Srobertoripencc_control( 619106424Sroberto int unit, /* unit (not used) */ 620285612Sdelphij const struct refclockstat *in, /* input parameters (not used) */ 621106424Sroberto struct refclockstat *out, /* output parameters (not used) */ 622106424Sroberto struct peer *peer /* peer structure pointer */ 623106424Sroberto ) 624106424Sroberto{ 625106424Sroberto struct refclockproc *pp; 626106424Sroberto 627106424Sroberto#ifdef DEBUG_NCC 628106424Sroberto msyslog(LOG_INFO,"%s()",__FUNCTION__); 629106424Sroberto#endif /* DEBUG_NCC */ 630106424Sroberto 631106424Sroberto pp = peer->procptr; 632106424Sroberto ripencc_ppsapi(peer, pp->sloppyclockflag & CLK_FLAG2, 633285612Sdelphij pp->sloppyclockflag & CLK_FLAG3); 634106424Sroberto} 635106424Sroberto 636106424Sroberto 637106424Sroberto/* 638106424Sroberto * Initialize PPSAPI 639106424Sroberto */ 640106424Srobertoint 641106424Srobertoripencc_ppsapi( 642106424Sroberto struct peer *peer, /* peer structure pointer */ 643106424Sroberto int enb_clear, /* clear enable */ 644106424Sroberto int enb_hardpps /* hardpps enable */ 645106424Sroberto ) 646106424Sroberto{ 647106424Sroberto struct refclockproc *pp; 648106424Sroberto struct ripencc_unit *up; 649106424Sroberto int capability; 650106424Sroberto 651106424Sroberto pp = peer->procptr; 652285612Sdelphij up = pp->unitptr; 653106424Sroberto if (time_pps_getcap(up->handle, &capability) < 0) { 654106424Sroberto msyslog(LOG_ERR, 655285612Sdelphij "refclock_ripencc: time_pps_getcap failed: %m"); 656106424Sroberto return (0); 657106424Sroberto } 658106424Sroberto memset(&up->pps_params, 0, sizeof(pps_params_t)); 659106424Sroberto if (enb_clear) 660106424Sroberto up->pps_params.mode = capability & PPS_CAPTURECLEAR; 661106424Sroberto else 662106424Sroberto up->pps_params.mode = capability & PPS_CAPTUREASSERT; 663106424Sroberto if (!up->pps_params.mode) { 664106424Sroberto msyslog(LOG_ERR, 665285612Sdelphij "refclock_ripencc: invalid capture edge %d", 666285612Sdelphij !enb_clear); 667106424Sroberto return (0); 668106424Sroberto } 669106424Sroberto up->pps_params.mode |= PPS_TSFMT_TSPEC; 670106424Sroberto if (time_pps_setparams(up->handle, &up->pps_params) < 0) { 671106424Sroberto msyslog(LOG_ERR, 672285612Sdelphij "refclock_ripencc: time_pps_setparams failed: %m"); 673106424Sroberto return (0); 674106424Sroberto } 675106424Sroberto if (enb_hardpps) { 676106424Sroberto if (time_pps_kcbind(up->handle, PPS_KC_HARDPPS, 677106424Sroberto up->pps_params.mode & ~PPS_TSFMT_TSPEC, 678106424Sroberto PPS_TSFMT_TSPEC) < 0) { 679106424Sroberto msyslog(LOG_ERR, 680285612Sdelphij "refclock_ripencc: time_pps_kcbind failed: %m"); 681106424Sroberto return (0); 682106424Sroberto } 683285612Sdelphij hardpps_enable = 1; 684106424Sroberto } 685106424Sroberto peer->precision = PPS_PRECISION; 686106424Sroberto 687106424Sroberto#if DEBUG_NCC 688106424Sroberto if (debug) { 689106424Sroberto time_pps_getparams(up->handle, &up->pps_params); 690106424Sroberto printf( 691285612Sdelphij "refclock_ripencc: capability 0x%x version %d mode 0x%x kern %d\n", 692285612Sdelphij capability, up->pps_params.api_version, 693285612Sdelphij up->pps_params.mode, enb_hardpps); 694106424Sroberto } 695106424Sroberto#endif /* DEBUG_NCC */ 696106424Sroberto 697106424Sroberto return (1); 698106424Sroberto} 699106424Sroberto 700106424Sroberto/* 701106424Sroberto * This function is called every 64 seconds from ripencc_receive 702106424Sroberto * It will fetch the pps time 703106424Sroberto * 704106424Sroberto * Return 0 on failure and 1 on success. 705106424Sroberto */ 706106424Srobertostatic int 707106424Srobertoripencc_get_pps_ts( 708106424Sroberto struct ripencc_unit *up, 709106424Sroberto l_fp *tsptr 710106424Sroberto ) 711106424Sroberto{ 712106424Sroberto pps_info_t pps_info; 713106424Sroberto struct timespec timeout, ts; 714106424Sroberto double dtemp; 715106424Sroberto l_fp tstmp; 716106424Sroberto 717106424Sroberto#ifdef DEBUG_PPS 718285612Sdelphij msyslog(LOG_INFO,"ripencc_get_pps_ts"); 719106424Sroberto#endif /* DEBUG_PPS */ 720106424Sroberto 721106424Sroberto 722106424Sroberto /* 723106424Sroberto * Convert the timespec nanoseconds field to ntp l_fp units. 724106424Sroberto */ 725106424Sroberto if (up->handle == 0) 726106424Sroberto return (0); 727106424Sroberto timeout.tv_sec = 0; 728106424Sroberto timeout.tv_nsec = 0; 729106424Sroberto memcpy(&pps_info, &up->pps_info, sizeof(pps_info_t)); 730106424Sroberto if (time_pps_fetch(up->handle, PPS_TSFMT_TSPEC, &up->pps_info, 731285612Sdelphij &timeout) < 0) 732106424Sroberto return (0); 733106424Sroberto if (up->pps_params.mode & PPS_CAPTUREASSERT) { 734106424Sroberto if (pps_info.assert_sequence == 735106424Sroberto up->pps_info.assert_sequence) 736106424Sroberto return (0); 737106424Sroberto ts = up->pps_info.assert_timestamp; 738106424Sroberto } else if (up->pps_params.mode & PPS_CAPTURECLEAR) { 739106424Sroberto if (pps_info.clear_sequence == 740106424Sroberto up->pps_info.clear_sequence) 741106424Sroberto return (0); 742106424Sroberto ts = up->pps_info.clear_timestamp; 743106424Sroberto } else { 744106424Sroberto return (0); 745106424Sroberto } 746106424Sroberto if ((up->ts.tv_sec == ts.tv_sec) && (up->ts.tv_nsec == ts.tv_nsec)) 747106424Sroberto return (0); 748106424Sroberto up->ts = ts; 749106424Sroberto 750106424Sroberto tstmp.l_ui = ts.tv_sec + JAN_1970; 751106424Sroberto dtemp = ts.tv_nsec * FRAC / 1e9; 752106424Sroberto tstmp.l_uf = (u_int32)dtemp; 753106424Sroberto 754106424Sroberto#ifdef DEBUG_PPS 755285612Sdelphij msyslog(LOG_INFO,"ts.tv_sec: %d",(int)ts.tv_sec); 756285612Sdelphij msyslog(LOG_INFO,"ts.tv_nsec: %ld",ts.tv_nsec); 757106424Sroberto#endif /* DEBUG_PPS */ 758106424Sroberto 759106424Sroberto *tsptr = tstmp; 760106424Sroberto return (1); 761106424Sroberto} 762106424Sroberto 763106424Sroberto/* 764106424Sroberto * ripencc_shutdown - shut down a GPS clock 765106424Sroberto */ 766106424Srobertostatic void 767106424Srobertoripencc_shutdown(int unit, struct peer *peer) 768106424Sroberto{ 769106424Sroberto register struct ripencc_unit *up; 770106424Sroberto struct refclockproc *pp; 771106424Sroberto 772106424Sroberto pp = peer->procptr; 773285612Sdelphij up = pp->unitptr; 774106424Sroberto 775285612Sdelphij if (up != NULL) { 776285612Sdelphij if (up->handle != 0) 777285612Sdelphij time_pps_destroy(up->handle); 778285612Sdelphij free(up); 779285612Sdelphij } 780285612Sdelphij if (-1 != pp->io.fd) 781285612Sdelphij io_closeclock(&pp->io); 782106424Sroberto 783285612Sdelphij return; 784106424Sroberto} 785106424Sroberto 786106424Sroberto/* 787106424Sroberto * ripencc_poll - called by the transmit procedure 788106424Sroberto */ 789106424Srobertostatic void 790106424Srobertoripencc_poll(int unit, struct peer *peer) 791106424Sroberto{ 792106424Sroberto register struct ripencc_unit *up; 793106424Sroberto struct refclockproc *pp; 794106424Sroberto TSIPPKT spt; 795106424Sroberto 796106424Sroberto#ifdef DEBUG_NCC 797106424Sroberto if (debug) 798106424Sroberto fprintf(stderr, "ripencc_poll(%d)\n", unit); 799106424Sroberto#endif /* DEBUG_NCC */ 800106424Sroberto pp = peer->procptr; 801285612Sdelphij up = pp->unitptr; 802106424Sroberto if (up->pollcnt == 0) 803106424Sroberto refclock_report(peer, CEVNT_TIMEOUT); 804106424Sroberto else 805106424Sroberto up->pollcnt--; 806106424Sroberto 807106424Sroberto pp->polls++; 808106424Sroberto up->polled = 1; 809106424Sroberto 810106424Sroberto /* poll for UTC superpacket */ 811106424Sroberto cmd_0x8EADq (&spt); 812106424Sroberto ripencc_send(peer,spt); 813106424Sroberto} 814106424Sroberto 815106424Sroberto/* 816106424Sroberto * ripencc_send - send message to clock 817106424Sroberto * use the structures being created by the trimble functions! 818106424Sroberto * makes the code more readable/clean 819106424Sroberto */ 820106424Srobertostatic void 821106424Srobertoripencc_send(struct peer *peer, TSIPPKT spt) 822106424Sroberto{ 823106424Sroberto unsigned char *ip, *op; 824106424Sroberto unsigned char obuf[512]; 825106424Sroberto 826106424Sroberto#ifdef DEBUG_RAW 827106424Sroberto { 828106424Sroberto register struct ripencc_unit *up; 829106424Sroberto register struct refclockproc *pp; 830106424Sroberto 831106424Sroberto pp = peer->procptr; 832285612Sdelphij up = pp->unitptr; 833106424Sroberto if (debug) 834106424Sroberto printf("ripencc_send(%d, %02X)\n", up->unit, cmd); 835106424Sroberto } 836106424Sroberto#endif /* DEBUG_RAW */ 837106424Sroberto 838106424Sroberto ip = spt.buf; 839106424Sroberto op = obuf; 840106424Sroberto 841106424Sroberto *op++ = 0x10; 842106424Sroberto *op++ = spt.code; 843106424Sroberto 844106424Sroberto while (spt.len--) { 845106424Sroberto if (op-obuf > sizeof(obuf)-5) { 846106424Sroberto msyslog(LOG_ERR, "ripencc_send obuf overflow!"); 847106424Sroberto refclock_report(peer, CEVNT_FAULT); 848106424Sroberto return; 849106424Sroberto } 850106424Sroberto 851285612Sdelphij if (*ip == 0x10) /* byte stuffing */ 852106424Sroberto *op++ = 0x10; 853106424Sroberto *op++ = *ip++; 854106424Sroberto } 855106424Sroberto 856106424Sroberto *op++ = 0x10; 857106424Sroberto *op++ = 0x03; 858106424Sroberto 859106424Sroberto#ifdef DEBUG_RAW 860106424Sroberto if (debug) { /* print raw packet */ 861106424Sroberto unsigned char *cp; 862106424Sroberto int i; 863106424Sroberto 864106424Sroberto printf("ripencc_send: len %d\n", op-obuf); 865106424Sroberto for (i=1, cp=obuf; cp<op; i++, cp++) { 866106424Sroberto printf(" %02X", *cp); 867106424Sroberto if (i%10 == 0) 868106424Sroberto printf("\n"); 869106424Sroberto } 870106424Sroberto printf("\n"); 871106424Sroberto } 872106424Sroberto#endif /* DEBUG_RAW */ 873106424Sroberto 874106424Sroberto if (write(peer->procptr->io.fd, obuf, op-obuf) == -1) { 875285612Sdelphij refclock_report(peer, CEVNT_FAULT); 876106424Sroberto } 877106424Sroberto} 878106424Sroberto 879106424Sroberto/* 880106424Sroberto * ripencc_receive() 881106424Sroberto * 882106424Sroberto * called when a packet is received on the serial port 883106424Sroberto * takes care of further processing 884106424Sroberto * 885106424Sroberto */ 886106424Srobertostatic void 887106424Srobertoripencc_receive(struct recvbuf *rbufp) 888106424Sroberto{ 889106424Sroberto register struct ripencc_unit *up; 890106424Sroberto register struct refclockproc *pp; 891106424Sroberto struct peer *peer; 892285612Sdelphij static TSIPPKT rpt; /* for current incoming TSIP report */ 893285612Sdelphij TSIPPKT spt; /* send packet */ 894106424Sroberto int ns_since_pps; 895106424Sroberto int i; 896106424Sroberto char *cp; 897285612Sdelphij /* these variables hold data until we decide it's worth keeping */ 898106424Sroberto char rd_lastcode[BMAX]; 899106424Sroberto l_fp rd_tmp; 900106424Sroberto u_short rd_lencode; 901106424Sroberto 902106424Sroberto /* msyslog(LOG_INFO, "%s",__FUNCTION__); */ 903106424Sroberto 904106424Sroberto /* 905106424Sroberto * Initialize pointers and read the timecode and timestamp 906106424Sroberto */ 907285612Sdelphij peer = rbufp->recv_peer; 908106424Sroberto pp = peer->procptr; 909285612Sdelphij up = pp->unitptr; 910106424Sroberto rd_lencode = refclock_gtlin(rbufp, rd_lastcode, BMAX, &rd_tmp); 911106424Sroberto 912106424Sroberto#ifdef DEBUG_RAW 913106424Sroberto if (debug) 914106424Sroberto fprintf(stderr, "ripencc_receive(%d)\n", up->unit); 915106424Sroberto#endif /* DEBUG_RAW */ 916106424Sroberto 917106424Sroberto#ifdef DEBUG_RAW 918285612Sdelphij if (debug) { /* print raw packet */ 919106424Sroberto int i; 920106424Sroberto unsigned char *cp; 921106424Sroberto 922106424Sroberto printf("ripencc_receive: len %d\n", rbufp->recv_length); 923285612Sdelphij for (i=1, cp=(char*)&rbufp->recv_space; 924285612Sdelphij i <= rbufp->recv_length; 925285612Sdelphij i++, cp++) { 926106424Sroberto printf(" %02X", *cp); 927106424Sroberto if (i%10 == 0) 928106424Sroberto printf("\n"); 929106424Sroberto } 930106424Sroberto printf("\n"); 931106424Sroberto } 932106424Sroberto#endif /* DEBUG_RAW */ 933106424Sroberto 934106424Sroberto cp = (char*) &rbufp->recv_space; 935106424Sroberto i=rbufp->recv_length; 936106424Sroberto 937285612Sdelphij while (i--) { /* loop over received chars */ 938106424Sroberto 939106424Sroberto tsip_input_proc(&rpt, (unsigned char) *cp++); 940106424Sroberto 941106424Sroberto if (rpt.status != TSIP_PARSED_FULL) 942106424Sroberto continue; 943106424Sroberto 944106424Sroberto switch (rpt.code) { 945106424Sroberto 946285612Sdelphij case 0x8F: /* superpacket */ 947106424Sroberto 948106424Sroberto switch (rpt.buf[0]) { 949106424Sroberto 950285612Sdelphij case 0xAD: /* UTC Time */ 951106424Sroberto /* 952285612Sdelphij ** When polling on port B the timecode is 953285612Sdelphij ** the time of the previous PPS. If we 954285612Sdelphij ** completed receiving the packet less than 955285612Sdelphij ** 150ms after the turn of the second, it 956285612Sdelphij ** may have the code of the previous second. 957285612Sdelphij ** We do not trust that and simply poll 958285612Sdelphij ** again without even parsing it. 959285612Sdelphij ** 960285612Sdelphij ** More elegant would be to re-schedule the 961285612Sdelphij ** poll, but I do not know (yet) how to do 962285612Sdelphij ** that cleanly. 963285612Sdelphij ** 964285612Sdelphij */ 965106424Sroberto /* BLA ns_since_pps = ncc_tstmp(rbufp, &trtmp); */ 966106424Sroberto/* if (up->polled && ns_since_pps > -1 && ns_since_pps < 150) { */ 967106424Sroberto 968285612Sdelphij ns_since_pps = 200; 969106424Sroberto if (up->polled && ns_since_pps < 150) { 970285612Sdelphij msyslog(LOG_INFO, "%s(): up->polled", 971285612Sdelphij __FUNCTION__); 972106424Sroberto ripencc_poll(up->unit, peer); 973106424Sroberto break; 974106424Sroberto } 975106424Sroberto 976106424Sroberto /* 977106424Sroberto * Parse primary utc time packet 978106424Sroberto * and fill refclock structure 979106424Sroberto * from results. 980106424Sroberto */ 981106424Sroberto if (parse0x8FAD(&rpt, peer) < 0) { 982285612Sdelphij msyslog(LOG_INFO, "%s(): parse0x8FAD < 0",__FUNCTION__); 983285612Sdelphij refclock_report(peer, CEVNT_BADREPLY); 984285612Sdelphij break; 985106424Sroberto } 986106424Sroberto /* 987106424Sroberto * If the PPSAPI is working, rather use its 988106424Sroberto * timestamps. 989106424Sroberto * assume that the PPS occurs on the second 990106424Sroberto * so blow any msec 991106424Sroberto */ 992106424Sroberto if (ripencc_get_pps_ts(up, &rd_tmp) == 1) { 993106424Sroberto pp->lastrec = up->tstamp = rd_tmp; 994132451Sroberto pp->nsec = 0; 995106424Sroberto } 996106424Sroberto else 997285612Sdelphij msyslog(LOG_INFO, "%s(): ripencc_get_pps_ts returns failure",__FUNCTION__); 998106424Sroberto 999106424Sroberto 1000106424Sroberto if (!up->polled) { 1001285612Sdelphij msyslog(LOG_INFO, "%s(): unrequested packet",__FUNCTION__); 1002106424Sroberto /* unrequested packet */ 1003106424Sroberto break; 1004106424Sroberto } 1005106424Sroberto 1006106424Sroberto /* we have been polled ! */ 1007106424Sroberto up->polled = 0; 1008106424Sroberto up->pollcnt = 2; 1009106424Sroberto 1010106424Sroberto /* poll for next packet */ 1011106424Sroberto cmd_0x8E0Bq(&spt); 1012106424Sroberto ripencc_send(peer,spt); 1013106424Sroberto 1014106424Sroberto if (ns_since_pps < 0) { /* no PPS */ 1015106424Sroberto msyslog(LOG_INFO, "%s(): ns_since_pps < 0",__FUNCTION__); 1016106424Sroberto refclock_report(peer, CEVNT_BADTIME); 1017106424Sroberto break; 1018106424Sroberto } 1019106424Sroberto 1020106424Sroberto /* 1021285612Sdelphij ** Process the new sample in the median 1022285612Sdelphij ** filter and determine the reference clock 1023285612Sdelphij ** offset and dispersion. 1024285612Sdelphij */ 1025106424Sroberto if (!refclock_process(pp)) { 1026106424Sroberto msyslog(LOG_INFO, "%s(): !refclock_process",__FUNCTION__); 1027106424Sroberto refclock_report(peer, CEVNT_BADTIME); 1028106424Sroberto break; 1029106424Sroberto } 1030106424Sroberto 1031106424Sroberto refclock_receive(peer); 1032106424Sroberto break; 1033106424Sroberto 1034285612Sdelphij case 0x0B: /* comprehensive time packet */ 1035106424Sroberto parse0x8F0B(&rpt, peer); 1036106424Sroberto break; 1037106424Sroberto 1038285612Sdelphij default: /* other superpackets */ 1039106424Sroberto#ifdef DEBUG_NCC 1040285612Sdelphij msyslog(LOG_INFO, "%s(): calling parseany", 1041285612Sdelphij __FUNCTION__); 1042106424Sroberto#endif /* DEBUG_NCC */ 1043106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 1044106424Sroberto parseany(&rpt, peer); 1045106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 1046106424Sroberto break; 1047106424Sroberto } 1048106424Sroberto break; 1049106424Sroberto 1050285612Sdelphij case 0x4F: /* UTC parameters, for leap info */ 1051106424Sroberto parse0x4F(&rpt, peer); 1052106424Sroberto break; 1053106424Sroberto 1054285612Sdelphij case 0x5C: /* sat tracking data */ 1055106424Sroberto parse0x5C(&rpt, peer); 1056106424Sroberto break; 1057106424Sroberto 1058285612Sdelphij default: /* other packets */ 1059106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 1060106424Sroberto parseany(&rpt, peer); 1061106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 1062106424Sroberto break; 1063106424Sroberto } 1064106424Sroberto rpt.status = TSIP_PARSED_EMPTY; 1065106424Sroberto } 1066106424Sroberto} 1067106424Sroberto 1068106424Sroberto/* 1069106424Sroberto * All trimble functions that are directly referenced from driver code 1070106424Sroberto * (so not from parseany) 1071106424Sroberto */ 1072106424Sroberto 1073106424Sroberto/* request software versions */ 1074285612Sdelphijvoid 1075285612Sdelphijcmd_0x1F( 1076285612Sdelphij TSIPPKT *cmd 1077285612Sdelphij ) 1078106424Sroberto{ 1079106424Sroberto cmd->len = 0; 1080106424Sroberto cmd->code = 0x1F; 1081106424Sroberto} 1082106424Sroberto 1083106424Sroberto/* request receiver health */ 1084285612Sdelphijvoid 1085285612Sdelphijcmd_0x26( 1086285612Sdelphij TSIPPKT *cmd 1087285612Sdelphij ) 1088106424Sroberto{ 1089106424Sroberto cmd->len = 0; 1090106424Sroberto cmd->code = 0x26; 1091106424Sroberto} 1092106424Sroberto 1093106424Sroberto/* request UTC params */ 1094285612Sdelphijvoid 1095285612Sdelphijcmd_0x2F( 1096285612Sdelphij TSIPPKT *cmd 1097285612Sdelphij ) 1098106424Sroberto{ 1099106424Sroberto cmd->len = 0; 1100106424Sroberto cmd->code = 0x2F; 1101106424Sroberto} 1102106424Sroberto 1103106424Sroberto/* set serial I/O options */ 1104285612Sdelphijvoid 1105285612Sdelphijcmd_0x35s( 1106285612Sdelphij TSIPPKT *cmd, 1107285612Sdelphij unsigned char pos_code, 1108285612Sdelphij unsigned char vel_code, 1109285612Sdelphij unsigned char time_code, 1110285612Sdelphij unsigned char opts_code 1111285612Sdelphij ) 1112106424Sroberto{ 1113106424Sroberto cmd->buf[0] = pos_code; 1114106424Sroberto cmd->buf[1] = vel_code; 1115106424Sroberto cmd->buf[2] = time_code; 1116106424Sroberto cmd->buf[3] = opts_code; 1117106424Sroberto cmd->len = 4; 1118106424Sroberto cmd->code = 0x35; 1119106424Sroberto} 1120285612Sdelphij 1121106424Sroberto/* request tracking status */ 1122285612Sdelphijvoid 1123285612Sdelphijcmd_0x3C( 1124285612Sdelphij TSIPPKT *cmd, 1125285612Sdelphij unsigned char sv_prn 1126285612Sdelphij ) 1127106424Sroberto{ 1128106424Sroberto cmd->buf[0] = sv_prn; 1129106424Sroberto cmd->len = 1; 1130106424Sroberto cmd->code = 0x3C; 1131106424Sroberto} 1132106424Sroberto 1133106424Sroberto/* set Channel A configuration for dual-port operation */ 1134285612Sdelphijvoid 1135285612Sdelphijcmd_0x3Ds( 1136285612Sdelphij TSIPPKT *cmd, 1137285612Sdelphij unsigned char baud_out, 1138285612Sdelphij unsigned char baud_inp, 1139285612Sdelphij unsigned char char_code, 1140285612Sdelphij unsigned char stopbitcode, 1141285612Sdelphij unsigned char output_mode, 1142285612Sdelphij unsigned char input_mode 1143285612Sdelphij ) 1144106424Sroberto{ 1145106424Sroberto cmd->buf[0] = baud_out; /* XMT baud rate */ 1146106424Sroberto cmd->buf[1] = baud_inp; /* RCV baud rate */ 1147285612Sdelphij cmd->buf[2] = char_code; /* parity and #bits per byte */ 1148106424Sroberto cmd->buf[3] = stopbitcode; /* number of stop bits code */ 1149106424Sroberto cmd->buf[4] = output_mode; /* Ch. A transmission mode */ 1150106424Sroberto cmd->buf[5] = input_mode; /* Ch. A reception mode */ 1151106424Sroberto cmd->len = 6; 1152106424Sroberto cmd->code = 0x3D; 1153106424Sroberto} 1154106424Sroberto 1155106424Sroberto 1156106424Sroberto/* query primary configuration */ 1157285612Sdelphijvoid 1158285612Sdelphijcmd_0xBBq( 1159285612Sdelphij TSIPPKT *cmd, 1160285612Sdelphij unsigned char subcode 1161285612Sdelphij ) 1162106424Sroberto{ 1163106424Sroberto cmd->len = 1; 1164106424Sroberto cmd->code = 0xBB; 1165106424Sroberto cmd->buf[0] = subcode; 1166106424Sroberto} 1167106424Sroberto 1168106424Sroberto 1169106424Sroberto/**** Superpackets ****/ 1170106424Sroberto/* 8E-0B to query 8F-0B controls */ 1171285612Sdelphijvoid 1172285612Sdelphijcmd_0x8E0Bq( 1173285612Sdelphij TSIPPKT *cmd 1174285612Sdelphij ) 1175106424Sroberto{ 1176106424Sroberto cmd->len = 1; 1177106424Sroberto cmd->code = 0x8E; 1178106424Sroberto cmd->buf[0] = 0x0B; 1179106424Sroberto} 1180106424Sroberto 1181106424Sroberto 1182106424Sroberto/* 8F-41 to query board serial number */ 1183285612Sdelphijvoid 1184285612Sdelphijcmd_0x8E41q( 1185285612Sdelphij TSIPPKT *cmd 1186285612Sdelphij ) 1187106424Sroberto{ 1188106424Sroberto cmd->len = 1; 1189106424Sroberto cmd->code = 0x8E; 1190106424Sroberto cmd->buf[0] = 0x41; 1191106424Sroberto} 1192106424Sroberto 1193106424Sroberto 1194106424Sroberto/* 8F-42 to query product serial number */ 1195285612Sdelphijvoid 1196285612Sdelphijcmd_0x8E42q( 1197285612Sdelphij TSIPPKT *cmd 1198285612Sdelphij ) 1199106424Sroberto{ 1200106424Sroberto cmd->len = 1; 1201106424Sroberto cmd->code = 0x8E; 1202106424Sroberto cmd->buf[0] = 0x42; 1203106424Sroberto} 1204285612Sdelphij 1205285612Sdelphij 1206106424Sroberto/* 8F-4A to query PPS parameters */ 1207285612Sdelphijvoid 1208285612Sdelphijcmd_0x8E4Aq( 1209285612Sdelphij TSIPPKT *cmd 1210285612Sdelphij ) 1211106424Sroberto{ 1212106424Sroberto cmd->len = 1; 1213106424Sroberto cmd->code = 0x8E; 1214106424Sroberto cmd->buf[0] = 0x4A; 1215106424Sroberto} 1216106424Sroberto 1217106424Sroberto 1218106424Sroberto/* set i/o options */ 1219285612Sdelphijvoid 1220285612Sdelphijcmd_0x8E4As( 1221285612Sdelphij TSIPPKT *cmd, 1222285612Sdelphij unsigned char PPSOnOff, 1223285612Sdelphij unsigned char TimeBase, 1224285612Sdelphij unsigned char Polarity, 1225285612Sdelphij double PPSOffset, 1226285612Sdelphij float Uncertainty 1227285612Sdelphij ) 1228106424Sroberto{ 1229106424Sroberto cmd->len = 16; 1230106424Sroberto cmd->code = 0x8E; 1231106424Sroberto cmd->buf[0] = 0x4A; 1232106424Sroberto cmd->buf[1] = PPSOnOff; 1233106424Sroberto cmd->buf[2] = TimeBase; 1234106424Sroberto cmd->buf[3] = Polarity; 1235106424Sroberto bPutDouble (&PPSOffset, &cmd->buf[4]); 1236106424Sroberto bPutFloat (&Uncertainty, &cmd->buf[12]); 1237106424Sroberto} 1238285612Sdelphij 1239106424Sroberto/* 8F-4B query survey limit */ 1240285612Sdelphijvoid 1241285612Sdelphijcmd_0x8E4Bq( 1242285612Sdelphij TSIPPKT *cmd 1243285612Sdelphij ) 1244106424Sroberto{ 1245106424Sroberto cmd->len = 1; 1246106424Sroberto cmd->code = 0x8E; 1247106424Sroberto cmd->buf[0] = 0x4B; 1248106424Sroberto} 1249106424Sroberto 1250106424Sroberto/* poll for UTC superpacket */ 1251106424Sroberto/* 8E-AD to query 8F-AD controls */ 1252285612Sdelphijvoid 1253285612Sdelphijcmd_0x8EADq( 1254285612Sdelphij TSIPPKT *cmd 1255285612Sdelphij ) 1256106424Sroberto{ 1257106424Sroberto cmd->len = 1; 1258106424Sroberto cmd->code = 0x8E; 1259106424Sroberto cmd->buf[0] = 0xAD; 1260106424Sroberto} 1261106424Sroberto 1262106424Sroberto/* all outomatic packet output off */ 1263285612Sdelphijvoid 1264285612Sdelphijcmd_0x8E4Ds( 1265285612Sdelphij TSIPPKT *cmd, 1266285612Sdelphij unsigned long AutoOutputMask 1267285612Sdelphij ) 1268106424Sroberto{ 1269106424Sroberto cmd->len = 5; 1270106424Sroberto cmd->code = 0x8E; 1271106424Sroberto cmd->buf[0] = 0x4D; 1272106424Sroberto bPutULong (&AutoOutputMask, &cmd->buf[1]); 1273106424Sroberto} 1274106424Sroberto 1275106424Sroberto 1276285612Sdelphij/* 1277285612Sdelphij * for DOS machines, reverse order of bytes as they come through the 1278285612Sdelphij * serial port. 1279285612Sdelphij */ 1280106424Sroberto#ifdef BYTESWAP 1281285612Sdelphijstatic short 1282285612SdelphijbGetShort( 1283285612Sdelphij unsigned char *bp 1284285612Sdelphij ) 1285106424Sroberto{ 1286106424Sroberto short outval; 1287285612Sdelphij unsigned char *optr; 1288106424Sroberto 1289285612Sdelphij optr = (unsigned char*)&outval + 1; 1290285612Sdelphij *optr-- = *bp++; 1291285612Sdelphij *optr = *bp; 1292106424Sroberto return outval; 1293106424Sroberto} 1294106424Sroberto 1295106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 1296285612Sdelphijstatic unsigned short 1297285612SdelphijbGetUShort( 1298285612Sdelphij unsigned char *bp 1299285612Sdelphij ) 1300106424Sroberto{ 1301106424Sroberto unsigned short outval; 1302285612Sdelphij unsigned char *optr; 1303106424Sroberto 1304285612Sdelphij optr = (unsigned char*)&outval + 1; 1305285612Sdelphij *optr-- = *bp++; 1306285612Sdelphij *optr = *bp; 1307106424Sroberto return outval; 1308106424Sroberto} 1309106424Sroberto 1310285612Sdelphijstatic long 1311285612SdelphijbGetLong( 1312285612Sdelphij unsigned char *bp 1313285612Sdelphij ) 1314106424Sroberto{ 1315106424Sroberto long outval; 1316285612Sdelphij unsigned char *optr; 1317106424Sroberto 1318285612Sdelphij optr = (unsigned char*)&outval + 3; 1319285612Sdelphij *optr-- = *bp++; 1320285612Sdelphij *optr-- = *bp++; 1321285612Sdelphij *optr-- = *bp++; 1322285612Sdelphij *optr = *bp; 1323106424Sroberto return outval; 1324106424Sroberto} 1325106424Sroberto 1326285612Sdelphijstatic unsigned long 1327285612SdelphijbGetULong( 1328285612Sdelphij unsigned char *bp 1329285612Sdelphij ) 1330106424Sroberto{ 1331106424Sroberto unsigned long outval; 1332285612Sdelphij unsigned char *optr; 1333106424Sroberto 1334285612Sdelphij optr = (unsigned char*)&outval + 3; 1335285612Sdelphij *optr-- = *bp++; 1336285612Sdelphij *optr-- = *bp++; 1337285612Sdelphij *optr-- = *bp++; 1338285612Sdelphij *optr = *bp; 1339106424Sroberto return outval; 1340106424Sroberto} 1341106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 1342106424Sroberto 1343285612Sdelphijstatic float 1344285612SdelphijbGetSingle( 1345285612Sdelphij unsigned char *bp 1346285612Sdelphij ) 1347106424Sroberto{ 1348106424Sroberto float outval; 1349285612Sdelphij unsigned char *optr; 1350106424Sroberto 1351285612Sdelphij optr = (unsigned char*)&outval + 3; 1352285612Sdelphij *optr-- = *bp++; 1353285612Sdelphij *optr-- = *bp++; 1354285612Sdelphij *optr-- = *bp++; 1355285612Sdelphij *optr = *bp; 1356106424Sroberto return outval; 1357106424Sroberto} 1358106424Sroberto 1359285612Sdelphijstatic double 1360285612SdelphijbGetDouble( 1361285612Sdelphij unsigned char *bp 1362285612Sdelphij ) 1363106424Sroberto{ 1364106424Sroberto double outval; 1365285612Sdelphij unsigned char *optr; 1366106424Sroberto 1367285612Sdelphij optr = (unsigned char*)&outval + 7; 1368285612Sdelphij *optr-- = *bp++; 1369285612Sdelphij *optr-- = *bp++; 1370285612Sdelphij *optr-- = *bp++; 1371285612Sdelphij *optr-- = *bp++; 1372285612Sdelphij *optr-- = *bp++; 1373285612Sdelphij *optr-- = *bp++; 1374285612Sdelphij *optr-- = *bp++; 1375285612Sdelphij *optr = *bp; 1376106424Sroberto return outval; 1377106424Sroberto} 1378106424Sroberto 1379106424Sroberto#else /* not BYTESWAP */ 1380106424Sroberto 1381106424Sroberto#define bGetShort(bp) (*(short*)(bp)) 1382106424Sroberto#define bGetLong(bp) (*(long*)(bp)) 1383106424Sroberto#define bGetULong(bp) (*(unsigned long*)(bp)) 1384106424Sroberto#define bGetSingle(bp) (*(float*)(bp)) 1385106424Sroberto#define bGetDouble(bp) (*(double*)(bp)) 1386106424Sroberto 1387106424Sroberto#endif /* BYTESWAP */ 1388106424Sroberto/* 1389106424Sroberto * Byte-reversal is necessary for little-endian (Intel-based) machines. 1390106424Sroberto * TSIP streams are Big-endian (Motorola-based). 1391106424Sroberto */ 1392106424Sroberto#ifdef BYTESWAP 1393106424Sroberto 1394106424Srobertovoid 1395285612SdelphijbPutFloat( 1396285612Sdelphij float *in, 1397285612Sdelphij unsigned char *out 1398285612Sdelphij ) 1399106424Sroberto{ 1400106424Sroberto unsigned char *inptr; 1401106424Sroberto 1402285612Sdelphij inptr = (unsigned char*)in + 3; 1403285612Sdelphij *out++ = *inptr--; 1404285612Sdelphij *out++ = *inptr--; 1405285612Sdelphij *out++ = *inptr--; 1406285612Sdelphij *out = *inptr; 1407106424Sroberto} 1408106424Sroberto 1409106424Srobertostatic void 1410285612SdelphijbPutULong( 1411285612Sdelphij unsigned long *in, 1412285612Sdelphij unsigned char *out 1413285612Sdelphij ) 1414106424Sroberto{ 1415106424Sroberto unsigned char *inptr; 1416106424Sroberto 1417285612Sdelphij inptr = (unsigned char*)in + 3; 1418285612Sdelphij *out++ = *inptr--; 1419285612Sdelphij *out++ = *inptr--; 1420285612Sdelphij *out++ = *inptr--; 1421285612Sdelphij *out = *inptr; 1422106424Sroberto} 1423106424Sroberto 1424106424Srobertostatic void 1425285612SdelphijbPutDouble( 1426285612Sdelphij double *in, 1427285612Sdelphij unsigned char *out 1428285612Sdelphij ) 1429106424Sroberto{ 1430106424Sroberto unsigned char *inptr; 1431106424Sroberto 1432285612Sdelphij inptr = (unsigned char*)in + 7; 1433285612Sdelphij *out++ = *inptr--; 1434285612Sdelphij *out++ = *inptr--; 1435285612Sdelphij *out++ = *inptr--; 1436285612Sdelphij *out++ = *inptr--; 1437285612Sdelphij *out++ = *inptr--; 1438285612Sdelphij *out++ = *inptr--; 1439285612Sdelphij *out++ = *inptr--; 1440285612Sdelphij *out = *inptr; 1441106424Sroberto} 1442106424Sroberto 1443106424Sroberto#else /* not BYTESWAP */ 1444106424Sroberto 1445106424Srobertovoid bPutShort (short a, unsigned char *cmdbuf) {*(short*) cmdbuf = a;} 1446106424Srobertovoid bPutULong (long a, unsigned char *cmdbuf) {*(long*) cmdbuf = a;} 1447106424Srobertovoid bPutFloat (float a, unsigned char *cmdbuf) {*(float*) cmdbuf = a;} 1448106424Srobertovoid bPutDouble (double a, unsigned char *cmdbuf){*(double*) cmdbuf = a;} 1449106424Sroberto 1450106424Sroberto#endif /* BYTESWAP */ 1451106424Sroberto 1452106424Sroberto/* 1453106424Sroberto * Parse primary utc time packet 1454106424Sroberto * and fill refclock structure 1455106424Sroberto * from results. 1456106424Sroberto * 1457106424Sroberto * 0 = success 1458106424Sroberto * -1 = errors 1459106424Sroberto */ 1460106424Sroberto 1461106424Srobertostatic int 1462285612Sdelphijparse0x8FAD( 1463285612Sdelphij TSIPPKT *rpt, 1464285612Sdelphij struct peer *peer 1465285612Sdelphij ) 1466106424Sroberto{ 1467106424Sroberto register struct refclockproc *pp; 1468106424Sroberto register struct ripencc_unit *up; 1469106424Sroberto 1470106424Sroberto unsigned day, month, year; /* data derived from received timecode */ 1471106424Sroberto unsigned hour, minute, second; 1472106424Sroberto unsigned char trackstat, utcflags; 1473106424Sroberto 1474106424Sroberto static char logbuf[1024]; /* logging string buffer */ 1475106424Sroberto int i; 1476106424Sroberto unsigned char *buf; 1477106424Sroberto 1478106424Sroberto buf = rpt->buf; 1479106424Sroberto pp = peer->procptr; 1480106424Sroberto 1481106424Sroberto if (rpt->len != 22) 1482106424Sroberto return (-1); 1483106424Sroberto 1484106424Sroberto if (bGetShort(&buf[1]) != 0) { 1485106424Sroberto#ifdef DEBUG_NCC 1486106424Sroberto if (debug) 1487106424Sroberto printf("parse0x8FAD: event count != 0\n"); 1488106424Sroberto#endif /* DEBUG_NCC */ 1489106424Sroberto return(-1); 1490106424Sroberto } 1491106424Sroberto 1492106424Sroberto if (bGetDouble(&buf[3]) != 0.0) { 1493106424Sroberto#ifdef DEBUG_NCC 1494106424Sroberto if (debug) 1495106424Sroberto printf("parse0x8FAD: fracsecs != 0\n"); 1496106424Sroberto#endif /* DEBUG_NCC */ 1497106424Sroberto return(-1); 1498106424Sroberto } 1499106424Sroberto 1500285612Sdelphij hour = (unsigned int) buf[11]; 1501285612Sdelphij minute = (unsigned int) buf[12]; 1502285612Sdelphij second = (unsigned int) buf[13]; 1503106424Sroberto day = (unsigned int) buf[14]; 1504106424Sroberto month = (unsigned int) buf[15]; 1505106424Sroberto year = bGetShort(&buf[16]); 1506285612Sdelphij trackstat = buf[18]; 1507285612Sdelphij utcflags = buf[19]; 1508106424Sroberto 1509106424Sroberto 1510106424Sroberto sprintf(logbuf, "U1 %d.%d.%d %02d:%02d:%02d %d %02x", 1511106424Sroberto day, month, year, hour, minute, second, trackstat, utcflags); 1512106424Sroberto 1513106424Sroberto#ifdef DEBUG_NCC 1514106424Sroberto if (debug) 1515106424Sroberto puts(logbuf); 1516106424Sroberto#endif /* DEBUG_NCC */ 1517106424Sroberto 1518106424Sroberto record_clock_stats(&peer->srcadr, logbuf); 1519106424Sroberto 1520106424Sroberto if (!utcflags & UTCF_UTC_AVAIL) 1521106424Sroberto return(-1); 1522106424Sroberto 1523106424Sroberto /* poll for UTC parameters once and then if UTC flag changed */ 1524106424Sroberto up = (struct ripencc_unit *) pp->unitptr; 1525106424Sroberto if (utcflags != up->utcflags) { 1526285612Sdelphij TSIPPKT spt; /* local structure for send packet */ 1527106424Sroberto cmd_0x2F (&spt); /* request UTC params */ 1528106424Sroberto ripencc_send(peer,spt); 1529106424Sroberto up->utcflags = utcflags; 1530106424Sroberto } 1531106424Sroberto 1532106424Sroberto /* 1533106424Sroberto * If we hit the leap second, we choose to skip this sample 1534106424Sroberto * rather than rely on other code to be perfectly correct. 1535106424Sroberto * No offense, just defense ;-). 1536106424Sroberto */ 1537106424Sroberto if (second == 60) 1538106424Sroberto return(-1); 1539106424Sroberto 1540106424Sroberto /* now check and convert the time we received */ 1541106424Sroberto 1542106424Sroberto pp->year = year; 1543106424Sroberto if (month < 1 || month > 12 || day < 1 || day > 31) 1544106424Sroberto return(-1); 1545106424Sroberto 1546285612Sdelphij if (pp->year % 4) { /* XXX: use is_leapyear() ? */ 1547106424Sroberto if (day > day1tab[month - 1]) 1548106424Sroberto return(-1); 1549106424Sroberto for (i = 0; i < month - 1; i++) 1550106424Sroberto day += day1tab[i]; 1551106424Sroberto } else { 1552106424Sroberto if (day > day2tab[month - 1]) 1553106424Sroberto return(-1); 1554106424Sroberto for (i = 0; i < month - 1; i++) 1555106424Sroberto day += day2tab[i]; 1556106424Sroberto } 1557106424Sroberto pp->day = day; 1558106424Sroberto pp->hour = hour; 1559106424Sroberto pp->minute = minute; 1560106424Sroberto pp-> second = second; 1561132451Sroberto pp->nsec = 0; 1562106424Sroberto 1563106424Sroberto if ((utcflags&UTCF_LEAP_PNDG) && up->leapdelta != 0) 1564285612Sdelphij pp-> leap = (up->leapdelta > 0) 1565285612Sdelphij ? LEAP_ADDSECOND 1566285612Sdelphij : LEAP_DELSECOND; 1567106424Sroberto else 1568106424Sroberto pp-> leap = LEAP_NOWARNING; 1569106424Sroberto 1570106424Sroberto return (0); 1571106424Sroberto} 1572106424Sroberto 1573106424Sroberto/* 1574106424Sroberto * Parse comprehensive time packet 1575106424Sroberto * 1576285612Sdelphij * 0 = success 1577106424Sroberto * -1 = errors 1578106424Sroberto */ 1579106424Sroberto 1580285612Sdelphijint 1581285612Sdelphijparse0x8F0B( 1582285612Sdelphij TSIPPKT *rpt, 1583285612Sdelphij struct peer *peer 1584285612Sdelphij ) 1585106424Sroberto{ 1586106424Sroberto register struct refclockproc *pp; 1587106424Sroberto 1588106424Sroberto unsigned day, month, year; /* data derived from received timecode */ 1589106424Sroberto unsigned hour, minute, second; 1590106424Sroberto unsigned utcoff; 1591106424Sroberto unsigned char mode; 1592106424Sroberto double bias, rate; 1593106424Sroberto float biasunc, rateunc; 1594106424Sroberto double lat, lon, alt; 1595106424Sroberto short lat_deg, lon_deg; 1596106424Sroberto float lat_min, lon_min; 1597106424Sroberto unsigned char north_south, east_west; 1598106424Sroberto char sv[9]; 1599106424Sroberto 1600106424Sroberto static char logbuf[1024]; /* logging string buffer */ 1601106424Sroberto unsigned char b; 1602106424Sroberto int i; 1603106424Sroberto unsigned char *buf; 1604106424Sroberto double tow; 1605106424Sroberto 1606106424Sroberto buf = rpt->buf; 1607106424Sroberto pp = peer->procptr; 1608106424Sroberto 1609106424Sroberto if (rpt->len != 74) 1610106424Sroberto return (-1); 1611106424Sroberto 1612106424Sroberto if (bGetShort(&buf[1]) != 0) 1613106424Sroberto return(-1);; 1614106424Sroberto 1615106424Sroberto tow = bGetDouble(&buf[3]); 1616106424Sroberto 1617106424Sroberto if (tow == -1.0) { 1618106424Sroberto return(-1); 1619106424Sroberto } 1620106424Sroberto else if ((tow >= 604800.0) || (tow < 0.0)) { 1621106424Sroberto return(-1); 1622106424Sroberto } 1623106424Sroberto else 1624106424Sroberto { 1625106424Sroberto if (tow < 604799.9) tow = tow + .00000001; 1626106424Sroberto second = (unsigned int) fmod(tow, 60.); 1627106424Sroberto minute = (unsigned int) fmod(tow/60., 60.); 1628106424Sroberto hour = (unsigned int )fmod(tow / 3600., 24.); 1629106424Sroberto } 1630106424Sroberto 1631106424Sroberto day = (unsigned int) buf[11]; 1632106424Sroberto month = (unsigned int) buf[12]; 1633106424Sroberto year = bGetShort(&buf[13]); 1634106424Sroberto mode = buf[15]; 1635106424Sroberto utcoff = bGetShort(&buf[16]); 1636106424Sroberto bias = bGetDouble(&buf[18]) / GPS_C * 1e9; /* ns */ 1637106424Sroberto rate = bGetDouble(&buf[26]) / GPS_C * 1e9; /* ppb */ 1638106424Sroberto biasunc = bGetSingle(&buf[34]) / GPS_C * 1e9; /* ns */ 1639106424Sroberto rateunc = bGetSingle(&buf[38]) / GPS_C * 1e9; /* ppb */ 1640106424Sroberto lat = bGetDouble(&buf[42]) * R2D; 1641106424Sroberto lon = bGetDouble(&buf[50]) * R2D; 1642106424Sroberto alt = bGetDouble(&buf[58]); 1643106424Sroberto 1644106424Sroberto if (lat < 0.0) { 1645106424Sroberto north_south = 'S'; 1646106424Sroberto lat = -lat; 1647106424Sroberto } 1648106424Sroberto else { 1649106424Sroberto north_south = 'N'; 1650106424Sroberto } 1651106424Sroberto lat_deg = (short)lat; 1652106424Sroberto lat_min = (lat - lat_deg) * 60.0; 1653106424Sroberto 1654106424Sroberto if (lon < 0.0) { 1655106424Sroberto east_west = 'W'; 1656106424Sroberto lon = -lon; 1657106424Sroberto } 1658106424Sroberto else { 1659106424Sroberto east_west = 'E'; 1660106424Sroberto } 1661106424Sroberto 1662106424Sroberto lon_deg = (short)lon; 1663106424Sroberto lon_min = (lon - lon_deg) * 60.0; 1664106424Sroberto 1665106424Sroberto for (i=0; i<8; i++) { 1666106424Sroberto sv[i] = buf[i + 66]; 1667106424Sroberto if (sv[i]) { 1668106424Sroberto TSIPPKT spt; /* local structure for sendpacket */ 1669106424Sroberto b = (unsigned char) (sv[i]<0 ? -sv[i] : sv[i]); 1670106424Sroberto /* request tracking status */ 1671106424Sroberto cmd_0x3C (&spt, b); 1672106424Sroberto ripencc_send(peer,spt); 1673106424Sroberto } 1674106424Sroberto } 1675106424Sroberto 1676106424Sroberto 1677106424Sroberto sprintf(logbuf, "C1 %02d%02d%04d %02d%02d%02d %d %7.0f %.1f %.0f %.1f %d %02d%09.6f %c %02d%09.6f %c %.0f %d %d %d %d %d %d %d %d", 1678285612Sdelphij day, month, year, hour, minute, second, mode, bias, biasunc, 1679285612Sdelphij rate, rateunc, utcoff, lat_deg, lat_min, north_south, lon_deg, 1680285612Sdelphij lon_min, east_west, alt, sv[0], sv[1], sv[2], sv[3], sv[4], 1681285612Sdelphij sv[5], sv[6], sv[7]); 1682106424Sroberto 1683106424Sroberto#ifdef DEBUG_NCC 1684106424Sroberto if (debug) 1685106424Sroberto puts(logbuf); 1686106424Sroberto#endif /* DEBUG_NCC */ 1687106424Sroberto 1688106424Sroberto record_clock_stats(&peer->srcadr, logbuf); 1689106424Sroberto 1690106424Sroberto return (0); 1691106424Sroberto} 1692106424Sroberto 1693106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 1694106424Sroberto/* 1695106424Sroberto * Parse any packet using Trimble machinery 1696106424Sroberto */ 1697285612Sdelphijint 1698285612Sdelphijparseany( 1699285612Sdelphij TSIPPKT *rpt, 1700285612Sdelphij struct peer *peer 1701285612Sdelphij ) 1702106424Sroberto{ 1703106424Sroberto static char logbuf[1024]; /* logging string buffer */ 1704106424Sroberto 1705106424Sroberto TranslateTSIPReportToText (rpt, logbuf); /* anything else */ 1706106424Sroberto#ifdef DEBUG_NCC 1707106424Sroberto if (debug) 1708106424Sroberto puts(&logbuf[1]); 1709106424Sroberto#endif /* DEBUG_NCC */ 1710106424Sroberto record_clock_stats(&peer->srcadr, &logbuf[1]); 1711106424Sroberto return(0); 1712106424Sroberto} 1713106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 1714106424Sroberto 1715106424Sroberto 1716106424Sroberto/* 1717106424Sroberto * Parse UTC Parameter Packet 1718106424Sroberto * 1719106424Sroberto * See the IDE for documentation! 1720106424Sroberto * 1721106424Sroberto * 0 = success 1722106424Sroberto * -1 = errors 1723106424Sroberto */ 1724106424Sroberto 1725285612Sdelphijint 1726285612Sdelphijparse0x4F( 1727285612Sdelphij TSIPPKT *rpt, 1728285612Sdelphij struct peer *peer 1729285612Sdelphij ) 1730106424Sroberto{ 1731106424Sroberto register struct ripencc_unit *up; 1732106424Sroberto 1733106424Sroberto double a0; 1734106424Sroberto float a1, tot; 1735106424Sroberto int dt_ls, wn_t, wn_lsf, dn, dt_lsf; 1736106424Sroberto 1737106424Sroberto static char logbuf[1024]; /* logging string buffer */ 1738106424Sroberto unsigned char *buf; 1739106424Sroberto 1740106424Sroberto buf = rpt->buf; 1741106424Sroberto 1742106424Sroberto if (rpt->len != 26) 1743106424Sroberto return (-1); 1744106424Sroberto a0 = bGetDouble (buf); 1745106424Sroberto a1 = bGetSingle (&buf[8]); 1746106424Sroberto dt_ls = bGetShort (&buf[12]); 1747106424Sroberto tot = bGetSingle (&buf[14]); 1748106424Sroberto wn_t = bGetShort (&buf[18]); 1749106424Sroberto wn_lsf = bGetShort (&buf[20]); 1750106424Sroberto dn = bGetShort (&buf[22]); 1751106424Sroberto dt_lsf = bGetShort (&buf[24]); 1752106424Sroberto 1753106424Sroberto sprintf(logbuf, "L1 %d %d %d %g %g %g %d %d %d", 1754106424Sroberto dt_lsf - dt_ls, dt_ls, dt_lsf, a0, a1, tot, wn_t, wn_lsf, dn); 1755106424Sroberto 1756106424Sroberto#ifdef DEBUG_NCC 1757106424Sroberto if (debug) 1758106424Sroberto puts(logbuf); 1759106424Sroberto#endif /* DEBUG_NCC */ 1760106424Sroberto 1761106424Sroberto record_clock_stats(&peer->srcadr, logbuf); 1762106424Sroberto 1763106424Sroberto up = (struct ripencc_unit *) peer->procptr->unitptr; 1764106424Sroberto up->leapdelta = dt_lsf - dt_ls; 1765106424Sroberto 1766106424Sroberto return (0); 1767106424Sroberto} 1768106424Sroberto 1769106424Sroberto/* 1770106424Sroberto * Parse Tracking Status packet 1771106424Sroberto * 1772106424Sroberto * 0 = success 1773106424Sroberto * -1 = errors 1774106424Sroberto */ 1775106424Sroberto 1776285612Sdelphijint 1777285612Sdelphijparse0x5C( 1778285612Sdelphij TSIPPKT *rpt, 1779285612Sdelphij struct peer *peer 1780285612Sdelphij ) 1781106424Sroberto{ 1782106424Sroberto unsigned char prn, channel, aqflag, ephstat; 1783106424Sroberto float snr, azinuth, elevation; 1784106424Sroberto 1785106424Sroberto static char logbuf[1024]; /* logging string buffer */ 1786106424Sroberto unsigned char *buf; 1787106424Sroberto 1788106424Sroberto buf = rpt->buf; 1789106424Sroberto 1790106424Sroberto if (rpt->len != 24) 1791106424Sroberto return(-1); 1792106424Sroberto 1793106424Sroberto prn = buf[0]; 1794106424Sroberto channel = (unsigned char)(buf[1] >> 3); 1795106424Sroberto if (channel == 0x10) 1796106424Sroberto channel = 2; 1797106424Sroberto else 1798106424Sroberto channel++; 1799106424Sroberto aqflag = buf[2]; 1800106424Sroberto ephstat = buf[3]; 1801106424Sroberto snr = bGetSingle(&buf[4]); 1802106424Sroberto elevation = bGetSingle(&buf[12]) * R2D; 1803106424Sroberto azinuth = bGetSingle(&buf[16]) * R2D; 1804106424Sroberto 1805106424Sroberto sprintf(logbuf, "S1 %02d %d %d %02x %4.1f %5.1f %4.1f", 1806106424Sroberto prn, channel, aqflag, ephstat, snr, azinuth, elevation); 1807106424Sroberto 1808106424Sroberto#ifdef DEBUG_NCC 1809106424Sroberto if (debug) 1810106424Sroberto puts(logbuf); 1811106424Sroberto#endif /* DEBUG_NCC */ 1812106424Sroberto 1813106424Sroberto record_clock_stats(&peer->srcadr, logbuf); 1814106424Sroberto 1815106424Sroberto return (0); 1816106424Sroberto} 1817106424Sroberto 1818106424Sroberto/******* Code below is from Trimble Tsipchat *************/ 1819106424Sroberto 1820106424Sroberto/* 1821106424Sroberto * ************************************************************************* 1822106424Sroberto * 1823106424Sroberto * Trimble Navigation, Ltd. 1824106424Sroberto * OEM Products Development Group 1825106424Sroberto * P.O. Box 3642 1826106424Sroberto * 645 North Mary Avenue 1827106424Sroberto * Sunnyvale, California 94088-3642 1828106424Sroberto * 1829106424Sroberto * Corporate Headquarter: 1830106424Sroberto * Telephone: (408) 481-8000 1831106424Sroberto * Fax: (408) 481-6005 1832106424Sroberto * 1833106424Sroberto * Technical Support Center: 1834106424Sroberto * Telephone: (800) 767-4822 (U.S. and Canada) 1835106424Sroberto * (408) 481-6940 (outside U.S. and Canada) 1836106424Sroberto * Fax: (408) 481-6020 1837106424Sroberto * BBS: (408) 481-7800 1838106424Sroberto * e-mail: trimble_support@trimble.com 1839106424Sroberto * ftp://ftp.trimble.com/pub/sct/embedded/bin 1840106424Sroberto * 1841106424Sroberto * ************************************************************************* 1842106424Sroberto * 1843106424Sroberto * ------- BYTE-SWAPPING ------- 1844106424Sroberto * TSIP is big-endian (Motorola) protocol. To use on little-endian (Intel) 1845106424Sroberto * systems, the bytes of all multi-byte types (shorts, floats, doubles, etc.) 1846106424Sroberto * must be reversed. This is controlled by the MACRO BYTESWAP; if defined, it 1847106424Sroberto * assumes little-endian protocol. 1848106424Sroberto * -------------------------------- 1849106424Sroberto * 1850106424Sroberto * T_PARSER.C and T_PARSER.H contains primitive functions that interpret 1851106424Sroberto * reports received from the receiver. A second source file pair, 1852106424Sroberto * T_FORMAT.C and T_FORMAT.H, contin the matching TSIP command formatters. 1853106424Sroberto * 1854106424Sroberto * The module is in very portable, basic C language. It can be used as is, or 1855106424Sroberto * with minimal changes if a TSIP communications application is needed separate 1856106424Sroberto * from TSIPCHAT. The construction of most argument lists avoid the use of 1857106424Sroberto * structures, but the developer is encouraged to reconstruct them using such 1858106424Sroberto * definitions to meet project requirements. Declarations of T_PARSER.C 1859106424Sroberto * functions are included in T_PARSER.H to provide prototyping definitions. 1860106424Sroberto * 1861106424Sroberto * There are two types of functions: a serial input processing routine, 1862106424Sroberto * tsip_input_proc() 1863106424Sroberto * which assembles incoming bytes into a TSIPPKT structure, and the 1864106424Sroberto * report parsers, rpt_0x??(). 1865106424Sroberto * 1866106424Sroberto * 1) The function tsip_input_proc() accumulates bytes from the receiver, 1867106424Sroberto * strips control bytes (DLE), and checks if the report end sequence (DLE ETX) 1868106424Sroberto * has been received. rpt.status is defined as TSIP_PARSED_FULL (== 1) 1869106424Sroberto * if a complete packet is available. 1870106424Sroberto * 1871106424Sroberto * 2) The functions rpt_0x??() are report string interpreters patterned after 1872106424Sroberto * the document called "Trimble Standard Interface Protocol". It should be 1873106424Sroberto * noted that if the report buffer is sent into the receiver with the wrong 1874106424Sroberto * length (byte count), the rpt_0x??() returns the Boolean equivalence for 1875106424Sroberto * TRUE. 1876106424Sroberto * 1877106424Sroberto * ************************************************************************* 1878106424Sroberto * 1879106424Sroberto */ 1880106424Sroberto 1881106424Sroberto 1882285612Sdelphij/* 1883285612Sdelphij * reads bytes until serial buffer is empty or a complete report 1884106424Sroberto * has been received; end of report is signified by DLE ETX. 1885106424Sroberto */ 1886285612Sdelphijstatic void 1887285612Sdelphijtsip_input_proc( 1888285612Sdelphij TSIPPKT *rpt, 1889285612Sdelphij int inbyte 1890285612Sdelphij ) 1891106424Sroberto{ 1892106424Sroberto unsigned char newbyte; 1893106424Sroberto 1894106424Sroberto if (inbyte < 0 || inbyte > 0xFF) return; 1895106424Sroberto 1896106424Sroberto newbyte = (unsigned char)(inbyte); 1897106424Sroberto switch (rpt->status) 1898106424Sroberto { 1899285612Sdelphij case TSIP_PARSED_DLE_1: 1900106424Sroberto switch (newbyte) 1901106424Sroberto { 1902285612Sdelphij case 0: 1903285612Sdelphij case ETX: 1904285612Sdelphij /* illegal TSIP IDs */ 1905285612Sdelphij rpt->len = 0; 1906106424Sroberto rpt->status = TSIP_PARSED_EMPTY; 1907106424Sroberto break; 1908285612Sdelphij case DLE: 1909285612Sdelphij /* try normal message start again */ 1910106424Sroberto rpt->len = 0; 1911106424Sroberto rpt->status = TSIP_PARSED_DLE_1; 1912106424Sroberto break; 1913285612Sdelphij default: 1914285612Sdelphij /* legal TSIP ID; start message */ 1915106424Sroberto rpt->code = newbyte; 1916285612Sdelphij rpt->len = 0; 1917106424Sroberto rpt->status = TSIP_PARSED_DATA; 1918106424Sroberto break; 1919106424Sroberto } 1920106424Sroberto break; 1921285612Sdelphij case TSIP_PARSED_DATA: 1922106424Sroberto switch (newbyte) { 1923285612Sdelphij case DLE: 1924285612Sdelphij /* expect DLE or ETX next */ 1925106424Sroberto rpt->status = TSIP_PARSED_DLE_2; 1926106424Sroberto break; 1927285612Sdelphij default: 1928285612Sdelphij /* normal data byte */ 1929106424Sroberto rpt->buf[rpt->len] = newbyte; 1930106424Sroberto rpt->len++; 1931285612Sdelphij /* no change in rpt->status */ 1932106424Sroberto break; 1933106424Sroberto } 1934106424Sroberto break; 1935285612Sdelphij case TSIP_PARSED_DLE_2: 1936106424Sroberto switch (newbyte) { 1937285612Sdelphij case DLE: 1938285612Sdelphij /* normal data byte */ 1939106424Sroberto rpt->buf[rpt->len] = newbyte; 1940106424Sroberto rpt->len++; 1941106424Sroberto rpt->status = TSIP_PARSED_DATA; 1942106424Sroberto break; 1943285612Sdelphij case ETX: 1944106424Sroberto /* end of message; return TRUE here. */ 1945106424Sroberto rpt->status = TSIP_PARSED_FULL; 1946106424Sroberto break; 1947285612Sdelphij default: 1948106424Sroberto /* error: treat as TSIP_PARSED_DLE_1; start new report packet */ 1949106424Sroberto rpt->code = newbyte; 1950285612Sdelphij rpt->len = 0; 1951106424Sroberto rpt->status = TSIP_PARSED_DATA; 1952106424Sroberto } 1953106424Sroberto break; 1954285612Sdelphij case TSIP_PARSED_FULL: 1955285612Sdelphij case TSIP_PARSED_EMPTY: 1956285612Sdelphij default: 1957106424Sroberto switch (newbyte) { 1958285612Sdelphij case DLE: 1959285612Sdelphij /* normal message start */ 1960106424Sroberto rpt->len = 0; 1961106424Sroberto rpt->status = TSIP_PARSED_DLE_1; 1962106424Sroberto break; 1963285612Sdelphij default: 1964106424Sroberto /* error: ignore newbyte */ 1965106424Sroberto rpt->len = 0; 1966106424Sroberto rpt->status = TSIP_PARSED_EMPTY; 1967106424Sroberto } 1968106424Sroberto break; 1969106424Sroberto } 1970106424Sroberto if (rpt->len > MAX_RPTBUF) { 1971106424Sroberto /* error: start new report packet */ 1972106424Sroberto rpt->status = TSIP_PARSED_EMPTY; 1973106424Sroberto rpt->len = 0; 1974106424Sroberto } 1975106424Sroberto} 1976106424Sroberto 1977106424Sroberto#ifdef TRIMBLE_OUTPUT_FUNC 1978106424Sroberto 1979106424Sroberto/**/ 1980106424Sroberto/* Channel A configuration for dual port operation */ 1981285612Sdelphijshort 1982285612Sdelphijrpt_0x3D( 1983285612Sdelphij TSIPPKT *rpt, 1984285612Sdelphij unsigned char *tx_baud_index, 1985285612Sdelphij unsigned char *rx_baud_index, 1986285612Sdelphij unsigned char *char_format_index, 1987285612Sdelphij unsigned char *stop_bits, 1988285612Sdelphij unsigned char *tx_mode_index, 1989285612Sdelphij unsigned char *rx_mode_index 1990285612Sdelphij ) 1991106424Sroberto{ 1992106424Sroberto unsigned char *buf; 1993106424Sroberto buf = rpt->buf; 1994106424Sroberto 1995106424Sroberto if (rpt->len != 6) return TRUE; 1996106424Sroberto *tx_baud_index = buf[0]; 1997106424Sroberto *rx_baud_index = buf[1]; 1998106424Sroberto *char_format_index = buf[2]; 1999106424Sroberto *stop_bits = (unsigned char)((buf[3] == 0x07) ? 1 : 2); 2000106424Sroberto *tx_mode_index = buf[4]; 2001106424Sroberto *rx_mode_index = buf[5]; 2002106424Sroberto return FALSE; 2003106424Sroberto} 2004106424Sroberto 2005106424Sroberto/**/ 2006106424Sroberto/* almanac data for specified satellite */ 2007285612Sdelphijshort 2008285612Sdelphijrpt_0x40( 2009285612Sdelphij TSIPPKT *rpt, 2010285612Sdelphij unsigned char *sv_prn, 2011285612Sdelphij short *week_num, 2012285612Sdelphij float *t_zc, 2013285612Sdelphij float *eccentricity, 2014285612Sdelphij float *t_oa, 2015285612Sdelphij float *i_0, 2016285612Sdelphij float *OMEGA_dot, 2017285612Sdelphij float *sqrt_A, 2018285612Sdelphij float *OMEGA_0, 2019285612Sdelphij float *omega, 2020285612Sdelphij float *M_0 2021285612Sdelphij ) 2022106424Sroberto{ 2023106424Sroberto unsigned char *buf; 2024106424Sroberto buf = rpt->buf; 2025106424Sroberto 2026106424Sroberto if (rpt->len != 39) return TRUE; 2027106424Sroberto *sv_prn = buf[0]; 2028106424Sroberto *t_zc = bGetSingle (&buf[1]); 2029106424Sroberto *week_num = bGetShort (&buf[5]); 2030106424Sroberto *eccentricity = bGetSingle (&buf[7]); 2031106424Sroberto *t_oa = bGetSingle (&buf[11]); 2032106424Sroberto *i_0 = bGetSingle (&buf[15]); 2033106424Sroberto *OMEGA_dot = bGetSingle (&buf[19]); 2034106424Sroberto *sqrt_A = bGetSingle (&buf[23]); 2035106424Sroberto *OMEGA_0 = bGetSingle (&buf[27]); 2036106424Sroberto *omega = bGetSingle (&buf[31]); 2037106424Sroberto *M_0 = bGetSingle (&buf[35]); 2038106424Sroberto return FALSE; 2039106424Sroberto} 2040106424Sroberto 2041106424Sroberto/* GPS time */ 2042285612Sdelphijshort 2043285612Sdelphijrpt_0x41( 2044285612Sdelphij TSIPPKT *rpt, 2045285612Sdelphij float *time_of_week, 2046285612Sdelphij float *UTC_offset, 2047285612Sdelphij short *week_num 2048285612Sdelphij ) 2049106424Sroberto{ 2050106424Sroberto unsigned char *buf; 2051106424Sroberto buf = rpt->buf; 2052106424Sroberto 2053106424Sroberto if (rpt->len != 10) return TRUE; 2054106424Sroberto *time_of_week = bGetSingle (buf); 2055106424Sroberto *week_num = bGetShort (&buf[4]); 2056106424Sroberto *UTC_offset = bGetSingle (&buf[6]); 2057106424Sroberto return FALSE; 2058106424Sroberto} 2059106424Sroberto 2060106424Sroberto/* position in ECEF, single precision */ 2061285612Sdelphijshort 2062285612Sdelphijrpt_0x42( 2063285612Sdelphij TSIPPKT *rpt, 2064285612Sdelphij float pos_ECEF[3], 2065285612Sdelphij float *time_of_fix 2066285612Sdelphij ) 2067106424Sroberto{ 2068106424Sroberto unsigned char *buf; 2069106424Sroberto buf = rpt->buf; 2070106424Sroberto 2071106424Sroberto if (rpt->len != 16) return TRUE; 2072106424Sroberto pos_ECEF[0] = bGetSingle (buf); 2073106424Sroberto pos_ECEF[1]= bGetSingle (&buf[4]); 2074106424Sroberto pos_ECEF[2]= bGetSingle (&buf[8]); 2075106424Sroberto *time_of_fix = bGetSingle (&buf[12]); 2076106424Sroberto return FALSE; 2077106424Sroberto} 2078106424Sroberto 2079106424Sroberto/* velocity in ECEF, single precision */ 2080285612Sdelphijshort 2081285612Sdelphijrpt_0x43( 2082285612Sdelphij TSIPPKT *rpt, 2083285612Sdelphij float ECEF_vel[3], 2084285612Sdelphij float *freq_offset, 2085285612Sdelphij float *time_of_fix 2086285612Sdelphij ) 2087106424Sroberto{ 2088106424Sroberto unsigned char *buf; 2089106424Sroberto buf = rpt->buf; 2090106424Sroberto 2091106424Sroberto if (rpt->len != 20) return TRUE; 2092106424Sroberto ECEF_vel[0] = bGetSingle (buf); 2093106424Sroberto ECEF_vel[1] = bGetSingle (&buf[4]); 2094106424Sroberto ECEF_vel[2] = bGetSingle (&buf[8]); 2095106424Sroberto *freq_offset = bGetSingle (&buf[12]); 2096106424Sroberto *time_of_fix = bGetSingle (&buf[16]); 2097106424Sroberto return FALSE; 2098106424Sroberto} 2099106424Sroberto 2100106424Sroberto/* software versions */ 2101285612Sdelphijshort 2102285612Sdelphijrpt_0x45( 2103285612Sdelphij TSIPPKT *rpt, 2104285612Sdelphij unsigned char *major_nav_version, 2105285612Sdelphij unsigned char *minor_nav_version, 2106285612Sdelphij unsigned char *nav_day, 2107285612Sdelphij unsigned char *nav_month, 2108285612Sdelphij unsigned char *nav_year, 2109285612Sdelphij unsigned char *major_dsp_version, 2110285612Sdelphij unsigned char *minor_dsp_version, 2111285612Sdelphij unsigned char *dsp_day, 2112285612Sdelphij unsigned char *dsp_month, 2113285612Sdelphij unsigned char *dsp_year 2114285612Sdelphij ) 2115106424Sroberto{ 2116106424Sroberto unsigned char *buf; 2117106424Sroberto buf = rpt->buf; 2118106424Sroberto 2119106424Sroberto if (rpt->len != 10) return TRUE; 2120106424Sroberto *major_nav_version = buf[0]; 2121106424Sroberto *minor_nav_version = buf[1]; 2122106424Sroberto *nav_day = buf[2]; 2123106424Sroberto *nav_month = buf[3]; 2124106424Sroberto *nav_year = buf[4]; 2125106424Sroberto *major_dsp_version = buf[5]; 2126106424Sroberto *minor_dsp_version = buf[6]; 2127106424Sroberto *dsp_day = buf[7]; 2128106424Sroberto *dsp_month = buf[8]; 2129106424Sroberto *dsp_year = buf[9]; 2130106424Sroberto return FALSE; 2131106424Sroberto} 2132106424Sroberto 2133106424Sroberto/* receiver health and status */ 2134285612Sdelphijshort 2135285612Sdelphijrpt_0x46( 2136285612Sdelphij TSIPPKT *rpt, 2137285612Sdelphij unsigned char *status1, 2138285612Sdelphij unsigned char *status2 2139285612Sdelphij ) 2140106424Sroberto{ 2141106424Sroberto unsigned char *buf; 2142106424Sroberto buf = rpt->buf; 2143106424Sroberto 2144106424Sroberto if (rpt->len != 2) return TRUE; 2145106424Sroberto *status1 = buf[0]; 2146106424Sroberto *status2 = buf[1]; 2147106424Sroberto return FALSE; 2148106424Sroberto} 2149106424Sroberto 2150106424Sroberto/* signal levels for all satellites tracked */ 2151285612Sdelphijshort 2152285612Sdelphijrpt_0x47( 2153285612Sdelphij TSIPPKT *rpt, 2154285612Sdelphij unsigned char *nsvs, 2155285612Sdelphij unsigned char *sv_prn, 2156285612Sdelphij float *snr 2157285612Sdelphij ) 2158106424Sroberto{ 2159106424Sroberto short isv; 2160106424Sroberto unsigned char *buf; 2161106424Sroberto buf = rpt->buf; 2162106424Sroberto 2163106424Sroberto if (rpt->len != 1 + 5*buf[0]) return TRUE; 2164106424Sroberto *nsvs = buf[0]; 2165106424Sroberto for (isv = 0; isv < (*nsvs); isv++) { 2166106424Sroberto sv_prn[isv] = buf[5*isv + 1]; 2167106424Sroberto snr[isv] = bGetSingle (&buf[5*isv + 2]); 2168106424Sroberto } 2169106424Sroberto return FALSE; 2170106424Sroberto} 2171106424Sroberto 2172106424Sroberto/* GPS system message */ 2173285612Sdelphijshort 2174285612Sdelphijrpt_0x48( 2175285612Sdelphij TSIPPKT *rpt, 2176285612Sdelphij unsigned char *message 2177285612Sdelphij ) 2178106424Sroberto{ 2179106424Sroberto unsigned char *buf; 2180106424Sroberto buf = rpt->buf; 2181106424Sroberto 2182106424Sroberto if (rpt->len != 22) return TRUE; 2183106424Sroberto memcpy (message, buf, 22); 2184106424Sroberto message[22] = 0; 2185106424Sroberto return FALSE; 2186106424Sroberto} 2187106424Sroberto 2188106424Sroberto/* health for all satellites from almanac health page */ 2189285612Sdelphijshort 2190285612Sdelphijrpt_0x49( 2191285612Sdelphij TSIPPKT *rpt, 2192285612Sdelphij unsigned char *sv_health 2193285612Sdelphij ) 2194106424Sroberto{ 2195106424Sroberto short i; 2196106424Sroberto unsigned char *buf; 2197106424Sroberto buf = rpt->buf; 2198106424Sroberto 2199106424Sroberto if (rpt->len != 32) return TRUE; 2200106424Sroberto for (i = 0; i < 32; i++) sv_health [i]= buf[i]; 2201106424Sroberto return FALSE; 2202106424Sroberto} 2203106424Sroberto 2204106424Sroberto/* position in lat-lon-alt, single precision */ 2205285612Sdelphijshort 2206285612Sdelphijrpt_0x4A( 2207285612Sdelphij TSIPPKT *rpt, 2208285612Sdelphij float *lat, 2209285612Sdelphij float *lon, 2210285612Sdelphij float *alt, 2211285612Sdelphij float *clock_bias, 2212285612Sdelphij float *time_of_fix 2213285612Sdelphij ) 2214106424Sroberto{ 2215106424Sroberto unsigned char *buf; 2216106424Sroberto buf = rpt->buf; 2217106424Sroberto 2218106424Sroberto if (rpt->len != 20) return TRUE; 2219106424Sroberto *lat = bGetSingle (buf); 2220106424Sroberto *lon = bGetSingle (&buf[4]); 2221106424Sroberto *alt = bGetSingle (&buf[8]); 2222106424Sroberto *clock_bias = bGetSingle (&buf[12]); 2223106424Sroberto *time_of_fix = bGetSingle (&buf[16]); 2224106424Sroberto return FALSE; 2225106424Sroberto} 2226106424Sroberto 2227106424Sroberto/* reference altitude parameters */ 2228285612Sdelphijshort 2229285612Sdelphijrpt_0x4A_2( 2230285612Sdelphij TSIPPKT *rpt, 2231285612Sdelphij float *alt, 2232285612Sdelphij float *dummy, 2233285612Sdelphij unsigned char *alt_flag 2234285612Sdelphij ) 2235106424Sroberto{ 2236106424Sroberto unsigned char *buf; 2237106424Sroberto 2238106424Sroberto buf = rpt->buf; 2239106424Sroberto 2240106424Sroberto if (rpt->len != 9) return TRUE; 2241106424Sroberto *alt = bGetSingle (buf); 2242106424Sroberto *dummy = bGetSingle (&buf[4]); 2243106424Sroberto *alt_flag = buf[8]; 2244106424Sroberto return FALSE; 2245106424Sroberto} 2246106424Sroberto 2247106424Sroberto/* machine ID code, status */ 2248285612Sdelphijshort 2249285612Sdelphijrpt_0x4B( 2250285612Sdelphij TSIPPKT *rpt, 2251285612Sdelphij unsigned char *machine_id, 2252285612Sdelphij unsigned char *status3, 2253285612Sdelphij unsigned char *status4 2254285612Sdelphij ) 2255106424Sroberto{ 2256106424Sroberto unsigned char *buf; 2257106424Sroberto buf = rpt->buf; 2258106424Sroberto 2259106424Sroberto if (rpt->len != 3) return TRUE; 2260106424Sroberto *machine_id = buf[0]; 2261106424Sroberto *status3 = buf[1]; 2262106424Sroberto *status4 = buf[2]; 2263106424Sroberto return FALSE; 2264106424Sroberto} 2265106424Sroberto 2266106424Sroberto/* operating parameters and masks */ 2267285612Sdelphijshort 2268285612Sdelphijrpt_0x4C( 2269285612Sdelphij TSIPPKT *rpt, 2270285612Sdelphij unsigned char *dyn_code, 2271285612Sdelphij float *el_mask, 2272285612Sdelphij float *snr_mask, 2273285612Sdelphij float *dop_mask, 2274285612Sdelphij float *dop_switch 2275285612Sdelphij ) 2276106424Sroberto{ 2277106424Sroberto unsigned char *buf; 2278106424Sroberto buf = rpt->buf; 2279106424Sroberto 2280106424Sroberto if (rpt->len != 17) return TRUE; 2281106424Sroberto *dyn_code = buf[0]; 2282106424Sroberto *el_mask = bGetSingle (&buf[1]); 2283106424Sroberto *snr_mask = bGetSingle (&buf[5]); 2284106424Sroberto *dop_mask = bGetSingle (&buf[9]); 2285106424Sroberto *dop_switch = bGetSingle (&buf[13]); 2286106424Sroberto return FALSE; 2287106424Sroberto} 2288106424Sroberto 2289106424Sroberto/* oscillator offset */ 2290285612Sdelphijshort 2291285612Sdelphijrpt_0x4D( 2292285612Sdelphij TSIPPKT *rpt, 2293285612Sdelphij float *osc_offset 2294285612Sdelphij ) 2295106424Sroberto{ 2296106424Sroberto unsigned char *buf; 2297106424Sroberto buf = rpt->buf; 2298106424Sroberto 2299106424Sroberto if (rpt->len != 4) return TRUE; 2300106424Sroberto *osc_offset = bGetSingle (buf); 2301106424Sroberto return FALSE; 2302106424Sroberto} 2303106424Sroberto 2304106424Sroberto/* yes/no response to command to set GPS time */ 2305285612Sdelphijshort 2306285612Sdelphijrpt_0x4E( 2307285612Sdelphij TSIPPKT *rpt, 2308285612Sdelphij unsigned char *response 2309285612Sdelphij ) 2310106424Sroberto{ 2311106424Sroberto unsigned char *buf; 2312106424Sroberto buf = rpt->buf; 2313106424Sroberto 2314106424Sroberto if (rpt->len != 1) return TRUE; 2315106424Sroberto *response = buf[0]; 2316106424Sroberto return FALSE; 2317106424Sroberto} 2318106424Sroberto 2319106424Sroberto/* UTC data */ 2320285612Sdelphijshort 2321285612Sdelphijrpt_0x4F( 2322285612Sdelphij TSIPPKT *rpt, 2323285612Sdelphij double *a0, 2324285612Sdelphij float *a1, 2325285612Sdelphij float *time_of_data, 2326285612Sdelphij short *dt_ls, 2327285612Sdelphij short *wn_t, 2328285612Sdelphij short *wn_lsf, 2329285612Sdelphij short *dn, 2330285612Sdelphij short *dt_lsf 2331285612Sdelphij ) 2332106424Sroberto{ 2333106424Sroberto unsigned char *buf; 2334106424Sroberto buf = rpt->buf; 2335106424Sroberto 2336106424Sroberto if (rpt->len != 26) return TRUE; 2337106424Sroberto *a0 = bGetDouble (buf); 2338106424Sroberto *a1 = bGetSingle (&buf[8]); 2339106424Sroberto *dt_ls = bGetShort (&buf[12]); 2340106424Sroberto *time_of_data = bGetSingle (&buf[14]); 2341106424Sroberto *wn_t = bGetShort (&buf[18]); 2342106424Sroberto *wn_lsf = bGetShort (&buf[20]); 2343106424Sroberto *dn = bGetShort (&buf[22]); 2344106424Sroberto *dt_lsf = bGetShort (&buf[24]); 2345106424Sroberto return FALSE; 2346106424Sroberto} 2347106424Sroberto 2348106424Sroberto/**/ 2349106424Sroberto/* clock offset and frequency offset in 1-SV (0-D) mode */ 2350285612Sdelphijshort 2351285612Sdelphijrpt_0x54( 2352285612Sdelphij TSIPPKT *rpt, 2353285612Sdelphij float *clock_bias, 2354285612Sdelphij float *freq_offset, 2355285612Sdelphij float *time_of_fix 2356285612Sdelphij ) 2357106424Sroberto{ 2358106424Sroberto unsigned char *buf; 2359106424Sroberto buf = rpt->buf; 2360106424Sroberto 2361106424Sroberto if (rpt->len != 12) return TRUE; 2362106424Sroberto *clock_bias = bGetSingle (buf); 2363106424Sroberto *freq_offset = bGetSingle (&buf[4]); 2364106424Sroberto *time_of_fix = bGetSingle (&buf[8]); 2365106424Sroberto return FALSE; 2366106424Sroberto} 2367106424Sroberto 2368106424Sroberto/* I/O serial options */ 2369285612Sdelphijshort 2370285612Sdelphijrpt_0x55( 2371285612Sdelphij TSIPPKT *rpt, 2372285612Sdelphij unsigned char *pos_code, 2373285612Sdelphij unsigned char *vel_code, 2374285612Sdelphij unsigned char *time_code, 2375285612Sdelphij unsigned char *aux_code 2376285612Sdelphij ) 2377106424Sroberto{ 2378106424Sroberto unsigned char *buf; 2379106424Sroberto buf = rpt->buf; 2380106424Sroberto 2381106424Sroberto if (rpt->len != 4) return TRUE; 2382106424Sroberto *pos_code = buf[0]; 2383106424Sroberto *vel_code = buf[1]; 2384106424Sroberto *time_code = buf[2]; 2385106424Sroberto *aux_code = buf[3]; 2386106424Sroberto return FALSE; 2387106424Sroberto} 2388106424Sroberto 2389106424Sroberto/* velocity in east-north-up coordinates */ 2390285612Sdelphijshort 2391285612Sdelphijrpt_0x56( 2392285612Sdelphij TSIPPKT *rpt, 2393285612Sdelphij float vel_ENU[3], 2394285612Sdelphij float *freq_offset, 2395285612Sdelphij float *time_of_fix 2396285612Sdelphij ) 2397106424Sroberto{ 2398106424Sroberto unsigned char *buf; 2399106424Sroberto buf = rpt->buf; 2400106424Sroberto 2401106424Sroberto if (rpt->len != 20) return TRUE; 2402106424Sroberto /* east */ 2403106424Sroberto vel_ENU[0] = bGetSingle (buf); 2404106424Sroberto /* north */ 2405106424Sroberto vel_ENU[1] = bGetSingle (&buf[4]); 2406106424Sroberto /* up */ 2407106424Sroberto vel_ENU[2] = bGetSingle (&buf[8]); 2408106424Sroberto *freq_offset = bGetSingle (&buf[12]); 2409106424Sroberto *time_of_fix = bGetSingle (&buf[16]); 2410106424Sroberto return FALSE; 2411106424Sroberto} 2412106424Sroberto 2413106424Sroberto/* info about last computed fix */ 2414285612Sdelphijshort 2415285612Sdelphijrpt_0x57( 2416285612Sdelphij TSIPPKT *rpt, 2417285612Sdelphij unsigned char *source_code, 2418285612Sdelphij unsigned char *diag_code, 2419285612Sdelphij short *week_num, 2420285612Sdelphij float *time_of_fix 2421285612Sdelphij ) 2422106424Sroberto{ 2423106424Sroberto unsigned char *buf; 2424106424Sroberto buf = rpt->buf; 2425106424Sroberto 2426106424Sroberto if (rpt->len != 8) return TRUE; 2427106424Sroberto *source_code = buf[0]; 2428106424Sroberto *diag_code = buf[1]; 2429106424Sroberto *time_of_fix = bGetSingle (&buf[2]); 2430106424Sroberto *week_num = bGetShort (&buf[6]); 2431106424Sroberto return FALSE; 2432106424Sroberto} 2433106424Sroberto 2434106424Sroberto/* GPS system data or acknowledgment of GPS system data load */ 2435285612Sdelphijshort 2436285612Sdelphijrpt_0x58( 2437285612Sdelphij TSIPPKT *rpt, 2438285612Sdelphij unsigned char *op_code, 2439285612Sdelphij unsigned char *data_type, 2440285612Sdelphij unsigned char *sv_prn, 2441285612Sdelphij unsigned char *data_length, 2442285612Sdelphij unsigned char *data_packet 2443285612Sdelphij ) 2444106424Sroberto{ 2445106424Sroberto unsigned char *buf, *buf4; 2446106424Sroberto short dl; 2447106424Sroberto ALM_INFO* alminfo; 2448106424Sroberto ION_INFO* ioninfo; 2449106424Sroberto UTC_INFO* utcinfo; 2450106424Sroberto NAV_INFO* navinfo; 2451106424Sroberto 2452106424Sroberto buf = rpt->buf; 2453106424Sroberto 2454106424Sroberto if (buf[0] == 2) { 2455106424Sroberto if (rpt->len < 4) return TRUE; 2456106424Sroberto if (rpt->len != 4+buf[3]) return TRUE; 2457106424Sroberto } 2458106424Sroberto else if (rpt->len != 3) { 2459106424Sroberto return TRUE; 2460106424Sroberto } 2461106424Sroberto *op_code = buf[0]; 2462106424Sroberto *data_type = buf[1]; 2463106424Sroberto *sv_prn = buf[2]; 2464106424Sroberto if (*op_code == 2) { 2465106424Sroberto dl = buf[3]; 2466106424Sroberto *data_length = (unsigned char)dl; 2467106424Sroberto buf4 = &buf[4]; 2468106424Sroberto switch (*data_type) { 2469285612Sdelphij case 2: 2470106424Sroberto /* Almanac */ 2471106424Sroberto if (*data_length != sizeof (ALM_INFO)) return TRUE; 2472106424Sroberto alminfo = (ALM_INFO*)data_packet; 2473106424Sroberto alminfo->t_oa_raw = buf4[0]; 2474106424Sroberto alminfo->SV_health = buf4[1]; 2475106424Sroberto alminfo->e = bGetSingle(&buf4[2]); 2476106424Sroberto alminfo->t_oa = bGetSingle(&buf4[6]); 2477106424Sroberto alminfo->i_0 = bGetSingle(&buf4[10]); 2478106424Sroberto alminfo->OMEGADOT = bGetSingle(&buf4[14]); 2479106424Sroberto alminfo->sqrt_A = bGetSingle(&buf4[18]); 2480106424Sroberto alminfo->OMEGA_0 = bGetSingle(&buf4[22]); 2481106424Sroberto alminfo->omega = bGetSingle(&buf4[26]); 2482106424Sroberto alminfo->M_0 = bGetSingle(&buf4[30]); 2483106424Sroberto alminfo->a_f0 = bGetSingle(&buf4[34]); 2484106424Sroberto alminfo->a_f1 = bGetSingle(&buf4[38]); 2485106424Sroberto alminfo->Axis = bGetSingle(&buf4[42]); 2486106424Sroberto alminfo->n = bGetSingle(&buf4[46]); 2487106424Sroberto alminfo->OMEGA_n = bGetSingle(&buf4[50]); 2488106424Sroberto alminfo->ODOT_n = bGetSingle(&buf4[54]); 2489106424Sroberto alminfo->t_zc = bGetSingle(&buf4[58]); 2490106424Sroberto alminfo->weeknum = bGetShort(&buf4[62]); 2491106424Sroberto alminfo->wn_oa = bGetShort(&buf4[64]); 2492106424Sroberto break; 2493106424Sroberto 2494285612Sdelphij case 3: 2495106424Sroberto /* Almanac health page */ 2496106424Sroberto if (*data_length != sizeof (ALH_PARMS) + 3) return TRUE; 2497106424Sroberto 2498106424Sroberto /* this record is returned raw */ 2499106424Sroberto memcpy (data_packet, buf4, dl); 2500106424Sroberto break; 2501106424Sroberto 2502285612Sdelphij case 4: 2503106424Sroberto /* Ionosphere */ 2504106424Sroberto if (*data_length != sizeof (ION_INFO) + 8) return TRUE; 2505106424Sroberto ioninfo = (ION_INFO*)data_packet; 2506106424Sroberto ioninfo->alpha_0 = bGetSingle (&buf4[8]); 2507106424Sroberto ioninfo->alpha_1 = bGetSingle (&buf4[12]); 2508106424Sroberto ioninfo->alpha_2 = bGetSingle (&buf4[16]); 2509106424Sroberto ioninfo->alpha_3 = bGetSingle (&buf4[20]); 2510106424Sroberto ioninfo->beta_0 = bGetSingle (&buf4[24]); 2511106424Sroberto ioninfo->beta_1 = bGetSingle (&buf4[28]); 2512106424Sroberto ioninfo->beta_2 = bGetSingle (&buf4[32]); 2513106424Sroberto ioninfo->beta_3 = bGetSingle (&buf4[36]); 2514106424Sroberto break; 2515106424Sroberto 2516285612Sdelphij case 5: 2517106424Sroberto /* UTC */ 2518106424Sroberto if (*data_length != sizeof (UTC_INFO) + 13) return TRUE; 2519106424Sroberto utcinfo = (UTC_INFO*)data_packet; 2520106424Sroberto utcinfo->A_0 = bGetDouble (&buf4[13]); 2521106424Sroberto utcinfo->A_1 = bGetSingle (&buf4[21]); 2522106424Sroberto utcinfo->delta_t_LS = bGetShort (&buf4[25]); 2523106424Sroberto utcinfo->t_ot = bGetSingle(&buf4[27]); 2524106424Sroberto utcinfo->WN_t = bGetShort (&buf4[31]); 2525106424Sroberto utcinfo->WN_LSF = bGetShort (&buf4[33]); 2526106424Sroberto utcinfo->DN = bGetShort (&buf4[35]); 2527106424Sroberto utcinfo->delta_t_LSF = bGetShort (&buf4[37]); 2528106424Sroberto break; 2529106424Sroberto 2530285612Sdelphij case 6: 2531106424Sroberto /* Ephemeris */ 2532106424Sroberto if (*data_length != sizeof (NAV_INFO) - 1) return TRUE; 2533106424Sroberto 2534106424Sroberto navinfo = (NAV_INFO*)data_packet; 2535106424Sroberto 2536106424Sroberto navinfo->sv_number = buf4[0]; 2537106424Sroberto navinfo->t_ephem = bGetSingle (&buf4[1]); 2538106424Sroberto navinfo->ephclk.weeknum = bGetShort (&buf4[5]); 2539106424Sroberto 2540106424Sroberto navinfo->ephclk.codeL2 = buf4[7]; 2541106424Sroberto navinfo->ephclk.L2Pdata = buf4[8]; 2542106424Sroberto navinfo->ephclk.SVacc_raw = buf4[9]; 2543106424Sroberto navinfo->ephclk.SV_health = buf4[10]; 2544106424Sroberto navinfo->ephclk.IODC = bGetShort (&buf4[11]); 2545106424Sroberto navinfo->ephclk.T_GD = bGetSingle (&buf4[13]); 2546106424Sroberto navinfo->ephclk.t_oc = bGetSingle (&buf4[17]); 2547106424Sroberto navinfo->ephclk.a_f2 = bGetSingle (&buf4[21]); 2548106424Sroberto navinfo->ephclk.a_f1 = bGetSingle (&buf4[25]); 2549106424Sroberto navinfo->ephclk.a_f0 = bGetSingle (&buf4[29]); 2550106424Sroberto navinfo->ephclk.SVacc = bGetSingle (&buf4[33]); 2551106424Sroberto 2552106424Sroberto navinfo->ephorb.IODE = buf4[37]; 2553106424Sroberto navinfo->ephorb.fit_interval = buf4[38]; 2554106424Sroberto navinfo->ephorb.C_rs = bGetSingle (&buf4[39]); 2555106424Sroberto navinfo->ephorb.delta_n = bGetSingle (&buf4[43]); 2556106424Sroberto navinfo->ephorb.M_0 = bGetDouble (&buf4[47]); 2557106424Sroberto navinfo->ephorb.C_uc = bGetSingle (&buf4[55]); 2558106424Sroberto navinfo->ephorb.e = bGetDouble (&buf4[59]); 2559106424Sroberto navinfo->ephorb.C_us = bGetSingle (&buf4[67]); 2560106424Sroberto navinfo->ephorb.sqrt_A = bGetDouble (&buf4[71]); 2561106424Sroberto navinfo->ephorb.t_oe = bGetSingle (&buf4[79]); 2562106424Sroberto navinfo->ephorb.C_ic = bGetSingle (&buf4[83]); 2563106424Sroberto navinfo->ephorb.OMEGA_0 = bGetDouble (&buf4[87]); 2564106424Sroberto navinfo->ephorb.C_is = bGetSingle (&buf4[95]); 2565106424Sroberto navinfo->ephorb.i_0 = bGetDouble (&buf4[99]); 2566106424Sroberto navinfo->ephorb.C_rc = bGetSingle (&buf4[107]); 2567106424Sroberto navinfo->ephorb.omega = bGetDouble (&buf4[111]); 2568106424Sroberto navinfo->ephorb.OMEGADOT=bGetSingle (&buf4[119]); 2569106424Sroberto navinfo->ephorb.IDOT = bGetSingle (&buf4[123]); 2570106424Sroberto navinfo->ephorb.Axis = bGetDouble (&buf4[127]); 2571106424Sroberto navinfo->ephorb.n = bGetDouble (&buf4[135]); 2572106424Sroberto navinfo->ephorb.r1me2 = bGetDouble (&buf4[143]); 2573106424Sroberto navinfo->ephorb.OMEGA_n=bGetDouble (&buf4[151]); 2574106424Sroberto navinfo->ephorb.ODOT_n = bGetDouble (&buf4[159]); 2575106424Sroberto break; 2576106424Sroberto } 2577106424Sroberto } 2578106424Sroberto return FALSE; 2579106424Sroberto} 2580106424Sroberto 2581106424Sroberto/* satellite enable/disable or health heed/ignore list */ 2582285612Sdelphijshort 2583285612Sdelphijrpt_0x59( 2584285612Sdelphij TSIPPKT *rpt, 2585285612Sdelphij unsigned char *code_type, 2586285612Sdelphij unsigned char status_code[32] 2587285612Sdelphij ) 2588106424Sroberto{ 2589106424Sroberto short iprn; 2590106424Sroberto unsigned char *buf; 2591106424Sroberto buf = rpt->buf; 2592106424Sroberto 2593106424Sroberto if (rpt->len != 33) return TRUE; 2594106424Sroberto *code_type = buf[0]; 2595106424Sroberto for (iprn = 0; iprn < 32; iprn++) 2596106424Sroberto status_code[iprn] = buf[iprn + 1]; 2597106424Sroberto return FALSE; 2598106424Sroberto} 2599106424Sroberto 2600106424Sroberto/* raw measurement data - code phase/Doppler */ 2601285612Sdelphijshort 2602285612Sdelphijrpt_0x5A( 2603285612Sdelphij TSIPPKT *rpt, 2604285612Sdelphij unsigned char *sv_prn, 2605285612Sdelphij float *sample_length, 2606285612Sdelphij float *signal_level, 2607285612Sdelphij float *code_phase, 2608285612Sdelphij float *Doppler, 2609285612Sdelphij double *time_of_fix 2610285612Sdelphij ) 2611106424Sroberto{ 2612106424Sroberto unsigned char *buf; 2613106424Sroberto buf = rpt->buf; 2614106424Sroberto 2615106424Sroberto if (rpt->len != 25) return TRUE; 2616106424Sroberto *sv_prn = buf[0]; 2617106424Sroberto *sample_length = bGetSingle (&buf[1]); 2618106424Sroberto *signal_level = bGetSingle (&buf[5]); 2619106424Sroberto *code_phase = bGetSingle (&buf[9]); 2620106424Sroberto *Doppler = bGetSingle (&buf[13]); 2621106424Sroberto *time_of_fix = bGetDouble (&buf[17]); 2622106424Sroberto return FALSE; 2623106424Sroberto} 2624106424Sroberto 2625106424Sroberto/* satellite ephorb status */ 2626285612Sdelphijshort 2627285612Sdelphijrpt_0x5B( 2628285612Sdelphij TSIPPKT *rpt, 2629285612Sdelphij unsigned char *sv_prn, 2630285612Sdelphij unsigned char *sv_health, 2631285612Sdelphij unsigned char *sv_iode, 2632285612Sdelphij unsigned char *fit_interval_flag, 2633285612Sdelphij float *time_of_collection, 2634285612Sdelphij float *time_of_eph, 2635285612Sdelphij float *sv_accy 2636285612Sdelphij ) 2637106424Sroberto{ 2638106424Sroberto unsigned char *buf; 2639106424Sroberto buf = rpt->buf; 2640106424Sroberto 2641106424Sroberto if (rpt->len != 16) return TRUE; 2642106424Sroberto *sv_prn = buf[0]; 2643106424Sroberto *time_of_collection = bGetSingle (&buf[1]); 2644106424Sroberto *sv_health = buf[5]; 2645106424Sroberto *sv_iode = buf[6]; 2646106424Sroberto *time_of_eph = bGetSingle (&buf[7]); 2647106424Sroberto *fit_interval_flag = buf[11]; 2648106424Sroberto *sv_accy = bGetSingle (&buf[12]); 2649106424Sroberto return FALSE; 2650106424Sroberto} 2651106424Sroberto 2652106424Sroberto/* satellite tracking status */ 2653285612Sdelphijshort 2654285612Sdelphijrpt_0x5C( 2655285612Sdelphij TSIPPKT *rpt, 2656285612Sdelphij unsigned char *sv_prn, 2657285612Sdelphij unsigned char *slot, 2658285612Sdelphij unsigned char *chan, 2659285612Sdelphij unsigned char *acq_flag, 2660285612Sdelphij unsigned char *eph_flag, 2661285612Sdelphij float *signal_level, 2662285612Sdelphij float *time_of_last_msmt, 2663285612Sdelphij float *elev, 2664285612Sdelphij float *azim, 2665285612Sdelphij unsigned char *old_msmt_flag, 2666285612Sdelphij unsigned char *integer_msec_flag, 2667285612Sdelphij unsigned char *bad_data_flag, 2668285612Sdelphij unsigned char *data_collect_flag 2669285612Sdelphij ) 2670106424Sroberto{ 2671106424Sroberto unsigned char *buf; 2672106424Sroberto buf = rpt->buf; 2673106424Sroberto 2674106424Sroberto if (rpt->len != 24) return TRUE; 2675106424Sroberto *sv_prn = buf[0]; 2676106424Sroberto *slot = (unsigned char)((buf[1] & 0x07) + 1); 2677106424Sroberto *chan = (unsigned char)(buf[1] >> 3); 2678106424Sroberto if (*chan == 0x10) *chan = 2; 2679106424Sroberto else (*chan)++; 2680106424Sroberto *acq_flag = buf[2]; 2681106424Sroberto *eph_flag = buf[3]; 2682106424Sroberto *signal_level = bGetSingle (&buf[4]); 2683106424Sroberto *time_of_last_msmt = bGetSingle (&buf[8]); 2684106424Sroberto *elev = bGetSingle (&buf[12]); 2685106424Sroberto *azim = bGetSingle (&buf[16]); 2686106424Sroberto *old_msmt_flag = buf[20]; 2687106424Sroberto *integer_msec_flag = buf[21]; 2688106424Sroberto *bad_data_flag = buf[22]; 2689106424Sroberto *data_collect_flag = buf[23]; 2690106424Sroberto return FALSE; 2691106424Sroberto} 2692106424Sroberto 2693106424Sroberto/**/ 2694106424Sroberto/* over-determined satellite selection for position fixes, PDOP, fix mode */ 2695285612Sdelphijshort 2696285612Sdelphijrpt_0x6D( 2697285612Sdelphij TSIPPKT *rpt, 2698285612Sdelphij unsigned char *manual_mode, 2699285612Sdelphij unsigned char *nsvs, 2700285612Sdelphij unsigned char *ndim, 2701285612Sdelphij unsigned char sv_prn[], 2702285612Sdelphij float *pdop, 2703285612Sdelphij float *hdop, 2704285612Sdelphij float *vdop, 2705285612Sdelphij float *tdop 2706285612Sdelphij ) 2707106424Sroberto{ 2708106424Sroberto short islot; 2709106424Sroberto unsigned char *buf; 2710106424Sroberto buf = rpt->buf; 2711106424Sroberto 2712106424Sroberto *nsvs = (unsigned char)((buf[0] & 0xF0) >> 4); 2713106424Sroberto if ((*nsvs)>8) return TRUE; 2714106424Sroberto if (rpt->len != 17 + (*nsvs) ) return TRUE; 2715106424Sroberto 2716106424Sroberto *manual_mode = (unsigned char)(buf[0] & 0x08); 2717106424Sroberto *ndim = (unsigned char)((buf[0] & 0x07)); 2718106424Sroberto *pdop = bGetSingle (&buf[1]); 2719106424Sroberto *hdop = bGetSingle (&buf[5]); 2720106424Sroberto *vdop = bGetSingle (&buf[9]); 2721106424Sroberto *tdop = bGetSingle (&buf[13]); 2722106424Sroberto for (islot = 0; islot < (*nsvs); islot++) 2723106424Sroberto sv_prn[islot] = buf[islot + 17]; 2724106424Sroberto return FALSE; 2725106424Sroberto} 2726106424Sroberto 2727106424Sroberto/**/ 2728106424Sroberto/* differential fix mode */ 2729285612Sdelphijshort 2730285612Sdelphijrpt_0x82( 2731285612Sdelphij TSIPPKT *rpt, 2732285612Sdelphij unsigned char *diff_mode 2733285612Sdelphij ) 2734106424Sroberto{ 2735106424Sroberto unsigned char *buf; 2736106424Sroberto buf = rpt->buf; 2737106424Sroberto 2738106424Sroberto if (rpt->len != 1) return TRUE; 2739106424Sroberto *diff_mode = buf[0]; 2740106424Sroberto return FALSE; 2741106424Sroberto} 2742106424Sroberto 2743106424Sroberto/* position, ECEF double precision */ 2744285612Sdelphijshort 2745285612Sdelphijrpt_0x83( 2746285612Sdelphij TSIPPKT *rpt, 2747285612Sdelphij double ECEF_pos[3], 2748285612Sdelphij double *clock_bias, 2749285612Sdelphij float *time_of_fix 2750285612Sdelphij ) 2751106424Sroberto{ 2752106424Sroberto unsigned char *buf; 2753106424Sroberto buf = rpt->buf; 2754106424Sroberto 2755106424Sroberto if (rpt->len != 36) return TRUE; 2756106424Sroberto ECEF_pos[0] = bGetDouble (buf); 2757106424Sroberto ECEF_pos[1] = bGetDouble (&buf[8]); 2758106424Sroberto ECEF_pos[2] = bGetDouble (&buf[16]); 2759106424Sroberto *clock_bias = bGetDouble (&buf[24]); 2760106424Sroberto *time_of_fix = bGetSingle (&buf[32]); 2761106424Sroberto return FALSE; 2762106424Sroberto} 2763106424Sroberto 2764106424Sroberto/* position, lat-lon-alt double precision */ 2765285612Sdelphijshort 2766285612Sdelphijrpt_0x84( 2767285612Sdelphij TSIPPKT *rpt, 2768285612Sdelphij double *lat, 2769285612Sdelphij double *lon, 2770285612Sdelphij double *alt, 2771285612Sdelphij double *clock_bias, 2772285612Sdelphij float *time_of_fix 2773285612Sdelphij ) 2774106424Sroberto{ 2775106424Sroberto unsigned char *buf; 2776106424Sroberto buf = rpt->buf; 2777106424Sroberto 2778106424Sroberto if (rpt->len != 36) return TRUE; 2779106424Sroberto *lat = bGetDouble (buf); 2780106424Sroberto *lon = bGetDouble (&buf[8]); 2781106424Sroberto *alt = bGetDouble (&buf[16]); 2782106424Sroberto *clock_bias = bGetDouble (&buf[24]); 2783106424Sroberto *time_of_fix = bGetSingle (&buf[32]); 2784106424Sroberto return FALSE; 2785106424Sroberto} 2786106424Sroberto 2787285612Sdelphijshort 2788285612Sdelphijrpt_Paly0xBB( 2789285612Sdelphij TSIPPKT *rpt, 2790285612Sdelphij TSIP_RCVR_CFG *TsipxBB 2791285612Sdelphij ) 2792106424Sroberto{ 2793106424Sroberto unsigned char *buf; 2794106424Sroberto buf = rpt->buf; 2795106424Sroberto 2796285612Sdelphij /* Palisade is inconsistent with other TSIP, which has a length of 40 */ 2797106424Sroberto /* if (rpt->len != 40) return TRUE; */ 2798106424Sroberto if (rpt->len != 43) return TRUE; 2799106424Sroberto 2800285612Sdelphij TsipxBB->bSubcode = buf[0]; 2801285612Sdelphij TsipxBB->operating_mode = buf[1]; 2802285612Sdelphij TsipxBB->dyn_code = buf[3]; 2803285612Sdelphij TsipxBB->elev_mask = bGetSingle (&buf[5]); 2804285612Sdelphij TsipxBB->cno_mask = bGetSingle (&buf[9]); 2805285612Sdelphij TsipxBB->dop_mask = bGetSingle (&buf[13]); 2806106424Sroberto TsipxBB->dop_switch = bGetSingle (&buf[17]); 2807106424Sroberto return FALSE; 2808106424Sroberto} 2809106424Sroberto 2810106424Sroberto/* Receiver serial port configuration */ 2811285612Sdelphijshort 2812285612Sdelphijrpt_0xBC( 2813285612Sdelphij TSIPPKT *rpt, 2814285612Sdelphij unsigned char *port_num, 2815285612Sdelphij unsigned char *in_baud, 2816285612Sdelphij unsigned char *out_baud, 2817285612Sdelphij unsigned char *data_bits, 2818285612Sdelphij unsigned char *parity, 2819285612Sdelphij unsigned char *stop_bits, 2820285612Sdelphij unsigned char *flow_control, 2821285612Sdelphij unsigned char *protocols_in, 2822285612Sdelphij unsigned char *protocols_out, 2823285612Sdelphij unsigned char *reserved 2824285612Sdelphij ) 2825106424Sroberto{ 2826106424Sroberto unsigned char *buf; 2827106424Sroberto buf = rpt->buf; 2828106424Sroberto 2829106424Sroberto if (rpt->len != 10) return TRUE; 2830106424Sroberto *port_num = buf[0]; 2831106424Sroberto *in_baud = buf[1]; 2832106424Sroberto *out_baud = buf[2]; 2833106424Sroberto *data_bits = buf[3]; 2834106424Sroberto *parity = buf[4]; 2835106424Sroberto *stop_bits = buf[5]; 2836106424Sroberto *flow_control = buf[6]; 2837106424Sroberto *protocols_in = buf[7]; 2838106424Sroberto *protocols_out = buf[8]; 2839106424Sroberto *reserved = buf[9]; 2840106424Sroberto 2841106424Sroberto return FALSE; 2842106424Sroberto} 2843106424Sroberto 2844106424Sroberto/**** Superpackets ****/ 2845106424Sroberto 2846285612Sdelphijshort 2847285612Sdelphijrpt_0x8F0B( 2848285612Sdelphij TSIPPKT *rpt, 2849285612Sdelphij unsigned short *event, 2850285612Sdelphij double *tow, 2851285612Sdelphij unsigned char *date, 2852285612Sdelphij unsigned char *month, 2853285612Sdelphij short *year, 2854285612Sdelphij unsigned char *dim_mode, 2855285612Sdelphij short *utc_offset, 2856285612Sdelphij double *bias, 2857285612Sdelphij double *drift, 2858285612Sdelphij float *bias_unc, 2859285612Sdelphij float *dr_unc, 2860285612Sdelphij double *lat, 2861285612Sdelphij double *lon, 2862285612Sdelphij double *alt, 2863285612Sdelphij char sv_id[8] 2864285612Sdelphij ) 2865106424Sroberto{ 2866285612Sdelphij short local_index; 2867285612Sdelphij unsigned char *buf; 2868106424Sroberto 2869106424Sroberto buf = rpt->buf; 2870285612Sdelphij if (rpt->len != 74) return TRUE; 2871285612Sdelphij *event = bGetShort(&buf[1]); 2872285612Sdelphij *tow = bGetDouble(&buf[3]); 2873285612Sdelphij *date = buf[11]; 2874285612Sdelphij *month = buf[12]; 2875285612Sdelphij *year = bGetShort(&buf[13]); 2876285612Sdelphij *dim_mode = buf[15]; 2877285612Sdelphij *utc_offset = bGetShort(&buf[16]); 2878285612Sdelphij *bias = bGetDouble(&buf[18]); 2879285612Sdelphij *drift = bGetDouble(&buf[26]); 2880285612Sdelphij *bias_unc = bGetSingle(&buf[34]); 2881285612Sdelphij *dr_unc = bGetSingle(&buf[38]); 2882285612Sdelphij *lat = bGetDouble(&buf[42]); 2883285612Sdelphij *lon = bGetDouble(&buf[50]); 2884285612Sdelphij *alt = bGetDouble(&buf[58]); 2885106424Sroberto 2886285612Sdelphij for (local_index=0; local_index<8; local_index++) sv_id[local_index] = buf[local_index + 66]; 2887285612Sdelphij return FALSE; 2888106424Sroberto} 2889106424Sroberto 2890285612Sdelphij/* datum index and coefficients */ 2891285612Sdelphijshort 2892285612Sdelphijrpt_0x8F14( 2893285612Sdelphij TSIPPKT *rpt, 2894285612Sdelphij short *datum_idx, 2895285612Sdelphij double datum_coeffs[5] 2896285612Sdelphij ) 2897106424Sroberto{ 2898106424Sroberto unsigned char *buf; 2899106424Sroberto buf = rpt->buf; 2900106424Sroberto 2901106424Sroberto if (rpt->len != 43) return TRUE; 2902106424Sroberto *datum_idx = bGetShort(&buf[1]); 2903106424Sroberto datum_coeffs[0] = bGetDouble (&buf[3]); 2904106424Sroberto datum_coeffs[1] = bGetDouble (&buf[11]); 2905106424Sroberto datum_coeffs[2] = bGetDouble (&buf[19]); 2906106424Sroberto datum_coeffs[3] = bGetDouble (&buf[27]); 2907106424Sroberto datum_coeffs[4] = bGetDouble (&buf[35]); 2908106424Sroberto return FALSE; 2909106424Sroberto} 2910106424Sroberto 2911106424Sroberto 2912285612Sdelphij/* datum index and coefficients */ 2913285612Sdelphijshort 2914285612Sdelphijrpt_0x8F15( 2915285612Sdelphij TSIPPKT *rpt, 2916285612Sdelphij short *datum_idx, 2917285612Sdelphij double datum_coeffs[5] 2918285612Sdelphij ) 2919106424Sroberto{ 2920106424Sroberto unsigned char *buf; 2921106424Sroberto buf = rpt->buf; 2922106424Sroberto 2923106424Sroberto if (rpt->len != 43) return TRUE; 2924106424Sroberto *datum_idx = bGetShort(&buf[1]); 2925106424Sroberto datum_coeffs[0] = bGetDouble (&buf[3]); 2926106424Sroberto datum_coeffs[1] = bGetDouble (&buf[11]); 2927106424Sroberto datum_coeffs[2] = bGetDouble (&buf[19]); 2928106424Sroberto datum_coeffs[3] = bGetDouble (&buf[27]); 2929106424Sroberto datum_coeffs[4] = bGetDouble (&buf[35]); 2930106424Sroberto return FALSE; 2931106424Sroberto} 2932106424Sroberto 2933106424Sroberto 2934106424Sroberto#define MAX_LONG (2147483648.) /* 2**31 */ 2935106424Sroberto 2936285612Sdelphijshort 2937285612Sdelphijrpt_0x8F20( 2938285612Sdelphij TSIPPKT *rpt, 2939285612Sdelphij unsigned char *info, 2940285612Sdelphij double *lat, 2941285612Sdelphij double *lon, 2942285612Sdelphij double *alt, 2943285612Sdelphij double vel_enu[], 2944285612Sdelphij double *time_of_fix, 2945285612Sdelphij short *week_num, 2946285612Sdelphij unsigned char *nsvs, 2947285612Sdelphij unsigned char sv_prn[], 2948285612Sdelphij short sv_IODC[], 2949285612Sdelphij short *datum_index 2950285612Sdelphij ) 2951106424Sroberto{ 2952106424Sroberto short 2953285612Sdelphij isv; 2954106424Sroberto unsigned char 2955285612Sdelphij *buf, prnx, iode; 2956106424Sroberto unsigned long 2957285612Sdelphij ulongtemp; 2958106424Sroberto long 2959285612Sdelphij longtemp; 2960106424Sroberto double 2961285612Sdelphij vel_scale; 2962106424Sroberto 2963106424Sroberto buf = rpt->buf; 2964106424Sroberto 2965106424Sroberto if (rpt->len != 56) return TRUE; 2966106424Sroberto 2967106424Sroberto vel_scale = (buf[24]&1)? 0.020 : 0.005; 2968106424Sroberto vel_enu[0] = bGetShort (buf+2)*vel_scale; 2969106424Sroberto vel_enu[1] = bGetShort (buf+4)*vel_scale; 2970106424Sroberto vel_enu[2] = bGetShort (buf+6)*vel_scale; 2971106424Sroberto 2972106424Sroberto *time_of_fix = bGetULong (buf+8)*.001; 2973106424Sroberto 2974106424Sroberto longtemp = bGetLong (buf+12); 2975106424Sroberto *lat = longtemp*(GPS_PI/MAX_LONG); 2976106424Sroberto 2977106424Sroberto ulongtemp = bGetULong (buf+16); 2978106424Sroberto *lon = ulongtemp*(GPS_PI/MAX_LONG); 2979106424Sroberto if (*lon > GPS_PI) *lon -= 2.0*GPS_PI; 2980106424Sroberto 2981106424Sroberto *alt = bGetLong (buf+20)*.001; 2982106424Sroberto /* 25 blank; 29 = UTC */ 2983106424Sroberto (*datum_index) = (short)((short)buf[26]-1); 2984106424Sroberto *info = buf[27]; 2985106424Sroberto *nsvs = buf[28]; 2986106424Sroberto *week_num = bGetShort (&buf[30]); 2987106424Sroberto for (isv = 0; isv < 8; isv++) { 2988106424Sroberto prnx = buf[32+2*isv]; 2989106424Sroberto sv_prn[isv] = (unsigned char)(prnx&0x3F); 2990285612Sdelphij iode = buf[33+2*isv]; 2991106424Sroberto sv_IODC[isv] = (short)(iode | ((prnx>>6)<<8)); 2992106424Sroberto } 2993106424Sroberto return FALSE; 2994106424Sroberto} 2995106424Sroberto 2996285612Sdelphijshort 2997285612Sdelphijrpt_0x8F41( 2998285612Sdelphij TSIPPKT *rpt, 2999285612Sdelphij unsigned char *bSearchRange, 3000285612Sdelphij unsigned char *bBoardOptions, 3001285612Sdelphij unsigned long *iiSerialNumber, 3002285612Sdelphij unsigned char *bBuildYear, 3003285612Sdelphij unsigned char *bBuildMonth, 3004285612Sdelphij unsigned char *bBuildDay, 3005285612Sdelphij unsigned char *bBuildHour, 3006285612Sdelphij float *fOscOffset, 3007285612Sdelphij unsigned short *iTestCodeId 3008285612Sdelphij ) 3009106424Sroberto{ 3010285612Sdelphij if (rpt->len != 17) return FALSE; 3011106424Sroberto *bSearchRange = rpt->buf[1]; 3012106424Sroberto *bBoardOptions = rpt->buf[2]; 3013106424Sroberto *iiSerialNumber = bGetLong(&rpt->buf[3]); 3014106424Sroberto *bBuildYear = rpt->buf[7]; 3015106424Sroberto *bBuildMonth = rpt->buf[8]; 3016106424Sroberto *bBuildDay = rpt->buf[9]; 3017106424Sroberto *bBuildHour = rpt->buf[10]; 3018106424Sroberto *fOscOffset = bGetSingle(&rpt->buf[11]); 3019106424Sroberto *iTestCodeId = bGetShort(&rpt->buf[15]); 3020106424Sroberto/* Tsipx8E41Data = *Tsipx8E41; */ 3021106424Sroberto return TRUE; 3022106424Sroberto} 3023106424Sroberto 3024285612Sdelphijshort 3025285612Sdelphijrpt_0x8F42( 3026285612Sdelphij TSIPPKT *rpt, 3027285612Sdelphij unsigned char *bProdOptionsPre, 3028285612Sdelphij unsigned char *bProdNumberExt, 3029285612Sdelphij unsigned short *iCaseSerialNumberPre, 3030285612Sdelphij unsigned long *iiCaseSerialNumber, 3031285612Sdelphij unsigned long *iiProdNumber, 3032285612Sdelphij unsigned short *iPremiumOptions, 3033285612Sdelphij unsigned short *iMachineID, 3034285612Sdelphij unsigned short *iKey 3035285612Sdelphij ) 3036106424Sroberto{ 3037285612Sdelphij if (rpt->len != 19) return FALSE; 3038106424Sroberto *bProdOptionsPre = rpt->buf[1]; 3039106424Sroberto *bProdNumberExt = rpt->buf[2]; 3040106424Sroberto *iCaseSerialNumberPre = bGetShort(&rpt->buf[3]); 3041106424Sroberto *iiCaseSerialNumber = bGetLong(&rpt->buf[5]); 3042106424Sroberto *iiProdNumber = bGetLong(&rpt->buf[9]); 3043106424Sroberto *iPremiumOptions = bGetShort(&rpt->buf[13]); 3044106424Sroberto *iMachineID = bGetShort(&rpt->buf[15]); 3045106424Sroberto *iKey = bGetShort(&rpt->buf[17]); 3046106424Sroberto return TRUE; 3047106424Sroberto} 3048106424Sroberto 3049285612Sdelphijshort 3050285612Sdelphijrpt_0x8F45( 3051285612Sdelphij TSIPPKT *rpt, 3052285612Sdelphij unsigned char *bSegMask 3053285612Sdelphij ) 3054106424Sroberto{ 3055285612Sdelphij if (rpt->len != 2) return FALSE; 3056106424Sroberto *bSegMask = rpt->buf[1]; 3057106424Sroberto return TRUE; 3058106424Sroberto} 3059106424Sroberto 3060106424Sroberto/* Stinger PPS definition */ 3061285612Sdelphijshort 3062285612Sdelphijrpt_0x8F4A_16( 3063285612Sdelphij TSIPPKT *rpt, 3064285612Sdelphij unsigned char *pps_enabled, 3065285612Sdelphij unsigned char *pps_timebase, 3066285612Sdelphij unsigned char *pos_polarity, 3067285612Sdelphij double *pps_offset, 3068285612Sdelphij float *bias_unc_threshold 3069285612Sdelphij ) 3070106424Sroberto{ 3071106424Sroberto unsigned char 3072285612Sdelphij *buf; 3073106424Sroberto 3074285612Sdelphij buf = rpt->buf; 3075285612Sdelphij if (rpt->len != 16) return TRUE; 3076285612Sdelphij *pps_enabled = buf[1]; 3077285612Sdelphij *pps_timebase = buf[2]; 3078285612Sdelphij *pos_polarity = buf[3]; 3079285612Sdelphij *pps_offset = bGetDouble(&buf[4]); 3080285612Sdelphij *bias_unc_threshold = bGetSingle(&buf[12]); 3081106424Sroberto return FALSE; 3082106424Sroberto} 3083106424Sroberto 3084285612Sdelphijshort 3085285612Sdelphijrpt_0x8F4B( 3086285612Sdelphij TSIPPKT *rpt, 3087285612Sdelphij unsigned long *decorr_max 3088285612Sdelphij ) 3089106424Sroberto{ 3090106424Sroberto unsigned char 3091285612Sdelphij *buf; 3092106424Sroberto 3093285612Sdelphij buf = rpt->buf; 3094285612Sdelphij if (rpt->len != 5) return TRUE; 3095285612Sdelphij *decorr_max = bGetLong(&buf[1]); 3096285612Sdelphij return FALSE; 3097106424Sroberto} 3098106424Sroberto 3099285612Sdelphijshort 3100285612Sdelphijrpt_0x8F4D( 3101285612Sdelphij TSIPPKT *rpt, 3102285612Sdelphij unsigned long *event_mask 3103285612Sdelphij ) 3104106424Sroberto{ 3105106424Sroberto unsigned char 3106285612Sdelphij *buf; 3107106424Sroberto 3108285612Sdelphij buf = rpt->buf; 3109285612Sdelphij if (rpt->len != 5) return TRUE; 3110285612Sdelphij *event_mask = bGetULong (&buf[1]); 3111285612Sdelphij return FALSE; 3112106424Sroberto} 3113106424Sroberto 3114285612Sdelphijshort 3115285612Sdelphijrpt_0x8FA5( 3116285612Sdelphij TSIPPKT *rpt, 3117285612Sdelphij unsigned char *spktmask 3118285612Sdelphij ) 3119106424Sroberto{ 3120106424Sroberto unsigned char 3121285612Sdelphij *buf; 3122106424Sroberto 3123285612Sdelphij buf = rpt->buf; 3124285612Sdelphij if (rpt->len != 5) return TRUE; 3125285612Sdelphij spktmask[0] = buf[1]; 3126285612Sdelphij spktmask[1] = buf[2]; 3127285612Sdelphij spktmask[2] = buf[3]; 3128285612Sdelphij spktmask[3] = buf[4]; 3129285612Sdelphij return FALSE; 3130106424Sroberto} 3131106424Sroberto 3132285612Sdelphijshort 3133285612Sdelphijrpt_0x8FAD( 3134285612Sdelphij TSIPPKT *rpt, 3135285612Sdelphij unsigned short *COUNT, 3136285612Sdelphij double *FracSec, 3137285612Sdelphij unsigned char *Hour, 3138285612Sdelphij unsigned char *Minute, 3139285612Sdelphij unsigned char *Second, 3140285612Sdelphij unsigned char *Day, 3141285612Sdelphij unsigned char *Month, 3142285612Sdelphij unsigned short *Year, 3143285612Sdelphij unsigned char *Status, 3144285612Sdelphij unsigned char *Flags 3145285612Sdelphij ) 3146106424Sroberto{ 3147106424Sroberto if (rpt->len != 22) return TRUE; 3148106424Sroberto 3149285612Sdelphij *COUNT = bGetUShort(&rpt->buf[1]); 3150285612Sdelphij *FracSec = bGetDouble(&rpt->buf[3]); 3151285612Sdelphij *Hour = rpt->buf[11]; 3152285612Sdelphij *Minute = rpt->buf[12]; 3153285612Sdelphij *Second = rpt->buf[13]; 3154285612Sdelphij *Day = rpt->buf[14]; 3155285612Sdelphij *Month = rpt->buf[15]; 3156285612Sdelphij *Year = bGetUShort(&rpt->buf[16]); 3157285612Sdelphij *Status = rpt->buf[18]; 3158285612Sdelphij *Flags = rpt->buf[19]; 3159285612Sdelphij return FALSE; 3160106424Sroberto} 3161106424Sroberto 3162106424Sroberto 3163106424Sroberto/* 3164106424Sroberto * ************************************************************************* 3165106424Sroberto * 3166106424Sroberto * Trimble Navigation, Ltd. 3167106424Sroberto * OEM Products Development Group 3168106424Sroberto * P.O. Box 3642 3169106424Sroberto * 645 North Mary Avenue 3170106424Sroberto * Sunnyvale, California 94088-3642 3171106424Sroberto * 3172106424Sroberto * Corporate Headquarter: 3173106424Sroberto * Telephone: (408) 481-8000 3174106424Sroberto * Fax: (408) 481-6005 3175106424Sroberto * 3176106424Sroberto * Technical Support Center: 3177106424Sroberto * Telephone: (800) 767-4822 (U.S. and Canada) 3178106424Sroberto * (408) 481-6940 (outside U.S. and Canada) 3179106424Sroberto * Fax: (408) 481-6020 3180106424Sroberto * BBS: (408) 481-7800 3181106424Sroberto * e-mail: trimble_support@trimble.com 3182106424Sroberto * ftp://ftp.trimble.com/pub/sct/embedded/bin 3183106424Sroberto * 3184106424Sroberto * ************************************************************************* 3185106424Sroberto * 3186106424Sroberto * T_REPORT.C consists of a primary function TranslateTSIPReportToText() 3187106424Sroberto * called by main(). 3188106424Sroberto * 3189106424Sroberto * This function takes a character buffer that has been received as a report 3190106424Sroberto * from a TSIP device and interprets it. The character buffer has been 3191106424Sroberto * assembled using tsip_input_proc() in T_PARSER.C. 3192106424Sroberto * 3193106424Sroberto * A large case statement directs processing to one of many mid-level 3194106424Sroberto * functions. The mid-level functions specific to the current report 3195106424Sroberto * code passes the report buffer to the appropriate report decoder 3196106424Sroberto * rpt_0x?? () in T_PARSER.C, which converts the byte stream in rpt.buf 3197106424Sroberto * to data values approporaite for use. 3198106424Sroberto * 3199106424Sroberto * ************************************************************************* 3200106424Sroberto * 3201106424Sroberto */ 3202106424Sroberto 3203106424Sroberto 3204106424Sroberto#define GOOD_PARSE 0 3205106424Sroberto#define BADID_PARSE 1 3206106424Sroberto#define BADLEN_PARSE 2 3207106424Sroberto#define BADDATA_PARSE 3 3208106424Sroberto 3209106424Sroberto#define B_TSIP 0x02 3210106424Sroberto#define B_NMEA 0x04 3211106424Sroberto 3212106424Sroberto 3213106424Sroberto/* pbuf is the pointer to the current location of the text output */ 3214106424Srobertostatic char 3215285612Sdelphij*pbuf; 3216106424Sroberto 3217106424Sroberto/* keep track of whether the message has been successfully parsed */ 3218106424Srobertostatic short 3219285612Sdelphijparsed; 3220106424Sroberto 3221106424Sroberto 3222106424Sroberto/* convert time of week into day-hour-minute-second and print */ 3223285612Sdelphijchar * 3224285612Sdelphijshow_time( 3225285612Sdelphij float time_of_week 3226285612Sdelphij ) 3227106424Sroberto{ 3228106424Sroberto short days, hours, minutes; 3229106424Sroberto float seconds; 3230106424Sroberto double tow = 0; 3231285612Sdelphij static char timestring [80]; 3232106424Sroberto 3233106424Sroberto if (time_of_week == -1.0) 3234285612Sdelphij { 3235106424Sroberto sprintf(timestring, " <No time yet> "); 3236106424Sroberto } 3237106424Sroberto else if ((time_of_week >= 604800.0) || (time_of_week < 0.0)) 3238285612Sdelphij { 3239106424Sroberto sprintf(timestring, " <Bad time> "); 3240106424Sroberto } 3241285612Sdelphij else 3242285612Sdelphij { 3243106424Sroberto if (time_of_week < 604799.9) 3244106424Sroberto tow = time_of_week + .00000001; 3245106424Sroberto seconds = (float)fmod(tow, 60.); 3246106424Sroberto minutes = (short) fmod(tow/60., 60.); 3247106424Sroberto hours = (short)fmod(tow / 3600., 24.); 3248106424Sroberto days = (short)(tow / 86400.0); 3249106424Sroberto sprintf(timestring, " %s %02d:%02d:%05.2f ", 3250285612Sdelphij dayname[days], hours, minutes, seconds); 3251285612Sdelphij } 3252285612Sdelphij return timestring; 3253106424Sroberto} 3254106424Sroberto 3255106424Sroberto/**/ 3256106424Sroberto/* 0x3D */ 3257285612Sdelphijstatic void 3258285612Sdelphijrpt_chan_A_config( 3259285612Sdelphij TSIPPKT *rpt 3260285612Sdelphij ) 3261106424Sroberto{ 3262106424Sroberto unsigned char 3263285612Sdelphij tx_baud_index, rx_baud_index, 3264285612Sdelphij char_format_index, stop_bits, 3265285612Sdelphij tx_mode_index, rx_mode_index, 3266285612Sdelphij databits, parity; 3267106424Sroberto int 3268285612Sdelphij i, nbaud; 3269106424Sroberto 3270106424Sroberto /* unload rptbuf */ 3271106424Sroberto if (rpt_0x3D (rpt, 3272285612Sdelphij &tx_baud_index, &rx_baud_index, &char_format_index, 3273285612Sdelphij &stop_bits, &tx_mode_index, &rx_mode_index)) { 3274106424Sroberto parsed = BADLEN_PARSE; 3275106424Sroberto return; 3276106424Sroberto } 3277106424Sroberto 3278106424Sroberto pbuf += sprintf(pbuf, "\nChannel A Configuration"); 3279106424Sroberto 3280285612Sdelphij nbaud = sizeof(old_baudnum); 3281106424Sroberto 3282106424Sroberto for (i = 0; i < nbaud; ++i) if (tx_baud_index == old_baudnum[i]) break; 3283106424Sroberto pbuf += sprintf(pbuf, "\n Transmit speed: %s at %s", 3284285612Sdelphij old_output_ch[tx_mode_index], st_baud_text_app[i]); 3285106424Sroberto 3286106424Sroberto for (i = 0; i < nbaud; ++i) if (rx_baud_index == old_baudnum[i]) break; 3287106424Sroberto pbuf += sprintf(pbuf, "\n Receive speed: %s at %s", 3288285612Sdelphij old_input_ch[rx_mode_index], st_baud_text_app[i]); 3289106424Sroberto 3290106424Sroberto databits = (unsigned char)((char_format_index & 0x03) + 5); 3291106424Sroberto 3292106424Sroberto parity = (unsigned char)(char_format_index >> 2); 3293106424Sroberto if (parity > 4) parity = 2; 3294106424Sroberto 3295106424Sroberto pbuf += sprintf(pbuf, "\n Character format (bits/char, parity, stop bits): %d-%s-%d", 3296285612Sdelphij databits, old_parity_text[parity], stop_bits); 3297106424Sroberto} 3298106424Sroberto 3299106424Sroberto/**/ 3300106424Sroberto/* 0x40 */ 3301285612Sdelphijstatic void 3302285612Sdelphijrpt_almanac_data_page( 3303285612Sdelphij TSIPPKT *rpt 3304285612Sdelphij ) 3305106424Sroberto{ 3306106424Sroberto unsigned char 3307285612Sdelphij sv_prn; 3308106424Sroberto short 3309285612Sdelphij week_num; 3310106424Sroberto float 3311285612Sdelphij t_zc, 3312285612Sdelphij eccentricity, 3313285612Sdelphij t_oa, 3314285612Sdelphij i_0, 3315285612Sdelphij OMEGA_dot, 3316285612Sdelphij sqrt_A, 3317285612Sdelphij OMEGA_0, 3318285612Sdelphij omega, 3319285612Sdelphij M_0; 3320106424Sroberto 3321106424Sroberto /* unload rptbuf */ 3322106424Sroberto if (rpt_0x40 (rpt, 3323285612Sdelphij &sv_prn, &week_num, &t_zc, &eccentricity, &t_oa, 3324285612Sdelphij &i_0, &OMEGA_dot, &sqrt_A, &OMEGA_0, &omega, &M_0)) { 3325106424Sroberto parsed = BADLEN_PARSE; 3326106424Sroberto return; 3327106424Sroberto } 3328106424Sroberto 3329106424Sroberto pbuf += sprintf(pbuf, "\nAlmanac for SV %02d", sv_prn); 3330106424Sroberto pbuf += sprintf(pbuf, "\n Captured:%15.0f %s", 3331285612Sdelphij t_zc, show_time (t_zc)); 3332106424Sroberto pbuf += sprintf(pbuf, "\n week:%15d", week_num); 3333106424Sroberto pbuf += sprintf(pbuf, "\n Eccentricity:%15g", eccentricity); 3334106424Sroberto pbuf += sprintf(pbuf, "\n T_oa:%15.0f %s", 3335285612Sdelphij t_oa, show_time (t_oa)); 3336106424Sroberto pbuf += sprintf(pbuf, "\n i 0:%15g", i_0); 3337106424Sroberto pbuf += sprintf(pbuf, "\n OMEGA dot:%15g", OMEGA_dot); 3338106424Sroberto pbuf += sprintf(pbuf, "\n sqrt A:%15g", sqrt_A); 3339106424Sroberto pbuf += sprintf(pbuf, "\n OMEGA 0:%15g", OMEGA_0); 3340106424Sroberto pbuf += sprintf(pbuf, "\n omega:%15g", omega); 3341106424Sroberto pbuf += sprintf(pbuf, "\n M 0:%15g", M_0); 3342106424Sroberto} 3343106424Sroberto 3344106424Sroberto/* 0x41 */ 3345285612Sdelphijstatic void 3346285612Sdelphijrpt_GPS_time( 3347285612Sdelphij TSIPPKT *rpt 3348285612Sdelphij ) 3349106424Sroberto{ 3350106424Sroberto float 3351285612Sdelphij time_of_week, UTC_offset; 3352106424Sroberto short 3353285612Sdelphij week_num; 3354106424Sroberto 3355106424Sroberto /* unload rptbuf */ 3356106424Sroberto if (rpt_0x41 (rpt, &time_of_week, &UTC_offset, &week_num)) { 3357106424Sroberto parsed = BADLEN_PARSE; 3358106424Sroberto return; 3359106424Sroberto } 3360106424Sroberto 3361106424Sroberto pbuf += sprintf(pbuf, "\nGPS time:%s GPS week: %d UTC offset %.1f", 3362285612Sdelphij show_time(time_of_week), week_num, UTC_offset); 3363106424Sroberto 3364106424Sroberto} 3365106424Sroberto 3366106424Sroberto/* 0x42 */ 3367285612Sdelphijstatic void 3368285612Sdelphijrpt_single_ECEF_position( 3369285612Sdelphij TSIPPKT *rpt 3370285612Sdelphij ) 3371106424Sroberto{ 3372106424Sroberto float 3373285612Sdelphij ECEF_pos[3], time_of_fix; 3374106424Sroberto 3375106424Sroberto /* unload rptbuf */ 3376106424Sroberto if (rpt_0x42 (rpt, ECEF_pos, &time_of_fix)) { 3377106424Sroberto parsed = BADLEN_PARSE; 3378106424Sroberto return; 3379106424Sroberto } 3380106424Sroberto 3381106424Sroberto pbuf += sprintf(pbuf, "\nSXYZ: %15.0f %15.0f %15.0f %s", 3382285612Sdelphij ECEF_pos[0], ECEF_pos[1], ECEF_pos[2], 3383285612Sdelphij show_time(time_of_fix)); 3384106424Sroberto} 3385106424Sroberto 3386106424Sroberto/* 0x43 */ 3387285612Sdelphijstatic void 3388285612Sdelphijrpt_single_ECEF_velocity( 3389285612Sdelphij TSIPPKT *rpt 3390285612Sdelphij ) 3391106424Sroberto{ 3392106424Sroberto 3393106424Sroberto float 3394285612Sdelphij ECEF_vel[3], freq_offset, time_of_fix; 3395106424Sroberto 3396106424Sroberto /* unload rptbuf */ 3397106424Sroberto if (rpt_0x43 (rpt, ECEF_vel, &freq_offset, &time_of_fix)) { 3398106424Sroberto parsed = BADLEN_PARSE; 3399106424Sroberto return; 3400106424Sroberto } 3401106424Sroberto 3402106424Sroberto pbuf += sprintf(pbuf, "\nVelECEF: %11.3f %11.3f %11.3f %12.3f%s", 3403285612Sdelphij ECEF_vel[0], ECEF_vel[1], ECEF_vel[2], freq_offset, 3404285612Sdelphij show_time(time_of_fix)); 3405106424Sroberto} 3406106424Sroberto 3407106424Sroberto/* 0x45 */ 3408285612Sdelphijstatic void 3409285612Sdelphijrpt_SW_version( 3410285612Sdelphij TSIPPKT *rpt 3411285612Sdelphij ) 3412285612Sdelphij{ 3413106424Sroberto unsigned char 3414285612Sdelphij major_nav_version, minor_nav_version, 3415285612Sdelphij nav_day, nav_month, nav_year, 3416285612Sdelphij major_dsp_version, minor_dsp_version, 3417285612Sdelphij dsp_day, dsp_month, dsp_year; 3418106424Sroberto 3419106424Sroberto /* unload rptbuf */ 3420106424Sroberto if (rpt_0x45 (rpt, 3421285612Sdelphij &major_nav_version, &minor_nav_version, 3422285612Sdelphij &nav_day, &nav_month, &nav_year, 3423285612Sdelphij &major_dsp_version, &minor_dsp_version, 3424285612Sdelphij &dsp_day, &dsp_month, &dsp_year)) { 3425106424Sroberto parsed = BADLEN_PARSE; 3426106424Sroberto return; 3427106424Sroberto } 3428106424Sroberto 3429106424Sroberto pbuf += sprintf(pbuf, 3430285612Sdelphij "\nFW Versions: Nav Proc %2d.%02d %2d/%2d/%2d Sig Proc %2d.%02d %2d/%2d/%2d", 3431285612Sdelphij major_nav_version, minor_nav_version, nav_day, nav_month, nav_year, 3432285612Sdelphij major_dsp_version, minor_dsp_version, dsp_day, dsp_month, dsp_year); 3433106424Sroberto} 3434106424Sroberto 3435106424Sroberto/* 0x46 */ 3436285612Sdelphijstatic void 3437285612Sdelphijrpt_rcvr_health( 3438285612Sdelphij TSIPPKT *rpt 3439285612Sdelphij ) 3440106424Sroberto{ 3441106424Sroberto unsigned char 3442285612Sdelphij status1, status2; 3443285612Sdelphij const char 3444285612Sdelphij *text; 3445285612Sdelphij static const char const 3446285612Sdelphij *sc_text[] = { 3447285612Sdelphij "Doing position fixes", 3448285612Sdelphij "Don't have GPS time yet", 3449285612Sdelphij "Waiting for almanac collection", 3450285612Sdelphij "DOP too high ", 3451285612Sdelphij "No satellites available", 3452285612Sdelphij "Only 1 satellite available", 3453285612Sdelphij "Only 2 satellites available", 3454285612Sdelphij "Only 3 satellites available", 3455285612Sdelphij "No satellites usable ", 3456285612Sdelphij "Only 1 satellite usable", 3457285612Sdelphij "Only 2 satellites usable", 3458285612Sdelphij "Only 3 satellites usable", 3459285612Sdelphij "Chosen satellite unusable"}; 3460106424Sroberto 3461106424Sroberto 3462106424Sroberto /* unload rptbuf */ 3463106424Sroberto if (rpt_0x46 (rpt, &status1, &status2)) 3464106424Sroberto { 3465106424Sroberto parsed = BADLEN_PARSE; 3466106424Sroberto return; 3467106424Sroberto } 3468106424Sroberto 3469285612Sdelphij text = (status1 < COUNTOF(sc_text)) 3470285612Sdelphij ? sc_text[status1] 3471285612Sdelphij : "(out of range)"; 3472106424Sroberto pbuf += sprintf(pbuf, "\nRcvr status1: %s (%02Xh); ", 3473285612Sdelphij text, status1); 3474106424Sroberto 3475106424Sroberto pbuf += sprintf(pbuf, "status2: %s, %s (%02Xh)", 3476285612Sdelphij (status2 & 0x01)?"No BBRAM":"BBRAM OK", 3477285612Sdelphij (status2 & 0x10)?"No Ant":"Ant OK", 3478285612Sdelphij status2); 3479106424Sroberto} 3480106424Sroberto 3481106424Sroberto/* 0x47 */ 3482285612Sdelphijstatic void 3483285612Sdelphijrpt_SNR_all_SVs( 3484285612Sdelphij TSIPPKT *rpt 3485285612Sdelphij ) 3486106424Sroberto{ 3487106424Sroberto unsigned char 3488285612Sdelphij nsvs, sv_prn[12]; 3489106424Sroberto short 3490285612Sdelphij isv; 3491106424Sroberto float 3492285612Sdelphij snr[12]; 3493106424Sroberto 3494106424Sroberto /* unload rptbuf */ 3495106424Sroberto if (rpt_0x47 (rpt, &nsvs, sv_prn, snr)) 3496285612Sdelphij { 3497106424Sroberto parsed = BADLEN_PARSE; 3498106424Sroberto return; 3499106424Sroberto } 3500106424Sroberto 3501106424Sroberto pbuf += sprintf(pbuf, "\nSNR for satellites: %d", nsvs); 3502106424Sroberto for (isv = 0; isv < nsvs; isv++) 3503285612Sdelphij { 3504106424Sroberto pbuf += sprintf(pbuf, "\n SV %02d %6.2f", 3505285612Sdelphij sv_prn[isv], snr[isv]); 3506106424Sroberto } 3507106424Sroberto} 3508106424Sroberto 3509106424Sroberto/* 0x48 */ 3510285612Sdelphijstatic void 3511285612Sdelphijrpt_GPS_system_message( 3512285612Sdelphij TSIPPKT *rpt 3513285612Sdelphij ) 3514106424Sroberto{ 3515106424Sroberto unsigned char 3516285612Sdelphij message[23]; 3517106424Sroberto 3518106424Sroberto /* unload rptbuf */ 3519106424Sroberto if (rpt_0x48 (rpt, message)) 3520285612Sdelphij { 3521106424Sroberto parsed = BADLEN_PARSE; 3522106424Sroberto return; 3523106424Sroberto } 3524106424Sroberto 3525106424Sroberto pbuf += sprintf(pbuf, "\nGPS message: %s", message); 3526106424Sroberto} 3527106424Sroberto 3528106424Sroberto/* 0x49 */ 3529285612Sdelphijstatic void 3530285612Sdelphijrpt_almanac_health_page( 3531285612Sdelphij TSIPPKT *rpt 3532285612Sdelphij ) 3533106424Sroberto{ 3534106424Sroberto short 3535285612Sdelphij iprn; 3536106424Sroberto unsigned char 3537285612Sdelphij sv_health [32]; 3538106424Sroberto 3539106424Sroberto /* unload rptbuf */ 3540106424Sroberto if (rpt_0x49 (rpt, sv_health)) 3541285612Sdelphij { 3542106424Sroberto parsed = BADLEN_PARSE; 3543106424Sroberto return; 3544106424Sroberto } 3545106424Sroberto 3546106424Sroberto pbuf += sprintf(pbuf, "\nAlmanac health page:"); 3547106424Sroberto for (iprn = 0; iprn < 32; iprn++) 3548285612Sdelphij { 3549106424Sroberto if (!(iprn%5)) *pbuf++ = '\n'; 3550106424Sroberto pbuf += sprintf(pbuf, " SV%02d %2X", 3551285612Sdelphij (iprn+1) , sv_health[iprn]); 3552106424Sroberto } 3553106424Sroberto} 3554106424Sroberto 3555106424Sroberto/* 0x4A */ 3556285612Sdelphijstatic void 3557285612Sdelphijrpt_single_lla_position( 3558285612Sdelphij TSIPPKT *rpt 3559285612Sdelphij ) 3560285612Sdelphij{ 3561106424Sroberto short 3562285612Sdelphij lat_deg, lon_deg; 3563106424Sroberto float 3564285612Sdelphij lat, lon, 3565285612Sdelphij alt, clock_bias, time_of_fix; 3566106424Sroberto double lat_min, lon_min; 3567106424Sroberto unsigned char 3568285612Sdelphij north_south, east_west; 3569106424Sroberto 3570106424Sroberto if (rpt_0x4A (rpt, 3571285612Sdelphij &lat, &lon, &alt, &clock_bias, &time_of_fix)) 3572285612Sdelphij { 3573106424Sroberto parsed = BADLEN_PARSE; 3574106424Sroberto return; 3575106424Sroberto } 3576106424Sroberto 3577106424Sroberto /* convert from radians to degrees */ 3578106424Sroberto lat *= (float)R2D; 3579106424Sroberto north_south = 'N'; 3580106424Sroberto if (lat < 0.0) 3581285612Sdelphij { 3582106424Sroberto north_south = 'S'; 3583106424Sroberto lat = -lat; 3584106424Sroberto } 3585106424Sroberto lat_deg = (short)lat; 3586106424Sroberto lat_min = (lat - lat_deg) * 60.0; 3587106424Sroberto 3588106424Sroberto lon *= (float)R2D; 3589106424Sroberto east_west = 'E'; 3590106424Sroberto if (lon < 0.0) 3591285612Sdelphij { 3592106424Sroberto east_west = 'W'; 3593106424Sroberto lon = -lon; 3594106424Sroberto } 3595106424Sroberto lon_deg = (short)lon; 3596106424Sroberto lon_min = (lon - lon_deg) * 60.0; 3597106424Sroberto 3598106424Sroberto pbuf += sprintf(pbuf, "\nSLLA: %4d: %06.3f %c%5d:%06.3f %c%10.2f %12.2f%s", 3599285612Sdelphij lat_deg, lat_min, north_south, 3600285612Sdelphij lon_deg, lon_min, east_west, 3601285612Sdelphij alt, clock_bias, 3602285612Sdelphij show_time(time_of_fix)); 3603106424Sroberto} 3604106424Sroberto 3605106424Sroberto/* 0x4A */ 3606285612Sdelphijstatic void 3607285612Sdelphijrpt_ref_alt( 3608285612Sdelphij TSIPPKT *rpt 3609285612Sdelphij ) 3610285612Sdelphij{ 3611106424Sroberto float 3612285612Sdelphij alt, dummy; 3613106424Sroberto unsigned char 3614285612Sdelphij alt_flag; 3615106424Sroberto 3616285612Sdelphij if (rpt_0x4A_2 (rpt, &alt, &dummy, &alt_flag)) 3617285612Sdelphij { 3618106424Sroberto parsed = BADLEN_PARSE; 3619106424Sroberto return; 3620106424Sroberto } 3621106424Sroberto 3622106424Sroberto pbuf += sprintf(pbuf, "\nReference Alt: %.1f m; %s", 3623285612Sdelphij alt, alt_flag?"ON":"OFF"); 3624106424Sroberto} 3625106424Sroberto 3626106424Sroberto/* 0x4B */ 3627285612Sdelphijstatic void 3628285612Sdelphijrpt_rcvr_id_and_status( 3629285612Sdelphij TSIPPKT *rpt 3630285612Sdelphij ) 3631106424Sroberto{ 3632106424Sroberto 3633106424Sroberto unsigned char 3634285612Sdelphij machine_id, status3, status4; 3635106424Sroberto 3636106424Sroberto /* unload rptbuf */ 3637106424Sroberto if (rpt_0x4B (rpt, &machine_id, &status3, &status4)) 3638285612Sdelphij { 3639106424Sroberto parsed = BADLEN_PARSE; 3640106424Sroberto return; 3641106424Sroberto } 3642106424Sroberto 3643106424Sroberto pbuf += sprintf(pbuf, "\nRcvr Machine ID: %d; Status3 = %s, %s (%02Xh)", 3644285612Sdelphij machine_id, 3645285612Sdelphij (status3 & 0x02)?"No RTC":"RTC OK", 3646285612Sdelphij (status3 & 0x08)?"No Alm":"Alm OK", 3647285612Sdelphij status3); 3648106424Sroberto} 3649106424Sroberto 3650106424Sroberto/* 0x4C */ 3651285612Sdelphijstatic void 3652285612Sdelphijrpt_operating_parameters( 3653285612Sdelphij TSIPPKT *rpt 3654285612Sdelphij ) 3655106424Sroberto{ 3656106424Sroberto unsigned char 3657285612Sdelphij dyn_code; 3658106424Sroberto float 3659285612Sdelphij el_mask, snr_mask, dop_mask, dop_switch; 3660106424Sroberto 3661106424Sroberto /* unload rptbuf */ 3662106424Sroberto if (rpt_0x4C (rpt, &dyn_code, &el_mask, 3663285612Sdelphij &snr_mask, &dop_mask, &dop_switch)) 3664285612Sdelphij { 3665106424Sroberto parsed = BADLEN_PARSE; 3666106424Sroberto return; 3667106424Sroberto } 3668106424Sroberto 3669106424Sroberto pbuf += sprintf(pbuf, "\nOperating Parameters:"); 3670106424Sroberto pbuf += sprintf(pbuf, "\n Dynamics code = %d %s", 3671285612Sdelphij dyn_code, dyn_text[dyn_code]); 3672285612Sdelphij pbuf += sprintf(pbuf, "\n Elevation mask = %.2f", el_mask * R2D); 3673106424Sroberto pbuf += sprintf(pbuf, "\n SNR mask = %.2f", snr_mask); 3674106424Sroberto pbuf += sprintf(pbuf, "\n DOP mask = %.2f", dop_mask); 3675106424Sroberto pbuf += sprintf(pbuf, "\n DOP switch = %.2f", dop_switch); 3676106424Sroberto} 3677106424Sroberto 3678106424Sroberto/* 0x4D */ 3679285612Sdelphijstatic void 3680285612Sdelphijrpt_oscillator_offset( 3681285612Sdelphij TSIPPKT *rpt 3682285612Sdelphij ) 3683106424Sroberto{ 3684106424Sroberto float 3685285612Sdelphij osc_offset; 3686106424Sroberto 3687106424Sroberto /* unload rptbuf */ 3688106424Sroberto if (rpt_0x4D (rpt, &osc_offset)) 3689285612Sdelphij { 3690106424Sroberto parsed = BADLEN_PARSE; 3691106424Sroberto return; 3692106424Sroberto } 3693106424Sroberto 3694106424Sroberto pbuf += sprintf(pbuf, "\nOscillator offset: %.2f Hz = %.3f PPM", 3695285612Sdelphij osc_offset, osc_offset/1575.42); 3696106424Sroberto} 3697106424Sroberto 3698106424Sroberto/* 0x4E */ 3699285612Sdelphijstatic void 3700285612Sdelphijrpt_GPS_time_set_response( 3701285612Sdelphij TSIPPKT *rpt 3702285612Sdelphij ) 3703106424Sroberto{ 3704106424Sroberto unsigned char 3705285612Sdelphij response; 3706106424Sroberto 3707106424Sroberto /* unload rptbuf */ 3708106424Sroberto if (rpt_0x4E (rpt, &response)) 3709285612Sdelphij { 3710106424Sroberto parsed = BADLEN_PARSE; 3711106424Sroberto return; 3712106424Sroberto } 3713106424Sroberto 3714106424Sroberto switch (response) 3715285612Sdelphij { 3716285612Sdelphij case 'Y': 3717106424Sroberto pbuf += sprintf(pbuf, "\nTime set accepted"); 3718106424Sroberto break; 3719106424Sroberto 3720285612Sdelphij case 'N': 3721106424Sroberto pbuf += sprintf(pbuf, "\nTime set rejected or not required"); 3722106424Sroberto break; 3723106424Sroberto 3724285612Sdelphij default: 3725106424Sroberto parsed = BADDATA_PARSE; 3726106424Sroberto } 3727106424Sroberto} 3728106424Sroberto 3729106424Sroberto/* 0x4F */ 3730285612Sdelphijstatic void 3731285612Sdelphijrpt_UTC_offset( 3732285612Sdelphij TSIPPKT *rpt 3733285612Sdelphij ) 3734106424Sroberto{ 3735106424Sroberto double 3736285612Sdelphij a0; 3737106424Sroberto float 3738285612Sdelphij a1, time_of_data; 3739106424Sroberto short 3740285612Sdelphij dt_ls, wn_t, wn_lsf, dn, dt_lsf; 3741106424Sroberto 3742106424Sroberto /* unload rptbuf */ 3743106424Sroberto if (rpt_0x4F (rpt, &a0, &a1, &time_of_data, 3744285612Sdelphij &dt_ls, &wn_t, &wn_lsf, &dn, &dt_lsf)) { 3745106424Sroberto parsed = BADLEN_PARSE; 3746106424Sroberto return; 3747106424Sroberto } 3748106424Sroberto 3749106424Sroberto pbuf += sprintf(pbuf, "\nUTC Correction Data"); 3750106424Sroberto pbuf += sprintf(pbuf, "\n A_0 = %g ", a0); 3751106424Sroberto pbuf += sprintf(pbuf, "\n A_1 = %g ", a1); 3752106424Sroberto pbuf += sprintf(pbuf, "\n delta_t_LS = %d ", dt_ls); 3753106424Sroberto pbuf += sprintf(pbuf, "\n t_ot = %.0f ", time_of_data); 3754106424Sroberto pbuf += sprintf(pbuf, "\n WN_t = %d ", wn_t ); 3755106424Sroberto pbuf += sprintf(pbuf, "\n WN_LSF = %d ", wn_lsf ); 3756106424Sroberto pbuf += sprintf(pbuf, "\n DN = %d ", dn ); 3757106424Sroberto pbuf += sprintf(pbuf, "\n delta_t_LSF = %d ", dt_lsf ); 3758106424Sroberto} 3759106424Sroberto 3760106424Sroberto/**/ 3761106424Sroberto/* 0x54 */ 3762285612Sdelphijstatic void 3763285612Sdelphijrpt_1SV_bias( 3764285612Sdelphij TSIPPKT *rpt 3765285612Sdelphij ) 3766106424Sroberto{ 3767106424Sroberto float 3768285612Sdelphij clock_bias, freq_offset, time_of_fix; 3769106424Sroberto 3770106424Sroberto /* unload rptbuf */ 3771106424Sroberto if (rpt_0x54 (rpt, &clock_bias, &freq_offset, &time_of_fix)) { 3772106424Sroberto parsed = BADLEN_PARSE; 3773106424Sroberto return; 3774106424Sroberto } 3775106424Sroberto 3776106424Sroberto pbuf += sprintf (pbuf, "\nTime Fix Clock Bias: %6.2f m Freq Bias: %6.2f m/s%s", 3777285612Sdelphij clock_bias, freq_offset, show_time (time_of_fix)); 3778106424Sroberto} 3779106424Sroberto 3780106424Sroberto/* 0x55 */ 3781285612Sdelphijstatic void 3782285612Sdelphijrpt_io_opt( 3783285612Sdelphij TSIPPKT *rpt 3784285612Sdelphij ) 3785106424Sroberto{ 3786106424Sroberto unsigned char 3787285612Sdelphij pos_code, vel_code, time_code, aux_code; 3788106424Sroberto 3789106424Sroberto /* unload rptbuf */ 3790106424Sroberto if (rpt_0x55 (rpt, 3791285612Sdelphij &pos_code, &vel_code, &time_code, &aux_code)) { 3792106424Sroberto parsed = BADLEN_PARSE; 3793106424Sroberto return; 3794106424Sroberto } 3795106424Sroberto /* rptbuf unloaded */ 3796106424Sroberto 3797106424Sroberto pbuf += sprintf(pbuf, "\nI/O Options: %2X %2X %2X %2X", 3798285612Sdelphij pos_code, vel_code, time_code, aux_code); 3799106424Sroberto 3800106424Sroberto if (pos_code & 0x01) { 3801106424Sroberto pbuf += sprintf(pbuf, "\n ECEF XYZ position output"); 3802106424Sroberto } 3803106424Sroberto 3804106424Sroberto if (pos_code & 0x02) { 3805106424Sroberto pbuf += sprintf(pbuf, "\n LLA position output"); 3806106424Sroberto } 3807106424Sroberto 3808106424Sroberto pbuf += sprintf(pbuf, (pos_code & 0x04)? 3809285612Sdelphij "\n MSL altitude output (Geoid height) ": 3810285612Sdelphij "\n WGS-84 altitude output"); 3811106424Sroberto 3812106424Sroberto pbuf += sprintf(pbuf, (pos_code & 0x08)? 3813285612Sdelphij "\n MSL altitude input": 3814285612Sdelphij "\n WGS-84 altitude input"); 3815106424Sroberto 3816106424Sroberto pbuf += sprintf(pbuf, (pos_code & 0x10)? 3817285612Sdelphij "\n Double precision": 3818285612Sdelphij "\n Single precision"); 3819106424Sroberto 3820106424Sroberto if (pos_code & 0x20) { 3821106424Sroberto pbuf += sprintf(pbuf, "\n All Enabled Superpackets"); 3822106424Sroberto } 3823106424Sroberto 3824106424Sroberto if (vel_code & 0x01) { 3825106424Sroberto pbuf += sprintf(pbuf, "\n ECEF XYZ velocity output"); 3826106424Sroberto } 3827106424Sroberto 3828106424Sroberto if (vel_code & 0x02) { 3829106424Sroberto pbuf += sprintf(pbuf, "\n ENU velocity output"); 3830106424Sroberto } 3831106424Sroberto 3832106424Sroberto pbuf += sprintf(pbuf, (time_code & 0x01)? 3833285612Sdelphij "\n Time tags in UTC": 3834285612Sdelphij "\n Time tags in GPS time"); 3835106424Sroberto 3836106424Sroberto if (time_code & 0x02) { 3837106424Sroberto pbuf += sprintf(pbuf, "\n Fixes delayed to integer seconds"); 3838106424Sroberto } 3839106424Sroberto 3840106424Sroberto if (time_code & 0x04) { 3841106424Sroberto pbuf += sprintf(pbuf, "\n Fixes sent only on request"); 3842106424Sroberto } 3843106424Sroberto 3844106424Sroberto if (time_code & 0x08) { 3845106424Sroberto pbuf += sprintf(pbuf, "\n Synchronized measurements"); 3846106424Sroberto } 3847106424Sroberto 3848106424Sroberto if (time_code & 0x10) { 3849106424Sroberto pbuf += sprintf(pbuf, "\n Minimize measurement propagation"); 3850106424Sroberto } 3851106424Sroberto 3852285612Sdelphij pbuf += sprintf(pbuf, (time_code & 0x20) ? 3853285612Sdelphij "\n PPS output at all times" : 3854285612Sdelphij "\n PPS output during fixes"); 3855106424Sroberto 3856106424Sroberto if (aux_code & 0x01) { 3857106424Sroberto pbuf += sprintf(pbuf, "\n Raw measurement output"); 3858106424Sroberto } 3859106424Sroberto 3860106424Sroberto if (aux_code & 0x02) { 3861106424Sroberto pbuf += sprintf(pbuf, "\n Code-phase smoothed before output"); 3862106424Sroberto } 3863106424Sroberto 3864106424Sroberto if (aux_code & 0x04) { 3865106424Sroberto pbuf += sprintf(pbuf, "\n Additional fix status"); 3866106424Sroberto } 3867106424Sroberto 3868106424Sroberto pbuf += sprintf(pbuf, (aux_code & 0x08)? 3869285612Sdelphij "\n Signal Strength Output as dBHz" : 3870285612Sdelphij "\n Signal Strength Output as AMU"); 3871106424Sroberto} 3872106424Sroberto 3873106424Sroberto/* 0x56 */ 3874285612Sdelphijstatic void 3875285612Sdelphijrpt_ENU_velocity( 3876285612Sdelphij TSIPPKT *rpt 3877285612Sdelphij ) 3878106424Sroberto{ 3879106424Sroberto float 3880285612Sdelphij vel_ENU[3], freq_offset, time_of_fix; 3881106424Sroberto 3882106424Sroberto /* unload rptbuf */ 3883106424Sroberto if (rpt_0x56 (rpt, vel_ENU, &freq_offset, &time_of_fix)) { 3884106424Sroberto parsed = BADLEN_PARSE; 3885106424Sroberto return; 3886106424Sroberto } 3887106424Sroberto 3888106424Sroberto pbuf += sprintf(pbuf, "\nVel ENU: %11.3f %11.3f %11.3f %12.3f%s", 3889285612Sdelphij vel_ENU[0], vel_ENU[1], vel_ENU[2], freq_offset, 3890285612Sdelphij show_time (time_of_fix)); 3891106424Sroberto} 3892106424Sroberto 3893106424Sroberto/* 0x57 */ 3894285612Sdelphijstatic void 3895285612Sdelphijrpt_last_fix_info( 3896285612Sdelphij TSIPPKT *rpt 3897285612Sdelphij ) 3898106424Sroberto{ 3899106424Sroberto unsigned char 3900285612Sdelphij source_code, diag_code; 3901106424Sroberto short 3902285612Sdelphij week_num; 3903106424Sroberto float 3904285612Sdelphij time_of_fix; 3905106424Sroberto 3906106424Sroberto /* unload rptbuf */ 3907106424Sroberto if (rpt_0x57 (rpt, &source_code, &diag_code, &week_num, &time_of_fix)) { 3908106424Sroberto parsed = BADLEN_PARSE; 3909106424Sroberto return; 3910106424Sroberto } 3911106424Sroberto 3912106424Sroberto pbuf += sprintf(pbuf, "\n source code %d; diag code: %2Xh", 3913285612Sdelphij source_code, diag_code); 3914106424Sroberto pbuf += sprintf(pbuf, "\n Time of last fix:%s", show_time(time_of_fix)); 3915106424Sroberto pbuf += sprintf(pbuf, "\n Week of last fix: %d", week_num); 3916106424Sroberto} 3917106424Sroberto 3918106424Sroberto/* 0x58 */ 3919285612Sdelphijstatic void 3920285612Sdelphijrpt_GPS_system_data( 3921285612Sdelphij TSIPPKT *rpt 3922285612Sdelphij ) 3923106424Sroberto{ 3924106424Sroberto unsigned char 3925285612Sdelphij iprn, 3926285612Sdelphij op_code, data_type, sv_prn, 3927285612Sdelphij data_length, data_packet[250]; 3928106424Sroberto ALM_INFO 3929285612Sdelphij *almanac; 3930106424Sroberto ALH_PARMS 3931285612Sdelphij *almh; 3932106424Sroberto UTC_INFO 3933285612Sdelphij *utc; 3934106424Sroberto ION_INFO 3935285612Sdelphij *ionosphere; 3936106424Sroberto EPHEM_CLOCK 3937285612Sdelphij *cdata; 3938106424Sroberto EPHEM_ORBIT 3939285612Sdelphij *edata; 3940106424Sroberto NAV_INFO 3941285612Sdelphij *nav_data; 3942106424Sroberto unsigned char 3943285612Sdelphij curr_t_oa; 3944106424Sroberto unsigned short 3945285612Sdelphij curr_wn_oa; 3946106424Sroberto static char 3947285612Sdelphij *datname[] = 3948285612Sdelphij {"", "", "Almanac Orbit", 3949285612Sdelphij "Health Page & Ref Time", "Ionosphere", "UTC ", 3950285612Sdelphij "Ephemeris"}; 3951106424Sroberto 3952106424Sroberto /* unload rptbuf */ 3953106424Sroberto if (rpt_0x58 (rpt, &op_code, &data_type, &sv_prn, 3954285612Sdelphij &data_length, data_packet)) 3955285612Sdelphij { 3956106424Sroberto parsed = BADLEN_PARSE; 3957106424Sroberto return; 3958106424Sroberto } 3959106424Sroberto 3960106424Sroberto pbuf += sprintf(pbuf, "\nSystem data [%d]: %s SV%02d", 3961285612Sdelphij data_type, datname[data_type], sv_prn); 3962106424Sroberto switch (op_code) 3963106424Sroberto { 3964285612Sdelphij case 1: 3965106424Sroberto pbuf += sprintf(pbuf, " Acknowledgment"); 3966106424Sroberto break; 3967285612Sdelphij case 2: 3968106424Sroberto pbuf += sprintf(pbuf, " length = %d bytes", data_length); 3969106424Sroberto switch (data_type) { 3970285612Sdelphij case 2: 3971106424Sroberto /* Almanac */ 3972106424Sroberto if (sv_prn == 0 || sv_prn > 32) { 3973106424Sroberto pbuf += sprintf(pbuf, " Binary PRN invalid"); 3974106424Sroberto return; 3975106424Sroberto } 3976106424Sroberto almanac = (ALM_INFO*)data_packet; 3977106424Sroberto pbuf += sprintf(pbuf, "\n t_oa_raw = % -12d SV_hlth = % -12d ", 3978285612Sdelphij almanac->t_oa_raw , almanac->SV_health ); 3979106424Sroberto pbuf += sprintf(pbuf, "\n e = % -12g t_oa = % -12g ", 3980285612Sdelphij almanac->e , almanac->t_oa ); 3981106424Sroberto pbuf += sprintf(pbuf, "\n i_0 = % -12g OMEGADOT = % -12g ", 3982285612Sdelphij almanac->i_0 , almanac->OMEGADOT ); 3983106424Sroberto pbuf += sprintf(pbuf, "\n sqrt_A = % -12g OMEGA_0 = % -12g ", 3984285612Sdelphij almanac->sqrt_A , almanac->OMEGA_0 ); 3985106424Sroberto pbuf += sprintf(pbuf, "\n omega = % -12g M_0 = % -12g ", 3986285612Sdelphij almanac->omega , almanac->M_0 ); 3987106424Sroberto pbuf += sprintf(pbuf, "\n a_f0 = % -12g a_f1 = % -12g ", 3988285612Sdelphij almanac->a_f0 , almanac->a_f1 ); 3989106424Sroberto pbuf += sprintf(pbuf, "\n Axis = % -12g n = % -12g ", 3990285612Sdelphij almanac->Axis , almanac->n ); 3991106424Sroberto pbuf += sprintf(pbuf, "\n OMEGA_n = % -12g ODOT_n = % -12g ", 3992285612Sdelphij almanac->OMEGA_n , almanac->ODOT_n ); 3993106424Sroberto pbuf += sprintf(pbuf, "\n t_zc = % -12g weeknum = % -12d ", 3994285612Sdelphij almanac->t_zc , almanac->weeknum ); 3995106424Sroberto pbuf += sprintf(pbuf, "\n wn_oa = % -12d", almanac->wn_oa ); 3996106424Sroberto break; 3997106424Sroberto 3998285612Sdelphij case 3: 3999106424Sroberto /* Almanac health page */ 4000106424Sroberto almh = (ALH_PARMS*)data_packet; 4001106424Sroberto pbuf += sprintf(pbuf, "\n t_oa = %d, wn_oa&0xFF = %d ", 4002285612Sdelphij almh->t_oa, almh->WN_a); 4003106424Sroberto pbuf += sprintf(pbuf, "\nAlmanac health page:"); 4004106424Sroberto for (iprn = 0; iprn < 32; iprn++) { 4005106424Sroberto if (!(iprn%5)) *pbuf++ = '\n'; 4006106424Sroberto pbuf += sprintf(pbuf, " SV%02d %2X", 4007285612Sdelphij (iprn+1) , almh->SV_health[iprn]); 4008106424Sroberto } 4009106424Sroberto curr_t_oa = data_packet[34]; 4010106424Sroberto curr_wn_oa = (unsigned short)((data_packet[35]<<8) + data_packet[36]); 4011106424Sroberto pbuf += sprintf(pbuf, "\n current t_oa = %d, wn_oa = %d ", 4012285612Sdelphij curr_t_oa, curr_wn_oa); 4013106424Sroberto break; 4014106424Sroberto 4015285612Sdelphij case 4: 4016106424Sroberto /* Ionosphere */ 4017106424Sroberto ionosphere = (ION_INFO*)data_packet; 4018106424Sroberto pbuf += sprintf(pbuf, "\n alpha_0 = % -12g alpha_1 = % -12g ", 4019285612Sdelphij ionosphere->alpha_0, ionosphere->alpha_1); 4020106424Sroberto pbuf += sprintf(pbuf, "\n alpha_2 = % -12g alpha_3 = % -12g ", 4021285612Sdelphij ionosphere->alpha_2, ionosphere->alpha_3); 4022106424Sroberto pbuf += sprintf(pbuf, "\n beta_0 = % -12g beta_1 = % -12g ", 4023285612Sdelphij ionosphere->beta_0, ionosphere->beta_1); 4024106424Sroberto pbuf += sprintf(pbuf, "\n beta_2 = % -12g beta_3 = % -12g ", 4025285612Sdelphij ionosphere->beta_2, ionosphere->beta_3); 4026106424Sroberto break; 4027106424Sroberto 4028285612Sdelphij case 5: 4029106424Sroberto /* UTC */ 4030106424Sroberto utc = (UTC_INFO*)data_packet; 4031106424Sroberto pbuf += sprintf(pbuf, "\n A_0 = %g ", utc->A_0); 4032106424Sroberto pbuf += sprintf(pbuf, "\n A_1 = %g ", utc->A_1); 4033106424Sroberto pbuf += sprintf(pbuf, "\n delta_t_LS = %d ", utc->delta_t_LS); 4034106424Sroberto pbuf += sprintf(pbuf, "\n t_ot = %.0f ", utc->t_ot ); 4035106424Sroberto pbuf += sprintf(pbuf, "\n WN_t = %d ", utc->WN_t ); 4036106424Sroberto pbuf += sprintf(pbuf, "\n WN_LSF = %d ", utc->WN_LSF ); 4037106424Sroberto pbuf += sprintf(pbuf, "\n DN = %d ", utc->DN ); 4038106424Sroberto pbuf += sprintf(pbuf, "\n delta_t_LSF = %d ", utc->delta_t_LSF ); 4039106424Sroberto break; 4040106424Sroberto 4041285612Sdelphij case 6: /* Ephemeris */ 4042106424Sroberto if (sv_prn == 0 || sv_prn > 32) { 4043106424Sroberto pbuf += sprintf(pbuf, " Binary PRN invalid"); 4044106424Sroberto return; 4045106424Sroberto } 4046106424Sroberto nav_data = (NAV_INFO*)data_packet; 4047106424Sroberto 4048106424Sroberto pbuf += sprintf(pbuf, "\n SV_PRN = % -12d . t_ephem = % -12g . ", 4049285612Sdelphij nav_data->sv_number , nav_data->t_ephem ); 4050106424Sroberto cdata = &(nav_data->ephclk); 4051106424Sroberto pbuf += sprintf(pbuf, 4052285612Sdelphij "\n weeknum = % -12d . codeL2 = % -12d . L2Pdata = % -12d", 4053285612Sdelphij cdata->weeknum , cdata->codeL2 , cdata->L2Pdata ); 4054106424Sroberto pbuf += sprintf(pbuf, 4055285612Sdelphij "\n SVacc_raw = % -12d .SV_health = % -12d . IODC = % -12d", 4056285612Sdelphij cdata->SVacc_raw, cdata->SV_health, cdata->IODC ); 4057106424Sroberto pbuf += sprintf(pbuf, 4058285612Sdelphij "\n T_GD = % -12g . t_oc = % -12g . a_f2 = % -12g", 4059285612Sdelphij cdata->T_GD, cdata->t_oc, cdata->a_f2 ); 4060106424Sroberto pbuf += sprintf(pbuf, 4061285612Sdelphij "\n a_f1 = % -12g . a_f0 = % -12g . SVacc = % -12g", 4062285612Sdelphij cdata->a_f1, cdata->a_f0, cdata->SVacc ); 4063106424Sroberto edata = &(nav_data->ephorb); 4064106424Sroberto pbuf += sprintf(pbuf, 4065285612Sdelphij "\n IODE = % -12d .fit_intvl = % -12d . C_rs = % -12g", 4066285612Sdelphij edata->IODE, edata->fit_interval, edata->C_rs ); 4067106424Sroberto pbuf += sprintf(pbuf, 4068285612Sdelphij "\n delta_n = % -12g . M_0 = % -12g . C_uc = % -12g", 4069285612Sdelphij edata->delta_n, edata->M_0, edata->C_uc ); 4070106424Sroberto pbuf += sprintf(pbuf, 4071285612Sdelphij "\n ecc = % -12g . C_us = % -12g . sqrt_A = % -12g", 4072285612Sdelphij edata->e, edata->C_us, edata->sqrt_A ); 4073106424Sroberto pbuf += sprintf(pbuf, 4074285612Sdelphij "\n t_oe = % -12g . C_ic = % -12g . OMEGA_0 = % -12g", 4075285612Sdelphij edata->t_oe, edata->C_ic, edata->OMEGA_0 ); 4076106424Sroberto pbuf += sprintf(pbuf, 4077285612Sdelphij "\n C_is = % -12g . i_0 = % -12g . C_rc = % -12g", 4078285612Sdelphij edata->C_is, edata->i_0, edata->C_rc ); 4079106424Sroberto pbuf += sprintf(pbuf, 4080285612Sdelphij "\n omega = % -12g . OMEGADOT = % -12g . IDOT = % -12g", 4081285612Sdelphij edata->omega, edata->OMEGADOT, edata->IDOT ); 4082106424Sroberto pbuf += sprintf(pbuf, 4083285612Sdelphij "\n Axis = % -12g . n = % -12g . r1me2 = % -12g", 4084285612Sdelphij edata->Axis, edata->n, edata->r1me2 ); 4085106424Sroberto pbuf += sprintf(pbuf, 4086285612Sdelphij "\n OMEGA_n = % -12g . ODOT_n = % -12g", 4087285612Sdelphij edata->OMEGA_n, edata->ODOT_n ); 4088106424Sroberto break; 4089106424Sroberto } 4090106424Sroberto } 4091106424Sroberto} 4092106424Sroberto 4093106424Sroberto 4094106424Sroberto/* 0x59: */ 4095285612Sdelphijstatic void 4096285612Sdelphijrpt_SVs_enabled( 4097285612Sdelphij TSIPPKT *rpt 4098285612Sdelphij ) 4099106424Sroberto{ 4100106424Sroberto unsigned char 4101285612Sdelphij numsvs, 4102285612Sdelphij code_type, 4103285612Sdelphij status_code[32]; 4104106424Sroberto short 4105285612Sdelphij iprn; 4106106424Sroberto 4107106424Sroberto /* unload rptbuf */ 4108106424Sroberto if (rpt_0x59 (rpt, &code_type, status_code)) 4109285612Sdelphij { 4110106424Sroberto parsed = BADLEN_PARSE; 4111106424Sroberto return; 4112106424Sroberto } 4113285612Sdelphij switch (code_type) 4114285612Sdelphij { 4115285612Sdelphij case 3: pbuf += sprintf(pbuf, "\nSVs Disabled:\n"); break; 4116285612Sdelphij case 6: pbuf += sprintf(pbuf, "\nSVs with Health Ignored:\n"); break; 4117285612Sdelphij default: return; 4118285612Sdelphij } 4119285612Sdelphij numsvs = 0; 4120285612Sdelphij for (iprn = 0; iprn < 32; iprn++) 4121285612Sdelphij { 4122285612Sdelphij if (status_code[iprn]) 4123285612Sdelphij { 4124285612Sdelphij pbuf += sprintf(pbuf, " %02d", iprn+1); 4125285612Sdelphij numsvs++; 4126285612Sdelphij } 4127285612Sdelphij } 4128285612Sdelphij if (numsvs == 0) pbuf += sprintf(pbuf, "None"); 4129106424Sroberto} 4130106424Sroberto 4131106424Sroberto 4132106424Sroberto/* 0x5A */ 4133285612Sdelphijstatic void 4134285612Sdelphijrpt_raw_msmt( 4135285612Sdelphij TSIPPKT *rpt 4136285612Sdelphij ) 4137106424Sroberto{ 4138106424Sroberto unsigned char 4139285612Sdelphij sv_prn; 4140106424Sroberto float 4141285612Sdelphij sample_length, signal_level, code_phase, Doppler; 4142106424Sroberto double 4143285612Sdelphij time_of_fix; 4144106424Sroberto 4145106424Sroberto /* unload rptbuf */ 4146106424Sroberto if (rpt_0x5A (rpt, &sv_prn, &sample_length, &signal_level, 4147285612Sdelphij &code_phase, &Doppler, &time_of_fix)) 4148285612Sdelphij { 4149106424Sroberto parsed = BADLEN_PARSE; 4150106424Sroberto return; 4151106424Sroberto } 4152106424Sroberto 4153106424Sroberto pbuf += sprintf(pbuf, "\n %02d %5.0f %7.1f %10.2f %10.2f %12.3f %s", 4154285612Sdelphij sv_prn, sample_length, signal_level, code_phase, Doppler, time_of_fix, 4155285612Sdelphij show_time ((float)time_of_fix)); 4156106424Sroberto} 4157106424Sroberto 4158106424Sroberto/* 0x5B */ 4159285612Sdelphijstatic void 4160285612Sdelphijrpt_SV_ephemeris_status( 4161285612Sdelphij TSIPPKT *rpt 4162285612Sdelphij ) 4163106424Sroberto{ 4164106424Sroberto unsigned char 4165285612Sdelphij sv_prn, sv_health, sv_iode, fit_interval_flag; 4166106424Sroberto float 4167285612Sdelphij time_of_collection, time_of_eph, sv_accy; 4168106424Sroberto 4169106424Sroberto /* unload rptbuf */ 4170106424Sroberto if (rpt_0x5B (rpt, &sv_prn, &sv_health, &sv_iode, &fit_interval_flag, 4171285612Sdelphij &time_of_collection, &time_of_eph, &sv_accy)) 4172285612Sdelphij { 4173106424Sroberto parsed = BADLEN_PARSE; 4174106424Sroberto return; 4175106424Sroberto } 4176106424Sroberto 4177106424Sroberto pbuf += sprintf(pbuf, "\n SV%02d %s %2Xh %2Xh ", 4178285612Sdelphij sv_prn, show_time (time_of_collection), sv_health, sv_iode); 4179106424Sroberto /* note: cannot use show_time twice in same call */ 4180106424Sroberto pbuf += sprintf(pbuf, "%s %1d %4.1f", 4181285612Sdelphij show_time (time_of_eph), fit_interval_flag, sv_accy); 4182106424Sroberto} 4183106424Sroberto 4184106424Sroberto/* 0x5C */ 4185285612Sdelphijstatic void 4186285612Sdelphijrpt_SV_tracking_status( 4187285612Sdelphij TSIPPKT *rpt 4188285612Sdelphij ) 4189106424Sroberto{ 4190106424Sroberto unsigned char 4191285612Sdelphij sv_prn, chan, slot, acq_flag, eph_flag, 4192285612Sdelphij old_msmt_flag, integer_msec_flag, bad_data_flag, 4193285612Sdelphij data_collect_flag; 4194106424Sroberto float 4195285612Sdelphij signal_level, time_of_last_msmt, 4196285612Sdelphij elev, azim; 4197106424Sroberto 4198106424Sroberto /* unload rptbuf */ 4199106424Sroberto if (rpt_0x5C (rpt, 4200285612Sdelphij &sv_prn, &slot, &chan, &acq_flag, &eph_flag, 4201285612Sdelphij &signal_level, &time_of_last_msmt, &elev, &azim, 4202285612Sdelphij &old_msmt_flag, &integer_msec_flag, &bad_data_flag, 4203285612Sdelphij &data_collect_flag)) 4204285612Sdelphij { 4205106424Sroberto parsed = BADLEN_PARSE; 4206106424Sroberto return; 4207106424Sroberto } 4208106424Sroberto 4209106424Sroberto pbuf += sprintf(pbuf, 4210285612Sdelphij "\n SV%2d %1d %1d %1d %4.1f %s %5.1f %5.1f", 4211285612Sdelphij sv_prn, chan, 4212285612Sdelphij acq_flag, eph_flag, signal_level, 4213285612Sdelphij show_time(time_of_last_msmt), 4214285612Sdelphij elev*R2D, azim*R2D); 4215106424Sroberto} 4216106424Sroberto 4217106424Sroberto/**/ 4218106424Sroberto/* 0x6D */ 4219285612Sdelphijstatic void 4220285612Sdelphijrpt_allSV_selection( 4221285612Sdelphij TSIPPKT *rpt 4222285612Sdelphij ) 4223106424Sroberto{ 4224106424Sroberto unsigned char 4225285612Sdelphij manual_mode, nsvs, sv_prn[8], ndim; 4226106424Sroberto short 4227285612Sdelphij islot; 4228106424Sroberto float 4229285612Sdelphij pdop, hdop, vdop, tdop; 4230106424Sroberto 4231106424Sroberto /* unload rptbuf */ 4232106424Sroberto if (rpt_0x6D (rpt, 4233285612Sdelphij &manual_mode, &nsvs, &ndim, sv_prn, 4234285612Sdelphij &pdop, &hdop, &vdop, &tdop)) 4235285612Sdelphij { 4236106424Sroberto parsed = BADLEN_PARSE; 4237106424Sroberto return; 4238106424Sroberto } 4239106424Sroberto 4240106424Sroberto switch (ndim) 4241285612Sdelphij { 4242285612Sdelphij case 0: 4243106424Sroberto pbuf += sprintf(pbuf, "\nMode: Searching, %d-SV:", nsvs); 4244285612Sdelphij break; 4245285612Sdelphij case 1: 4246106424Sroberto pbuf += sprintf(pbuf, "\nMode: One-SV Timing:"); 4247285612Sdelphij break; 4248285612Sdelphij case 3: case 4: 4249106424Sroberto pbuf += sprintf(pbuf, "\nMode: %c-%dD, %d-SV:", 4250285612Sdelphij manual_mode ? 'M' : 'A', ndim - 1, nsvs); 4251285612Sdelphij break; 4252285612Sdelphij case 5: 4253106424Sroberto pbuf += sprintf(pbuf, "\nMode: Timing, %d-SV:", nsvs); 4254285612Sdelphij break; 4255285612Sdelphij default: 4256106424Sroberto pbuf += sprintf(pbuf, "\nMode: Unknown = %d:", ndim); 4257285612Sdelphij break; 4258285612Sdelphij } 4259106424Sroberto 4260106424Sroberto for (islot = 0; islot < nsvs; islot++) 4261285612Sdelphij { 4262106424Sroberto if (sv_prn[islot]) pbuf += sprintf(pbuf, " %02d", sv_prn[islot]); 4263106424Sroberto } 4264285612Sdelphij if (ndim == 3 || ndim == 4) 4265285612Sdelphij { 4266106424Sroberto pbuf += sprintf(pbuf, "; DOPs: P %.1f H %.1f V %.1f T %.1f", 4267285612Sdelphij pdop, hdop, vdop, tdop); 4268285612Sdelphij } 4269106424Sroberto} 4270106424Sroberto 4271106424Sroberto/**/ 4272106424Sroberto/* 0x82 */ 4273285612Sdelphijstatic void 4274285612Sdelphijrpt_DGPS_position_mode( 4275285612Sdelphij TSIPPKT *rpt 4276285612Sdelphij ) 4277106424Sroberto{ 4278106424Sroberto unsigned char 4279285612Sdelphij diff_mode; 4280106424Sroberto 4281106424Sroberto /* unload rptbuf */ 4282106424Sroberto if (rpt_0x82 (rpt, &diff_mode)) { 4283106424Sroberto parsed = BADLEN_PARSE; 4284106424Sroberto return; 4285106424Sroberto } 4286106424Sroberto 4287106424Sroberto pbuf += sprintf(pbuf, "\nFix is%s DGPS-corrected (%s mode) (%d)", 4288285612Sdelphij (diff_mode&1) ? "" : " not", 4289285612Sdelphij (diff_mode&2) ? "auto" : "manual", 4290285612Sdelphij diff_mode); 4291106424Sroberto} 4292106424Sroberto 4293106424Sroberto/* 0x83 */ 4294285612Sdelphijstatic void 4295285612Sdelphijrpt_double_ECEF_position( 4296285612Sdelphij TSIPPKT *rpt 4297285612Sdelphij ) 4298106424Sroberto{ 4299106424Sroberto double 4300285612Sdelphij ECEF_pos[3], clock_bias; 4301106424Sroberto float 4302285612Sdelphij time_of_fix; 4303106424Sroberto 4304106424Sroberto /* unload rptbuf */ 4305106424Sroberto if (rpt_0x83 (rpt, ECEF_pos, &clock_bias, &time_of_fix)) 4306285612Sdelphij { 4307106424Sroberto parsed = BADLEN_PARSE; 4308106424Sroberto return; 4309106424Sroberto } 4310106424Sroberto 4311106424Sroberto pbuf += sprintf(pbuf, "\nDXYZ:%12.2f %13.2f %13.2f %12.2f%s", 4312285612Sdelphij ECEF_pos[0], ECEF_pos[1], ECEF_pos[2], clock_bias, 4313285612Sdelphij show_time(time_of_fix)); 4314106424Sroberto} 4315106424Sroberto 4316106424Sroberto/* 0x84 */ 4317285612Sdelphijstatic void 4318285612Sdelphijrpt_double_lla_position( 4319285612Sdelphij TSIPPKT *rpt 4320285612Sdelphij ) 4321106424Sroberto{ 4322106424Sroberto short 4323285612Sdelphij lat_deg, lon_deg; 4324106424Sroberto double 4325285612Sdelphij lat, lon, lat_min, lon_min, 4326285612Sdelphij alt, clock_bias; 4327106424Sroberto float 4328285612Sdelphij time_of_fix; 4329106424Sroberto unsigned char 4330285612Sdelphij north_south, east_west; 4331106424Sroberto 4332106424Sroberto /* unload rptbuf */ 4333106424Sroberto if (rpt_0x84 (rpt, 4334285612Sdelphij &lat, &lon, &alt, &clock_bias, &time_of_fix)) 4335285612Sdelphij { 4336106424Sroberto parsed = BADLEN_PARSE; 4337106424Sroberto return; 4338106424Sroberto } 4339106424Sroberto 4340106424Sroberto lat *= R2D; 4341106424Sroberto lon *= R2D; 4342106424Sroberto if (lat < 0.0) { 4343106424Sroberto north_south = 'S'; 4344106424Sroberto lat = -lat; 4345106424Sroberto } else { 4346106424Sroberto north_south = 'N'; 4347106424Sroberto } 4348106424Sroberto lat_deg = (short)lat; 4349106424Sroberto lat_min = (lat - lat_deg) * 60.0; 4350106424Sroberto 4351106424Sroberto if (lon < 0.0) { 4352106424Sroberto east_west = 'W'; 4353106424Sroberto lon = -lon; 4354106424Sroberto } else { 4355106424Sroberto east_west = 'E'; 4356106424Sroberto } 4357106424Sroberto lon_deg = (short)lon; 4358106424Sroberto lon_min = (lon - lon_deg) * 60.0; 4359106424Sroberto pbuf += sprintf(pbuf, "\nDLLA: %2d:%08.5f %c; %3d:%08.5f %c; %10.2f %12.2f%s", 4360285612Sdelphij lat_deg, lat_min, north_south, 4361285612Sdelphij lon_deg, lon_min, east_west, 4362285612Sdelphij alt, clock_bias, 4363285612Sdelphij show_time(time_of_fix)); 4364106424Sroberto} 4365106424Sroberto 4366106424Sroberto/* 0xBB */ 4367285612Sdelphijstatic void 4368285612Sdelphijrpt_complete_rcvr_config( 4369285612Sdelphij TSIPPKT *rpt 4370285612Sdelphij ) 4371106424Sroberto{ 4372106424Sroberto TSIP_RCVR_CFG TsipxBB ; 4373106424Sroberto /* unload rptbuf */ 4374106424Sroberto if (rpt_Paly0xBB (rpt, &TsipxBB)) 4375106424Sroberto { 4376106424Sroberto parsed = BADLEN_PARSE; 4377106424Sroberto return; 4378106424Sroberto } 4379106424Sroberto 4380106424Sroberto pbuf += sprintf(pbuf, "\n operating mode: %s", 4381285612Sdelphij NavModeText0xBB[TsipxBB.operating_mode]); 4382106424Sroberto pbuf += sprintf(pbuf, "\n dynamics: %s", 4383285612Sdelphij dyn_text[TsipxBB.dyn_code]); 4384106424Sroberto pbuf += sprintf(pbuf, "\n elev angle mask: %g deg", 4385285612Sdelphij TsipxBB.elev_mask * R2D); 4386106424Sroberto pbuf += sprintf(pbuf, "\n SNR mask: %g AMU", 4387285612Sdelphij TsipxBB.cno_mask); 4388106424Sroberto pbuf += sprintf(pbuf, "\n DOP mask: %g", 4389285612Sdelphij TsipxBB.dop_mask); 4390106424Sroberto pbuf += sprintf(pbuf, "\n DOP switch: %g", 4391285612Sdelphij TsipxBB.dop_switch); 4392106424Sroberto return ; 4393106424Sroberto} 4394106424Sroberto 4395106424Sroberto/* 0xBC */ 4396285612Sdelphijstatic void 4397285612Sdelphijrpt_rcvr_serial_port_config( 4398285612Sdelphij TSIPPKT *rpt 4399285612Sdelphij ) 4400106424Sroberto{ 4401106424Sroberto unsigned char 4402285612Sdelphij port_num, in_baud, out_baud, data_bits, parity, stop_bits, flow_control, 4403285612Sdelphij protocols_in, protocols_out, reserved; 4404106424Sroberto unsigned char known; 4405106424Sroberto 4406106424Sroberto /* unload rptbuf */ 4407106424Sroberto if (rpt_0xBC (rpt, &port_num, &in_baud, &out_baud, &data_bits, &parity, 4408285612Sdelphij &stop_bits, &flow_control, &protocols_in, &protocols_out, &reserved)) { 4409106424Sroberto parsed = BADLEN_PARSE; 4410106424Sroberto return; 4411106424Sroberto } 4412106424Sroberto /* rptbuf unloaded */ 4413106424Sroberto 4414106424Sroberto pbuf += sprintf(pbuf, "\n RECEIVER serial port %s config:", 4415285612Sdelphij rcvr_port_text[port_num]); 4416106424Sroberto 4417106424Sroberto pbuf += sprintf(pbuf, "\n I/O Baud %s/%s, %d - %s - %d", 4418285612Sdelphij st_baud_text_app[in_baud], 4419285612Sdelphij st_baud_text_app[out_baud], 4420285612Sdelphij data_bits+5, 4421285612Sdelphij parity_text[parity], 4422285612Sdelphij stop_bits=1); 4423106424Sroberto pbuf += sprintf(pbuf, "\n Input protocols: "); 4424106424Sroberto known = FALSE; 4425106424Sroberto if (protocols_in&B_TSIP) 4426285612Sdelphij { 4427106424Sroberto pbuf += sprintf(pbuf, "%s ", protocols_in_text[1]); 4428106424Sroberto known = TRUE; 4429106424Sroberto } 4430106424Sroberto if (known == FALSE) pbuf += sprintf(pbuf, "No known"); 4431106424Sroberto 4432106424Sroberto pbuf += sprintf(pbuf, "\n Output protocols: "); 4433106424Sroberto known = FALSE; 4434106424Sroberto if (protocols_out&B_TSIP) 4435285612Sdelphij { 4436106424Sroberto pbuf += sprintf(pbuf, "%s ", protocols_out_text[1]); 4437106424Sroberto known = TRUE; 4438106424Sroberto } 4439106424Sroberto if (protocols_out&B_NMEA) 4440285612Sdelphij { 4441106424Sroberto pbuf += sprintf(pbuf, "%s ", protocols_out_text[2]); 4442106424Sroberto known = TRUE; 4443106424Sroberto } 4444106424Sroberto if (known == FALSE) pbuf += sprintf(pbuf, "No known"); 4445106424Sroberto reserved = reserved; 4446106424Sroberto 4447285612Sdelphij} 4448106424Sroberto 4449106424Sroberto/* 0x8F */ 4450106424Sroberto/* 8F0B */ 4451285612Sdelphijstatic void 4452285612Sdelphijrpt_8F0B( 4453285612Sdelphij TSIPPKT *rpt 4454285612Sdelphij ) 4455106424Sroberto{ 4456106424Sroberto const char 4457285612Sdelphij *oprtng_dim[7] = { 4458285612Sdelphij "horizontal (2-D)", 4459285612Sdelphij "full position (3-D)", 4460285612Sdelphij "single satellite (0-D)", 4461285612Sdelphij "automatic", 4462285612Sdelphij "N/A", 4463285612Sdelphij "N/A", 4464285612Sdelphij "overdetermined clock"}; 4465285612Sdelphij char 4466285612Sdelphij sv_id[8]; 4467285612Sdelphij unsigned char 4468285612Sdelphij month, 4469285612Sdelphij date, 4470285612Sdelphij dim_mode, 4471285612Sdelphij north_south, 4472285612Sdelphij east_west; 4473285612Sdelphij unsigned short 4474285612Sdelphij event; 4475106424Sroberto short 4476285612Sdelphij utc_offset, 4477285612Sdelphij year, 4478285612Sdelphij local_index; 4479285612Sdelphij short 4480285612Sdelphij lat_deg, 4481285612Sdelphij lon_deg; 4482285612Sdelphij float 4483285612Sdelphij bias_unc, 4484285612Sdelphij dr_unc; 4485285612Sdelphij double 4486285612Sdelphij tow, 4487285612Sdelphij bias, 4488285612Sdelphij drift, 4489285612Sdelphij lat, 4490285612Sdelphij lon, 4491285612Sdelphij alt, 4492285612Sdelphij lat_min, 4493285612Sdelphij lon_min; 4494285612Sdelphij int 4495285612Sdelphij numfix, 4496285612Sdelphij numnotfix; 4497106424Sroberto 4498106424Sroberto if (rpt_0x8F0B(rpt, 4499285612Sdelphij &event, 4500285612Sdelphij &tow, 4501285612Sdelphij &date, 4502285612Sdelphij &month, 4503285612Sdelphij &year, 4504285612Sdelphij &dim_mode, 4505285612Sdelphij &utc_offset, 4506285612Sdelphij &bias, 4507285612Sdelphij &drift, 4508285612Sdelphij &bias_unc, 4509285612Sdelphij &dr_unc, 4510285612Sdelphij &lat, 4511285612Sdelphij &lon, 4512285612Sdelphij &alt, 4513285612Sdelphij sv_id)) 4514285612Sdelphij { 4515106424Sroberto parsed = BADLEN_PARSE; 4516106424Sroberto return; 4517106424Sroberto } 4518106424Sroberto 4519106424Sroberto if (event == 0) 4520285612Sdelphij { 4521285612Sdelphij pbuf += sprintf(pbuf, "\nNew partial+full meas"); 4522106424Sroberto } 4523285612Sdelphij else 4524285612Sdelphij { 4525106424Sroberto pbuf += sprintf(pbuf, "\nEvent count: %5d", event); 4526285612Sdelphij } 4527106424Sroberto 4528106424Sroberto pbuf += sprintf(pbuf, "\nGPS time : %s %2d/%2d/%2d (DMY)", 4529285612Sdelphij show_time(tow), date, month, year); 4530106424Sroberto pbuf += sprintf(pbuf, "\nMode : %s", oprtng_dim[dim_mode]); 4531106424Sroberto pbuf += sprintf(pbuf, "\nUTC offset: %2d", utc_offset); 4532106424Sroberto pbuf += sprintf(pbuf, "\nClock Bias: %6.2f m", bias); 4533106424Sroberto pbuf += sprintf(pbuf, "\nFreq bias : %6.2f m/s", drift); 4534106424Sroberto pbuf += sprintf(pbuf, "\nBias unc : %6.2f m", bias_unc); 4535106424Sroberto pbuf += sprintf(pbuf, "\nFreq unc : %6.2f m/s", dr_unc); 4536106424Sroberto 4537106424Sroberto lat *= R2D; /* convert from radians to degrees */ 4538106424Sroberto lon *= R2D; 4539106424Sroberto if (lat < 0.0) 4540285612Sdelphij { 4541106424Sroberto north_south = 'S'; 4542106424Sroberto lat = -lat; 4543106424Sroberto } 4544285612Sdelphij else 4545285612Sdelphij { 4546106424Sroberto north_south = 'N'; 4547106424Sroberto } 4548106424Sroberto 4549106424Sroberto lat_deg = (short)lat; 4550106424Sroberto lat_min = (lat - lat_deg) * 60.0; 4551106424Sroberto if (lon < 0.0) 4552285612Sdelphij { 4553106424Sroberto east_west = 'W'; 4554106424Sroberto lon = -lon; 4555106424Sroberto } 4556285612Sdelphij else 4557285612Sdelphij { 4558106424Sroberto east_west = 'E'; 4559106424Sroberto } 4560106424Sroberto 4561106424Sroberto lon_deg = (short)lon; 4562106424Sroberto lon_min = (lon - lon_deg) * 60.0; 4563106424Sroberto pbuf += sprintf(pbuf, "\nPosition :"); 4564106424Sroberto pbuf += sprintf(pbuf, " %4d %6.3f %c", lat_deg, lat_min, north_south); 4565106424Sroberto pbuf += sprintf(pbuf, " %5d %6.3f %c", lon_deg, lon_min, east_west); 4566106424Sroberto pbuf += sprintf(pbuf, " %10.2f", alt); 4567106424Sroberto 4568285612Sdelphij numfix = numnotfix = 0; 4569106424Sroberto for (local_index=0; local_index<8; local_index++) 4570285612Sdelphij { 4571106424Sroberto if (sv_id[local_index] < 0) numnotfix++; 4572106424Sroberto if (sv_id[local_index] > 0) numfix++; 4573285612Sdelphij } 4574285612Sdelphij if (numfix > 0) 4575285612Sdelphij { 4576106424Sroberto pbuf += sprintf(pbuf, "\nSVs used in fix : "); 4577106424Sroberto for (local_index=0; local_index<8; local_index++) 4578285612Sdelphij { 4579106424Sroberto if (sv_id[local_index] > 0) 4580285612Sdelphij { 4581285612Sdelphij pbuf += sprintf(pbuf, "%2d ", sv_id[local_index]); 4582285612Sdelphij } 4583285612Sdelphij } 4584285612Sdelphij } 4585285612Sdelphij if (numnotfix > 0) 4586285612Sdelphij { 4587106424Sroberto pbuf += sprintf(pbuf, "\nOther SVs tracked: "); 4588106424Sroberto for (local_index=0; local_index<8; local_index++) 4589285612Sdelphij { 4590106424Sroberto if (sv_id[local_index] < 0) 4591285612Sdelphij { 4592285612Sdelphij pbuf += sprintf(pbuf, "%2d ", sv_id[local_index]); 4593285612Sdelphij } 4594285612Sdelphij } 4595285612Sdelphij } 4596106424Sroberto} 4597106424Sroberto 4598106424Sroberto/* 0x8F14 */ 4599106424Sroberto/* Datum parameters */ 4600285612Sdelphijstatic void 4601285612Sdelphijrpt_8F14( 4602285612Sdelphij TSIPPKT *rpt 4603285612Sdelphij ) 4604106424Sroberto{ 4605106424Sroberto double 4606285612Sdelphij datum_coeffs[5]; 4607106424Sroberto short 4608285612Sdelphij datum_idx; 4609106424Sroberto 4610106424Sroberto /* unload rptbuf */ 4611106424Sroberto if (rpt_0x8F14 (rpt, &datum_idx, datum_coeffs)) 4612285612Sdelphij { 4613106424Sroberto parsed = BADLEN_PARSE; 4614106424Sroberto return; 4615106424Sroberto } 4616106424Sroberto 4617106424Sroberto if (datum_idx == -1) 4618285612Sdelphij { 4619285612Sdelphij pbuf += sprintf(pbuf, "\nUser-Entered Datum:"); 4620106424Sroberto pbuf += sprintf(pbuf, "\n dx = %6.1f", datum_coeffs[0]); 4621106424Sroberto pbuf += sprintf(pbuf, "\n dy = %6.1f", datum_coeffs[1]); 4622106424Sroberto pbuf += sprintf(pbuf, "\n dz = %6.1f", datum_coeffs[2]); 4623106424Sroberto pbuf += sprintf(pbuf, "\n a-axis = %10.3f", datum_coeffs[3]); 4624106424Sroberto pbuf += sprintf(pbuf, "\n e-squared = %16.14f", datum_coeffs[4]); 4625285612Sdelphij } 4626285612Sdelphij else if (datum_idx == 0) 4627285612Sdelphij { 4628285612Sdelphij pbuf += sprintf(pbuf, "\nWGS-84 datum, Index 0 "); 4629285612Sdelphij } 4630285612Sdelphij else 4631285612Sdelphij { 4632285612Sdelphij pbuf += sprintf(pbuf, "\nStandard Datum, Index %3d ", datum_idx); 4633285612Sdelphij } 4634106424Sroberto} 4635106424Sroberto 4636106424Sroberto/* 0x8F15 */ 4637106424Sroberto/* Datum parameters */ 4638285612Sdelphijstatic void 4639285612Sdelphijrpt_8F15( 4640285612Sdelphij TSIPPKT *rpt 4641285612Sdelphij ) 4642106424Sroberto{ 4643106424Sroberto double 4644285612Sdelphij datum_coeffs[5]; 4645106424Sroberto short 4646285612Sdelphij datum_idx; 4647106424Sroberto 4648106424Sroberto /* unload rptbuf */ 4649106424Sroberto if (rpt_0x8F15 (rpt, &datum_idx, datum_coeffs)) { 4650106424Sroberto parsed = BADLEN_PARSE; 4651106424Sroberto return; 4652106424Sroberto } 4653106424Sroberto 4654106424Sroberto if (datum_idx == -1) 4655285612Sdelphij { 4656285612Sdelphij pbuf += sprintf(pbuf, "\nUser-Entered Datum:"); 4657106424Sroberto pbuf += sprintf(pbuf, "\n dx = %6.1f", datum_coeffs[0]); 4658106424Sroberto pbuf += sprintf(pbuf, "\n dy = %6.1f", datum_coeffs[1]); 4659106424Sroberto pbuf += sprintf(pbuf, "\n dz = %6.1f", datum_coeffs[2]); 4660106424Sroberto pbuf += sprintf(pbuf, "\n a-axis = %10.3f", datum_coeffs[3]); 4661106424Sroberto pbuf += sprintf(pbuf, "\n e-squared = %16.14f", datum_coeffs[4]); 4662285612Sdelphij } 4663285612Sdelphij else if (datum_idx == 0) 4664285612Sdelphij { 4665285612Sdelphij pbuf += sprintf(pbuf, "\nWGS-84 datum, Index 0 "); 4666285612Sdelphij } 4667285612Sdelphij else 4668285612Sdelphij { 4669285612Sdelphij pbuf += sprintf(pbuf, "\nStandard Datum, Index %3d ", datum_idx); 4670285612Sdelphij } 4671106424Sroberto} 4672106424Sroberto 4673106424Sroberto/* 0x8F20 */ 4674106424Sroberto#define INFO_DGPS 0x02 4675106424Sroberto#define INFO_2D 0x04 4676106424Sroberto#define INFO_ALTSET 0x08 4677106424Sroberto#define INFO_FILTERED 0x10 4678285612Sdelphijstatic void 4679285612Sdelphijrpt_8F20( 4680285612Sdelphij TSIPPKT *rpt 4681285612Sdelphij ) 4682106424Sroberto{ 4683106424Sroberto unsigned char 4684285612Sdelphij info, nsvs, sv_prn[32]; 4685106424Sroberto short 4686285612Sdelphij week_num, datum_index, sv_IODC[32]; 4687106424Sroberto double 4688285612Sdelphij lat, lon, alt, time_of_fix; 4689106424Sroberto double 4690285612Sdelphij londeg, latdeg, vel[3]; 4691106424Sroberto short 4692285612Sdelphij isv; 4693285612Sdelphij char 4694285612Sdelphij datum_string[20]; 4695106424Sroberto 4696106424Sroberto /* unload rptbuf */ 4697106424Sroberto if (rpt_0x8F20 (rpt, 4698285612Sdelphij &info, &lat, &lon, &alt, vel, 4699285612Sdelphij &time_of_fix, 4700285612Sdelphij &week_num, &nsvs, sv_prn, sv_IODC, &datum_index)) 4701106424Sroberto { 4702106424Sroberto parsed = BADLEN_PARSE; 4703106424Sroberto return; 4704106424Sroberto } 4705106424Sroberto pbuf += sprintf(pbuf, 4706285612Sdelphij "\nFix at: %04d:%3s:%02d:%02d:%06.3f GPS (=UTC+%2ds) FixType: %s%s%s", 4707285612Sdelphij week_num, 4708285612Sdelphij dayname[(short)(time_of_fix/86400.0)], 4709285612Sdelphij (short)fmod(time_of_fix/3600., 24.), 4710285612Sdelphij (short)fmod(time_of_fix/60., 60.), 4711285612Sdelphij fmod(time_of_fix, 60.), 4712285612Sdelphij (char)rpt->buf[29], /* UTC offset */ 4713285612Sdelphij (info & INFO_DGPS)?"Diff":"", 4714285612Sdelphij (info & INFO_2D)?"2D":"3D", 4715285612Sdelphij (info & INFO_FILTERED)?"-Filtrd":""); 4716106424Sroberto 4717285612Sdelphij if (datum_index > 0) 4718285612Sdelphij { 4719106424Sroberto sprintf(datum_string, "Datum%3d", datum_index); 4720285612Sdelphij } 4721285612Sdelphij else if (datum_index) 4722285612Sdelphij { 4723106424Sroberto sprintf(datum_string, "Unknown "); 4724285612Sdelphij } 4725285612Sdelphij else 4726285612Sdelphij { 4727106424Sroberto sprintf(datum_string, "WGS-84"); 4728285612Sdelphij } 4729106424Sroberto 4730106424Sroberto /* convert from radians to degrees */ 4731106424Sroberto latdeg = R2D * fabs(lat); 4732106424Sroberto londeg = R2D * fabs(lon); 4733106424Sroberto pbuf += sprintf(pbuf, 4734285612Sdelphij "\n Pos: %4d:%09.6f %c %5d:%09.6f %c %10.2f m HAE (%s)", 4735285612Sdelphij (short)latdeg, fmod (latdeg, 1.)*60.0, 4736285612Sdelphij (lat<0.0)?'S':'N', 4737285612Sdelphij (short)londeg, fmod (londeg, 1.)*60.0, 4738285612Sdelphij (lon<0.0)?'W':'E', 4739285612Sdelphij alt, 4740285612Sdelphij datum_string); 4741106424Sroberto pbuf += sprintf(pbuf, 4742285612Sdelphij "\n Vel: %9.3f E %9.3f N %9.3f U (m/sec)", 4743285612Sdelphij vel[0], vel[1], vel[2]); 4744106424Sroberto 4745106424Sroberto pbuf += sprintf(pbuf, 4746285612Sdelphij "\n SVs: "); 4747106424Sroberto for (isv = 0; isv < nsvs; isv++) { 4748106424Sroberto pbuf += sprintf(pbuf, " %02d", sv_prn[isv]); 4749106424Sroberto } 4750106424Sroberto pbuf += sprintf(pbuf, " (IODEs:"); 4751106424Sroberto for (isv = 0; isv < nsvs; isv++) { 4752106424Sroberto pbuf += sprintf(pbuf, " %02X", sv_IODC[isv]&0xFF); 4753106424Sroberto } 4754106424Sroberto pbuf += sprintf(pbuf, ")"); 4755106424Sroberto} 4756106424Sroberto 4757106424Sroberto/* 0x8F41 */ 4758285612Sdelphijstatic void 4759285612Sdelphijrpt_8F41( 4760285612Sdelphij TSIPPKT *rpt 4761285612Sdelphij ) 4762106424Sroberto{ 4763106424Sroberto unsigned char 4764285612Sdelphij bSearchRange, 4765285612Sdelphij bBoardOptions, 4766285612Sdelphij bBuildYear, 4767285612Sdelphij bBuildMonth, 4768285612Sdelphij bBuildDay, 4769285612Sdelphij bBuildHour; 4770106424Sroberto float 4771285612Sdelphij fOscOffset; 4772106424Sroberto unsigned short 4773285612Sdelphij iTestCodeId; 4774106424Sroberto unsigned long 4775285612Sdelphij iiSerialNumber; 4776106424Sroberto 4777285612Sdelphij if (!rpt_0x8F41(rpt, 4778285612Sdelphij &bSearchRange, 4779285612Sdelphij &bBoardOptions, 4780285612Sdelphij &iiSerialNumber, 4781285612Sdelphij &bBuildYear, 4782285612Sdelphij &bBuildMonth, 4783285612Sdelphij &bBuildDay, 4784285612Sdelphij &bBuildHour, 4785285612Sdelphij &fOscOffset, 4786285612Sdelphij &iTestCodeId)) 4787285612Sdelphij { 4788106424Sroberto parsed = BADLEN_PARSE; 4789285612Sdelphij return; 4790285612Sdelphij } 4791106424Sroberto 4792285612Sdelphij pbuf += sprintf(pbuf, "\n search range: %d", 4793285612Sdelphij bSearchRange); 4794285612Sdelphij pbuf += sprintf(pbuf, "\n board options: %d", 4795285612Sdelphij bBoardOptions); 4796285612Sdelphij pbuf += sprintf(pbuf, "\n board serial #: %ld", 4797285612Sdelphij iiSerialNumber); 4798285612Sdelphij pbuf += sprintf(pbuf, "\n build date/hour: %02d/%02d/%02d %02d:00", 4799285612Sdelphij bBuildDay, bBuildMonth, bBuildYear, bBuildHour); 4800285612Sdelphij pbuf += sprintf(pbuf, "\n osc offset: %.3f PPM (%.0f Hz)", 4801285612Sdelphij fOscOffset/1575.42, fOscOffset); 4802285612Sdelphij pbuf += sprintf(pbuf, "\n test code: %d", 4803285612Sdelphij iTestCodeId); 4804106424Sroberto} 4805106424Sroberto 4806106424Sroberto/* 0x8F42 */ 4807285612Sdelphijstatic void 4808285612Sdelphijrpt_8F42( 4809285612Sdelphij TSIPPKT *rpt 4810285612Sdelphij ) 4811106424Sroberto{ 4812106424Sroberto unsigned char 4813285612Sdelphij bProdOptionsPre, 4814285612Sdelphij bProdNumberExt; 4815106424Sroberto unsigned short 4816285612Sdelphij iCaseSerialNumberPre, 4817285612Sdelphij iPremiumOptions, 4818285612Sdelphij iMachineID, 4819285612Sdelphij iKey; 4820106424Sroberto unsigned long 4821285612Sdelphij iiCaseSerialNumber, 4822285612Sdelphij iiProdNumber; 4823106424Sroberto 4824285612Sdelphij if (!rpt_0x8F42(rpt, 4825285612Sdelphij &bProdOptionsPre, 4826285612Sdelphij &bProdNumberExt, 4827285612Sdelphij &iCaseSerialNumberPre, 4828285612Sdelphij &iiCaseSerialNumber, 4829285612Sdelphij &iiProdNumber, 4830285612Sdelphij &iPremiumOptions, 4831285612Sdelphij &iMachineID, 4832285612Sdelphij &iKey)) 4833285612Sdelphij { 4834106424Sroberto parsed = BADLEN_PARSE; 4835285612Sdelphij return; 4836285612Sdelphij } 4837106424Sroberto 4838106424Sroberto pbuf += sprintf(pbuf, "\nProduct ID 8F42"); 4839285612Sdelphij pbuf += sprintf(pbuf, "\n extension: %d", bProdNumberExt); 4840285612Sdelphij pbuf += sprintf(pbuf, "\n case serial # prefix: %d", iCaseSerialNumberPre); 4841285612Sdelphij pbuf += sprintf(pbuf, "\n case serial #: %ld", iiCaseSerialNumber); 4842285612Sdelphij pbuf += sprintf(pbuf, "\n prod. #: %ld", iiProdNumber); 4843106424Sroberto pbuf += sprintf(pbuf, "\n premium options: %Xh", iPremiumOptions); 4844285612Sdelphij pbuf += sprintf(pbuf, "\n machine ID: %d", iMachineID); 4845285612Sdelphij pbuf += sprintf(pbuf, "\n key: %Xh", iKey); 4846106424Sroberto} 4847106424Sroberto 4848106424Sroberto/* 0x8F45 */ 4849285612Sdelphijstatic void 4850285612Sdelphijrpt_8F45( 4851285612Sdelphij TSIPPKT *rpt 4852285612Sdelphij ) 4853106424Sroberto{ 4854285612Sdelphij unsigned char bSegMask; 4855106424Sroberto 4856285612Sdelphij if (!rpt_0x8F45(rpt, 4857285612Sdelphij &bSegMask)) 4858285612Sdelphij { 4859106424Sroberto parsed = BADLEN_PARSE; 4860106424Sroberto return; 4861106424Sroberto } 4862106424Sroberto pbuf += sprintf(pbuf, "\nCleared Segment Mask: %Xh", bSegMask); 4863106424Sroberto} 4864106424Sroberto 4865106424Sroberto/* Stinger PPS def */ 4866285612Sdelphijstatic void 4867285612Sdelphijrpt_8F4A( 4868285612Sdelphij TSIPPKT *rpt 4869285612Sdelphij ) 4870106424Sroberto{ 4871106424Sroberto unsigned char 4872285612Sdelphij pps_enabled, 4873285612Sdelphij pps_timebase, 4874285612Sdelphij pps_polarity; 4875285612Sdelphij float 4876285612Sdelphij bias_unc_threshold; 4877285612Sdelphij double 4878285612Sdelphij pps_offset; 4879106424Sroberto 4880106424Sroberto if (rpt_0x8F4A_16 (rpt, 4881285612Sdelphij &pps_enabled, 4882285612Sdelphij &pps_timebase, 4883285612Sdelphij &pps_polarity, 4884285612Sdelphij &pps_offset, 4885285612Sdelphij &bias_unc_threshold)) 4886285612Sdelphij { 4887285612Sdelphij parsed = BADLEN_PARSE; 4888285612Sdelphij return; 4889285612Sdelphij } 4890106424Sroberto 4891106424Sroberto pbuf += sprintf(pbuf, "\nPPS is %s", pps_enabled?"enabled":"disabled"); 4892285612Sdelphij pbuf += sprintf(pbuf, "\n timebase: %s", PPSTimeBaseText[pps_timebase]); 4893285612Sdelphij pbuf += sprintf(pbuf, "\n polarity: %s", PPSPolarityText[pps_polarity]); 4894285612Sdelphij pbuf += sprintf(pbuf, "\n offset: %.1f ns, ", pps_offset*1.e9); 4895285612Sdelphij pbuf += sprintf(pbuf, "\n biasunc: %.1f ns", bias_unc_threshold/GPS_C*1.e9); 4896106424Sroberto} 4897106424Sroberto 4898106424Sroberto/* fast-SA decorrolation time for self-survey */ 4899285612Sdelphijstatic void 4900285612Sdelphijrpt_8F4B( 4901285612Sdelphij TSIPPKT *rpt 4902285612Sdelphij ) 4903106424Sroberto{ 4904106424Sroberto unsigned long 4905285612Sdelphij decorr_max; 4906106424Sroberto 4907285612Sdelphij if (rpt_0x8F4B(rpt, &decorr_max)) 4908285612Sdelphij { 4909106424Sroberto parsed = BADLEN_PARSE; 4910285612Sdelphij return; 4911285612Sdelphij } 4912106424Sroberto 4913285612Sdelphij pbuf += sprintf(pbuf, 4914285612Sdelphij "\nMax # of position fixes for self-survey : %ld", 4915285612Sdelphij decorr_max); 4916106424Sroberto} 4917106424Sroberto 4918285612Sdelphijstatic void 4919285612Sdelphijrpt_8F4D( 4920285612Sdelphij TSIPPKT *rpt 4921285612Sdelphij ) 4922106424Sroberto{ 4923106424Sroberto static char 4924285612Sdelphij *linestart; 4925106424Sroberto unsigned long 4926285612Sdelphij OutputMask; 4927285612Sdelphij static unsigned long 4928285612Sdelphij MaskBit[] = { 4929285612Sdelphij 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 4930285612Sdelphij 0x00000020, 4931285612Sdelphij 0x00000100L, 0x00000800L, 0x00001000L, 4932285612Sdelphij 0x40000000L, 0x80000000L}; 4933285612Sdelphij int 4934285612Sdelphij ichoice, 4935285612Sdelphij numchoices; 4936106424Sroberto 4937285612Sdelphij if (rpt_0x8F4D(rpt, &OutputMask)) 4938285612Sdelphij { 4939106424Sroberto parsed = BADLEN_PARSE; 4940285612Sdelphij return; 4941285612Sdelphij } 4942106424Sroberto 4943285612Sdelphij pbuf += sprintf(pbuf, "\nAuto-Report Mask: %02X %02X %02X %02X", 4944285612Sdelphij (unsigned char)(OutputMask>>24), 4945285612Sdelphij (unsigned char)(OutputMask>>16), 4946285612Sdelphij (unsigned char)(OutputMask>>8), 4947285612Sdelphij (unsigned char)OutputMask); 4948106424Sroberto 4949285612Sdelphij numchoices = sizeof(MaskText)/sizeof(char*); 4950285612Sdelphij pbuf += sprintf(pbuf, "\nAuto-Reports scheduled for Output:"); 4951285612Sdelphij linestart = pbuf; 4952285612Sdelphij for (ichoice = 0; ichoice < numchoices; ichoice++) 4953285612Sdelphij { 4954285612Sdelphij if (OutputMask&MaskBit[ichoice]) 4955285612Sdelphij { 4956285612Sdelphij pbuf += sprintf(pbuf, "%s %s", 4957285612Sdelphij (pbuf==linestart)?"\n ":",", 4958285612Sdelphij MaskText[ichoice]); 4959106424Sroberto if (pbuf-linestart > 60) linestart = pbuf; 4960285612Sdelphij } 4961285612Sdelphij } 4962106424Sroberto 4963285612Sdelphij pbuf += sprintf(pbuf, "\nAuto-Reports NOT scheduled for Output:"); 4964285612Sdelphij linestart = pbuf; 4965285612Sdelphij for (ichoice = 0; ichoice < numchoices; ichoice++) 4966285612Sdelphij { 4967285612Sdelphij if (OutputMask&MaskBit[ichoice]) continue; 4968106424Sroberto pbuf += sprintf(pbuf, "%s %s", 4969285612Sdelphij (pbuf==linestart)?"\n ":",", 4970285612Sdelphij MaskText[ichoice]); 4971106424Sroberto if (pbuf-linestart > 60) linestart = pbuf; 4972285612Sdelphij } 4973106424Sroberto} 4974106424Sroberto 4975285612Sdelphijstatic void 4976285612Sdelphijrpt_8FA5( 4977285612Sdelphij TSIPPKT *rpt 4978285612Sdelphij ) 4979106424Sroberto{ 4980106424Sroberto unsigned char 4981285612Sdelphij spktmask[4]; 4982106424Sroberto 4983285612Sdelphij if (rpt_0x8FA5(rpt, spktmask)) 4984285612Sdelphij { 4985106424Sroberto parsed = BADLEN_PARSE; 4986285612Sdelphij return; 4987285612Sdelphij } 4988106424Sroberto 4989285612Sdelphij pbuf += sprintf(pbuf, "\nSuperpacket auto-output mask: %02X %02X %02X %02X", 4990285612Sdelphij spktmask[0], spktmask[1], spktmask[2], spktmask[3]); 4991106424Sroberto 4992285612Sdelphij if (spktmask[0]&0x01) pbuf+= sprintf (pbuf, "\n PPS 8F-0B"); 4993285612Sdelphij if (spktmask[0]&0x02) pbuf+= sprintf (pbuf, "\n Event 8F-0B"); 4994285612Sdelphij if (spktmask[0]&0x10) pbuf+= sprintf (pbuf, "\n PPS 8F-AD"); 4995285612Sdelphij if (spktmask[0]&0x20) pbuf+= sprintf (pbuf, "\n Event 8F-AD"); 4996285612Sdelphij if (spktmask[2]&0x01) pbuf+= sprintf (pbuf, "\n ppos Fix 8F-20"); 4997106424Sroberto} 4998106424Sroberto 4999285612Sdelphijstatic void 5000285612Sdelphijrpt_8FAD( 5001285612Sdelphij TSIPPKT *rpt 5002285612Sdelphij ) 5003106424Sroberto{ 5004285612Sdelphij unsigned short 5005285612Sdelphij Count, 5006285612Sdelphij Year; 5007285612Sdelphij double 5008285612Sdelphij FracSec; 5009285612Sdelphij unsigned char 5010285612Sdelphij Hour, 5011285612Sdelphij Minute, 5012285612Sdelphij Second, 5013285612Sdelphij Day, 5014285612Sdelphij Month, 5015285612Sdelphij Status, 5016285612Sdelphij Flags; 5017106424Sroberto static char* Status8FADText[] = { 5018285612Sdelphij "CODE_DOING_FIXES", 5019285612Sdelphij "CODE_GOOD_1_SV", 5020285612Sdelphij "CODE_APPX_1SV", 5021285612Sdelphij "CODE_NEED_TIME", 5022285612Sdelphij "CODE_NEED_INITIALIZATION", 5023285612Sdelphij "CODE_PDOP_HIGH", 5024285612Sdelphij "CODE_BAD_1SV", 5025285612Sdelphij "CODE_0SVS", 5026285612Sdelphij "CODE_1SV", 5027285612Sdelphij "CODE_2SVS", 5028285612Sdelphij "CODE_3SVS", 5029285612Sdelphij "CODE_NO_INTEGRITY", 5030285612Sdelphij "CODE_DCORR_GEN", 5031285612Sdelphij "CODE_OVERDET_CLK", 5032285612Sdelphij "Invalid Status"}, 5033285612Sdelphij *LeapStatusText[] = { 5034285612Sdelphij " UTC Avail", " ", " ", " ", 5035285612Sdelphij " Scheduled", " Pending", " Warning", " In Progress"}; 5036285612Sdelphij int i; 5037106424Sroberto 5038106424Sroberto if (rpt_0x8FAD (rpt, 5039285612Sdelphij &Count, 5040285612Sdelphij &FracSec, 5041285612Sdelphij &Hour, 5042285612Sdelphij &Minute, 5043285612Sdelphij &Second, 5044285612Sdelphij &Day, 5045285612Sdelphij &Month, 5046285612Sdelphij &Year, 5047285612Sdelphij &Status, 5048285612Sdelphij &Flags)) 5049285612Sdelphij { 5050106424Sroberto parsed = BADLEN_PARSE; 5051106424Sroberto return; 5052285612Sdelphij } 5053106424Sroberto 5054106424Sroberto pbuf += sprintf(pbuf, "\n8FAD Count: %d Status: %s", 5055285612Sdelphij Count, Status8FADText[Status]); 5056106424Sroberto 5057285612Sdelphij pbuf += sprintf(pbuf, "\n Leap Flags:"); 5058285612Sdelphij if (Flags) 5059285612Sdelphij { 5060285612Sdelphij for (i=0; i<8; i++) 5061285612Sdelphij { 5062285612Sdelphij if (Flags&(1<<i)) pbuf += sprintf(pbuf, LeapStatusText[i]); 5063285612Sdelphij } 5064285612Sdelphij } 5065285612Sdelphij else 5066285612Sdelphij { 5067285612Sdelphij pbuf += sprintf(pbuf, " UTC info not available"); 5068285612Sdelphij } 5069106424Sroberto 5070106424Sroberto pbuf += sprintf(pbuf, "\n %02d/%02d/%04d (DMY) %02d:%02d:%02d.%09ld UTC", 5071285612Sdelphij Day, Month, Year, Hour, Minute, Second, (long)(FracSec*1.e9)); 5072106424Sroberto} 5073106424Sroberto 5074106424Sroberto 5075285612Sdelphijint 5076285612Sdelphijprint_msg_table_header( 5077285612Sdelphij int rptcode, 5078285612Sdelphij char *HdrStr, 5079285612Sdelphij int force 5080285612Sdelphij ) 5081106424Sroberto{ 5082106424Sroberto /* force header is to help auto-output function */ 5083106424Sroberto /* last_rptcode is to determine whether to print a header */ 5084132451Sroberto /* for the first occurrence of a series of reports */ 5085106424Sroberto static int 5086285612Sdelphij last_rptcode = 0; 5087285612Sdelphij int 5088285612Sdelphij numchars; 5089106424Sroberto 5090285612Sdelphij numchars = 0; 5091106424Sroberto if (force || rptcode!=last_rptcode) 5092285612Sdelphij { 5093106424Sroberto /* supply a header in console output */ 5094285612Sdelphij switch (rptcode) 5095106424Sroberto { 5096285612Sdelphij case 0x5A: 5097106424Sroberto numchars = sprintf(HdrStr, "\nRaw Measurement Data"); 5098106424Sroberto numchars += sprintf(HdrStr+numchars, 5099285612Sdelphij "\n SV Sample SNR Code Phase Doppler Seconds Time of Meas"); 5100106424Sroberto break; 5101106424Sroberto 5102285612Sdelphij case 0x5B: 5103106424Sroberto numchars = sprintf(HdrStr, "\nEphemeris Status"); 5104106424Sroberto numchars += sprintf(HdrStr+numchars, 5105285612Sdelphij "\n SV Time collected Health IODE t oe Fit URA"); 5106106424Sroberto break; 5107106424Sroberto 5108285612Sdelphij case 0x5C: 5109106424Sroberto numchars = sprintf(HdrStr, "\nTracking Info"); 5110106424Sroberto numchars += sprintf(HdrStr+numchars, 5111285612Sdelphij "\n SV C Acq Eph SNR Time of Meas Elev Azim "); 5112106424Sroberto break; 5113106424Sroberto 5114285612Sdelphij } 5115106424Sroberto } 5116106424Sroberto last_rptcode = rptcode; 5117285612Sdelphij return (short)numchars; 5118106424Sroberto} 5119106424Sroberto 5120285612Sdelphijstatic void 5121285612Sdelphijunknown_rpt( 5122285612Sdelphij TSIPPKT *rpt 5123285612Sdelphij ) 5124106424Sroberto{ 5125106424Sroberto int i; 5126106424Sroberto 5127106424Sroberto /* app-specific rpt packets */ 5128106424Sroberto if (parsed == BADLEN_PARSE) 5129285612Sdelphij { 5130106424Sroberto pbuf += sprintf(pbuf, "\nTSIP report packet ID %2Xh, length %d: Bad length", 5131285612Sdelphij rpt->code, rpt->len); 5132285612Sdelphij } 5133106424Sroberto if (parsed == BADID_PARSE) 5134285612Sdelphij { 5135106424Sroberto pbuf += sprintf(pbuf, 5136285612Sdelphij "\nTSIP report packet ID %2Xh, length %d: translation not supported", 5137285612Sdelphij rpt->code, rpt->len); 5138285612Sdelphij } 5139106424Sroberto 5140106424Sroberto if (parsed == BADDATA_PARSE) 5141285612Sdelphij { 5142106424Sroberto pbuf += sprintf(pbuf, 5143285612Sdelphij "\nTSIP report packet ID %2Xh, length %d: data content incorrect", 5144285612Sdelphij rpt->code, rpt->len); 5145285612Sdelphij } 5146106424Sroberto 5147106424Sroberto for (i = 0; i < rpt->len; i++) { 5148106424Sroberto if ((i % 20) == 0) *pbuf++ = '\n'; 5149106424Sroberto pbuf += sprintf(pbuf, " %02X", rpt->buf[i]); 5150106424Sroberto } 5151106424Sroberto} 5152106424Sroberto/**/ 5153285612Sdelphij 5154106424Sroberto/* 5155106424Sroberto** main subroutine, called from ProcessInputBytesWhileWaitingForKBHit() 5156106424Sroberto*/ 5157285612Sdelphijvoid 5158285612SdelphijTranslateTSIPReportToText( 5159285612Sdelphij TSIPPKT *rpt, 5160285612Sdelphij char *TextOutputBuffer 5161285612Sdelphij ) 5162106424Sroberto{ 5163106424Sroberto 5164106424Sroberto /* pbuf is the pointer to the current location of the text output */ 5165106424Sroberto pbuf = TextOutputBuffer; 5166106424Sroberto 5167285612Sdelphij /* keep track of whether the message has been successfully parsed */ 5168106424Sroberto parsed = GOOD_PARSE; 5169106424Sroberto 5170106424Sroberto /* print a header if this is the first of a series of messages */ 5171106424Sroberto pbuf += print_msg_table_header (rpt->code, pbuf, FALSE); 5172106424Sroberto 5173285612Sdelphij /* process incoming TSIP report according to code */ 5174106424Sroberto switch (rpt->code) 5175285612Sdelphij { 5176285612Sdelphij case 0x3D: rpt_chan_A_config (rpt); break; 5177285612Sdelphij case 0x40: rpt_almanac_data_page (rpt); break; 5178285612Sdelphij case 0x41: rpt_GPS_time (rpt); break; 5179285612Sdelphij case 0x42: rpt_single_ECEF_position (rpt); break; 5180285612Sdelphij case 0x43: rpt_single_ECEF_velocity (rpt); break; 5181285612Sdelphij case 0x45: rpt_SW_version (rpt); break; 5182285612Sdelphij case 0x46: rpt_rcvr_health (rpt); break; 5183285612Sdelphij case 0x47: rpt_SNR_all_SVs (rpt); break; 5184285612Sdelphij case 0x48: rpt_GPS_system_message (rpt); break; 5185285612Sdelphij case 0x49: rpt_almanac_health_page (rpt); break; 5186285612Sdelphij case 0x4A: switch (rpt->len) { 5187285612Sdelphij /* 5188285612Sdelphij ** special case (=slip-up) in the TSIP protocol; 5189285612Sdelphij ** parsing method depends on length 5190285612Sdelphij */ 5191285612Sdelphij case 20: rpt_single_lla_position (rpt); break; 5192285612Sdelphij case 9: rpt_ref_alt (rpt); break; 5193106424Sroberto } break; 5194285612Sdelphij case 0x4B: rpt_rcvr_id_and_status (rpt);break; 5195285612Sdelphij case 0x4C: rpt_operating_parameters (rpt); break; 5196285612Sdelphij case 0x4D: rpt_oscillator_offset (rpt); break; 5197285612Sdelphij case 0x4E: rpt_GPS_time_set_response (rpt); break; 5198285612Sdelphij case 0x4F: rpt_UTC_offset (rpt); break; 5199285612Sdelphij case 0x54: rpt_1SV_bias (rpt); break; 5200285612Sdelphij case 0x55: rpt_io_opt (rpt); break; 5201285612Sdelphij case 0x56: rpt_ENU_velocity (rpt); break; 5202285612Sdelphij case 0x57: rpt_last_fix_info (rpt); break; 5203285612Sdelphij case 0x58: rpt_GPS_system_data (rpt); break; 5204285612Sdelphij case 0x59: rpt_SVs_enabled (rpt); break; 5205285612Sdelphij case 0x5A: rpt_raw_msmt (rpt); break; 5206285612Sdelphij case 0x5B: rpt_SV_ephemeris_status (rpt); break; 5207285612Sdelphij case 0x5C: rpt_SV_tracking_status (rpt); break; 5208285612Sdelphij case 0x6D: rpt_allSV_selection (rpt); break; 5209285612Sdelphij case 0x82: rpt_DGPS_position_mode (rpt); break; 5210285612Sdelphij case 0x83: rpt_double_ECEF_position (rpt); break; 5211285612Sdelphij case 0x84: rpt_double_lla_position (rpt); break; 5212285612Sdelphij case 0xBB: rpt_complete_rcvr_config (rpt); break; 5213285612Sdelphij case 0xBC: rpt_rcvr_serial_port_config (rpt); break; 5214106424Sroberto 5215285612Sdelphij case 0x8F: switch (rpt->buf[0]) 5216285612Sdelphij { 5217285612Sdelphij /* superpackets; parsed according to subcodes */ 5218285612Sdelphij case 0x0B: rpt_8F0B(rpt); break; 5219285612Sdelphij case 0x14: rpt_8F14(rpt); break; 5220285612Sdelphij case 0x15: rpt_8F15(rpt); break; 5221285612Sdelphij case 0x20: rpt_8F20(rpt); break; 5222285612Sdelphij case 0x41: rpt_8F41(rpt); break; 5223285612Sdelphij case 0x42: rpt_8F42(rpt); break; 5224285612Sdelphij case 0x45: rpt_8F45(rpt); break; 5225285612Sdelphij case 0x4A: rpt_8F4A(rpt); break; 5226285612Sdelphij case 0x4B: rpt_8F4B(rpt); break; 5227285612Sdelphij case 0x4D: rpt_8F4D(rpt); break; 5228285612Sdelphij case 0xA5: rpt_8FA5(rpt); break; 5229285612Sdelphij case 0xAD: rpt_8FAD(rpt); break; 5230285612Sdelphij default: parsed = BADID_PARSE; break; 5231106424Sroberto } 5232106424Sroberto break; 5233106424Sroberto 5234285612Sdelphij default: parsed = BADID_PARSE; break; 5235106424Sroberto } 5236106424Sroberto 5237106424Sroberto if (parsed != GOOD_PARSE) 5238106424Sroberto { 5239285612Sdelphij /* 5240285612Sdelphij **The message has TSIP structure (DLEs, etc.) 5241285612Sdelphij ** but could not be parsed by above routines 5242285612Sdelphij */ 5243106424Sroberto unknown_rpt (rpt); 5244106424Sroberto } 5245106424Sroberto 5246285612Sdelphij /* close TextOutputBuffer */ 5247285612Sdelphij pbuf = '\0'; 5248106424Sroberto} 5249106424Sroberto 5250106424Sroberto#endif /* TRIMBLE_OUTPUT_FUNC */ 5251106424Sroberto 5252106424Sroberto#else /* defined(REFCLOCK) && defined(CLOCK_RIPENCC) */ 5253106424Srobertoint refclock_ripencc_bs; 5254106424Sroberto#endif /* defined(REFCLOCK) && defined(CLOCK_RIPENCC) */ 5255106424Sroberto 5256