1ba371819SOllivier Robert /* 2ba371819SOllivier Robert * $Id: refclock_ripencc.c,v 1.13 2002/06/18 14:20:55 marks Exp marks $ 3ba371819SOllivier Robert * 4ba371819SOllivier Robert * Copyright (c) 2002 RIPE NCC 5ba371819SOllivier Robert * 6ba371819SOllivier Robert * All Rights Reserved 7ba371819SOllivier Robert * 8ba371819SOllivier Robert * Permission to use, copy, modify, and distribute this software and its 9ba371819SOllivier Robert * documentation for any purpose and without fee is hereby granted, 10ba371819SOllivier Robert * provided that the above copyright notice appear in all copies and that 11ba371819SOllivier Robert * both that copyright notice and this permission notice appear in 12ba371819SOllivier Robert * supporting documentation, and that the name of the author not be 13ba371819SOllivier Robert * used in advertising or publicity pertaining to distribution of the 14ba371819SOllivier Robert * software without specific, written prior permission. 15ba371819SOllivier Robert * 16ba371819SOllivier Robert * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 17ba371819SOllivier Robert * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 18ba371819SOllivier Robert * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 19ba371819SOllivier Robert * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 20ba371819SOllivier Robert * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21ba371819SOllivier Robert * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22ba371819SOllivier Robert * 23ba371819SOllivier Robert * 24ba371819SOllivier Robert * 25ba371819SOllivier Robert * This driver was developed for use with the RIPE NCC TTM project. 26ba371819SOllivier Robert * 27ba371819SOllivier Robert * 28ba371819SOllivier Robert * The initial driver was developed by Daniel Karrenberg <dfk@ripe.net> 29ba371819SOllivier Robert * using the code made available by Trimble. This was for xntpd-3.x.x 30ba371819SOllivier Robert * 31ba371819SOllivier Robert * Rewrite of the driver for ntpd-4.x.x by Mark Santcroos <marks@ripe.net> 32ba371819SOllivier Robert * 33ba371819SOllivier Robert */ 34ba371819SOllivier Robert 35ba371819SOllivier Robert #ifdef HAVE_CONFIG_H 36ba371819SOllivier Robert #include <config.h> 37ba371819SOllivier Robert #endif /* HAVE_CONFIG_H */ 38ba371819SOllivier Robert 39ba371819SOllivier Robert #if defined(REFCLOCK) && defined(CLOCK_RIPENCC) 40ba371819SOllivier Robert 41ba371819SOllivier Robert #include "ntp_stdlib.h" 42ba371819SOllivier Robert #include "ntpd.h" 43ba371819SOllivier Robert #include "ntp_refclock.h" 44ba371819SOllivier Robert #include "ntp_unixtime.h" 45ba371819SOllivier Robert #include "ntp_io.h" 46ba371819SOllivier Robert 47ea906c41SOllivier Robert #ifdef HAVE_PPSAPI 48ea906c41SOllivier Robert # include "ppsapi_timepps.h" 49ea906c41SOllivier Robert #endif 50ba371819SOllivier Robert 51ba371819SOllivier Robert /* 52ba371819SOllivier Robert * Definitions 53ba371819SOllivier Robert */ 54ba371819SOllivier Robert 55ba371819SOllivier Robert /* we are on little endian */ 56ba371819SOllivier Robert #define BYTESWAP 57ba371819SOllivier Robert 58ba371819SOllivier Robert /* 59ba371819SOllivier Robert * DEBUG statements: uncomment if necessary 60ba371819SOllivier Robert */ 61ba371819SOllivier Robert /* #define DEBUG_NCC */ /* general debug statements */ 62ba371819SOllivier Robert /* #define DEBUG_PPS */ /* debug pps */ 63ba371819SOllivier Robert /* #define DEBUG_RAW */ /* print raw packets */ 64ba371819SOllivier Robert 65ba371819SOllivier Robert #define TRIMBLE_OUTPUT_FUNC 66ba371819SOllivier Robert #define TSIP_VERNUM "7.12a" 67ba371819SOllivier Robert 68ba371819SOllivier Robert #ifndef FALSE 69ba371819SOllivier Robert #define FALSE (0) 70ba371819SOllivier Robert #define TRUE (!FALSE) 71ba371819SOllivier Robert #endif /* FALSE */ 72ba371819SOllivier Robert 73ba371819SOllivier Robert #define GPS_PI (3.1415926535898) 74ba371819SOllivier Robert #define GPS_C (299792458.) 75ba371819SOllivier Robert #define D2R (GPS_PI/180.0) 76ba371819SOllivier Robert #define R2D (180.0/GPS_PI) 77ba371819SOllivier Robert #define WEEK (604800.) 78ba371819SOllivier Robert #define MAXCHAN (8) 79ba371819SOllivier Robert 80ba371819SOllivier Robert /* control characters for TSIP packets */ 81ba371819SOllivier Robert #define DLE (0x10) 82ba371819SOllivier Robert #define ETX (0x03) 83ba371819SOllivier Robert 84ba371819SOllivier Robert #define MAX_RPTBUF (256) 85ba371819SOllivier Robert 86ba371819SOllivier Robert /* values of TSIPPKT.status */ 87ba371819SOllivier Robert #define TSIP_PARSED_EMPTY 0 88ba371819SOllivier Robert #define TSIP_PARSED_FULL 1 89ba371819SOllivier Robert #define TSIP_PARSED_DLE_1 2 90ba371819SOllivier Robert #define TSIP_PARSED_DATA 3 91ba371819SOllivier Robert #define TSIP_PARSED_DLE_2 4 92ba371819SOllivier Robert 93ba371819SOllivier Robert #define UTCF_UTC_AVAIL (unsigned char) (1) /* UTC available */ 94ba371819SOllivier Robert #define UTCF_LEAP_SCHD (unsigned char) (1<<4) /* Leap scheduled */ 95ba371819SOllivier Robert #define UTCF_LEAP_PNDG (unsigned char) (1<<5) /* Leap pending, will occur at end of day */ 96ba371819SOllivier Robert 97ba371819SOllivier Robert #define DEVICE "/dev/gps%d" /* name of radio device */ 98ba371819SOllivier Robert #define PRECISION (-9) /* precision assumed (about 2 ms) */ 99ba371819SOllivier Robert #define PPS_PRECISION (-20) /* precision assumed (about 1 us) */ 100ba371819SOllivier Robert #define REFID "GPS\0" /* reference id */ 101ba371819SOllivier Robert #define REFID_LEN 4 102ba371819SOllivier Robert #define DESCRIPTION "RIPE NCC GPS (Palisade)" /* Description */ 103ba371819SOllivier Robert #define SPEED232 B9600 /* 9600 baud */ 104ba371819SOllivier Robert 105ba371819SOllivier Robert #define NSAMPLES 3 /* stages of median filter */ 106ba371819SOllivier Robert 107ba371819SOllivier Robert /* Structures */ 108ba371819SOllivier Robert 109ba371819SOllivier Robert /* TSIP packets have the following structure, whether report or command. */ 110ba371819SOllivier Robert typedef struct { 111ba371819SOllivier Robert short 112ba371819SOllivier Robert counter, /* counter */ 113ba371819SOllivier Robert len; /* size of buf; < MAX_RPTBUF unsigned chars */ 114ba371819SOllivier Robert unsigned char 115ba371819SOllivier Robert status, /* TSIP packet format/parse status */ 116ba371819SOllivier Robert code, /* TSIP code */ 117ba371819SOllivier Robert buf[MAX_RPTBUF]; /* report or command string */ 118ba371819SOllivier Robert } TSIPPKT; 119ba371819SOllivier Robert 120ba371819SOllivier Robert /* TSIP binary data structures */ 121ba371819SOllivier Robert typedef struct { 122ba371819SOllivier Robert unsigned char 123ba371819SOllivier Robert t_oa_raw, SV_health; 124ba371819SOllivier Robert float 125ba371819SOllivier Robert e, t_oa, i_0, OMEGADOT, sqrt_A, 126ba371819SOllivier Robert OMEGA_0, omega, M_0, a_f0, a_f1, 127ba371819SOllivier Robert Axis, n, OMEGA_n, ODOT_n, t_zc; 128ba371819SOllivier Robert short 129ba371819SOllivier Robert weeknum, wn_oa; 130ba371819SOllivier Robert } ALM_INFO; 131ba371819SOllivier Robert 132ba371819SOllivier Robert typedef struct { /* Almanac health page (25) parameters */ 133ba371819SOllivier Robert unsigned char 134ba371819SOllivier Robert WN_a, SV_health[32], t_oa; 135ba371819SOllivier Robert } ALH_PARMS; 136ba371819SOllivier Robert 137ba371819SOllivier Robert typedef struct { /* Universal Coordinated Time (UTC) parms */ 138ba371819SOllivier Robert double 139ba371819SOllivier Robert A_0; 140ba371819SOllivier Robert float 141ba371819SOllivier Robert A_1; 142ba371819SOllivier Robert short 143ba371819SOllivier Robert delta_t_LS; 144ba371819SOllivier Robert float 145ba371819SOllivier Robert t_ot; 146ba371819SOllivier Robert short 147ba371819SOllivier Robert WN_t, WN_LSF, DN, delta_t_LSF; 148ba371819SOllivier Robert } UTC_INFO; 149ba371819SOllivier Robert 150ba371819SOllivier Robert typedef struct { /* Ionospheric info (float) */ 151ba371819SOllivier Robert float 152ba371819SOllivier Robert alpha_0, alpha_1, alpha_2, alpha_3, 153ba371819SOllivier Robert beta_0, beta_1, beta_2, beta_3; 154ba371819SOllivier Robert } ION_INFO; 155ba371819SOllivier Robert 156ba371819SOllivier Robert typedef struct { /* Subframe 1 info (float) */ 157ba371819SOllivier Robert short 158ba371819SOllivier Robert weeknum; 159ba371819SOllivier Robert unsigned char 160ba371819SOllivier Robert codeL2, L2Pdata, SVacc_raw, SV_health; 161ba371819SOllivier Robert short 162ba371819SOllivier Robert IODC; 163ba371819SOllivier Robert float 164ba371819SOllivier Robert T_GD, t_oc, a_f2, a_f1, a_f0, SVacc; 165ba371819SOllivier Robert } EPHEM_CLOCK; 166ba371819SOllivier Robert 167ba371819SOllivier Robert typedef struct { /* Ephemeris info (float) */ 168ba371819SOllivier Robert unsigned char 169ba371819SOllivier Robert IODE, fit_interval; 170ba371819SOllivier Robert float 171ba371819SOllivier Robert C_rs, delta_n; 172ba371819SOllivier Robert double 173ba371819SOllivier Robert M_0; 174ba371819SOllivier Robert float 175ba371819SOllivier Robert C_uc; 176ba371819SOllivier Robert double 177ba371819SOllivier Robert e; 178ba371819SOllivier Robert float 179ba371819SOllivier Robert C_us; 180ba371819SOllivier Robert double 181ba371819SOllivier Robert sqrt_A; 182ba371819SOllivier Robert float 183ba371819SOllivier Robert t_oe, C_ic; 184ba371819SOllivier Robert double 185ba371819SOllivier Robert OMEGA_0; 186ba371819SOllivier Robert float 187ba371819SOllivier Robert C_is; 188ba371819SOllivier Robert double 189ba371819SOllivier Robert i_0; 190ba371819SOllivier Robert float 191ba371819SOllivier Robert C_rc; 192ba371819SOllivier Robert double 193ba371819SOllivier Robert omega; 194ba371819SOllivier Robert float 195ba371819SOllivier Robert OMEGADOT, IDOT; 196ba371819SOllivier Robert double 197ba371819SOllivier Robert Axis, n, r1me2, OMEGA_n, ODOT_n; 198ba371819SOllivier Robert } EPHEM_ORBIT; 199ba371819SOllivier Robert 200ba371819SOllivier Robert typedef struct { /* Navigation data structure */ 201ba371819SOllivier Robert short 202ba371819SOllivier Robert sv_number; /* SV number (0 = no entry) */ 203ba371819SOllivier Robert float 204ba371819SOllivier Robert t_ephem; /* time of ephemeris collection */ 205ba371819SOllivier Robert EPHEM_CLOCK 206ba371819SOllivier Robert ephclk; /* subframe 1 data */ 207ba371819SOllivier Robert EPHEM_ORBIT 208ba371819SOllivier Robert ephorb; /* ephemeris data */ 209ba371819SOllivier Robert } NAV_INFO; 210ba371819SOllivier Robert 211ba371819SOllivier Robert typedef struct { 212ba371819SOllivier Robert unsigned char 213ba371819SOllivier Robert bSubcode, 214ba371819SOllivier Robert operating_mode, 215ba371819SOllivier Robert dgps_mode, 216ba371819SOllivier Robert dyn_code, 217ba371819SOllivier Robert trackmode; 218ba371819SOllivier Robert float 219ba371819SOllivier Robert elev_mask, 220ba371819SOllivier Robert cno_mask, 221ba371819SOllivier Robert dop_mask, 222ba371819SOllivier Robert dop_switch; 223ba371819SOllivier Robert unsigned char 224ba371819SOllivier Robert dgps_age_limit; 225ba371819SOllivier Robert } TSIP_RCVR_CFG; 226ba371819SOllivier Robert 227ba371819SOllivier Robert 228ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 229ba371819SOllivier Robert static char 230ba371819SOllivier Robert *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, 231ba371819SOllivier Robert old_baudnum[] = {0, 1, 4, 5, 6, 8, 9, 11, 28, 12}, 232ba371819SOllivier Robert *st_baud_text_app [] = {"", "", " 300", " 600", " 1200", " 2400", 233ba371819SOllivier Robert " 4800", " 9600", "19200", "38400"}, 234ba371819SOllivier Robert *old_parity_text[] = {"EVEN", "ODD", "", "", "NONE"}, 235ba371819SOllivier Robert *parity_text [] = {"NONE", "ODD", "EVEN"}, 236ba371819SOllivier Robert *old_input_ch[] = { "TSIP", "RTCM (6 of 8 bits)"}, 237ba371819SOllivier Robert *old_output_ch[] = { "TSIP", "No output", "", "", "", "NMEA 0183"}, 238ba371819SOllivier Robert *protocols_in_text[] = { "", "TSIP", "", ""}, 239ba371819SOllivier Robert *protocols_out_text[] = { "", "TSIP", "NMEA"}, 240ba371819SOllivier Robert *rcvr_port_text [] = { "Port A ", "Port B ", "Current Port"}, 241ba371819SOllivier Robert *dyn_text [] = {"Unchanged", "Land", "Sea", "Air", "Static"}, 242ba371819SOllivier Robert *NavModeText0xBB[] = {"automatic", "time only (0-D)", "", "2-D", 243ba371819SOllivier Robert "3-D", "", "", "OverDetermined Time"}, 244ba371819SOllivier Robert *PPSTimeBaseText[] = {"GPS", "UTC", "USER"}, 245ba371819SOllivier Robert *PPSPolarityText[] = {"Positive", "Negative"}, 246ba371819SOllivier Robert *MaskText[] = { "Almanac ", "Ephemeris", "UTC ", "Iono ", 247ba371819SOllivier Robert "GPS Msg ", "Alm Hlth ", "Time Fix ", "SV Select", 248ba371819SOllivier Robert "Ext Event", "Pos Fix ", "Raw Meas "}; 249ba371819SOllivier Robert 250ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 251ba371819SOllivier Robert 252ba371819SOllivier Robert /* 253ba371819SOllivier Robert * Unit control structure 254ba371819SOllivier Robert */ 255ba371819SOllivier Robert struct ripencc_unit { 256ba371819SOllivier Robert int unit; /* unit number */ 257ba371819SOllivier Robert int pollcnt; /* poll message counter */ 258ba371819SOllivier Robert int polled; /* Hand in a sample? */ 259ba371819SOllivier Robert char leapdelta; /* delta of next leap event */ 260ba371819SOllivier Robert unsigned char utcflags; /* delta of next leap event */ 261ba371819SOllivier Robert l_fp tstamp; /* timestamp of last poll */ 262ba371819SOllivier Robert 263ba371819SOllivier Robert struct timespec ts; /* last timestamp */ 264ba371819SOllivier Robert pps_params_t pps_params; /* pps parameters */ 265ba371819SOllivier Robert pps_info_t pps_info; /* last pps data */ 266ba371819SOllivier Robert pps_handle_t handle; /* pps handlebars */ 267ba371819SOllivier Robert 268ba371819SOllivier Robert }; 269ba371819SOllivier Robert 270ba371819SOllivier Robert 271ba371819SOllivier Robert /******************* PROTOYPES *****************/ 272ba371819SOllivier Robert 273ba371819SOllivier Robert /* prototypes for report parsing primitives */ 274ba371819SOllivier Robert short rpt_0x3D (TSIPPKT *rpt, unsigned char *tx_baud_index, 275ba371819SOllivier Robert unsigned char *rx_baud_index, unsigned char *char_format_index, 276ba371819SOllivier Robert unsigned char *stop_bits, unsigned char *tx_mode_index, 277ba371819SOllivier Robert unsigned char *rx_mode_index); 278ba371819SOllivier Robert short rpt_0x40 (TSIPPKT *rpt, unsigned char *sv_prn, short *week_num, 279ba371819SOllivier Robert float *t_zc, float *eccentricity, float *t_oa, float *i_0, 280ba371819SOllivier Robert float *OMEGA_dot, float *sqrt_A, float *OMEGA_0, float *omega, 281ba371819SOllivier Robert float *M_0); 282ba371819SOllivier Robert short rpt_0x41 (TSIPPKT *rpt, float *time_of_week, float *UTC_offset, 283ba371819SOllivier Robert short *week_num); 284ba371819SOllivier Robert short rpt_0x42 (TSIPPKT *rpt, float ECEF_pos[3], float *time_of_fix); 285ba371819SOllivier Robert short rpt_0x43 (TSIPPKT *rpt, float ECEF_vel[3], float *freq_offset, 286ba371819SOllivier Robert float *time_of_fix); 287ba371819SOllivier Robert short rpt_0x45 (TSIPPKT *rpt, unsigned char *major_nav_version, 288ba371819SOllivier Robert unsigned char *minor_nav_version, unsigned char *nav_day, 289ba371819SOllivier Robert unsigned char *nav_month, unsigned char *nav_year, 290ba371819SOllivier Robert unsigned char *major_dsp_version, unsigned char *minor_dsp_version, 291ba371819SOllivier Robert unsigned char *dsp_day, unsigned char *dsp_month, 292ba371819SOllivier Robert unsigned char *dsp_year); 293ba371819SOllivier Robert short rpt_0x46 (TSIPPKT *rpt, unsigned char *status1, unsigned char *status2); 294ba371819SOllivier Robert short rpt_0x47 (TSIPPKT *rpt, unsigned char *nsvs, unsigned char *sv_prn, 295ba371819SOllivier Robert float *snr); 296ba371819SOllivier Robert short rpt_0x48 (TSIPPKT *rpt, unsigned char *message); 297ba371819SOllivier Robert short rpt_0x49 (TSIPPKT *rpt, unsigned char *sv_health); 298ba371819SOllivier Robert short rpt_0x4A (TSIPPKT *rpt, float *lat, float *lon, float *alt, 299ba371819SOllivier Robert float *clock_bias, float *time_of_fix); 300ba371819SOllivier Robert short rpt_0x4A_2 (TSIPPKT *rpt, float *alt, float *dummy, 301ba371819SOllivier Robert unsigned char *alt_flag); 302ba371819SOllivier Robert short rpt_0x4B (TSIPPKT *rpt, unsigned char *machine_id, 303ba371819SOllivier Robert unsigned char *status3, unsigned char *status4); 304ba371819SOllivier Robert short rpt_0x4C (TSIPPKT *rpt, unsigned char *dyn_code, float *el_mask, 305ba371819SOllivier Robert float *snr_mask, float *dop_mask, float *dop_switch); 306ba371819SOllivier Robert short rpt_0x4D (TSIPPKT *rpt, float *osc_offset); 307ba371819SOllivier Robert short rpt_0x4E (TSIPPKT *rpt, unsigned char *response); 308ba371819SOllivier Robert short rpt_0x4F (TSIPPKT *rpt, double *a0, float *a1, float *time_of_data, 309ba371819SOllivier Robert short *dt_ls, short *wn_t, short *wn_lsf, short *dn, short *dt_lsf); 310ba371819SOllivier Robert short rpt_0x54 (TSIPPKT *rpt, float *clock_bias, float *freq_offset, 311ba371819SOllivier Robert float *time_of_fix); 312ba371819SOllivier Robert short rpt_0x55 (TSIPPKT *rpt, unsigned char *pos_code, unsigned char *vel_code, 313ba371819SOllivier Robert unsigned char *time_code, unsigned char *aux_code); 314ba371819SOllivier Robert short rpt_0x56 (TSIPPKT *rpt, float vel_ENU[3], float *freq_offset, 315ba371819SOllivier Robert float *time_of_fix); 316ba371819SOllivier Robert short rpt_0x57 (TSIPPKT *rpt, unsigned char *source_code, 317ba371819SOllivier Robert unsigned char *diag_code, short *week_num, float *time_of_fix); 318ba371819SOllivier Robert short rpt_0x58 (TSIPPKT *rpt, unsigned char *op_code, unsigned char *data_type, 319ba371819SOllivier Robert unsigned char *sv_prn, unsigned char *data_length, 320ba371819SOllivier Robert unsigned char *data_packet); 321ba371819SOllivier Robert short rpt_0x59 (TSIPPKT *rpt, unsigned char *code_type, 322ba371819SOllivier Robert unsigned char status_code[32]); 323ba371819SOllivier Robert short rpt_0x5A (TSIPPKT *rpt, unsigned char *sv_prn, float *sample_length, 324ba371819SOllivier Robert float *signal_level, float *code_phase, float *Doppler, 325ba371819SOllivier Robert double *time_of_fix); 326ba371819SOllivier Robert short rpt_0x5B (TSIPPKT *rpt, unsigned char *sv_prn, unsigned char *sv_health, 327ba371819SOllivier Robert unsigned char *sv_iode, unsigned char *fit_interval_flag, 328ba371819SOllivier Robert float *time_of_collection, float *time_of_eph, float *sv_accy); 329ba371819SOllivier Robert short rpt_0x5C (TSIPPKT *rpt, unsigned char *sv_prn, unsigned char *slot, 330ba371819SOllivier Robert unsigned char *chan, unsigned char *acq_flag, unsigned char *eph_flag, 331ba371819SOllivier Robert float *signal_level, float *time_of_last_msmt, float *elev, 332ba371819SOllivier Robert float *azim, unsigned char *old_msmt_flag, 333ba371819SOllivier Robert unsigned char *integer_msec_flag, unsigned char *bad_data_flag, 334ba371819SOllivier Robert unsigned char *data_collect_flag); 335ba371819SOllivier Robert short rpt_0x6D (TSIPPKT *rpt, unsigned char *manual_mode, unsigned char *nsvs, 336ba371819SOllivier Robert unsigned char *ndim, unsigned char sv_prn[], float *pdop, 337ba371819SOllivier Robert float *hdop, float *vdop, float *tdop); 338ba371819SOllivier Robert short rpt_0x82 (TSIPPKT *rpt, unsigned char *diff_mode); 339ba371819SOllivier Robert short rpt_0x83 (TSIPPKT *rpt, double ECEF_pos[3], double *clock_bias, 340ba371819SOllivier Robert float *time_of_fix); 341ba371819SOllivier Robert short rpt_0x84 (TSIPPKT *rpt, double *lat, double *lon, double *alt, 342ba371819SOllivier Robert double *clock_bias, float *time_of_fix); 343ba371819SOllivier Robert short rpt_Paly0xBB(TSIPPKT *rpt, TSIP_RCVR_CFG *TsipxBB); 344ba371819SOllivier Robert short rpt_0xBC (TSIPPKT *rpt, unsigned char *port_num, 345ba371819SOllivier Robert unsigned char *in_baud, unsigned char *out_baud, 346ba371819SOllivier Robert unsigned char *data_bits, unsigned char *parity, 347ba371819SOllivier Robert unsigned char *stop_bits, unsigned char *flow_control, 348ba371819SOllivier Robert unsigned char *protocols_in, unsigned char *protocols_out, 349ba371819SOllivier Robert unsigned char *reserved); 350ba371819SOllivier Robert 351ba371819SOllivier Robert /* prototypes for superpacket parsers */ 352ba371819SOllivier Robert 353ba371819SOllivier Robert short rpt_0x8F0B (TSIPPKT *rpt, unsigned short *event, double *tow, 354ba371819SOllivier Robert unsigned char *date, unsigned char *month, short *year, 355ba371819SOllivier Robert unsigned char *dim_mode, short *utc_offset, double *bias, double *drift, 356ba371819SOllivier Robert float *bias_unc, float *dr_unc, double *lat, double *lon, double *alt, 357ba371819SOllivier Robert char sv_id[8]); 358ba371819SOllivier Robert short rpt_0x8F14 (TSIPPKT *rpt, short *datum_idx, double datum_coeffs[5]); 359ba371819SOllivier Robert short rpt_0x8F15 (TSIPPKT *rpt, short *datum_idx, double datum_coeffs[5]); 360ba371819SOllivier Robert short rpt_0x8F20 (TSIPPKT *rpt, unsigned char *info, double *lat, 361ba371819SOllivier Robert double *lon, double *alt, double vel_enu[], double *time_of_fix, 362ba371819SOllivier Robert short *week_num, unsigned char *nsvs, unsigned char sv_prn[], 363ba371819SOllivier Robert short sv_IODC[], short *datum_index); 364ba371819SOllivier Robert short rpt_0x8F41 (TSIPPKT *rpt, unsigned char *bSearchRange, 365ba371819SOllivier Robert unsigned char *bBoardOptions, unsigned long *iiSerialNumber, 366ba371819SOllivier Robert unsigned char *bBuildYear, unsigned char *bBuildMonth, 367ba371819SOllivier Robert unsigned char *bBuildDay, unsigned char *bBuildHour, 368ba371819SOllivier Robert float *fOscOffset, unsigned short *iTestCodeId); 369ba371819SOllivier Robert short rpt_0x8F42 (TSIPPKT *rpt, unsigned char *bProdOptionsPre, 370ba371819SOllivier Robert unsigned char *bProdNumberExt, unsigned short *iCaseSerialNumberPre, 371ba371819SOllivier Robert unsigned long *iiCaseSerialNumber, unsigned long *iiProdNumber, 372ba371819SOllivier Robert unsigned short *iPremiumOptions, unsigned short *iMachineID, 373ba371819SOllivier Robert unsigned short *iKey); 374ba371819SOllivier Robert short rpt_0x8F45 (TSIPPKT *rpt, unsigned char *bSegMask); 375ba371819SOllivier Robert short rpt_0x8F4A_16 (TSIPPKT *rpt, unsigned char *pps_enabled, 376ba371819SOllivier Robert unsigned char *pps_timebase, unsigned char *pos_polarity, 377ba371819SOllivier Robert double *pps_offset, float *bias_unc_threshold); 378ba371819SOllivier Robert short rpt_0x8F4B (TSIPPKT *rpt, unsigned long *decorr_max); 379ba371819SOllivier Robert short rpt_0x8F4D (TSIPPKT *rpt, unsigned long *event_mask); 380ba371819SOllivier Robert short rpt_0x8FA5 (TSIPPKT *rpt, unsigned char *spktmask); 381ba371819SOllivier Robert short rpt_0x8FAD (TSIPPKT *rpt, unsigned short *COUNT, double *FracSec, 382ba371819SOllivier Robert unsigned char *Hour, unsigned char *Minute, unsigned char *Second, 383ba371819SOllivier Robert unsigned char *Day, unsigned char *Month, unsigned short *Year, 384ba371819SOllivier Robert unsigned char *Status, unsigned char *Flags); 385ba371819SOllivier Robert 386ba371819SOllivier Robert /**/ 387ba371819SOllivier Robert /* prototypes for command-encode primitives with suffix convention: */ 388ba371819SOllivier Robert /* c = clear, s = set, q = query, e = enable, d = disable */ 389ba371819SOllivier Robert void cmd_0x1F (TSIPPKT *cmd); 390ba371819SOllivier Robert void cmd_0x26 (TSIPPKT *cmd); 391ba371819SOllivier Robert void cmd_0x2F (TSIPPKT *cmd); 392ba371819SOllivier Robert void cmd_0x35s (TSIPPKT *cmd, unsigned char pos_code, unsigned char vel_code, 393ba371819SOllivier Robert unsigned char time_code, unsigned char opts_code); 394ba371819SOllivier Robert void cmd_0x3C (TSIPPKT *cmd, unsigned char sv_prn); 395ba371819SOllivier Robert void cmd_0x3Ds (TSIPPKT *cmd, unsigned char baud_out, unsigned char baud_inp, 396ba371819SOllivier Robert unsigned char char_code, unsigned char stopbitcode, 397ba371819SOllivier Robert unsigned char output_mode, unsigned char input_mode); 398ba371819SOllivier Robert void cmd_0xBBq (TSIPPKT *cmd, unsigned char subcode) ; 399ba371819SOllivier Robert 400ba371819SOllivier Robert /* prototypes 8E commands */ 401ba371819SOllivier Robert void cmd_0x8E0Bq (TSIPPKT *cmd); 402ba371819SOllivier Robert void cmd_0x8E41q (TSIPPKT *cmd); 403ba371819SOllivier Robert void cmd_0x8E42q (TSIPPKT *cmd); 404ba371819SOllivier Robert void cmd_0x8E4Aq (TSIPPKT *cmd); 405ba371819SOllivier Robert void cmd_0x8E4As (TSIPPKT *cmd, unsigned char PPSOnOff, unsigned char TimeBase, 406ba371819SOllivier Robert unsigned char Polarity, double PPSOffset, float Uncertainty); 407ba371819SOllivier Robert void cmd_0x8E4Bq (TSIPPKT *cmd); 408ba371819SOllivier Robert void cmd_0x8E4Ds (TSIPPKT *cmd, unsigned long AutoOutputMask); 409ba371819SOllivier Robert void cmd_0x8EADq (TSIPPKT *cmd); 410ba371819SOllivier Robert 411ba371819SOllivier Robert /* header/source border XXXXXXXXXXXXXXXXXXXXXXXXXX */ 412ba371819SOllivier Robert 413ba371819SOllivier Robert /* Trimble parse functions */ 4142b15cb3dSCy Schubert static int parse0x8FAD (TSIPPKT *, struct peer *); 4152b15cb3dSCy Schubert static int parse0x8F0B (TSIPPKT *, struct peer *); 416ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 4172b15cb3dSCy Schubert static int parseany (TSIPPKT *, struct peer *); 4182b15cb3dSCy Schubert static void TranslateTSIPReportToText (TSIPPKT *, char *); 419ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 4202b15cb3dSCy Schubert static int parse0x5C (TSIPPKT *, struct peer *); 4212b15cb3dSCy Schubert static int parse0x4F (TSIPPKT *, struct peer *); 4222b15cb3dSCy Schubert static void tsip_input_proc (TSIPPKT *, int); 423ba371819SOllivier Robert 424ba371819SOllivier Robert /* Trimble helper functions */ 4252b15cb3dSCy Schubert static void bPutFloat (float *, unsigned char *); 4262b15cb3dSCy Schubert static void bPutDouble (double *, unsigned char *); 4272b15cb3dSCy Schubert static void bPutULong (unsigned long *, unsigned char *); 4282b15cb3dSCy Schubert static int print_msg_table_header (int rptcode, char *HdrStr, int force); 4292b15cb3dSCy Schubert static char * show_time (float time_of_week); 430ba371819SOllivier Robert 431ba371819SOllivier Robert /* RIPE NCC functions */ 4322b15cb3dSCy Schubert static void ripencc_control (int, const struct refclockstat *, 4332b15cb3dSCy Schubert struct refclockstat *, struct peer *); 4342b15cb3dSCy Schubert static int ripencc_ppsapi (struct peer *, int, int); 4352b15cb3dSCy Schubert static int ripencc_get_pps_ts (struct ripencc_unit *, l_fp *); 4362b15cb3dSCy Schubert static int ripencc_start (int, struct peer *); 4372b15cb3dSCy Schubert static void ripencc_shutdown (int, struct peer *); 4382b15cb3dSCy Schubert static void ripencc_poll (int, struct peer *); 4392b15cb3dSCy Schubert static void ripencc_send (struct peer *, TSIPPKT spt); 4402b15cb3dSCy Schubert static void ripencc_receive (struct recvbuf *); 441ba371819SOllivier Robert 442ba371819SOllivier Robert /* fill in reflock structure for our clock */ 443ba371819SOllivier Robert struct refclock refclock_ripencc = { 444ba371819SOllivier Robert ripencc_start, /* start up driver */ 445ba371819SOllivier Robert ripencc_shutdown, /* shut down driver */ 446ba371819SOllivier Robert ripencc_poll, /* transmit poll message */ 447ba371819SOllivier Robert ripencc_control, /* control function */ 448ba371819SOllivier Robert noentry, /* initialize driver */ 449ba371819SOllivier Robert noentry, /* debug info */ 450ba371819SOllivier Robert NOFLAGS /* clock flags */ 451ba371819SOllivier Robert }; 452ba371819SOllivier Robert 453ba371819SOllivier Robert /* 454ba371819SOllivier Robert * Tables to compute the ddd of year form icky dd/mm timecode. Viva la 455ba371819SOllivier Robert * leap. 456ba371819SOllivier Robert */ 457ba371819SOllivier Robert static int day1tab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 458ba371819SOllivier Robert static int day2tab[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 459ba371819SOllivier Robert 460ba371819SOllivier Robert 461ba371819SOllivier Robert /* 462ba371819SOllivier Robert * ripencc_start - open the GPS devices and initialize data for processing 463ba371819SOllivier Robert */ 464ba371819SOllivier Robert static int 465ba371819SOllivier Robert ripencc_start(int unit, struct peer *peer) 466ba371819SOllivier Robert { 467ba371819SOllivier Robert register struct ripencc_unit *up; 468ba371819SOllivier Robert struct refclockproc *pp; 469ba371819SOllivier Robert char device[40]; 470ba371819SOllivier Robert int fd; 471ba371819SOllivier Robert struct termios tio; 472ba371819SOllivier Robert TSIPPKT spt; 473ba371819SOllivier Robert 4742b15cb3dSCy Schubert pp = peer->procptr; 4752b15cb3dSCy Schubert 476ba371819SOllivier Robert /* 477ba371819SOllivier Robert * Open serial port 478ba371819SOllivier Robert */ 479ba371819SOllivier Robert (void)snprintf(device, sizeof(device), DEVICE, unit); 480a466cc55SCy Schubert fd = refclock_open(&peer->srcadr, device, SPEED232, LDISC_RAW); 4812b15cb3dSCy Schubert if (fd <= 0) { 4822b15cb3dSCy Schubert pp->io.fd = -1; 483ba371819SOllivier Robert return (0); 4842b15cb3dSCy Schubert } 4852b15cb3dSCy Schubert 4862b15cb3dSCy Schubert pp->io.fd = fd; 487ba371819SOllivier Robert 488ba371819SOllivier Robert /* from refclock_palisade.c */ 489ba371819SOllivier Robert if (tcgetattr(fd, &tio) < 0) { 490ba371819SOllivier Robert msyslog(LOG_ERR, "Palisade(%d) tcgetattr(fd, &tio): %m",unit); 491ba371819SOllivier Robert return (0); 492ba371819SOllivier Robert } 493ba371819SOllivier Robert 494ba371819SOllivier Robert /* 495ba371819SOllivier Robert * set flags 496ba371819SOllivier Robert */ 497ba371819SOllivier Robert tio.c_cflag |= (PARENB|PARODD); 498ba371819SOllivier Robert tio.c_iflag &= ~ICRNL; 499ba371819SOllivier Robert if (tcsetattr(fd, TCSANOW, &tio) == -1) { 500ba371819SOllivier Robert msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit); 501ba371819SOllivier Robert return (0); 502ba371819SOllivier Robert } 503ba371819SOllivier Robert 504ba371819SOllivier Robert /* 505ba371819SOllivier Robert * Allocate and initialize unit structure 506ba371819SOllivier Robert */ 5072b15cb3dSCy Schubert up = emalloc_zero(sizeof(*up)); 5082b15cb3dSCy Schubert 509ba371819SOllivier Robert pp->io.clock_recv = ripencc_receive; 5102b15cb3dSCy Schubert pp->io.srcclock = peer; 511ba371819SOllivier Robert pp->io.datalen = 0; 512ba371819SOllivier Robert if (!io_addclock(&pp->io)) { 5132b15cb3dSCy Schubert pp->io.fd = -1; 5142b15cb3dSCy Schubert close(fd); 515ba371819SOllivier Robert free(up); 516ba371819SOllivier Robert return (0); 517ba371819SOllivier Robert } 5182b15cb3dSCy Schubert pp->unitptr = up; 519ba371819SOllivier Robert 520ba371819SOllivier Robert /* 521ba371819SOllivier Robert * Initialize miscellaneous variables 522ba371819SOllivier Robert */ 523ba371819SOllivier Robert peer->precision = PRECISION; 524ba371819SOllivier Robert pp->clockdesc = DESCRIPTION; 525ba371819SOllivier Robert memcpy((char *)&pp->refid, REFID, REFID_LEN); 526ba371819SOllivier Robert up->pollcnt = 2; 527ba371819SOllivier Robert up->unit = unit; 528ba371819SOllivier Robert up->leapdelta = 0; 529ba371819SOllivier Robert up->utcflags = 0; 530ba371819SOllivier Robert 531ba371819SOllivier Robert /* 532ba371819SOllivier Robert * Initialize the Clock 533ba371819SOllivier Robert */ 534ba371819SOllivier Robert 535ba371819SOllivier Robert /* query software versions */ 536ba371819SOllivier Robert cmd_0x1F(&spt); 537ba371819SOllivier Robert ripencc_send(peer, spt); 538ba371819SOllivier Robert 539ba371819SOllivier Robert /* query receiver health */ 540ba371819SOllivier Robert cmd_0x26(&spt); 541ba371819SOllivier Robert ripencc_send(peer, spt); 542ba371819SOllivier Robert 543ba371819SOllivier Robert /* query serial numbers */ 544ba371819SOllivier Robert cmd_0x8E42q(&spt); 545ba371819SOllivier Robert ripencc_send(peer, spt); 546ba371819SOllivier Robert 547ba371819SOllivier Robert /* query manuf params */ 548ba371819SOllivier Robert cmd_0x8E41q(&spt); 549ba371819SOllivier Robert ripencc_send(peer, spt); 550ba371819SOllivier Robert 551ba371819SOllivier Robert /* i/o opts */ /* trimble manual page A30 */ 552ba371819SOllivier Robert cmd_0x35s(&spt, 553ba371819SOllivier Robert 0x1C, /* position */ 554ba371819SOllivier Robert 0x00, /* velocity */ 555ba371819SOllivier Robert 0x05, /* timing */ 556ba371819SOllivier Robert 0x0a); /* auxilary */ 557ba371819SOllivier Robert ripencc_send(peer, spt); 558ba371819SOllivier Robert 559ba371819SOllivier Robert /* turn off port A */ 560ba371819SOllivier Robert cmd_0x3Ds (&spt, 561ba371819SOllivier Robert 0x0B, /* baud_out */ 562ba371819SOllivier Robert 0x0B, /* baud_inp */ 563ba371819SOllivier Robert 0x07, /* char_code */ 564ba371819SOllivier Robert 0x07, /* stopbitcode */ 565ba371819SOllivier Robert 0x01, /* output_mode */ 566ba371819SOllivier Robert 0x00); /* input_mode */ 567ba371819SOllivier Robert ripencc_send(peer, spt); 568ba371819SOllivier Robert 569ba371819SOllivier Robert /* set i/o options */ 570ba371819SOllivier Robert cmd_0x8E4As (&spt, 571ba371819SOllivier Robert 0x01, /* PPS on */ 572ba371819SOllivier Robert 0x01, /* Timebase UTC */ 573ba371819SOllivier Robert 0x00, /* polarity positive */ 574ba371819SOllivier Robert 0., /* 100 ft. cable XXX make flag */ 575ba371819SOllivier Robert 1e-6 * GPS_C); /* turn of biasuncert. > (1us) */ 576ba371819SOllivier Robert ripencc_send(peer,spt); 577ba371819SOllivier Robert 578ba371819SOllivier Robert /* all outomatic packet output off */ 579ba371819SOllivier Robert cmd_0x8E4Ds(&spt, 580ba371819SOllivier Robert 0x00000000); /* AutoOutputMask */ 581ba371819SOllivier Robert ripencc_send(peer, spt); 582ba371819SOllivier Robert 583ba371819SOllivier Robert cmd_0xBBq (&spt, 584ba371819SOllivier Robert 0x00); /* query primary configuration */ 585ba371819SOllivier Robert ripencc_send(peer,spt); 586ba371819SOllivier Robert 587ba371819SOllivier Robert 588ba371819SOllivier Robert /* query PPS parameters */ 589ba371819SOllivier Robert cmd_0x8E4Aq (&spt); /* query PPS params */ 590ba371819SOllivier Robert ripencc_send(peer,spt); 591ba371819SOllivier Robert 592ba371819SOllivier Robert /* query survey limit */ 593ba371819SOllivier Robert cmd_0x8E4Bq (&spt); /* query survey limit */ 594ba371819SOllivier Robert ripencc_send(peer,spt); 595ba371819SOllivier Robert 596ba371819SOllivier Robert #ifdef DEBUG_NCC 597ba371819SOllivier Robert if (debug) 598ba371819SOllivier Robert printf("ripencc_start: success\n"); 599ba371819SOllivier Robert #endif /* DEBUG_NCC */ 600ba371819SOllivier Robert 601ba371819SOllivier Robert /* 602ba371819SOllivier Robert * Start the PPSAPI interface if it is there. Default to use 603ba371819SOllivier Robert * the assert edge and do not enable the kernel hardpps. 604ba371819SOllivier Robert */ 605ba371819SOllivier Robert if (time_pps_create(fd, &up->handle) < 0) { 606ba371819SOllivier Robert up->handle = 0; 607ba371819SOllivier Robert msyslog(LOG_ERR, "refclock_ripencc: time_pps_create failed: %m"); 608ba371819SOllivier Robert return (1); 609ba371819SOllivier Robert } 610ba371819SOllivier Robert 6119c2daa00SOllivier Robert return(ripencc_ppsapi(peer, 0, 0)); 612ba371819SOllivier Robert } 613ba371819SOllivier Robert 614ba371819SOllivier Robert /* 615ba371819SOllivier Robert * ripencc_control - fudge control 616ba371819SOllivier Robert */ 617ba371819SOllivier Robert static void 618ba371819SOllivier Robert ripencc_control( 619ba371819SOllivier Robert int unit, /* unit (not used) */ 6202b15cb3dSCy Schubert const struct refclockstat *in, /* input parameters (not used) */ 621ba371819SOllivier Robert struct refclockstat *out, /* output parameters (not used) */ 622ba371819SOllivier Robert struct peer *peer /* peer structure pointer */ 623ba371819SOllivier Robert ) 624ba371819SOllivier Robert { 625ba371819SOllivier Robert struct refclockproc *pp; 626ba371819SOllivier Robert 627ba371819SOllivier Robert #ifdef DEBUG_NCC 628ba371819SOllivier Robert msyslog(LOG_INFO,"%s()",__FUNCTION__); 629ba371819SOllivier Robert #endif /* DEBUG_NCC */ 630ba371819SOllivier Robert 631ba371819SOllivier Robert pp = peer->procptr; 632ba371819SOllivier Robert ripencc_ppsapi(peer, pp->sloppyclockflag & CLK_FLAG2, 633ba371819SOllivier Robert pp->sloppyclockflag & CLK_FLAG3); 634ba371819SOllivier Robert } 635ba371819SOllivier Robert 636ba371819SOllivier Robert 637ba371819SOllivier Robert /* 638ba371819SOllivier Robert * Initialize PPSAPI 639ba371819SOllivier Robert */ 640ba371819SOllivier Robert int 641ba371819SOllivier Robert ripencc_ppsapi( 642ba371819SOllivier Robert struct peer *peer, /* peer structure pointer */ 643ba371819SOllivier Robert int enb_clear, /* clear enable */ 644ba371819SOllivier Robert int enb_hardpps /* hardpps enable */ 645ba371819SOllivier Robert ) 646ba371819SOllivier Robert { 647ba371819SOllivier Robert struct refclockproc *pp; 648ba371819SOllivier Robert struct ripencc_unit *up; 649ba371819SOllivier Robert int capability; 650ba371819SOllivier Robert 651ba371819SOllivier Robert pp = peer->procptr; 6522b15cb3dSCy Schubert up = pp->unitptr; 653ba371819SOllivier Robert if (time_pps_getcap(up->handle, &capability) < 0) { 654ba371819SOllivier Robert msyslog(LOG_ERR, 655ba371819SOllivier Robert "refclock_ripencc: time_pps_getcap failed: %m"); 656ba371819SOllivier Robert return (0); 657ba371819SOllivier Robert } 658ba371819SOllivier Robert memset(&up->pps_params, 0, sizeof(pps_params_t)); 659ba371819SOllivier Robert if (enb_clear) 660ba371819SOllivier Robert up->pps_params.mode = capability & PPS_CAPTURECLEAR; 661ba371819SOllivier Robert else 662ba371819SOllivier Robert up->pps_params.mode = capability & PPS_CAPTUREASSERT; 663ba371819SOllivier Robert if (!up->pps_params.mode) { 664ba371819SOllivier Robert msyslog(LOG_ERR, 665ba371819SOllivier Robert "refclock_ripencc: invalid capture edge %d", 666ba371819SOllivier Robert !enb_clear); 667ba371819SOllivier Robert return (0); 668ba371819SOllivier Robert } 669ba371819SOllivier Robert up->pps_params.mode |= PPS_TSFMT_TSPEC; 670ba371819SOllivier Robert if (time_pps_setparams(up->handle, &up->pps_params) < 0) { 671ba371819SOllivier Robert msyslog(LOG_ERR, 672ba371819SOllivier Robert "refclock_ripencc: time_pps_setparams failed: %m"); 673ba371819SOllivier Robert return (0); 674ba371819SOllivier Robert } 675ba371819SOllivier Robert if (enb_hardpps) { 676ba371819SOllivier Robert if (time_pps_kcbind(up->handle, PPS_KC_HARDPPS, 677ba371819SOllivier Robert up->pps_params.mode & ~PPS_TSFMT_TSPEC, 678ba371819SOllivier Robert PPS_TSFMT_TSPEC) < 0) { 679ba371819SOllivier Robert msyslog(LOG_ERR, 680ba371819SOllivier Robert "refclock_ripencc: time_pps_kcbind failed: %m"); 681ba371819SOllivier Robert return (0); 682ba371819SOllivier Robert } 6832b15cb3dSCy Schubert hardpps_enable = 1; 684ba371819SOllivier Robert } 685ba371819SOllivier Robert peer->precision = PPS_PRECISION; 686ba371819SOllivier Robert 687ba371819SOllivier Robert #if DEBUG_NCC 688ba371819SOllivier Robert if (debug) { 689ba371819SOllivier Robert time_pps_getparams(up->handle, &up->pps_params); 690ba371819SOllivier Robert printf( 691ba371819SOllivier Robert "refclock_ripencc: capability 0x%x version %d mode 0x%x kern %d\n", 692ba371819SOllivier Robert capability, up->pps_params.api_version, 693ba371819SOllivier Robert up->pps_params.mode, enb_hardpps); 694ba371819SOllivier Robert } 695ba371819SOllivier Robert #endif /* DEBUG_NCC */ 696ba371819SOllivier Robert 697ba371819SOllivier Robert return (1); 698ba371819SOllivier Robert } 699ba371819SOllivier Robert 700ba371819SOllivier Robert /* 701ba371819SOllivier Robert * This function is called every 64 seconds from ripencc_receive 702ba371819SOllivier Robert * It will fetch the pps time 703ba371819SOllivier Robert * 704ba371819SOllivier Robert * Return 0 on failure and 1 on success. 705ba371819SOllivier Robert */ 706ba371819SOllivier Robert static int 707ba371819SOllivier Robert ripencc_get_pps_ts( 708ba371819SOllivier Robert struct ripencc_unit *up, 709ba371819SOllivier Robert l_fp *tsptr 710ba371819SOllivier Robert ) 711ba371819SOllivier Robert { 712ba371819SOllivier Robert pps_info_t pps_info; 713ba371819SOllivier Robert struct timespec timeout, ts; 714ba371819SOllivier Robert double dtemp; 715ba371819SOllivier Robert l_fp tstmp; 716ba371819SOllivier Robert 717ba371819SOllivier Robert #ifdef DEBUG_PPS 7182b15cb3dSCy Schubert msyslog(LOG_INFO,"ripencc_get_pps_ts"); 719ba371819SOllivier Robert #endif /* DEBUG_PPS */ 720ba371819SOllivier Robert 721ba371819SOllivier Robert 722ba371819SOllivier Robert /* 723ba371819SOllivier Robert * Convert the timespec nanoseconds field to ntp l_fp units. 724ba371819SOllivier Robert */ 725ba371819SOllivier Robert if (up->handle == 0) 726ba371819SOllivier Robert return (0); 727ba371819SOllivier Robert timeout.tv_sec = 0; 728ba371819SOllivier Robert timeout.tv_nsec = 0; 729ba371819SOllivier Robert memcpy(&pps_info, &up->pps_info, sizeof(pps_info_t)); 730ba371819SOllivier Robert if (time_pps_fetch(up->handle, PPS_TSFMT_TSPEC, &up->pps_info, 731ba371819SOllivier Robert &timeout) < 0) 732ba371819SOllivier Robert return (0); 733ba371819SOllivier Robert if (up->pps_params.mode & PPS_CAPTUREASSERT) { 734ba371819SOllivier Robert if (pps_info.assert_sequence == 735ba371819SOllivier Robert up->pps_info.assert_sequence) 736ba371819SOllivier Robert return (0); 737ba371819SOllivier Robert ts = up->pps_info.assert_timestamp; 738ba371819SOllivier Robert } else if (up->pps_params.mode & PPS_CAPTURECLEAR) { 739ba371819SOllivier Robert if (pps_info.clear_sequence == 740ba371819SOllivier Robert up->pps_info.clear_sequence) 741ba371819SOllivier Robert return (0); 742ba371819SOllivier Robert ts = up->pps_info.clear_timestamp; 743ba371819SOllivier Robert } else { 744ba371819SOllivier Robert return (0); 745ba371819SOllivier Robert } 746ba371819SOllivier Robert if ((up->ts.tv_sec == ts.tv_sec) && (up->ts.tv_nsec == ts.tv_nsec)) 747ba371819SOllivier Robert return (0); 748ba371819SOllivier Robert up->ts = ts; 749ba371819SOllivier Robert 750ba371819SOllivier Robert tstmp.l_ui = ts.tv_sec + JAN_1970; 751ba371819SOllivier Robert dtemp = ts.tv_nsec * FRAC / 1e9; 752ba371819SOllivier Robert tstmp.l_uf = (u_int32)dtemp; 753ba371819SOllivier Robert 754ba371819SOllivier Robert #ifdef DEBUG_PPS 7552b15cb3dSCy Schubert msyslog(LOG_INFO,"ts.tv_sec: %d",(int)ts.tv_sec); 7562b15cb3dSCy Schubert msyslog(LOG_INFO,"ts.tv_nsec: %ld",ts.tv_nsec); 757ba371819SOllivier Robert #endif /* DEBUG_PPS */ 758ba371819SOllivier Robert 759ba371819SOllivier Robert *tsptr = tstmp; 760ba371819SOllivier Robert return (1); 761ba371819SOllivier Robert } 762ba371819SOllivier Robert 763ba371819SOllivier Robert /* 764ba371819SOllivier Robert * ripencc_shutdown - shut down a GPS clock 765ba371819SOllivier Robert */ 766ba371819SOllivier Robert static void 767ba371819SOllivier Robert ripencc_shutdown(int unit, struct peer *peer) 768ba371819SOllivier Robert { 769ba371819SOllivier Robert register struct ripencc_unit *up; 770ba371819SOllivier Robert struct refclockproc *pp; 771ba371819SOllivier Robert 772ba371819SOllivier Robert pp = peer->procptr; 7732b15cb3dSCy Schubert up = pp->unitptr; 774ba371819SOllivier Robert 7752b15cb3dSCy Schubert if (up != NULL) { 776ba371819SOllivier Robert if (up->handle != 0) 777ba371819SOllivier Robert time_pps_destroy(up->handle); 7782b15cb3dSCy Schubert free(up); 7792b15cb3dSCy Schubert } 7802b15cb3dSCy Schubert if (-1 != pp->io.fd) 781ba371819SOllivier Robert io_closeclock(&pp->io); 782ba371819SOllivier Robert 7832b15cb3dSCy Schubert return; 784ba371819SOllivier Robert } 785ba371819SOllivier Robert 786ba371819SOllivier Robert /* 787ba371819SOllivier Robert * ripencc_poll - called by the transmit procedure 788ba371819SOllivier Robert */ 789ba371819SOllivier Robert static void 790ba371819SOllivier Robert ripencc_poll(int unit, struct peer *peer) 791ba371819SOllivier Robert { 792ba371819SOllivier Robert register struct ripencc_unit *up; 793ba371819SOllivier Robert struct refclockproc *pp; 794ba371819SOllivier Robert TSIPPKT spt; 795ba371819SOllivier Robert 796ba371819SOllivier Robert #ifdef DEBUG_NCC 797ba371819SOllivier Robert if (debug) 798ba371819SOllivier Robert fprintf(stderr, "ripencc_poll(%d)\n", unit); 799ba371819SOllivier Robert #endif /* DEBUG_NCC */ 800ba371819SOllivier Robert pp = peer->procptr; 8012b15cb3dSCy Schubert up = pp->unitptr; 802ba371819SOllivier Robert if (up->pollcnt == 0) 803ba371819SOllivier Robert refclock_report(peer, CEVNT_TIMEOUT); 804ba371819SOllivier Robert else 805ba371819SOllivier Robert up->pollcnt--; 806ba371819SOllivier Robert 807ba371819SOllivier Robert pp->polls++; 808ba371819SOllivier Robert up->polled = 1; 809ba371819SOllivier Robert 810ba371819SOllivier Robert /* poll for UTC superpacket */ 811ba371819SOllivier Robert cmd_0x8EADq (&spt); 812ba371819SOllivier Robert ripencc_send(peer,spt); 813ba371819SOllivier Robert } 814ba371819SOllivier Robert 815ba371819SOllivier Robert /* 816ba371819SOllivier Robert * ripencc_send - send message to clock 817ba371819SOllivier Robert * use the structures being created by the trimble functions! 818ba371819SOllivier Robert * makes the code more readable/clean 819ba371819SOllivier Robert */ 820ba371819SOllivier Robert static void 821ba371819SOllivier Robert ripencc_send(struct peer *peer, TSIPPKT spt) 822ba371819SOllivier Robert { 823ba371819SOllivier Robert unsigned char *ip, *op; 824ba371819SOllivier Robert unsigned char obuf[512]; 825ba371819SOllivier Robert 826ba371819SOllivier Robert #ifdef DEBUG_RAW 827ba371819SOllivier Robert { 828ba371819SOllivier Robert register struct ripencc_unit *up; 829ba371819SOllivier Robert register struct refclockproc *pp; 830ba371819SOllivier Robert 831ba371819SOllivier Robert pp = peer->procptr; 8322b15cb3dSCy Schubert up = pp->unitptr; 833ba371819SOllivier Robert if (debug) 834ba371819SOllivier Robert printf("ripencc_send(%d, %02X)\n", up->unit, cmd); 835ba371819SOllivier Robert } 836ba371819SOllivier Robert #endif /* DEBUG_RAW */ 837ba371819SOllivier Robert 838ba371819SOllivier Robert ip = spt.buf; 839ba371819SOllivier Robert op = obuf; 840ba371819SOllivier Robert 841ba371819SOllivier Robert *op++ = 0x10; 842ba371819SOllivier Robert *op++ = spt.code; 843ba371819SOllivier Robert 844ba371819SOllivier Robert while (spt.len--) { 845ba371819SOllivier Robert if (op-obuf > sizeof(obuf)-5) { 846ba371819SOllivier Robert msyslog(LOG_ERR, "ripencc_send obuf overflow!"); 847ba371819SOllivier Robert refclock_report(peer, CEVNT_FAULT); 848ba371819SOllivier Robert return; 849ba371819SOllivier Robert } 850ba371819SOllivier Robert 851ba371819SOllivier Robert if (*ip == 0x10) /* byte stuffing */ 852ba371819SOllivier Robert *op++ = 0x10; 853ba371819SOllivier Robert *op++ = *ip++; 854ba371819SOllivier Robert } 855ba371819SOllivier Robert 856ba371819SOllivier Robert *op++ = 0x10; 857ba371819SOllivier Robert *op++ = 0x03; 858ba371819SOllivier Robert 859ba371819SOllivier Robert #ifdef DEBUG_RAW 860ba371819SOllivier Robert if (debug) { /* print raw packet */ 861ba371819SOllivier Robert unsigned char *cp; 862ba371819SOllivier Robert int i; 863ba371819SOllivier Robert 864ba371819SOllivier Robert printf("ripencc_send: len %d\n", op-obuf); 865ba371819SOllivier Robert for (i=1, cp=obuf; cp<op; i++, cp++) { 866ba371819SOllivier Robert printf(" %02X", *cp); 867ba371819SOllivier Robert if (i%10 == 0) 868ba371819SOllivier Robert printf("\n"); 869ba371819SOllivier Robert } 870ba371819SOllivier Robert printf("\n"); 871ba371819SOllivier Robert } 872ba371819SOllivier Robert #endif /* DEBUG_RAW */ 873ba371819SOllivier Robert 874ba371819SOllivier Robert if (write(peer->procptr->io.fd, obuf, op-obuf) == -1) { 875ba371819SOllivier Robert refclock_report(peer, CEVNT_FAULT); 876ba371819SOllivier Robert } 877ba371819SOllivier Robert } 878ba371819SOllivier Robert 879ba371819SOllivier Robert /* 880ba371819SOllivier Robert * ripencc_receive() 881ba371819SOllivier Robert * 882ba371819SOllivier Robert * called when a packet is received on the serial port 883ba371819SOllivier Robert * takes care of further processing 884ba371819SOllivier Robert * 885ba371819SOllivier Robert */ 886ba371819SOllivier Robert static void 887ba371819SOllivier Robert ripencc_receive(struct recvbuf *rbufp) 888ba371819SOllivier Robert { 889ba371819SOllivier Robert register struct ripencc_unit *up; 890ba371819SOllivier Robert register struct refclockproc *pp; 891ba371819SOllivier Robert struct peer *peer; 8922b15cb3dSCy Schubert static TSIPPKT rpt; /* for current incoming TSIP report */ 893ba371819SOllivier Robert TSIPPKT spt; /* send packet */ 894ba371819SOllivier Robert int ns_since_pps; 895ba371819SOllivier Robert int i; 896ba371819SOllivier Robert char *cp; 8972b15cb3dSCy Schubert /* these variables hold data until we decide it's worth keeping */ 898ba371819SOllivier Robert char rd_lastcode[BMAX]; 899ba371819SOllivier Robert l_fp rd_tmp; 900ba371819SOllivier Robert u_short rd_lencode; 901ba371819SOllivier Robert 902ba371819SOllivier Robert /* msyslog(LOG_INFO, "%s",__FUNCTION__); */ 903ba371819SOllivier Robert 904ba371819SOllivier Robert /* 905ba371819SOllivier Robert * Initialize pointers and read the timecode and timestamp 906ba371819SOllivier Robert */ 9072b15cb3dSCy Schubert peer = rbufp->recv_peer; 908ba371819SOllivier Robert pp = peer->procptr; 9092b15cb3dSCy Schubert up = pp->unitptr; 910ba371819SOllivier Robert rd_lencode = refclock_gtlin(rbufp, rd_lastcode, BMAX, &rd_tmp); 911ba371819SOllivier Robert 912ba371819SOllivier Robert #ifdef DEBUG_RAW 913ba371819SOllivier Robert if (debug) 914ba371819SOllivier Robert fprintf(stderr, "ripencc_receive(%d)\n", up->unit); 915ba371819SOllivier Robert #endif /* DEBUG_RAW */ 916ba371819SOllivier Robert 917ba371819SOllivier Robert #ifdef DEBUG_RAW 918ba371819SOllivier Robert if (debug) { /* print raw packet */ 919ba371819SOllivier Robert int i; 920ba371819SOllivier Robert unsigned char *cp; 921ba371819SOllivier Robert 922ba371819SOllivier Robert printf("ripencc_receive: len %d\n", rbufp->recv_length); 9232b15cb3dSCy Schubert for (i=1, cp=(char*)&rbufp->recv_space; 9242b15cb3dSCy Schubert i <= rbufp->recv_length; 9252b15cb3dSCy Schubert i++, cp++) { 926ba371819SOllivier Robert printf(" %02X", *cp); 927ba371819SOllivier Robert if (i%10 == 0) 928ba371819SOllivier Robert printf("\n"); 929ba371819SOllivier Robert } 930ba371819SOllivier Robert printf("\n"); 931ba371819SOllivier Robert } 932ba371819SOllivier Robert #endif /* DEBUG_RAW */ 933ba371819SOllivier Robert 934ba371819SOllivier Robert cp = (char*) &rbufp->recv_space; 935ba371819SOllivier Robert i=rbufp->recv_length; 936ba371819SOllivier Robert 937ba371819SOllivier Robert while (i--) { /* loop over received chars */ 938ba371819SOllivier Robert 939ba371819SOllivier Robert tsip_input_proc(&rpt, (unsigned char) *cp++); 940ba371819SOllivier Robert 941ba371819SOllivier Robert if (rpt.status != TSIP_PARSED_FULL) 942ba371819SOllivier Robert continue; 943ba371819SOllivier Robert 944ba371819SOllivier Robert switch (rpt.code) { 945ba371819SOllivier Robert 946ba371819SOllivier Robert case 0x8F: /* superpacket */ 947ba371819SOllivier Robert 948ba371819SOllivier Robert switch (rpt.buf[0]) { 949ba371819SOllivier Robert 950ba371819SOllivier Robert case 0xAD: /* UTC Time */ 951ba371819SOllivier Robert /* 9522b15cb3dSCy Schubert ** When polling on port B the timecode is 9532b15cb3dSCy Schubert ** the time of the previous PPS. If we 9542b15cb3dSCy Schubert ** completed receiving the packet less than 9552b15cb3dSCy Schubert ** 150ms after the turn of the second, it 9562b15cb3dSCy Schubert ** may have the code of the previous second. 9572b15cb3dSCy Schubert ** We do not trust that and simply poll 9582b15cb3dSCy Schubert ** again without even parsing it. 9592b15cb3dSCy Schubert ** 9602b15cb3dSCy Schubert ** More elegant would be to re-schedule the 9612b15cb3dSCy Schubert ** poll, but I do not know (yet) how to do 9622b15cb3dSCy Schubert ** that cleanly. 9632b15cb3dSCy Schubert ** 964ba371819SOllivier Robert */ 965ba371819SOllivier Robert /* BLA ns_since_pps = ncc_tstmp(rbufp, &trtmp); */ 966ba371819SOllivier Robert /* if (up->polled && ns_since_pps > -1 && ns_since_pps < 150) { */ 967ba371819SOllivier Robert 968ba371819SOllivier Robert ns_since_pps = 200; 969ba371819SOllivier Robert if (up->polled && ns_since_pps < 150) { 9702b15cb3dSCy Schubert msyslog(LOG_INFO, "%s(): up->polled", 9712b15cb3dSCy Schubert __FUNCTION__); 972ba371819SOllivier Robert ripencc_poll(up->unit, peer); 973ba371819SOllivier Robert break; 974ba371819SOllivier Robert } 975ba371819SOllivier Robert 976ba371819SOllivier Robert /* 977ba371819SOllivier Robert * Parse primary utc time packet 978ba371819SOllivier Robert * and fill refclock structure 979ba371819SOllivier Robert * from results. 980ba371819SOllivier Robert */ 981ba371819SOllivier Robert if (parse0x8FAD(&rpt, peer) < 0) { 982ba371819SOllivier Robert msyslog(LOG_INFO, "%s(): parse0x8FAD < 0",__FUNCTION__); 983ba371819SOllivier Robert refclock_report(peer, CEVNT_BADREPLY); 984ba371819SOllivier Robert break; 985ba371819SOllivier Robert } 986ba371819SOllivier Robert /* 987ba371819SOllivier Robert * If the PPSAPI is working, rather use its 988ba371819SOllivier Robert * timestamps. 989ba371819SOllivier Robert * assume that the PPS occurs on the second 990ba371819SOllivier Robert * so blow any msec 991ba371819SOllivier Robert */ 992ba371819SOllivier Robert if (ripencc_get_pps_ts(up, &rd_tmp) == 1) { 993ba371819SOllivier Robert pp->lastrec = up->tstamp = rd_tmp; 9949c2daa00SOllivier Robert pp->nsec = 0; 995ba371819SOllivier Robert } 996ba371819SOllivier Robert else 9972b15cb3dSCy Schubert msyslog(LOG_INFO, "%s(): ripencc_get_pps_ts returns failure",__FUNCTION__); 998ba371819SOllivier Robert 999ba371819SOllivier Robert 1000ba371819SOllivier Robert if (!up->polled) { 10012b15cb3dSCy Schubert msyslog(LOG_INFO, "%s(): unrequested packet",__FUNCTION__); 1002ba371819SOllivier Robert /* unrequested packet */ 1003ba371819SOllivier Robert break; 1004ba371819SOllivier Robert } 1005ba371819SOllivier Robert 1006ba371819SOllivier Robert /* we have been polled ! */ 1007ba371819SOllivier Robert up->polled = 0; 1008ba371819SOllivier Robert up->pollcnt = 2; 1009ba371819SOllivier Robert 1010ba371819SOllivier Robert /* poll for next packet */ 1011ba371819SOllivier Robert cmd_0x8E0Bq(&spt); 1012ba371819SOllivier Robert ripencc_send(peer,spt); 1013ba371819SOllivier Robert 1014ba371819SOllivier Robert if (ns_since_pps < 0) { /* no PPS */ 1015ba371819SOllivier Robert msyslog(LOG_INFO, "%s(): ns_since_pps < 0",__FUNCTION__); 1016ba371819SOllivier Robert refclock_report(peer, CEVNT_BADTIME); 1017ba371819SOllivier Robert break; 1018ba371819SOllivier Robert } 1019ba371819SOllivier Robert 1020ba371819SOllivier Robert /* 10212b15cb3dSCy Schubert ** Process the new sample in the median 10222b15cb3dSCy Schubert ** filter and determine the reference clock 10232b15cb3dSCy Schubert ** offset and dispersion. 1024ba371819SOllivier Robert */ 1025ba371819SOllivier Robert if (!refclock_process(pp)) { 1026ba371819SOllivier Robert msyslog(LOG_INFO, "%s(): !refclock_process",__FUNCTION__); 1027ba371819SOllivier Robert refclock_report(peer, CEVNT_BADTIME); 1028ba371819SOllivier Robert break; 1029ba371819SOllivier Robert } 1030ba371819SOllivier Robert 1031ba371819SOllivier Robert refclock_receive(peer); 1032ba371819SOllivier Robert break; 1033ba371819SOllivier Robert 1034ba371819SOllivier Robert case 0x0B: /* comprehensive time packet */ 1035ba371819SOllivier Robert parse0x8F0B(&rpt, peer); 1036ba371819SOllivier Robert break; 1037ba371819SOllivier Robert 1038ba371819SOllivier Robert default: /* other superpackets */ 1039ba371819SOllivier Robert #ifdef DEBUG_NCC 10402b15cb3dSCy Schubert msyslog(LOG_INFO, "%s(): calling parseany", 10412b15cb3dSCy Schubert __FUNCTION__); 1042ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1043ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 1044ba371819SOllivier Robert parseany(&rpt, peer); 1045ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 1046ba371819SOllivier Robert break; 1047ba371819SOllivier Robert } 1048ba371819SOllivier Robert break; 1049ba371819SOllivier Robert 1050ba371819SOllivier Robert case 0x4F: /* UTC parameters, for leap info */ 1051ba371819SOllivier Robert parse0x4F(&rpt, peer); 1052ba371819SOllivier Robert break; 1053ba371819SOllivier Robert 1054ba371819SOllivier Robert case 0x5C: /* sat tracking data */ 1055ba371819SOllivier Robert parse0x5C(&rpt, peer); 1056ba371819SOllivier Robert break; 1057ba371819SOllivier Robert 1058ba371819SOllivier Robert default: /* other packets */ 1059ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 1060ba371819SOllivier Robert parseany(&rpt, peer); 1061ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 1062ba371819SOllivier Robert break; 1063ba371819SOllivier Robert } 1064ba371819SOllivier Robert rpt.status = TSIP_PARSED_EMPTY; 1065ba371819SOllivier Robert } 1066ba371819SOllivier Robert } 1067ba371819SOllivier Robert 1068ba371819SOllivier Robert /* 1069ba371819SOllivier Robert * All trimble functions that are directly referenced from driver code 1070ba371819SOllivier Robert * (so not from parseany) 1071ba371819SOllivier Robert */ 1072ba371819SOllivier Robert 1073ba371819SOllivier Robert /* request software versions */ 10742b15cb3dSCy Schubert void 10752b15cb3dSCy Schubert cmd_0x1F( 10762b15cb3dSCy Schubert TSIPPKT *cmd 10772b15cb3dSCy Schubert ) 1078ba371819SOllivier Robert { 1079ba371819SOllivier Robert cmd->len = 0; 1080ba371819SOllivier Robert cmd->code = 0x1F; 1081ba371819SOllivier Robert } 1082ba371819SOllivier Robert 1083ba371819SOllivier Robert /* request receiver health */ 10842b15cb3dSCy Schubert void 10852b15cb3dSCy Schubert cmd_0x26( 10862b15cb3dSCy Schubert TSIPPKT *cmd 10872b15cb3dSCy Schubert ) 1088ba371819SOllivier Robert { 1089ba371819SOllivier Robert cmd->len = 0; 1090ba371819SOllivier Robert cmd->code = 0x26; 1091ba371819SOllivier Robert } 1092ba371819SOllivier Robert 1093ba371819SOllivier Robert /* request UTC params */ 10942b15cb3dSCy Schubert void 10952b15cb3dSCy Schubert cmd_0x2F( 10962b15cb3dSCy Schubert TSIPPKT *cmd 10972b15cb3dSCy Schubert ) 1098ba371819SOllivier Robert { 1099ba371819SOllivier Robert cmd->len = 0; 1100ba371819SOllivier Robert cmd->code = 0x2F; 1101ba371819SOllivier Robert } 1102ba371819SOllivier Robert 1103ba371819SOllivier Robert /* set serial I/O options */ 11042b15cb3dSCy Schubert void 11052b15cb3dSCy Schubert cmd_0x35s( 11062b15cb3dSCy Schubert TSIPPKT *cmd, 11072b15cb3dSCy Schubert unsigned char pos_code, 11082b15cb3dSCy Schubert unsigned char vel_code, 11092b15cb3dSCy Schubert unsigned char time_code, 11102b15cb3dSCy Schubert unsigned char opts_code 11112b15cb3dSCy Schubert ) 1112ba371819SOllivier Robert { 1113ba371819SOllivier Robert cmd->buf[0] = pos_code; 1114ba371819SOllivier Robert cmd->buf[1] = vel_code; 1115ba371819SOllivier Robert cmd->buf[2] = time_code; 1116ba371819SOllivier Robert cmd->buf[3] = opts_code; 1117ba371819SOllivier Robert cmd->len = 4; 1118ba371819SOllivier Robert cmd->code = 0x35; 1119ba371819SOllivier Robert } 11202b15cb3dSCy Schubert 1121ba371819SOllivier Robert /* request tracking status */ 11222b15cb3dSCy Schubert void 11232b15cb3dSCy Schubert cmd_0x3C( 11242b15cb3dSCy Schubert TSIPPKT *cmd, 11252b15cb3dSCy Schubert unsigned char sv_prn 11262b15cb3dSCy Schubert ) 1127ba371819SOllivier Robert { 1128ba371819SOllivier Robert cmd->buf[0] = sv_prn; 1129ba371819SOllivier Robert cmd->len = 1; 1130ba371819SOllivier Robert cmd->code = 0x3C; 1131ba371819SOllivier Robert } 1132ba371819SOllivier Robert 1133ba371819SOllivier Robert /* set Channel A configuration for dual-port operation */ 11342b15cb3dSCy Schubert void 11352b15cb3dSCy Schubert cmd_0x3Ds( 11362b15cb3dSCy Schubert TSIPPKT *cmd, 11372b15cb3dSCy Schubert unsigned char baud_out, 11382b15cb3dSCy Schubert unsigned char baud_inp, 11392b15cb3dSCy Schubert unsigned char char_code, 11402b15cb3dSCy Schubert unsigned char stopbitcode, 11412b15cb3dSCy Schubert unsigned char output_mode, 11422b15cb3dSCy Schubert unsigned char input_mode 11432b15cb3dSCy Schubert ) 1144ba371819SOllivier Robert { 1145ba371819SOllivier Robert cmd->buf[0] = baud_out; /* XMT baud rate */ 1146ba371819SOllivier Robert cmd->buf[1] = baud_inp; /* RCV baud rate */ 1147ba371819SOllivier Robert cmd->buf[2] = char_code; /* parity and #bits per byte */ 1148ba371819SOllivier Robert cmd->buf[3] = stopbitcode; /* number of stop bits code */ 1149ba371819SOllivier Robert cmd->buf[4] = output_mode; /* Ch. A transmission mode */ 1150ba371819SOllivier Robert cmd->buf[5] = input_mode; /* Ch. A reception mode */ 1151ba371819SOllivier Robert cmd->len = 6; 1152ba371819SOllivier Robert cmd->code = 0x3D; 1153ba371819SOllivier Robert } 1154ba371819SOllivier Robert 1155ba371819SOllivier Robert 1156ba371819SOllivier Robert /* query primary configuration */ 11572b15cb3dSCy Schubert void 11582b15cb3dSCy Schubert cmd_0xBBq( 11592b15cb3dSCy Schubert TSIPPKT *cmd, 11602b15cb3dSCy Schubert unsigned char subcode 11612b15cb3dSCy Schubert ) 1162ba371819SOllivier Robert { 1163ba371819SOllivier Robert cmd->len = 1; 1164ba371819SOllivier Robert cmd->code = 0xBB; 1165ba371819SOllivier Robert cmd->buf[0] = subcode; 1166ba371819SOllivier Robert } 1167ba371819SOllivier Robert 1168ba371819SOllivier Robert 1169ba371819SOllivier Robert /**** Superpackets ****/ 1170ba371819SOllivier Robert /* 8E-0B to query 8F-0B controls */ 11712b15cb3dSCy Schubert void 11722b15cb3dSCy Schubert cmd_0x8E0Bq( 11732b15cb3dSCy Schubert TSIPPKT *cmd 11742b15cb3dSCy Schubert ) 1175ba371819SOllivier Robert { 1176ba371819SOllivier Robert cmd->len = 1; 1177ba371819SOllivier Robert cmd->code = 0x8E; 1178ba371819SOllivier Robert cmd->buf[0] = 0x0B; 1179ba371819SOllivier Robert } 1180ba371819SOllivier Robert 1181ba371819SOllivier Robert 1182ba371819SOllivier Robert /* 8F-41 to query board serial number */ 11832b15cb3dSCy Schubert void 11842b15cb3dSCy Schubert cmd_0x8E41q( 11852b15cb3dSCy Schubert TSIPPKT *cmd 11862b15cb3dSCy Schubert ) 1187ba371819SOllivier Robert { 1188ba371819SOllivier Robert cmd->len = 1; 1189ba371819SOllivier Robert cmd->code = 0x8E; 1190ba371819SOllivier Robert cmd->buf[0] = 0x41; 1191ba371819SOllivier Robert } 1192ba371819SOllivier Robert 1193ba371819SOllivier Robert 1194ba371819SOllivier Robert /* 8F-42 to query product serial number */ 11952b15cb3dSCy Schubert void 11962b15cb3dSCy Schubert cmd_0x8E42q( 11972b15cb3dSCy Schubert TSIPPKT *cmd 11982b15cb3dSCy Schubert ) 1199ba371819SOllivier Robert { 1200ba371819SOllivier Robert cmd->len = 1; 1201ba371819SOllivier Robert cmd->code = 0x8E; 1202ba371819SOllivier Robert cmd->buf[0] = 0x42; 1203ba371819SOllivier Robert } 12042b15cb3dSCy Schubert 12052b15cb3dSCy Schubert 1206ba371819SOllivier Robert /* 8F-4A to query PPS parameters */ 12072b15cb3dSCy Schubert void 12082b15cb3dSCy Schubert cmd_0x8E4Aq( 12092b15cb3dSCy Schubert TSIPPKT *cmd 12102b15cb3dSCy Schubert ) 1211ba371819SOllivier Robert { 1212ba371819SOllivier Robert cmd->len = 1; 1213ba371819SOllivier Robert cmd->code = 0x8E; 1214ba371819SOllivier Robert cmd->buf[0] = 0x4A; 1215ba371819SOllivier Robert } 1216ba371819SOllivier Robert 1217ba371819SOllivier Robert 1218ba371819SOllivier Robert /* set i/o options */ 12192b15cb3dSCy Schubert void 12202b15cb3dSCy Schubert cmd_0x8E4As( 12212b15cb3dSCy Schubert TSIPPKT *cmd, 1222ba371819SOllivier Robert unsigned char PPSOnOff, 1223ba371819SOllivier Robert unsigned char TimeBase, 1224ba371819SOllivier Robert unsigned char Polarity, 1225ba371819SOllivier Robert double PPSOffset, 12262b15cb3dSCy Schubert float Uncertainty 12272b15cb3dSCy Schubert ) 1228ba371819SOllivier Robert { 1229ba371819SOllivier Robert cmd->len = 16; 1230ba371819SOllivier Robert cmd->code = 0x8E; 1231ba371819SOllivier Robert cmd->buf[0] = 0x4A; 1232ba371819SOllivier Robert cmd->buf[1] = PPSOnOff; 1233ba371819SOllivier Robert cmd->buf[2] = TimeBase; 1234ba371819SOllivier Robert cmd->buf[3] = Polarity; 1235ba371819SOllivier Robert bPutDouble (&PPSOffset, &cmd->buf[4]); 1236ba371819SOllivier Robert bPutFloat (&Uncertainty, &cmd->buf[12]); 1237ba371819SOllivier Robert } 12382b15cb3dSCy Schubert 1239ba371819SOllivier Robert /* 8F-4B query survey limit */ 12402b15cb3dSCy Schubert void 12412b15cb3dSCy Schubert cmd_0x8E4Bq( 12422b15cb3dSCy Schubert TSIPPKT *cmd 12432b15cb3dSCy Schubert ) 1244ba371819SOllivier Robert { 1245ba371819SOllivier Robert cmd->len = 1; 1246ba371819SOllivier Robert cmd->code = 0x8E; 1247ba371819SOllivier Robert cmd->buf[0] = 0x4B; 1248ba371819SOllivier Robert } 1249ba371819SOllivier Robert 1250ba371819SOllivier Robert /* poll for UTC superpacket */ 1251ba371819SOllivier Robert /* 8E-AD to query 8F-AD controls */ 12522b15cb3dSCy Schubert void 12532b15cb3dSCy Schubert cmd_0x8EADq( 12542b15cb3dSCy Schubert TSIPPKT *cmd 12552b15cb3dSCy Schubert ) 1256ba371819SOllivier Robert { 1257ba371819SOllivier Robert cmd->len = 1; 1258ba371819SOllivier Robert cmd->code = 0x8E; 1259ba371819SOllivier Robert cmd->buf[0] = 0xAD; 1260ba371819SOllivier Robert } 1261ba371819SOllivier Robert 1262ba371819SOllivier Robert /* all outomatic packet output off */ 12632b15cb3dSCy Schubert void 12642b15cb3dSCy Schubert cmd_0x8E4Ds( 12652b15cb3dSCy Schubert TSIPPKT *cmd, 12662b15cb3dSCy Schubert unsigned long AutoOutputMask 12672b15cb3dSCy Schubert ) 1268ba371819SOllivier Robert { 1269ba371819SOllivier Robert cmd->len = 5; 1270ba371819SOllivier Robert cmd->code = 0x8E; 1271ba371819SOllivier Robert cmd->buf[0] = 0x4D; 1272ba371819SOllivier Robert bPutULong (&AutoOutputMask, &cmd->buf[1]); 1273ba371819SOllivier Robert } 1274ba371819SOllivier Robert 1275ba371819SOllivier Robert 12762b15cb3dSCy Schubert /* 12772b15cb3dSCy Schubert * for DOS machines, reverse order of bytes as they come through the 12782b15cb3dSCy Schubert * serial port. 12792b15cb3dSCy Schubert */ 1280ba371819SOllivier Robert #ifdef BYTESWAP 12812b15cb3dSCy Schubert static short 12822b15cb3dSCy Schubert bGetShort( 12832b15cb3dSCy Schubert unsigned char *bp 12842b15cb3dSCy Schubert ) 1285ba371819SOllivier Robert { 1286ba371819SOllivier Robert short outval; 1287ba371819SOllivier Robert unsigned char *optr; 1288ba371819SOllivier Robert 1289ba371819SOllivier Robert optr = (unsigned char*)&outval + 1; 1290ba371819SOllivier Robert *optr-- = *bp++; 1291ba371819SOllivier Robert *optr = *bp; 1292ba371819SOllivier Robert return outval; 1293ba371819SOllivier Robert } 1294ba371819SOllivier Robert 1295ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 12962b15cb3dSCy Schubert static unsigned short 12972b15cb3dSCy Schubert bGetUShort( 12982b15cb3dSCy Schubert unsigned char *bp 12992b15cb3dSCy Schubert ) 1300ba371819SOllivier Robert { 1301ba371819SOllivier Robert unsigned short outval; 1302ba371819SOllivier Robert unsigned char *optr; 1303ba371819SOllivier Robert 1304ba371819SOllivier Robert optr = (unsigned char*)&outval + 1; 1305ba371819SOllivier Robert *optr-- = *bp++; 1306ba371819SOllivier Robert *optr = *bp; 1307ba371819SOllivier Robert return outval; 1308ba371819SOllivier Robert } 1309ba371819SOllivier Robert 13102b15cb3dSCy Schubert static long 13112b15cb3dSCy Schubert bGetLong( 13122b15cb3dSCy Schubert unsigned char *bp 13132b15cb3dSCy Schubert ) 1314ba371819SOllivier Robert { 1315ba371819SOllivier Robert long outval; 1316ba371819SOllivier Robert unsigned char *optr; 1317ba371819SOllivier Robert 1318ba371819SOllivier Robert optr = (unsigned char*)&outval + 3; 1319ba371819SOllivier Robert *optr-- = *bp++; 1320ba371819SOllivier Robert *optr-- = *bp++; 1321ba371819SOllivier Robert *optr-- = *bp++; 1322ba371819SOllivier Robert *optr = *bp; 1323ba371819SOllivier Robert return outval; 1324ba371819SOllivier Robert } 1325ba371819SOllivier Robert 13262b15cb3dSCy Schubert static unsigned long 13272b15cb3dSCy Schubert bGetULong( 13282b15cb3dSCy Schubert unsigned char *bp 13292b15cb3dSCy Schubert ) 1330ba371819SOllivier Robert { 1331ba371819SOllivier Robert unsigned long outval; 1332ba371819SOllivier Robert unsigned char *optr; 1333ba371819SOllivier Robert 1334ba371819SOllivier Robert optr = (unsigned char*)&outval + 3; 1335ba371819SOllivier Robert *optr-- = *bp++; 1336ba371819SOllivier Robert *optr-- = *bp++; 1337ba371819SOllivier Robert *optr-- = *bp++; 1338ba371819SOllivier Robert *optr = *bp; 1339ba371819SOllivier Robert return outval; 1340ba371819SOllivier Robert } 1341ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 1342ba371819SOllivier Robert 13432b15cb3dSCy Schubert static float 13442b15cb3dSCy Schubert bGetSingle( 13452b15cb3dSCy Schubert unsigned char *bp 13462b15cb3dSCy Schubert ) 1347ba371819SOllivier Robert { 1348ba371819SOllivier Robert float outval; 1349ba371819SOllivier Robert unsigned char *optr; 1350ba371819SOllivier Robert 1351ba371819SOllivier Robert optr = (unsigned char*)&outval + 3; 1352ba371819SOllivier Robert *optr-- = *bp++; 1353ba371819SOllivier Robert *optr-- = *bp++; 1354ba371819SOllivier Robert *optr-- = *bp++; 1355ba371819SOllivier Robert *optr = *bp; 1356ba371819SOllivier Robert return outval; 1357ba371819SOllivier Robert } 1358ba371819SOllivier Robert 13592b15cb3dSCy Schubert static double 13602b15cb3dSCy Schubert bGetDouble( 13612b15cb3dSCy Schubert unsigned char *bp 13622b15cb3dSCy Schubert ) 1363ba371819SOllivier Robert { 1364ba371819SOllivier Robert double outval; 1365ba371819SOllivier Robert unsigned char *optr; 1366ba371819SOllivier Robert 1367ba371819SOllivier Robert optr = (unsigned char*)&outval + 7; 1368ba371819SOllivier Robert *optr-- = *bp++; 1369ba371819SOllivier Robert *optr-- = *bp++; 1370ba371819SOllivier Robert *optr-- = *bp++; 1371ba371819SOllivier Robert *optr-- = *bp++; 1372ba371819SOllivier Robert *optr-- = *bp++; 1373ba371819SOllivier Robert *optr-- = *bp++; 1374ba371819SOllivier Robert *optr-- = *bp++; 1375ba371819SOllivier Robert *optr = *bp; 1376ba371819SOllivier Robert return outval; 1377ba371819SOllivier Robert } 1378ba371819SOllivier Robert 1379ba371819SOllivier Robert #else /* not BYTESWAP */ 1380ba371819SOllivier Robert 1381ba371819SOllivier Robert #define bGetShort(bp) (*(short*)(bp)) 1382ba371819SOllivier Robert #define bGetLong(bp) (*(long*)(bp)) 1383ba371819SOllivier Robert #define bGetULong(bp) (*(unsigned long*)(bp)) 1384ba371819SOllivier Robert #define bGetSingle(bp) (*(float*)(bp)) 1385ba371819SOllivier Robert #define bGetDouble(bp) (*(double*)(bp)) 1386ba371819SOllivier Robert 1387ba371819SOllivier Robert #endif /* BYTESWAP */ 1388ba371819SOllivier Robert /* 1389ba371819SOllivier Robert * Byte-reversal is necessary for little-endian (Intel-based) machines. 1390ba371819SOllivier Robert * TSIP streams are Big-endian (Motorola-based). 1391ba371819SOllivier Robert */ 1392ba371819SOllivier Robert #ifdef BYTESWAP 1393ba371819SOllivier Robert 1394ba371819SOllivier Robert void 13952b15cb3dSCy Schubert bPutFloat( 13962b15cb3dSCy Schubert float *in, 13972b15cb3dSCy Schubert unsigned char *out 13982b15cb3dSCy Schubert ) 1399ba371819SOllivier Robert { 1400ba371819SOllivier Robert unsigned char *inptr; 1401ba371819SOllivier Robert 1402ba371819SOllivier Robert inptr = (unsigned char*)in + 3; 1403ba371819SOllivier Robert *out++ = *inptr--; 1404ba371819SOllivier Robert *out++ = *inptr--; 1405ba371819SOllivier Robert *out++ = *inptr--; 1406ba371819SOllivier Robert *out = *inptr; 1407ba371819SOllivier Robert } 1408ba371819SOllivier Robert 1409ba371819SOllivier Robert static void 14102b15cb3dSCy Schubert bPutULong( 14112b15cb3dSCy Schubert unsigned long *in, 14122b15cb3dSCy Schubert unsigned char *out 14132b15cb3dSCy Schubert ) 1414ba371819SOllivier Robert { 1415ba371819SOllivier Robert unsigned char *inptr; 1416ba371819SOllivier Robert 1417ba371819SOllivier Robert inptr = (unsigned char*)in + 3; 1418ba371819SOllivier Robert *out++ = *inptr--; 1419ba371819SOllivier Robert *out++ = *inptr--; 1420ba371819SOllivier Robert *out++ = *inptr--; 1421ba371819SOllivier Robert *out = *inptr; 1422ba371819SOllivier Robert } 1423ba371819SOllivier Robert 1424ba371819SOllivier Robert static void 14252b15cb3dSCy Schubert bPutDouble( 14262b15cb3dSCy Schubert double *in, 14272b15cb3dSCy Schubert unsigned char *out 14282b15cb3dSCy Schubert ) 1429ba371819SOllivier Robert { 1430ba371819SOllivier Robert unsigned char *inptr; 1431ba371819SOllivier Robert 1432ba371819SOllivier Robert inptr = (unsigned char*)in + 7; 1433ba371819SOllivier Robert *out++ = *inptr--; 1434ba371819SOllivier Robert *out++ = *inptr--; 1435ba371819SOllivier Robert *out++ = *inptr--; 1436ba371819SOllivier Robert *out++ = *inptr--; 1437ba371819SOllivier Robert *out++ = *inptr--; 1438ba371819SOllivier Robert *out++ = *inptr--; 1439ba371819SOllivier Robert *out++ = *inptr--; 1440ba371819SOllivier Robert *out = *inptr; 1441ba371819SOllivier Robert } 1442ba371819SOllivier Robert 1443ba371819SOllivier Robert #else /* not BYTESWAP */ 1444ba371819SOllivier Robert 1445ba371819SOllivier Robert void bPutShort (short a, unsigned char *cmdbuf) {*(short*) cmdbuf = a;} 1446ba371819SOllivier Robert void bPutULong (long a, unsigned char *cmdbuf) {*(long*) cmdbuf = a;} 1447ba371819SOllivier Robert void bPutFloat (float a, unsigned char *cmdbuf) {*(float*) cmdbuf = a;} 1448ba371819SOllivier Robert void bPutDouble (double a, unsigned char *cmdbuf){*(double*) cmdbuf = a;} 1449ba371819SOllivier Robert 1450ba371819SOllivier Robert #endif /* BYTESWAP */ 1451ba371819SOllivier Robert 1452ba371819SOllivier Robert /* 1453ba371819SOllivier Robert * Parse primary utc time packet 1454ba371819SOllivier Robert * and fill refclock structure 1455ba371819SOllivier Robert * from results. 1456ba371819SOllivier Robert * 1457ba371819SOllivier Robert * 0 = success 1458ba371819SOllivier Robert * -1 = errors 1459ba371819SOllivier Robert */ 1460ba371819SOllivier Robert 1461ba371819SOllivier Robert static int 14622b15cb3dSCy Schubert parse0x8FAD( 14632b15cb3dSCy Schubert TSIPPKT *rpt, 14642b15cb3dSCy Schubert struct peer *peer 14652b15cb3dSCy Schubert ) 1466ba371819SOllivier Robert { 1467ba371819SOllivier Robert register struct refclockproc *pp; 1468ba371819SOllivier Robert register struct ripencc_unit *up; 1469ba371819SOllivier Robert 1470ba371819SOllivier Robert unsigned day, month, year; /* data derived from received timecode */ 1471ba371819SOllivier Robert unsigned hour, minute, second; 1472ba371819SOllivier Robert unsigned char trackstat, utcflags; 1473ba371819SOllivier Robert 1474ba371819SOllivier Robert static char logbuf[1024]; /* logging string buffer */ 1475ba371819SOllivier Robert int i; 1476ba371819SOllivier Robert unsigned char *buf; 1477ba371819SOllivier Robert 1478ba371819SOllivier Robert buf = rpt->buf; 1479ba371819SOllivier Robert pp = peer->procptr; 1480ba371819SOllivier Robert 1481ba371819SOllivier Robert if (rpt->len != 22) 1482ba371819SOllivier Robert return (-1); 1483ba371819SOllivier Robert 1484ba371819SOllivier Robert if (bGetShort(&buf[1]) != 0) { 1485ba371819SOllivier Robert #ifdef DEBUG_NCC 1486ba371819SOllivier Robert if (debug) 1487ba371819SOllivier Robert printf("parse0x8FAD: event count != 0\n"); 1488ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1489ba371819SOllivier Robert return(-1); 1490ba371819SOllivier Robert } 1491ba371819SOllivier Robert 1492ba371819SOllivier Robert if (bGetDouble(&buf[3]) != 0.0) { 1493ba371819SOllivier Robert #ifdef DEBUG_NCC 1494ba371819SOllivier Robert if (debug) 1495ba371819SOllivier Robert printf("parse0x8FAD: fracsecs != 0\n"); 1496ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1497ba371819SOllivier Robert return(-1); 1498ba371819SOllivier Robert } 1499ba371819SOllivier Robert 1500ba371819SOllivier Robert hour = (unsigned int) buf[11]; 1501ba371819SOllivier Robert minute = (unsigned int) buf[12]; 1502ba371819SOllivier Robert second = (unsigned int) buf[13]; 1503ba371819SOllivier Robert day = (unsigned int) buf[14]; 1504ba371819SOllivier Robert month = (unsigned int) buf[15]; 1505ba371819SOllivier Robert year = bGetShort(&buf[16]); 1506ba371819SOllivier Robert trackstat = buf[18]; 1507ba371819SOllivier Robert utcflags = buf[19]; 1508ba371819SOllivier Robert 1509ba371819SOllivier Robert 1510ba371819SOllivier Robert sprintf(logbuf, "U1 %d.%d.%d %02d:%02d:%02d %d %02x", 1511ba371819SOllivier Robert day, month, year, hour, minute, second, trackstat, utcflags); 1512ba371819SOllivier Robert 1513ba371819SOllivier Robert #ifdef DEBUG_NCC 1514ba371819SOllivier Robert if (debug) 1515ba371819SOllivier Robert puts(logbuf); 1516ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1517ba371819SOllivier Robert 1518ba371819SOllivier Robert record_clock_stats(&peer->srcadr, logbuf); 1519ba371819SOllivier Robert 1520ba371819SOllivier Robert if (!utcflags & UTCF_UTC_AVAIL) 1521ba371819SOllivier Robert return(-1); 1522ba371819SOllivier Robert 1523ba371819SOllivier Robert /* poll for UTC parameters once and then if UTC flag changed */ 1524ba371819SOllivier Robert up = (struct ripencc_unit *) pp->unitptr; 1525ba371819SOllivier Robert if (utcflags != up->utcflags) { 1526ba371819SOllivier Robert TSIPPKT spt; /* local structure for send packet */ 1527ba371819SOllivier Robert cmd_0x2F (&spt); /* request UTC params */ 1528ba371819SOllivier Robert ripencc_send(peer,spt); 1529ba371819SOllivier Robert up->utcflags = utcflags; 1530ba371819SOllivier Robert } 1531ba371819SOllivier Robert 1532ba371819SOllivier Robert /* 1533ba371819SOllivier Robert * If we hit the leap second, we choose to skip this sample 1534ba371819SOllivier Robert * rather than rely on other code to be perfectly correct. 1535ba371819SOllivier Robert * No offense, just defense ;-). 1536ba371819SOllivier Robert */ 1537ba371819SOllivier Robert if (second == 60) 1538ba371819SOllivier Robert return(-1); 1539ba371819SOllivier Robert 1540ba371819SOllivier Robert /* now check and convert the time we received */ 1541ba371819SOllivier Robert 1542ba371819SOllivier Robert pp->year = year; 1543ba371819SOllivier Robert if (month < 1 || month > 12 || day < 1 || day > 31) 1544ba371819SOllivier Robert return(-1); 1545ba371819SOllivier Robert 15462b15cb3dSCy Schubert if (pp->year % 4) { /* XXX: use is_leapyear() ? */ 1547ba371819SOllivier Robert if (day > day1tab[month - 1]) 1548ba371819SOllivier Robert return(-1); 1549ba371819SOllivier Robert for (i = 0; i < month - 1; i++) 1550ba371819SOllivier Robert day += day1tab[i]; 1551ba371819SOllivier Robert } else { 1552ba371819SOllivier Robert if (day > day2tab[month - 1]) 1553ba371819SOllivier Robert return(-1); 1554ba371819SOllivier Robert for (i = 0; i < month - 1; i++) 1555ba371819SOllivier Robert day += day2tab[i]; 1556ba371819SOllivier Robert } 1557ba371819SOllivier Robert pp->day = day; 1558ba371819SOllivier Robert pp->hour = hour; 1559ba371819SOllivier Robert pp->minute = minute; 1560ba371819SOllivier Robert pp-> second = second; 15619c2daa00SOllivier Robert pp->nsec = 0; 1562ba371819SOllivier Robert 1563ba371819SOllivier Robert if ((utcflags&UTCF_LEAP_PNDG) && up->leapdelta != 0) 15642b15cb3dSCy Schubert pp-> leap = (up->leapdelta > 0) 15652b15cb3dSCy Schubert ? LEAP_ADDSECOND 15662b15cb3dSCy Schubert : LEAP_DELSECOND; 1567ba371819SOllivier Robert else 1568ba371819SOllivier Robert pp-> leap = LEAP_NOWARNING; 1569ba371819SOllivier Robert 1570ba371819SOllivier Robert return (0); 1571ba371819SOllivier Robert } 1572ba371819SOllivier Robert 1573ba371819SOllivier Robert /* 1574ba371819SOllivier Robert * Parse comprehensive time packet 1575ba371819SOllivier Robert * 1576ba371819SOllivier Robert * 0 = success 1577ba371819SOllivier Robert * -1 = errors 1578ba371819SOllivier Robert */ 1579ba371819SOllivier Robert 15802b15cb3dSCy Schubert int 15812b15cb3dSCy Schubert parse0x8F0B( 15822b15cb3dSCy Schubert TSIPPKT *rpt, 15832b15cb3dSCy Schubert struct peer *peer 15842b15cb3dSCy Schubert ) 1585ba371819SOllivier Robert { 1586ba371819SOllivier Robert register struct refclockproc *pp; 1587ba371819SOllivier Robert 1588ba371819SOllivier Robert unsigned day, month, year; /* data derived from received timecode */ 1589ba371819SOllivier Robert unsigned hour, minute, second; 1590ba371819SOllivier Robert unsigned utcoff; 1591ba371819SOllivier Robert unsigned char mode; 1592ba371819SOllivier Robert double bias, rate; 1593ba371819SOllivier Robert float biasunc, rateunc; 1594ba371819SOllivier Robert double lat, lon, alt; 1595ba371819SOllivier Robert short lat_deg, lon_deg; 1596ba371819SOllivier Robert float lat_min, lon_min; 1597ba371819SOllivier Robert unsigned char north_south, east_west; 1598ba371819SOllivier Robert char sv[9]; 1599ba371819SOllivier Robert 1600ba371819SOllivier Robert static char logbuf[1024]; /* logging string buffer */ 1601ba371819SOllivier Robert unsigned char b; 1602ba371819SOllivier Robert int i; 1603ba371819SOllivier Robert unsigned char *buf; 1604ba371819SOllivier Robert double tow; 1605ba371819SOllivier Robert 1606ba371819SOllivier Robert buf = rpt->buf; 1607ba371819SOllivier Robert pp = peer->procptr; 1608ba371819SOllivier Robert 1609ba371819SOllivier Robert if (rpt->len != 74) 1610ba371819SOllivier Robert return (-1); 1611ba371819SOllivier Robert 1612ba371819SOllivier Robert if (bGetShort(&buf[1]) != 0) 1613ba371819SOllivier Robert return(-1);; 1614ba371819SOllivier Robert 1615ba371819SOllivier Robert tow = bGetDouble(&buf[3]); 1616ba371819SOllivier Robert 1617ba371819SOllivier Robert if (tow == -1.0) { 1618ba371819SOllivier Robert return(-1); 1619ba371819SOllivier Robert } 1620ba371819SOllivier Robert else if ((tow >= 604800.0) || (tow < 0.0)) { 1621ba371819SOllivier Robert return(-1); 1622ba371819SOllivier Robert } 1623ba371819SOllivier Robert else 1624ba371819SOllivier Robert { 1625ba371819SOllivier Robert if (tow < 604799.9) tow = tow + .00000001; 1626ba371819SOllivier Robert second = (unsigned int) fmod(tow, 60.); 1627ba371819SOllivier Robert minute = (unsigned int) fmod(tow/60., 60.); 1628ba371819SOllivier Robert hour = (unsigned int )fmod(tow / 3600., 24.); 1629ba371819SOllivier Robert } 1630ba371819SOllivier Robert 1631ba371819SOllivier Robert day = (unsigned int) buf[11]; 1632ba371819SOllivier Robert month = (unsigned int) buf[12]; 1633ba371819SOllivier Robert year = bGetShort(&buf[13]); 1634ba371819SOllivier Robert mode = buf[15]; 1635ba371819SOllivier Robert utcoff = bGetShort(&buf[16]); 1636ba371819SOllivier Robert bias = bGetDouble(&buf[18]) / GPS_C * 1e9; /* ns */ 1637ba371819SOllivier Robert rate = bGetDouble(&buf[26]) / GPS_C * 1e9; /* ppb */ 1638ba371819SOllivier Robert biasunc = bGetSingle(&buf[34]) / GPS_C * 1e9; /* ns */ 1639ba371819SOllivier Robert rateunc = bGetSingle(&buf[38]) / GPS_C * 1e9; /* ppb */ 1640ba371819SOllivier Robert lat = bGetDouble(&buf[42]) * R2D; 1641ba371819SOllivier Robert lon = bGetDouble(&buf[50]) * R2D; 1642ba371819SOllivier Robert alt = bGetDouble(&buf[58]); 1643ba371819SOllivier Robert 1644ba371819SOllivier Robert if (lat < 0.0) { 1645ba371819SOllivier Robert north_south = 'S'; 1646ba371819SOllivier Robert lat = -lat; 1647ba371819SOllivier Robert } 1648ba371819SOllivier Robert else { 1649ba371819SOllivier Robert north_south = 'N'; 1650ba371819SOllivier Robert } 1651ba371819SOllivier Robert lat_deg = (short)lat; 1652ba371819SOllivier Robert lat_min = (lat - lat_deg) * 60.0; 1653ba371819SOllivier Robert 1654ba371819SOllivier Robert if (lon < 0.0) { 1655ba371819SOllivier Robert east_west = 'W'; 1656ba371819SOllivier Robert lon = -lon; 1657ba371819SOllivier Robert } 1658ba371819SOllivier Robert else { 1659ba371819SOllivier Robert east_west = 'E'; 1660ba371819SOllivier Robert } 1661ba371819SOllivier Robert 1662ba371819SOllivier Robert lon_deg = (short)lon; 1663ba371819SOllivier Robert lon_min = (lon - lon_deg) * 60.0; 1664ba371819SOllivier Robert 1665ba371819SOllivier Robert for (i=0; i<8; i++) { 1666ba371819SOllivier Robert sv[i] = buf[i + 66]; 1667ba371819SOllivier Robert if (sv[i]) { 1668ba371819SOllivier Robert TSIPPKT spt; /* local structure for sendpacket */ 1669ba371819SOllivier Robert b = (unsigned char) (sv[i]<0 ? -sv[i] : sv[i]); 1670ba371819SOllivier Robert /* request tracking status */ 1671ba371819SOllivier Robert cmd_0x3C (&spt, b); 1672ba371819SOllivier Robert ripencc_send(peer,spt); 1673ba371819SOllivier Robert } 1674ba371819SOllivier Robert } 1675ba371819SOllivier Robert 1676ba371819SOllivier Robert 1677ba371819SOllivier Robert 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", 16782b15cb3dSCy Schubert day, month, year, hour, minute, second, mode, bias, biasunc, 16792b15cb3dSCy Schubert rate, rateunc, utcoff, lat_deg, lat_min, north_south, lon_deg, 16802b15cb3dSCy Schubert lon_min, east_west, alt, sv[0], sv[1], sv[2], sv[3], sv[4], 16812b15cb3dSCy Schubert sv[5], sv[6], sv[7]); 1682ba371819SOllivier Robert 1683ba371819SOllivier Robert #ifdef DEBUG_NCC 1684ba371819SOllivier Robert if (debug) 1685ba371819SOllivier Robert puts(logbuf); 1686ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1687ba371819SOllivier Robert 1688ba371819SOllivier Robert record_clock_stats(&peer->srcadr, logbuf); 1689ba371819SOllivier Robert 1690ba371819SOllivier Robert return (0); 1691ba371819SOllivier Robert } 1692ba371819SOllivier Robert 1693ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 1694ba371819SOllivier Robert /* 1695ba371819SOllivier Robert * Parse any packet using Trimble machinery 1696ba371819SOllivier Robert */ 16972b15cb3dSCy Schubert int 16982b15cb3dSCy Schubert parseany( 16992b15cb3dSCy Schubert TSIPPKT *rpt, 17002b15cb3dSCy Schubert struct peer *peer 17012b15cb3dSCy Schubert ) 1702ba371819SOllivier Robert { 1703ba371819SOllivier Robert static char logbuf[1024]; /* logging string buffer */ 1704ba371819SOllivier Robert 1705ba371819SOllivier Robert TranslateTSIPReportToText (rpt, logbuf); /* anything else */ 1706ba371819SOllivier Robert #ifdef DEBUG_NCC 1707ba371819SOllivier Robert if (debug) 1708ba371819SOllivier Robert puts(&logbuf[1]); 1709ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1710ba371819SOllivier Robert record_clock_stats(&peer->srcadr, &logbuf[1]); 1711ba371819SOllivier Robert return(0); 1712ba371819SOllivier Robert } 1713ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 1714ba371819SOllivier Robert 1715ba371819SOllivier Robert 1716ba371819SOllivier Robert /* 1717ba371819SOllivier Robert * Parse UTC Parameter Packet 1718ba371819SOllivier Robert * 1719ba371819SOllivier Robert * See the IDE for documentation! 1720ba371819SOllivier Robert * 1721ba371819SOllivier Robert * 0 = success 1722ba371819SOllivier Robert * -1 = errors 1723ba371819SOllivier Robert */ 1724ba371819SOllivier Robert 17252b15cb3dSCy Schubert int 17262b15cb3dSCy Schubert parse0x4F( 17272b15cb3dSCy Schubert TSIPPKT *rpt, 17282b15cb3dSCy Schubert struct peer *peer 17292b15cb3dSCy Schubert ) 1730ba371819SOllivier Robert { 1731ba371819SOllivier Robert register struct ripencc_unit *up; 1732ba371819SOllivier Robert 1733ba371819SOllivier Robert double a0; 1734ba371819SOllivier Robert float a1, tot; 1735ba371819SOllivier Robert int dt_ls, wn_t, wn_lsf, dn, dt_lsf; 1736ba371819SOllivier Robert 1737ba371819SOllivier Robert static char logbuf[1024]; /* logging string buffer */ 1738ba371819SOllivier Robert unsigned char *buf; 1739ba371819SOllivier Robert 1740ba371819SOllivier Robert buf = rpt->buf; 1741ba371819SOllivier Robert 1742ba371819SOllivier Robert if (rpt->len != 26) 1743ba371819SOllivier Robert return (-1); 1744ba371819SOllivier Robert a0 = bGetDouble (buf); 1745ba371819SOllivier Robert a1 = bGetSingle (&buf[8]); 1746ba371819SOllivier Robert dt_ls = bGetShort (&buf[12]); 1747ba371819SOllivier Robert tot = bGetSingle (&buf[14]); 1748ba371819SOllivier Robert wn_t = bGetShort (&buf[18]); 1749ba371819SOllivier Robert wn_lsf = bGetShort (&buf[20]); 1750ba371819SOllivier Robert dn = bGetShort (&buf[22]); 1751ba371819SOllivier Robert dt_lsf = bGetShort (&buf[24]); 1752ba371819SOllivier Robert 1753ba371819SOllivier Robert sprintf(logbuf, "L1 %d %d %d %g %g %g %d %d %d", 1754ba371819SOllivier Robert dt_lsf - dt_ls, dt_ls, dt_lsf, a0, a1, tot, wn_t, wn_lsf, dn); 1755ba371819SOllivier Robert 1756ba371819SOllivier Robert #ifdef DEBUG_NCC 1757ba371819SOllivier Robert if (debug) 1758ba371819SOllivier Robert puts(logbuf); 1759ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1760ba371819SOllivier Robert 1761ba371819SOllivier Robert record_clock_stats(&peer->srcadr, logbuf); 1762ba371819SOllivier Robert 1763ba371819SOllivier Robert up = (struct ripencc_unit *) peer->procptr->unitptr; 1764ba371819SOllivier Robert up->leapdelta = dt_lsf - dt_ls; 1765ba371819SOllivier Robert 1766ba371819SOllivier Robert return (0); 1767ba371819SOllivier Robert } 1768ba371819SOllivier Robert 1769ba371819SOllivier Robert /* 1770ba371819SOllivier Robert * Parse Tracking Status packet 1771ba371819SOllivier Robert * 1772ba371819SOllivier Robert * 0 = success 1773ba371819SOllivier Robert * -1 = errors 1774ba371819SOllivier Robert */ 1775ba371819SOllivier Robert 17762b15cb3dSCy Schubert int 17772b15cb3dSCy Schubert parse0x5C( 17782b15cb3dSCy Schubert TSIPPKT *rpt, 17792b15cb3dSCy Schubert struct peer *peer 17802b15cb3dSCy Schubert ) 1781ba371819SOllivier Robert { 1782ba371819SOllivier Robert unsigned char prn, channel, aqflag, ephstat; 1783ba371819SOllivier Robert float snr, azinuth, elevation; 1784ba371819SOllivier Robert 1785ba371819SOllivier Robert static char logbuf[1024]; /* logging string buffer */ 1786ba371819SOllivier Robert unsigned char *buf; 1787ba371819SOllivier Robert 1788ba371819SOllivier Robert buf = rpt->buf; 1789ba371819SOllivier Robert 1790ba371819SOllivier Robert if (rpt->len != 24) 1791ba371819SOllivier Robert return(-1); 1792ba371819SOllivier Robert 1793ba371819SOllivier Robert prn = buf[0]; 1794ba371819SOllivier Robert channel = (unsigned char)(buf[1] >> 3); 1795ba371819SOllivier Robert if (channel == 0x10) 1796ba371819SOllivier Robert channel = 2; 1797ba371819SOllivier Robert else 1798ba371819SOllivier Robert channel++; 1799ba371819SOllivier Robert aqflag = buf[2]; 1800ba371819SOllivier Robert ephstat = buf[3]; 1801ba371819SOllivier Robert snr = bGetSingle(&buf[4]); 1802ba371819SOllivier Robert elevation = bGetSingle(&buf[12]) * R2D; 1803ba371819SOllivier Robert azinuth = bGetSingle(&buf[16]) * R2D; 1804ba371819SOllivier Robert 1805ba371819SOllivier Robert sprintf(logbuf, "S1 %02d %d %d %02x %4.1f %5.1f %4.1f", 1806ba371819SOllivier Robert prn, channel, aqflag, ephstat, snr, azinuth, elevation); 1807ba371819SOllivier Robert 1808ba371819SOllivier Robert #ifdef DEBUG_NCC 1809ba371819SOllivier Robert if (debug) 1810ba371819SOllivier Robert puts(logbuf); 1811ba371819SOllivier Robert #endif /* DEBUG_NCC */ 1812ba371819SOllivier Robert 1813ba371819SOllivier Robert record_clock_stats(&peer->srcadr, logbuf); 1814ba371819SOllivier Robert 1815ba371819SOllivier Robert return (0); 1816ba371819SOllivier Robert } 1817ba371819SOllivier Robert 1818ba371819SOllivier Robert /******* Code below is from Trimble Tsipchat *************/ 1819ba371819SOllivier Robert 1820ba371819SOllivier Robert /* 1821ba371819SOllivier Robert * ************************************************************************* 1822ba371819SOllivier Robert * 1823ba371819SOllivier Robert * Trimble Navigation, Ltd. 1824ba371819SOllivier Robert * OEM Products Development Group 1825ba371819SOllivier Robert * P.O. Box 3642 1826ba371819SOllivier Robert * 645 North Mary Avenue 1827ba371819SOllivier Robert * Sunnyvale, California 94088-3642 1828ba371819SOllivier Robert * 1829ba371819SOllivier Robert * Corporate Headquarter: 1830ba371819SOllivier Robert * Telephone: (408) 481-8000 1831ba371819SOllivier Robert * Fax: (408) 481-6005 1832ba371819SOllivier Robert * 1833ba371819SOllivier Robert * Technical Support Center: 1834ba371819SOllivier Robert * Telephone: (800) 767-4822 (U.S. and Canada) 1835ba371819SOllivier Robert * (408) 481-6940 (outside U.S. and Canada) 1836ba371819SOllivier Robert * Fax: (408) 481-6020 1837ba371819SOllivier Robert * BBS: (408) 481-7800 1838ba371819SOllivier Robert * e-mail: trimble_support@trimble.com 1839ba371819SOllivier Robert * ftp://ftp.trimble.com/pub/sct/embedded/bin 1840ba371819SOllivier Robert * 1841ba371819SOllivier Robert * ************************************************************************* 1842ba371819SOllivier Robert * 1843ba371819SOllivier Robert * ------- BYTE-SWAPPING ------- 1844ba371819SOllivier Robert * TSIP is big-endian (Motorola) protocol. To use on little-endian (Intel) 1845ba371819SOllivier Robert * systems, the bytes of all multi-byte types (shorts, floats, doubles, etc.) 1846ba371819SOllivier Robert * must be reversed. This is controlled by the MACRO BYTESWAP; if defined, it 1847ba371819SOllivier Robert * assumes little-endian protocol. 1848ba371819SOllivier Robert * -------------------------------- 1849ba371819SOllivier Robert * 1850ba371819SOllivier Robert * T_PARSER.C and T_PARSER.H contains primitive functions that interpret 1851ba371819SOllivier Robert * reports received from the receiver. A second source file pair, 1852ba371819SOllivier Robert * T_FORMAT.C and T_FORMAT.H, contin the matching TSIP command formatters. 1853ba371819SOllivier Robert * 1854ba371819SOllivier Robert * The module is in very portable, basic C language. It can be used as is, or 1855ba371819SOllivier Robert * with minimal changes if a TSIP communications application is needed separate 1856ba371819SOllivier Robert * from TSIPCHAT. The construction of most argument lists avoid the use of 1857ba371819SOllivier Robert * structures, but the developer is encouraged to reconstruct them using such 1858ba371819SOllivier Robert * definitions to meet project requirements. Declarations of T_PARSER.C 1859ba371819SOllivier Robert * functions are included in T_PARSER.H to provide prototyping definitions. 1860ba371819SOllivier Robert * 1861ba371819SOllivier Robert * There are two types of functions: a serial input processing routine, 1862ba371819SOllivier Robert * tsip_input_proc() 1863ba371819SOllivier Robert * which assembles incoming bytes into a TSIPPKT structure, and the 1864ba371819SOllivier Robert * report parsers, rpt_0x??(). 1865ba371819SOllivier Robert * 1866ba371819SOllivier Robert * 1) The function tsip_input_proc() accumulates bytes from the receiver, 1867ba371819SOllivier Robert * strips control bytes (DLE), and checks if the report end sequence (DLE ETX) 1868ba371819SOllivier Robert * has been received. rpt.status is defined as TSIP_PARSED_FULL (== 1) 1869ba371819SOllivier Robert * if a complete packet is available. 1870ba371819SOllivier Robert * 1871ba371819SOllivier Robert * 2) The functions rpt_0x??() are report string interpreters patterned after 1872ba371819SOllivier Robert * the document called "Trimble Standard Interface Protocol". It should be 1873ba371819SOllivier Robert * noted that if the report buffer is sent into the receiver with the wrong 1874ba371819SOllivier Robert * length (byte count), the rpt_0x??() returns the Boolean equivalence for 1875ba371819SOllivier Robert * TRUE. 1876ba371819SOllivier Robert * 1877ba371819SOllivier Robert * ************************************************************************* 1878ba371819SOllivier Robert * 1879ba371819SOllivier Robert */ 1880ba371819SOllivier Robert 1881ba371819SOllivier Robert 18822b15cb3dSCy Schubert /* 18832b15cb3dSCy Schubert * reads bytes until serial buffer is empty or a complete report 1884ba371819SOllivier Robert * has been received; end of report is signified by DLE ETX. 1885ba371819SOllivier Robert */ 18862b15cb3dSCy Schubert static void 18872b15cb3dSCy Schubert tsip_input_proc( 18882b15cb3dSCy Schubert TSIPPKT *rpt, 18892b15cb3dSCy Schubert int inbyte 18902b15cb3dSCy Schubert ) 1891ba371819SOllivier Robert { 1892ba371819SOllivier Robert unsigned char newbyte; 1893ba371819SOllivier Robert 1894ba371819SOllivier Robert if (inbyte < 0 || inbyte > 0xFF) return; 1895ba371819SOllivier Robert 1896ba371819SOllivier Robert newbyte = (unsigned char)(inbyte); 1897ba371819SOllivier Robert switch (rpt->status) 1898ba371819SOllivier Robert { 1899ba371819SOllivier Robert case TSIP_PARSED_DLE_1: 1900ba371819SOllivier Robert switch (newbyte) 1901ba371819SOllivier Robert { 1902ba371819SOllivier Robert case 0: 1903ba371819SOllivier Robert case ETX: 1904ba371819SOllivier Robert /* illegal TSIP IDs */ 1905ba371819SOllivier Robert rpt->len = 0; 1906ba371819SOllivier Robert rpt->status = TSIP_PARSED_EMPTY; 1907ba371819SOllivier Robert break; 1908ba371819SOllivier Robert case DLE: 1909ba371819SOllivier Robert /* try normal message start again */ 1910ba371819SOllivier Robert rpt->len = 0; 1911ba371819SOllivier Robert rpt->status = TSIP_PARSED_DLE_1; 1912ba371819SOllivier Robert break; 1913ba371819SOllivier Robert default: 1914ba371819SOllivier Robert /* legal TSIP ID; start message */ 1915ba371819SOllivier Robert rpt->code = newbyte; 1916ba371819SOllivier Robert rpt->len = 0; 1917ba371819SOllivier Robert rpt->status = TSIP_PARSED_DATA; 1918ba371819SOllivier Robert break; 1919ba371819SOllivier Robert } 1920ba371819SOllivier Robert break; 1921ba371819SOllivier Robert case TSIP_PARSED_DATA: 1922ba371819SOllivier Robert switch (newbyte) { 1923ba371819SOllivier Robert case DLE: 1924ba371819SOllivier Robert /* expect DLE or ETX next */ 1925ba371819SOllivier Robert rpt->status = TSIP_PARSED_DLE_2; 1926ba371819SOllivier Robert break; 1927ba371819SOllivier Robert default: 1928ba371819SOllivier Robert /* normal data byte */ 1929ba371819SOllivier Robert rpt->buf[rpt->len] = newbyte; 1930ba371819SOllivier Robert rpt->len++; 1931ba371819SOllivier Robert /* no change in rpt->status */ 1932ba371819SOllivier Robert break; 1933ba371819SOllivier Robert } 1934ba371819SOllivier Robert break; 1935ba371819SOllivier Robert case TSIP_PARSED_DLE_2: 1936ba371819SOllivier Robert switch (newbyte) { 1937ba371819SOllivier Robert case DLE: 1938ba371819SOllivier Robert /* normal data byte */ 1939ba371819SOllivier Robert rpt->buf[rpt->len] = newbyte; 1940ba371819SOllivier Robert rpt->len++; 1941ba371819SOllivier Robert rpt->status = TSIP_PARSED_DATA; 1942ba371819SOllivier Robert break; 1943ba371819SOllivier Robert case ETX: 1944ba371819SOllivier Robert /* end of message; return TRUE here. */ 1945ba371819SOllivier Robert rpt->status = TSIP_PARSED_FULL; 1946ba371819SOllivier Robert break; 1947ba371819SOllivier Robert default: 1948ba371819SOllivier Robert /* error: treat as TSIP_PARSED_DLE_1; start new report packet */ 1949ba371819SOllivier Robert rpt->code = newbyte; 1950ba371819SOllivier Robert rpt->len = 0; 1951ba371819SOllivier Robert rpt->status = TSIP_PARSED_DATA; 1952ba371819SOllivier Robert } 1953ba371819SOllivier Robert break; 1954ba371819SOllivier Robert case TSIP_PARSED_FULL: 1955ba371819SOllivier Robert case TSIP_PARSED_EMPTY: 1956ba371819SOllivier Robert default: 1957ba371819SOllivier Robert switch (newbyte) { 1958ba371819SOllivier Robert case DLE: 1959ba371819SOllivier Robert /* normal message start */ 1960ba371819SOllivier Robert rpt->len = 0; 1961ba371819SOllivier Robert rpt->status = TSIP_PARSED_DLE_1; 1962ba371819SOllivier Robert break; 1963ba371819SOllivier Robert default: 1964ba371819SOllivier Robert /* error: ignore newbyte */ 1965ba371819SOllivier Robert rpt->len = 0; 1966ba371819SOllivier Robert rpt->status = TSIP_PARSED_EMPTY; 1967ba371819SOllivier Robert } 1968ba371819SOllivier Robert break; 1969ba371819SOllivier Robert } 1970ba371819SOllivier Robert if (rpt->len > MAX_RPTBUF) { 1971ba371819SOllivier Robert /* error: start new report packet */ 1972ba371819SOllivier Robert rpt->status = TSIP_PARSED_EMPTY; 1973ba371819SOllivier Robert rpt->len = 0; 1974ba371819SOllivier Robert } 1975ba371819SOllivier Robert } 1976ba371819SOllivier Robert 1977ba371819SOllivier Robert #ifdef TRIMBLE_OUTPUT_FUNC 1978ba371819SOllivier Robert 1979ba371819SOllivier Robert /**/ 19802b15cb3dSCy Schubert /* Channel A configuration for dual port operation */ 19812b15cb3dSCy Schubert short 19822b15cb3dSCy Schubert rpt_0x3D( 19832b15cb3dSCy Schubert TSIPPKT *rpt, 1984ba371819SOllivier Robert unsigned char *tx_baud_index, 1985ba371819SOllivier Robert unsigned char *rx_baud_index, 1986ba371819SOllivier Robert unsigned char *char_format_index, 1987ba371819SOllivier Robert unsigned char *stop_bits, 1988ba371819SOllivier Robert unsigned char *tx_mode_index, 19892b15cb3dSCy Schubert unsigned char *rx_mode_index 19902b15cb3dSCy Schubert ) 1991ba371819SOllivier Robert { 1992ba371819SOllivier Robert unsigned char *buf; 1993ba371819SOllivier Robert buf = rpt->buf; 1994ba371819SOllivier Robert 1995ba371819SOllivier Robert if (rpt->len != 6) return TRUE; 1996ba371819SOllivier Robert *tx_baud_index = buf[0]; 1997ba371819SOllivier Robert *rx_baud_index = buf[1]; 1998ba371819SOllivier Robert *char_format_index = buf[2]; 1999ba371819SOllivier Robert *stop_bits = (unsigned char)((buf[3] == 0x07) ? 1 : 2); 2000ba371819SOllivier Robert *tx_mode_index = buf[4]; 2001ba371819SOllivier Robert *rx_mode_index = buf[5]; 2002ba371819SOllivier Robert return FALSE; 2003ba371819SOllivier Robert } 2004ba371819SOllivier Robert 2005ba371819SOllivier Robert /**/ 20062b15cb3dSCy Schubert /* almanac data for specified satellite */ 20072b15cb3dSCy Schubert short 20082b15cb3dSCy Schubert rpt_0x40( 20092b15cb3dSCy Schubert TSIPPKT *rpt, 2010ba371819SOllivier Robert unsigned char *sv_prn, 2011ba371819SOllivier Robert short *week_num, 2012ba371819SOllivier Robert float *t_zc, 2013ba371819SOllivier Robert float *eccentricity, 2014ba371819SOllivier Robert float *t_oa, 2015ba371819SOllivier Robert float *i_0, 2016ba371819SOllivier Robert float *OMEGA_dot, 2017ba371819SOllivier Robert float *sqrt_A, 2018ba371819SOllivier Robert float *OMEGA_0, 2019ba371819SOllivier Robert float *omega, 20202b15cb3dSCy Schubert float *M_0 20212b15cb3dSCy Schubert ) 2022ba371819SOllivier Robert { 2023ba371819SOllivier Robert unsigned char *buf; 2024ba371819SOllivier Robert buf = rpt->buf; 2025ba371819SOllivier Robert 2026ba371819SOllivier Robert if (rpt->len != 39) return TRUE; 2027ba371819SOllivier Robert *sv_prn = buf[0]; 2028ba371819SOllivier Robert *t_zc = bGetSingle (&buf[1]); 2029ba371819SOllivier Robert *week_num = bGetShort (&buf[5]); 2030ba371819SOllivier Robert *eccentricity = bGetSingle (&buf[7]); 2031ba371819SOllivier Robert *t_oa = bGetSingle (&buf[11]); 2032ba371819SOllivier Robert *i_0 = bGetSingle (&buf[15]); 2033ba371819SOllivier Robert *OMEGA_dot = bGetSingle (&buf[19]); 2034ba371819SOllivier Robert *sqrt_A = bGetSingle (&buf[23]); 2035ba371819SOllivier Robert *OMEGA_0 = bGetSingle (&buf[27]); 2036ba371819SOllivier Robert *omega = bGetSingle (&buf[31]); 2037ba371819SOllivier Robert *M_0 = bGetSingle (&buf[35]); 2038ba371819SOllivier Robert return FALSE; 2039ba371819SOllivier Robert } 2040ba371819SOllivier Robert 20412b15cb3dSCy Schubert /* GPS time */ 20422b15cb3dSCy Schubert short 20432b15cb3dSCy Schubert rpt_0x41( 20442b15cb3dSCy Schubert TSIPPKT *rpt, 2045ba371819SOllivier Robert float *time_of_week, 2046ba371819SOllivier Robert float *UTC_offset, 20472b15cb3dSCy Schubert short *week_num 20482b15cb3dSCy Schubert ) 2049ba371819SOllivier Robert { 2050ba371819SOllivier Robert unsigned char *buf; 2051ba371819SOllivier Robert buf = rpt->buf; 2052ba371819SOllivier Robert 2053ba371819SOllivier Robert if (rpt->len != 10) return TRUE; 2054ba371819SOllivier Robert *time_of_week = bGetSingle (buf); 2055ba371819SOllivier Robert *week_num = bGetShort (&buf[4]); 2056ba371819SOllivier Robert *UTC_offset = bGetSingle (&buf[6]); 2057ba371819SOllivier Robert return FALSE; 2058ba371819SOllivier Robert } 2059ba371819SOllivier Robert 2060ba371819SOllivier Robert /* position in ECEF, single precision */ 20612b15cb3dSCy Schubert short 20622b15cb3dSCy Schubert rpt_0x42( 20632b15cb3dSCy Schubert TSIPPKT *rpt, 20642b15cb3dSCy Schubert float pos_ECEF[3], 20652b15cb3dSCy Schubert float *time_of_fix 20662b15cb3dSCy Schubert ) 2067ba371819SOllivier Robert { 2068ba371819SOllivier Robert unsigned char *buf; 2069ba371819SOllivier Robert buf = rpt->buf; 2070ba371819SOllivier Robert 2071ba371819SOllivier Robert if (rpt->len != 16) return TRUE; 2072ba371819SOllivier Robert pos_ECEF[0] = bGetSingle (buf); 2073ba371819SOllivier Robert pos_ECEF[1]= bGetSingle (&buf[4]); 2074ba371819SOllivier Robert pos_ECEF[2]= bGetSingle (&buf[8]); 2075ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[12]); 2076ba371819SOllivier Robert return FALSE; 2077ba371819SOllivier Robert } 2078ba371819SOllivier Robert 20792b15cb3dSCy Schubert /* velocity in ECEF, single precision */ 20802b15cb3dSCy Schubert short 20812b15cb3dSCy Schubert rpt_0x43( 20822b15cb3dSCy Schubert TSIPPKT *rpt, 2083ba371819SOllivier Robert float ECEF_vel[3], 2084ba371819SOllivier Robert float *freq_offset, 20852b15cb3dSCy Schubert float *time_of_fix 20862b15cb3dSCy Schubert ) 2087ba371819SOllivier Robert { 2088ba371819SOllivier Robert unsigned char *buf; 2089ba371819SOllivier Robert buf = rpt->buf; 2090ba371819SOllivier Robert 2091ba371819SOllivier Robert if (rpt->len != 20) return TRUE; 2092ba371819SOllivier Robert ECEF_vel[0] = bGetSingle (buf); 2093ba371819SOllivier Robert ECEF_vel[1] = bGetSingle (&buf[4]); 2094ba371819SOllivier Robert ECEF_vel[2] = bGetSingle (&buf[8]); 2095ba371819SOllivier Robert *freq_offset = bGetSingle (&buf[12]); 2096ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[16]); 2097ba371819SOllivier Robert return FALSE; 2098ba371819SOllivier Robert } 2099ba371819SOllivier Robert 21002b15cb3dSCy Schubert /* software versions */ 21012b15cb3dSCy Schubert short 21022b15cb3dSCy Schubert rpt_0x45( 21032b15cb3dSCy Schubert TSIPPKT *rpt, 2104ba371819SOllivier Robert unsigned char *major_nav_version, 2105ba371819SOllivier Robert unsigned char *minor_nav_version, 2106ba371819SOllivier Robert unsigned char *nav_day, 2107ba371819SOllivier Robert unsigned char *nav_month, 2108ba371819SOllivier Robert unsigned char *nav_year, 2109ba371819SOllivier Robert unsigned char *major_dsp_version, 2110ba371819SOllivier Robert unsigned char *minor_dsp_version, 2111ba371819SOllivier Robert unsigned char *dsp_day, 2112ba371819SOllivier Robert unsigned char *dsp_month, 21132b15cb3dSCy Schubert unsigned char *dsp_year 21142b15cb3dSCy Schubert ) 2115ba371819SOllivier Robert { 2116ba371819SOllivier Robert unsigned char *buf; 2117ba371819SOllivier Robert buf = rpt->buf; 2118ba371819SOllivier Robert 2119ba371819SOllivier Robert if (rpt->len != 10) return TRUE; 2120ba371819SOllivier Robert *major_nav_version = buf[0]; 2121ba371819SOllivier Robert *minor_nav_version = buf[1]; 2122ba371819SOllivier Robert *nav_day = buf[2]; 2123ba371819SOllivier Robert *nav_month = buf[3]; 2124ba371819SOllivier Robert *nav_year = buf[4]; 2125ba371819SOllivier Robert *major_dsp_version = buf[5]; 2126ba371819SOllivier Robert *minor_dsp_version = buf[6]; 2127ba371819SOllivier Robert *dsp_day = buf[7]; 2128ba371819SOllivier Robert *dsp_month = buf[8]; 2129ba371819SOllivier Robert *dsp_year = buf[9]; 2130ba371819SOllivier Robert return FALSE; 2131ba371819SOllivier Robert } 2132ba371819SOllivier Robert 2133ba371819SOllivier Robert /* receiver health and status */ 21342b15cb3dSCy Schubert short 21352b15cb3dSCy Schubert rpt_0x46( 21362b15cb3dSCy Schubert TSIPPKT *rpt, 21372b15cb3dSCy Schubert unsigned char *status1, 21382b15cb3dSCy Schubert unsigned char *status2 21392b15cb3dSCy Schubert ) 2140ba371819SOllivier Robert { 2141ba371819SOllivier Robert unsigned char *buf; 2142ba371819SOllivier Robert buf = rpt->buf; 2143ba371819SOllivier Robert 2144ba371819SOllivier Robert if (rpt->len != 2) return TRUE; 2145ba371819SOllivier Robert *status1 = buf[0]; 2146ba371819SOllivier Robert *status2 = buf[1]; 2147ba371819SOllivier Robert return FALSE; 2148ba371819SOllivier Robert } 2149ba371819SOllivier Robert 2150ba371819SOllivier Robert /* signal levels for all satellites tracked */ 21512b15cb3dSCy Schubert short 21522b15cb3dSCy Schubert rpt_0x47( 21532b15cb3dSCy Schubert TSIPPKT *rpt, 21542b15cb3dSCy Schubert unsigned char *nsvs, 21552b15cb3dSCy Schubert unsigned char *sv_prn, 21562b15cb3dSCy Schubert float *snr 21572b15cb3dSCy Schubert ) 2158ba371819SOllivier Robert { 2159ba371819SOllivier Robert short isv; 2160ba371819SOllivier Robert unsigned char *buf; 2161ba371819SOllivier Robert buf = rpt->buf; 2162ba371819SOllivier Robert 2163ba371819SOllivier Robert if (rpt->len != 1 + 5*buf[0]) return TRUE; 2164ba371819SOllivier Robert *nsvs = buf[0]; 2165ba371819SOllivier Robert for (isv = 0; isv < (*nsvs); isv++) { 2166ba371819SOllivier Robert sv_prn[isv] = buf[5*isv + 1]; 2167ba371819SOllivier Robert snr[isv] = bGetSingle (&buf[5*isv + 2]); 2168ba371819SOllivier Robert } 2169ba371819SOllivier Robert return FALSE; 2170ba371819SOllivier Robert } 2171ba371819SOllivier Robert 2172ba371819SOllivier Robert /* GPS system message */ 21732b15cb3dSCy Schubert short 21742b15cb3dSCy Schubert rpt_0x48( 21752b15cb3dSCy Schubert TSIPPKT *rpt, 21762b15cb3dSCy Schubert unsigned char *message 21772b15cb3dSCy Schubert ) 2178ba371819SOllivier Robert { 2179ba371819SOllivier Robert unsigned char *buf; 2180ba371819SOllivier Robert buf = rpt->buf; 2181ba371819SOllivier Robert 2182ba371819SOllivier Robert if (rpt->len != 22) return TRUE; 2183ba371819SOllivier Robert memcpy (message, buf, 22); 2184ba371819SOllivier Robert message[22] = 0; 2185ba371819SOllivier Robert return FALSE; 2186ba371819SOllivier Robert } 2187ba371819SOllivier Robert 2188ba371819SOllivier Robert /* health for all satellites from almanac health page */ 21892b15cb3dSCy Schubert short 21902b15cb3dSCy Schubert rpt_0x49( 21912b15cb3dSCy Schubert TSIPPKT *rpt, 21922b15cb3dSCy Schubert unsigned char *sv_health 21932b15cb3dSCy Schubert ) 2194ba371819SOllivier Robert { 2195ba371819SOllivier Robert short i; 2196ba371819SOllivier Robert unsigned char *buf; 2197ba371819SOllivier Robert buf = rpt->buf; 2198ba371819SOllivier Robert 2199ba371819SOllivier Robert if (rpt->len != 32) return TRUE; 2200ba371819SOllivier Robert for (i = 0; i < 32; i++) sv_health [i]= buf[i]; 2201ba371819SOllivier Robert return FALSE; 2202ba371819SOllivier Robert } 2203ba371819SOllivier Robert 22042b15cb3dSCy Schubert /* position in lat-lon-alt, single precision */ 22052b15cb3dSCy Schubert short 22062b15cb3dSCy Schubert rpt_0x4A( 22072b15cb3dSCy Schubert TSIPPKT *rpt, 2208ba371819SOllivier Robert float *lat, 2209ba371819SOllivier Robert float *lon, 2210ba371819SOllivier Robert float *alt, 2211ba371819SOllivier Robert float *clock_bias, 22122b15cb3dSCy Schubert float *time_of_fix 22132b15cb3dSCy Schubert ) 2214ba371819SOllivier Robert { 2215ba371819SOllivier Robert unsigned char *buf; 2216ba371819SOllivier Robert buf = rpt->buf; 2217ba371819SOllivier Robert 2218ba371819SOllivier Robert if (rpt->len != 20) return TRUE; 2219ba371819SOllivier Robert *lat = bGetSingle (buf); 2220ba371819SOllivier Robert *lon = bGetSingle (&buf[4]); 2221ba371819SOllivier Robert *alt = bGetSingle (&buf[8]); 2222ba371819SOllivier Robert *clock_bias = bGetSingle (&buf[12]); 2223ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[16]); 2224ba371819SOllivier Robert return FALSE; 2225ba371819SOllivier Robert } 2226ba371819SOllivier Robert 2227ba371819SOllivier Robert /* reference altitude parameters */ 22282b15cb3dSCy Schubert short 22292b15cb3dSCy Schubert rpt_0x4A_2( 22302b15cb3dSCy Schubert TSIPPKT *rpt, 22312b15cb3dSCy Schubert float *alt, 22322b15cb3dSCy Schubert float *dummy, 22332b15cb3dSCy Schubert unsigned char *alt_flag 22342b15cb3dSCy Schubert ) 2235ba371819SOllivier Robert { 2236ba371819SOllivier Robert unsigned char *buf; 2237ba371819SOllivier Robert 2238ba371819SOllivier Robert buf = rpt->buf; 2239ba371819SOllivier Robert 2240ba371819SOllivier Robert if (rpt->len != 9) return TRUE; 2241ba371819SOllivier Robert *alt = bGetSingle (buf); 2242ba371819SOllivier Robert *dummy = bGetSingle (&buf[4]); 2243ba371819SOllivier Robert *alt_flag = buf[8]; 2244ba371819SOllivier Robert return FALSE; 2245ba371819SOllivier Robert } 2246ba371819SOllivier Robert 22472b15cb3dSCy Schubert /* machine ID code, status */ 22482b15cb3dSCy Schubert short 22492b15cb3dSCy Schubert rpt_0x4B( 22502b15cb3dSCy Schubert TSIPPKT *rpt, 2251ba371819SOllivier Robert unsigned char *machine_id, 2252ba371819SOllivier Robert unsigned char *status3, 22532b15cb3dSCy Schubert unsigned char *status4 22542b15cb3dSCy Schubert ) 2255ba371819SOllivier Robert { 2256ba371819SOllivier Robert unsigned char *buf; 2257ba371819SOllivier Robert buf = rpt->buf; 2258ba371819SOllivier Robert 2259ba371819SOllivier Robert if (rpt->len != 3) return TRUE; 2260ba371819SOllivier Robert *machine_id = buf[0]; 2261ba371819SOllivier Robert *status3 = buf[1]; 2262ba371819SOllivier Robert *status4 = buf[2]; 2263ba371819SOllivier Robert return FALSE; 2264ba371819SOllivier Robert } 2265ba371819SOllivier Robert 22662b15cb3dSCy Schubert /* operating parameters and masks */ 22672b15cb3dSCy Schubert short 22682b15cb3dSCy Schubert rpt_0x4C( 22692b15cb3dSCy Schubert TSIPPKT *rpt, 2270ba371819SOllivier Robert unsigned char *dyn_code, 2271ba371819SOllivier Robert float *el_mask, 2272ba371819SOllivier Robert float *snr_mask, 2273ba371819SOllivier Robert float *dop_mask, 22742b15cb3dSCy Schubert float *dop_switch 22752b15cb3dSCy Schubert ) 2276ba371819SOllivier Robert { 2277ba371819SOllivier Robert unsigned char *buf; 2278ba371819SOllivier Robert buf = rpt->buf; 2279ba371819SOllivier Robert 2280ba371819SOllivier Robert if (rpt->len != 17) return TRUE; 2281ba371819SOllivier Robert *dyn_code = buf[0]; 2282ba371819SOllivier Robert *el_mask = bGetSingle (&buf[1]); 2283ba371819SOllivier Robert *snr_mask = bGetSingle (&buf[5]); 2284ba371819SOllivier Robert *dop_mask = bGetSingle (&buf[9]); 2285ba371819SOllivier Robert *dop_switch = bGetSingle (&buf[13]); 2286ba371819SOllivier Robert return FALSE; 2287ba371819SOllivier Robert } 2288ba371819SOllivier Robert 2289ba371819SOllivier Robert /* oscillator offset */ 22902b15cb3dSCy Schubert short 22912b15cb3dSCy Schubert rpt_0x4D( 22922b15cb3dSCy Schubert TSIPPKT *rpt, 22932b15cb3dSCy Schubert float *osc_offset 22942b15cb3dSCy Schubert ) 2295ba371819SOllivier Robert { 2296ba371819SOllivier Robert unsigned char *buf; 2297ba371819SOllivier Robert buf = rpt->buf; 2298ba371819SOllivier Robert 2299ba371819SOllivier Robert if (rpt->len != 4) return TRUE; 2300ba371819SOllivier Robert *osc_offset = bGetSingle (buf); 2301ba371819SOllivier Robert return FALSE; 2302ba371819SOllivier Robert } 2303ba371819SOllivier Robert 2304ba371819SOllivier Robert /* yes/no response to command to set GPS time */ 23052b15cb3dSCy Schubert short 23062b15cb3dSCy Schubert rpt_0x4E( 23072b15cb3dSCy Schubert TSIPPKT *rpt, 23082b15cb3dSCy Schubert unsigned char *response 23092b15cb3dSCy Schubert ) 2310ba371819SOllivier Robert { 2311ba371819SOllivier Robert unsigned char *buf; 2312ba371819SOllivier Robert buf = rpt->buf; 2313ba371819SOllivier Robert 2314ba371819SOllivier Robert if (rpt->len != 1) return TRUE; 2315ba371819SOllivier Robert *response = buf[0]; 2316ba371819SOllivier Robert return FALSE; 2317ba371819SOllivier Robert } 2318ba371819SOllivier Robert 23192b15cb3dSCy Schubert /* UTC data */ 23202b15cb3dSCy Schubert short 23212b15cb3dSCy Schubert rpt_0x4F( 23222b15cb3dSCy Schubert TSIPPKT *rpt, 2323ba371819SOllivier Robert double *a0, 2324ba371819SOllivier Robert float *a1, 2325ba371819SOllivier Robert float *time_of_data, 2326ba371819SOllivier Robert short *dt_ls, 2327ba371819SOllivier Robert short *wn_t, 2328ba371819SOllivier Robert short *wn_lsf, 2329ba371819SOllivier Robert short *dn, 23302b15cb3dSCy Schubert short *dt_lsf 23312b15cb3dSCy Schubert ) 2332ba371819SOllivier Robert { 2333ba371819SOllivier Robert unsigned char *buf; 2334ba371819SOllivier Robert buf = rpt->buf; 2335ba371819SOllivier Robert 2336ba371819SOllivier Robert if (rpt->len != 26) return TRUE; 2337ba371819SOllivier Robert *a0 = bGetDouble (buf); 2338ba371819SOllivier Robert *a1 = bGetSingle (&buf[8]); 2339ba371819SOllivier Robert *dt_ls = bGetShort (&buf[12]); 2340ba371819SOllivier Robert *time_of_data = bGetSingle (&buf[14]); 2341ba371819SOllivier Robert *wn_t = bGetShort (&buf[18]); 2342ba371819SOllivier Robert *wn_lsf = bGetShort (&buf[20]); 2343ba371819SOllivier Robert *dn = bGetShort (&buf[22]); 2344ba371819SOllivier Robert *dt_lsf = bGetShort (&buf[24]); 2345ba371819SOllivier Robert return FALSE; 2346ba371819SOllivier Robert } 2347ba371819SOllivier Robert 2348ba371819SOllivier Robert /**/ 23492b15cb3dSCy Schubert /* clock offset and frequency offset in 1-SV (0-D) mode */ 23502b15cb3dSCy Schubert short 23512b15cb3dSCy Schubert rpt_0x54( 23522b15cb3dSCy Schubert TSIPPKT *rpt, 2353ba371819SOllivier Robert float *clock_bias, 2354ba371819SOllivier Robert float *freq_offset, 23552b15cb3dSCy Schubert float *time_of_fix 23562b15cb3dSCy Schubert ) 2357ba371819SOllivier Robert { 2358ba371819SOllivier Robert unsigned char *buf; 2359ba371819SOllivier Robert buf = rpt->buf; 2360ba371819SOllivier Robert 2361ba371819SOllivier Robert if (rpt->len != 12) return TRUE; 2362ba371819SOllivier Robert *clock_bias = bGetSingle (buf); 2363ba371819SOllivier Robert *freq_offset = bGetSingle (&buf[4]); 2364ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[8]); 2365ba371819SOllivier Robert return FALSE; 2366ba371819SOllivier Robert } 2367ba371819SOllivier Robert 23682b15cb3dSCy Schubert /* I/O serial options */ 23692b15cb3dSCy Schubert short 23702b15cb3dSCy Schubert rpt_0x55( 23712b15cb3dSCy Schubert TSIPPKT *rpt, 2372ba371819SOllivier Robert unsigned char *pos_code, 2373ba371819SOllivier Robert unsigned char *vel_code, 2374ba371819SOllivier Robert unsigned char *time_code, 23752b15cb3dSCy Schubert unsigned char *aux_code 23762b15cb3dSCy Schubert ) 2377ba371819SOllivier Robert { 2378ba371819SOllivier Robert unsigned char *buf; 2379ba371819SOllivier Robert buf = rpt->buf; 2380ba371819SOllivier Robert 2381ba371819SOllivier Robert if (rpt->len != 4) return TRUE; 2382ba371819SOllivier Robert *pos_code = buf[0]; 2383ba371819SOllivier Robert *vel_code = buf[1]; 2384ba371819SOllivier Robert *time_code = buf[2]; 2385ba371819SOllivier Robert *aux_code = buf[3]; 2386ba371819SOllivier Robert return FALSE; 2387ba371819SOllivier Robert } 2388ba371819SOllivier Robert 2389ba371819SOllivier Robert /* velocity in east-north-up coordinates */ 23902b15cb3dSCy Schubert short 23912b15cb3dSCy Schubert rpt_0x56( 23922b15cb3dSCy Schubert TSIPPKT *rpt, 23932b15cb3dSCy Schubert float vel_ENU[3], 23942b15cb3dSCy Schubert float *freq_offset, 23952b15cb3dSCy Schubert float *time_of_fix 23962b15cb3dSCy Schubert ) 2397ba371819SOllivier Robert { 2398ba371819SOllivier Robert unsigned char *buf; 2399ba371819SOllivier Robert buf = rpt->buf; 2400ba371819SOllivier Robert 2401ba371819SOllivier Robert if (rpt->len != 20) return TRUE; 2402ba371819SOllivier Robert /* east */ 2403ba371819SOllivier Robert vel_ENU[0] = bGetSingle (buf); 2404ba371819SOllivier Robert /* north */ 2405ba371819SOllivier Robert vel_ENU[1] = bGetSingle (&buf[4]); 2406ba371819SOllivier Robert /* up */ 2407ba371819SOllivier Robert vel_ENU[2] = bGetSingle (&buf[8]); 2408ba371819SOllivier Robert *freq_offset = bGetSingle (&buf[12]); 2409ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[16]); 2410ba371819SOllivier Robert return FALSE; 2411ba371819SOllivier Robert } 2412ba371819SOllivier Robert 2413ba371819SOllivier Robert /* info about last computed fix */ 24142b15cb3dSCy Schubert short 24152b15cb3dSCy Schubert rpt_0x57( 24162b15cb3dSCy Schubert TSIPPKT *rpt, 24172b15cb3dSCy Schubert unsigned char *source_code, 24182b15cb3dSCy Schubert unsigned char *diag_code, 24192b15cb3dSCy Schubert short *week_num, 24202b15cb3dSCy Schubert float *time_of_fix 24212b15cb3dSCy Schubert ) 2422ba371819SOllivier Robert { 2423ba371819SOllivier Robert unsigned char *buf; 2424ba371819SOllivier Robert buf = rpt->buf; 2425ba371819SOllivier Robert 2426ba371819SOllivier Robert if (rpt->len != 8) return TRUE; 2427ba371819SOllivier Robert *source_code = buf[0]; 2428ba371819SOllivier Robert *diag_code = buf[1]; 2429ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[2]); 2430ba371819SOllivier Robert *week_num = bGetShort (&buf[6]); 2431ba371819SOllivier Robert return FALSE; 2432ba371819SOllivier Robert } 2433ba371819SOllivier Robert 2434ba371819SOllivier Robert /* GPS system data or acknowledgment of GPS system data load */ 24352b15cb3dSCy Schubert short 24362b15cb3dSCy Schubert rpt_0x58( 24372b15cb3dSCy Schubert TSIPPKT *rpt, 24382b15cb3dSCy Schubert unsigned char *op_code, 24392b15cb3dSCy Schubert unsigned char *data_type, 24402b15cb3dSCy Schubert unsigned char *sv_prn, 24412b15cb3dSCy Schubert unsigned char *data_length, 24422b15cb3dSCy Schubert unsigned char *data_packet 24432b15cb3dSCy Schubert ) 2444ba371819SOllivier Robert { 2445ba371819SOllivier Robert unsigned char *buf, *buf4; 2446ba371819SOllivier Robert short dl; 2447ba371819SOllivier Robert ALM_INFO* alminfo; 2448ba371819SOllivier Robert ION_INFO* ioninfo; 2449ba371819SOllivier Robert UTC_INFO* utcinfo; 2450ba371819SOllivier Robert NAV_INFO* navinfo; 2451ba371819SOllivier Robert 2452ba371819SOllivier Robert buf = rpt->buf; 2453ba371819SOllivier Robert 2454ba371819SOllivier Robert if (buf[0] == 2) { 2455ba371819SOllivier Robert if (rpt->len < 4) return TRUE; 2456ba371819SOllivier Robert if (rpt->len != 4+buf[3]) return TRUE; 2457ba371819SOllivier Robert } 2458ba371819SOllivier Robert else if (rpt->len != 3) { 2459ba371819SOllivier Robert return TRUE; 2460ba371819SOllivier Robert } 2461ba371819SOllivier Robert *op_code = buf[0]; 2462ba371819SOllivier Robert *data_type = buf[1]; 2463ba371819SOllivier Robert *sv_prn = buf[2]; 2464ba371819SOllivier Robert if (*op_code == 2) { 2465ba371819SOllivier Robert dl = buf[3]; 2466ba371819SOllivier Robert *data_length = (unsigned char)dl; 2467ba371819SOllivier Robert buf4 = &buf[4]; 2468ba371819SOllivier Robert switch (*data_type) { 2469ba371819SOllivier Robert case 2: 2470ba371819SOllivier Robert /* Almanac */ 2471ba371819SOllivier Robert if (*data_length != sizeof (ALM_INFO)) return TRUE; 2472ba371819SOllivier Robert alminfo = (ALM_INFO*)data_packet; 2473ba371819SOllivier Robert alminfo->t_oa_raw = buf4[0]; 2474ba371819SOllivier Robert alminfo->SV_health = buf4[1]; 2475ba371819SOllivier Robert alminfo->e = bGetSingle(&buf4[2]); 2476ba371819SOllivier Robert alminfo->t_oa = bGetSingle(&buf4[6]); 2477ba371819SOllivier Robert alminfo->i_0 = bGetSingle(&buf4[10]); 2478ba371819SOllivier Robert alminfo->OMEGADOT = bGetSingle(&buf4[14]); 2479ba371819SOllivier Robert alminfo->sqrt_A = bGetSingle(&buf4[18]); 2480ba371819SOllivier Robert alminfo->OMEGA_0 = bGetSingle(&buf4[22]); 2481ba371819SOllivier Robert alminfo->omega = bGetSingle(&buf4[26]); 2482ba371819SOllivier Robert alminfo->M_0 = bGetSingle(&buf4[30]); 2483ba371819SOllivier Robert alminfo->a_f0 = bGetSingle(&buf4[34]); 2484ba371819SOllivier Robert alminfo->a_f1 = bGetSingle(&buf4[38]); 2485ba371819SOllivier Robert alminfo->Axis = bGetSingle(&buf4[42]); 2486ba371819SOllivier Robert alminfo->n = bGetSingle(&buf4[46]); 2487ba371819SOllivier Robert alminfo->OMEGA_n = bGetSingle(&buf4[50]); 2488ba371819SOllivier Robert alminfo->ODOT_n = bGetSingle(&buf4[54]); 2489ba371819SOllivier Robert alminfo->t_zc = bGetSingle(&buf4[58]); 2490ba371819SOllivier Robert alminfo->weeknum = bGetShort(&buf4[62]); 2491ba371819SOllivier Robert alminfo->wn_oa = bGetShort(&buf4[64]); 2492ba371819SOllivier Robert break; 2493ba371819SOllivier Robert 2494ba371819SOllivier Robert case 3: 2495ba371819SOllivier Robert /* Almanac health page */ 2496ba371819SOllivier Robert if (*data_length != sizeof (ALH_PARMS) + 3) return TRUE; 2497ba371819SOllivier Robert 2498ba371819SOllivier Robert /* this record is returned raw */ 2499ba371819SOllivier Robert memcpy (data_packet, buf4, dl); 2500ba371819SOllivier Robert break; 2501ba371819SOllivier Robert 2502ba371819SOllivier Robert case 4: 2503ba371819SOllivier Robert /* Ionosphere */ 2504ba371819SOllivier Robert if (*data_length != sizeof (ION_INFO) + 8) return TRUE; 2505ba371819SOllivier Robert ioninfo = (ION_INFO*)data_packet; 2506ba371819SOllivier Robert ioninfo->alpha_0 = bGetSingle (&buf4[8]); 2507ba371819SOllivier Robert ioninfo->alpha_1 = bGetSingle (&buf4[12]); 2508ba371819SOllivier Robert ioninfo->alpha_2 = bGetSingle (&buf4[16]); 2509ba371819SOllivier Robert ioninfo->alpha_3 = bGetSingle (&buf4[20]); 2510ba371819SOllivier Robert ioninfo->beta_0 = bGetSingle (&buf4[24]); 2511ba371819SOllivier Robert ioninfo->beta_1 = bGetSingle (&buf4[28]); 2512ba371819SOllivier Robert ioninfo->beta_2 = bGetSingle (&buf4[32]); 2513ba371819SOllivier Robert ioninfo->beta_3 = bGetSingle (&buf4[36]); 2514ba371819SOllivier Robert break; 2515ba371819SOllivier Robert 2516ba371819SOllivier Robert case 5: 2517ba371819SOllivier Robert /* UTC */ 2518ba371819SOllivier Robert if (*data_length != sizeof (UTC_INFO) + 13) return TRUE; 2519ba371819SOllivier Robert utcinfo = (UTC_INFO*)data_packet; 2520ba371819SOllivier Robert utcinfo->A_0 = bGetDouble (&buf4[13]); 2521ba371819SOllivier Robert utcinfo->A_1 = bGetSingle (&buf4[21]); 2522ba371819SOllivier Robert utcinfo->delta_t_LS = bGetShort (&buf4[25]); 2523ba371819SOllivier Robert utcinfo->t_ot = bGetSingle(&buf4[27]); 2524ba371819SOllivier Robert utcinfo->WN_t = bGetShort (&buf4[31]); 2525ba371819SOllivier Robert utcinfo->WN_LSF = bGetShort (&buf4[33]); 2526ba371819SOllivier Robert utcinfo->DN = bGetShort (&buf4[35]); 2527ba371819SOllivier Robert utcinfo->delta_t_LSF = bGetShort (&buf4[37]); 2528ba371819SOllivier Robert break; 2529ba371819SOllivier Robert 2530ba371819SOllivier Robert case 6: 2531ba371819SOllivier Robert /* Ephemeris */ 2532ba371819SOllivier Robert if (*data_length != sizeof (NAV_INFO) - 1) return TRUE; 2533ba371819SOllivier Robert 2534ba371819SOllivier Robert navinfo = (NAV_INFO*)data_packet; 2535ba371819SOllivier Robert 2536ba371819SOllivier Robert navinfo->sv_number = buf4[0]; 2537ba371819SOllivier Robert navinfo->t_ephem = bGetSingle (&buf4[1]); 2538ba371819SOllivier Robert navinfo->ephclk.weeknum = bGetShort (&buf4[5]); 2539ba371819SOllivier Robert 2540ba371819SOllivier Robert navinfo->ephclk.codeL2 = buf4[7]; 2541ba371819SOllivier Robert navinfo->ephclk.L2Pdata = buf4[8]; 2542ba371819SOllivier Robert navinfo->ephclk.SVacc_raw = buf4[9]; 2543ba371819SOllivier Robert navinfo->ephclk.SV_health = buf4[10]; 2544ba371819SOllivier Robert navinfo->ephclk.IODC = bGetShort (&buf4[11]); 2545ba371819SOllivier Robert navinfo->ephclk.T_GD = bGetSingle (&buf4[13]); 2546ba371819SOllivier Robert navinfo->ephclk.t_oc = bGetSingle (&buf4[17]); 2547ba371819SOllivier Robert navinfo->ephclk.a_f2 = bGetSingle (&buf4[21]); 2548ba371819SOllivier Robert navinfo->ephclk.a_f1 = bGetSingle (&buf4[25]); 2549ba371819SOllivier Robert navinfo->ephclk.a_f0 = bGetSingle (&buf4[29]); 2550ba371819SOllivier Robert navinfo->ephclk.SVacc = bGetSingle (&buf4[33]); 2551ba371819SOllivier Robert 2552ba371819SOllivier Robert navinfo->ephorb.IODE = buf4[37]; 2553ba371819SOllivier Robert navinfo->ephorb.fit_interval = buf4[38]; 2554ba371819SOllivier Robert navinfo->ephorb.C_rs = bGetSingle (&buf4[39]); 2555ba371819SOllivier Robert navinfo->ephorb.delta_n = bGetSingle (&buf4[43]); 2556ba371819SOllivier Robert navinfo->ephorb.M_0 = bGetDouble (&buf4[47]); 2557ba371819SOllivier Robert navinfo->ephorb.C_uc = bGetSingle (&buf4[55]); 2558ba371819SOllivier Robert navinfo->ephorb.e = bGetDouble (&buf4[59]); 2559ba371819SOllivier Robert navinfo->ephorb.C_us = bGetSingle (&buf4[67]); 2560ba371819SOllivier Robert navinfo->ephorb.sqrt_A = bGetDouble (&buf4[71]); 2561ba371819SOllivier Robert navinfo->ephorb.t_oe = bGetSingle (&buf4[79]); 2562ba371819SOllivier Robert navinfo->ephorb.C_ic = bGetSingle (&buf4[83]); 2563ba371819SOllivier Robert navinfo->ephorb.OMEGA_0 = bGetDouble (&buf4[87]); 2564ba371819SOllivier Robert navinfo->ephorb.C_is = bGetSingle (&buf4[95]); 2565ba371819SOllivier Robert navinfo->ephorb.i_0 = bGetDouble (&buf4[99]); 2566ba371819SOllivier Robert navinfo->ephorb.C_rc = bGetSingle (&buf4[107]); 2567ba371819SOllivier Robert navinfo->ephorb.omega = bGetDouble (&buf4[111]); 2568ba371819SOllivier Robert navinfo->ephorb.OMEGADOT=bGetSingle (&buf4[119]); 2569ba371819SOllivier Robert navinfo->ephorb.IDOT = bGetSingle (&buf4[123]); 2570ba371819SOllivier Robert navinfo->ephorb.Axis = bGetDouble (&buf4[127]); 2571ba371819SOllivier Robert navinfo->ephorb.n = bGetDouble (&buf4[135]); 2572ba371819SOllivier Robert navinfo->ephorb.r1me2 = bGetDouble (&buf4[143]); 2573ba371819SOllivier Robert navinfo->ephorb.OMEGA_n=bGetDouble (&buf4[151]); 2574ba371819SOllivier Robert navinfo->ephorb.ODOT_n = bGetDouble (&buf4[159]); 2575ba371819SOllivier Robert break; 2576ba371819SOllivier Robert } 2577ba371819SOllivier Robert } 2578ba371819SOllivier Robert return FALSE; 2579ba371819SOllivier Robert } 2580ba371819SOllivier Robert 2581ba371819SOllivier Robert /* satellite enable/disable or health heed/ignore list */ 25822b15cb3dSCy Schubert short 25832b15cb3dSCy Schubert rpt_0x59( 25842b15cb3dSCy Schubert TSIPPKT *rpt, 25852b15cb3dSCy Schubert unsigned char *code_type, 25862b15cb3dSCy Schubert unsigned char status_code[32] 25872b15cb3dSCy Schubert ) 2588ba371819SOllivier Robert { 2589ba371819SOllivier Robert short iprn; 2590ba371819SOllivier Robert unsigned char *buf; 2591ba371819SOllivier Robert buf = rpt->buf; 2592ba371819SOllivier Robert 2593ba371819SOllivier Robert if (rpt->len != 33) return TRUE; 2594ba371819SOllivier Robert *code_type = buf[0]; 2595ba371819SOllivier Robert for (iprn = 0; iprn < 32; iprn++) 2596ba371819SOllivier Robert status_code[iprn] = buf[iprn + 1]; 2597ba371819SOllivier Robert return FALSE; 2598ba371819SOllivier Robert } 2599ba371819SOllivier Robert 26002b15cb3dSCy Schubert /* raw measurement data - code phase/Doppler */ 26012b15cb3dSCy Schubert short 26022b15cb3dSCy Schubert rpt_0x5A( 26032b15cb3dSCy Schubert TSIPPKT *rpt, 2604ba371819SOllivier Robert unsigned char *sv_prn, 2605ba371819SOllivier Robert float *sample_length, 2606ba371819SOllivier Robert float *signal_level, 2607ba371819SOllivier Robert float *code_phase, 2608ba371819SOllivier Robert float *Doppler, 26092b15cb3dSCy Schubert double *time_of_fix 26102b15cb3dSCy Schubert ) 2611ba371819SOllivier Robert { 2612ba371819SOllivier Robert unsigned char *buf; 2613ba371819SOllivier Robert buf = rpt->buf; 2614ba371819SOllivier Robert 2615ba371819SOllivier Robert if (rpt->len != 25) return TRUE; 2616ba371819SOllivier Robert *sv_prn = buf[0]; 2617ba371819SOllivier Robert *sample_length = bGetSingle (&buf[1]); 2618ba371819SOllivier Robert *signal_level = bGetSingle (&buf[5]); 2619ba371819SOllivier Robert *code_phase = bGetSingle (&buf[9]); 2620ba371819SOllivier Robert *Doppler = bGetSingle (&buf[13]); 2621ba371819SOllivier Robert *time_of_fix = bGetDouble (&buf[17]); 2622ba371819SOllivier Robert return FALSE; 2623ba371819SOllivier Robert } 2624ba371819SOllivier Robert 26252b15cb3dSCy Schubert /* satellite ephorb status */ 26262b15cb3dSCy Schubert short 26272b15cb3dSCy Schubert rpt_0x5B( 26282b15cb3dSCy Schubert TSIPPKT *rpt, 2629ba371819SOllivier Robert unsigned char *sv_prn, 2630ba371819SOllivier Robert unsigned char *sv_health, 2631ba371819SOllivier Robert unsigned char *sv_iode, 2632ba371819SOllivier Robert unsigned char *fit_interval_flag, 2633ba371819SOllivier Robert float *time_of_collection, 2634ba371819SOllivier Robert float *time_of_eph, 26352b15cb3dSCy Schubert float *sv_accy 26362b15cb3dSCy Schubert ) 2637ba371819SOllivier Robert { 2638ba371819SOllivier Robert unsigned char *buf; 2639ba371819SOllivier Robert buf = rpt->buf; 2640ba371819SOllivier Robert 2641ba371819SOllivier Robert if (rpt->len != 16) return TRUE; 2642ba371819SOllivier Robert *sv_prn = buf[0]; 2643ba371819SOllivier Robert *time_of_collection = bGetSingle (&buf[1]); 2644ba371819SOllivier Robert *sv_health = buf[5]; 2645ba371819SOllivier Robert *sv_iode = buf[6]; 2646ba371819SOllivier Robert *time_of_eph = bGetSingle (&buf[7]); 2647ba371819SOllivier Robert *fit_interval_flag = buf[11]; 2648ba371819SOllivier Robert *sv_accy = bGetSingle (&buf[12]); 2649ba371819SOllivier Robert return FALSE; 2650ba371819SOllivier Robert } 2651ba371819SOllivier Robert 26522b15cb3dSCy Schubert /* satellite tracking status */ 26532b15cb3dSCy Schubert short 26542b15cb3dSCy Schubert rpt_0x5C( 26552b15cb3dSCy Schubert TSIPPKT *rpt, 2656ba371819SOllivier Robert unsigned char *sv_prn, 2657ba371819SOllivier Robert unsigned char *slot, 2658ba371819SOllivier Robert unsigned char *chan, 2659ba371819SOllivier Robert unsigned char *acq_flag, 2660ba371819SOllivier Robert unsigned char *eph_flag, 2661ba371819SOllivier Robert float *signal_level, 2662ba371819SOllivier Robert float *time_of_last_msmt, 2663ba371819SOllivier Robert float *elev, 2664ba371819SOllivier Robert float *azim, 2665ba371819SOllivier Robert unsigned char *old_msmt_flag, 2666ba371819SOllivier Robert unsigned char *integer_msec_flag, 2667ba371819SOllivier Robert unsigned char *bad_data_flag, 26682b15cb3dSCy Schubert unsigned char *data_collect_flag 26692b15cb3dSCy Schubert ) 2670ba371819SOllivier Robert { 2671ba371819SOllivier Robert unsigned char *buf; 2672ba371819SOllivier Robert buf = rpt->buf; 2673ba371819SOllivier Robert 2674ba371819SOllivier Robert if (rpt->len != 24) return TRUE; 2675ba371819SOllivier Robert *sv_prn = buf[0]; 2676ba371819SOllivier Robert *slot = (unsigned char)((buf[1] & 0x07) + 1); 2677ba371819SOllivier Robert *chan = (unsigned char)(buf[1] >> 3); 2678ba371819SOllivier Robert if (*chan == 0x10) *chan = 2; 2679ba371819SOllivier Robert else (*chan)++; 2680ba371819SOllivier Robert *acq_flag = buf[2]; 2681ba371819SOllivier Robert *eph_flag = buf[3]; 2682ba371819SOllivier Robert *signal_level = bGetSingle (&buf[4]); 2683ba371819SOllivier Robert *time_of_last_msmt = bGetSingle (&buf[8]); 2684ba371819SOllivier Robert *elev = bGetSingle (&buf[12]); 2685ba371819SOllivier Robert *azim = bGetSingle (&buf[16]); 2686ba371819SOllivier Robert *old_msmt_flag = buf[20]; 2687ba371819SOllivier Robert *integer_msec_flag = buf[21]; 2688ba371819SOllivier Robert *bad_data_flag = buf[22]; 2689ba371819SOllivier Robert *data_collect_flag = buf[23]; 2690ba371819SOllivier Robert return FALSE; 2691ba371819SOllivier Robert } 2692ba371819SOllivier Robert 2693ba371819SOllivier Robert /**/ 26942b15cb3dSCy Schubert /* over-determined satellite selection for position fixes, PDOP, fix mode */ 26952b15cb3dSCy Schubert short 26962b15cb3dSCy Schubert rpt_0x6D( 26972b15cb3dSCy Schubert TSIPPKT *rpt, 2698ba371819SOllivier Robert unsigned char *manual_mode, 2699ba371819SOllivier Robert unsigned char *nsvs, 2700ba371819SOllivier Robert unsigned char *ndim, 2701ba371819SOllivier Robert unsigned char sv_prn[], 2702ba371819SOllivier Robert float *pdop, 2703ba371819SOllivier Robert float *hdop, 2704ba371819SOllivier Robert float *vdop, 27052b15cb3dSCy Schubert float *tdop 27062b15cb3dSCy Schubert ) 2707ba371819SOllivier Robert { 2708ba371819SOllivier Robert short islot; 2709ba371819SOllivier Robert unsigned char *buf; 2710ba371819SOllivier Robert buf = rpt->buf; 2711ba371819SOllivier Robert 2712ba371819SOllivier Robert *nsvs = (unsigned char)((buf[0] & 0xF0) >> 4); 2713ba371819SOllivier Robert if ((*nsvs)>8) return TRUE; 2714ba371819SOllivier Robert if (rpt->len != 17 + (*nsvs) ) return TRUE; 2715ba371819SOllivier Robert 2716ba371819SOllivier Robert *manual_mode = (unsigned char)(buf[0] & 0x08); 2717ba371819SOllivier Robert *ndim = (unsigned char)((buf[0] & 0x07)); 2718ba371819SOllivier Robert *pdop = bGetSingle (&buf[1]); 2719ba371819SOllivier Robert *hdop = bGetSingle (&buf[5]); 2720ba371819SOllivier Robert *vdop = bGetSingle (&buf[9]); 2721ba371819SOllivier Robert *tdop = bGetSingle (&buf[13]); 2722ba371819SOllivier Robert for (islot = 0; islot < (*nsvs); islot++) 2723ba371819SOllivier Robert sv_prn[islot] = buf[islot + 17]; 2724ba371819SOllivier Robert return FALSE; 2725ba371819SOllivier Robert } 2726ba371819SOllivier Robert 2727ba371819SOllivier Robert /**/ 2728ba371819SOllivier Robert /* differential fix mode */ 27292b15cb3dSCy Schubert short 27302b15cb3dSCy Schubert rpt_0x82( 27312b15cb3dSCy Schubert TSIPPKT *rpt, 27322b15cb3dSCy Schubert unsigned char *diff_mode 27332b15cb3dSCy Schubert ) 2734ba371819SOllivier Robert { 2735ba371819SOllivier Robert unsigned char *buf; 2736ba371819SOllivier Robert buf = rpt->buf; 2737ba371819SOllivier Robert 2738ba371819SOllivier Robert if (rpt->len != 1) return TRUE; 2739ba371819SOllivier Robert *diff_mode = buf[0]; 2740ba371819SOllivier Robert return FALSE; 2741ba371819SOllivier Robert } 2742ba371819SOllivier Robert 27432b15cb3dSCy Schubert /* position, ECEF double precision */ 27442b15cb3dSCy Schubert short 27452b15cb3dSCy Schubert rpt_0x83( 27462b15cb3dSCy Schubert TSIPPKT *rpt, 2747ba371819SOllivier Robert double ECEF_pos[3], 2748ba371819SOllivier Robert double *clock_bias, 27492b15cb3dSCy Schubert float *time_of_fix 27502b15cb3dSCy Schubert ) 2751ba371819SOllivier Robert { 2752ba371819SOllivier Robert unsigned char *buf; 2753ba371819SOllivier Robert buf = rpt->buf; 2754ba371819SOllivier Robert 2755ba371819SOllivier Robert if (rpt->len != 36) return TRUE; 2756ba371819SOllivier Robert ECEF_pos[0] = bGetDouble (buf); 2757ba371819SOllivier Robert ECEF_pos[1] = bGetDouble (&buf[8]); 2758ba371819SOllivier Robert ECEF_pos[2] = bGetDouble (&buf[16]); 2759ba371819SOllivier Robert *clock_bias = bGetDouble (&buf[24]); 2760ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[32]); 2761ba371819SOllivier Robert return FALSE; 2762ba371819SOllivier Robert } 2763ba371819SOllivier Robert 27642b15cb3dSCy Schubert /* position, lat-lon-alt double precision */ 27652b15cb3dSCy Schubert short 27662b15cb3dSCy Schubert rpt_0x84( 27672b15cb3dSCy Schubert TSIPPKT *rpt, 2768ba371819SOllivier Robert double *lat, 2769ba371819SOllivier Robert double *lon, 2770ba371819SOllivier Robert double *alt, 2771ba371819SOllivier Robert double *clock_bias, 27722b15cb3dSCy Schubert float *time_of_fix 27732b15cb3dSCy Schubert ) 2774ba371819SOllivier Robert { 2775ba371819SOllivier Robert unsigned char *buf; 2776ba371819SOllivier Robert buf = rpt->buf; 2777ba371819SOllivier Robert 2778ba371819SOllivier Robert if (rpt->len != 36) return TRUE; 2779ba371819SOllivier Robert *lat = bGetDouble (buf); 2780ba371819SOllivier Robert *lon = bGetDouble (&buf[8]); 2781ba371819SOllivier Robert *alt = bGetDouble (&buf[16]); 2782ba371819SOllivier Robert *clock_bias = bGetDouble (&buf[24]); 2783ba371819SOllivier Robert *time_of_fix = bGetSingle (&buf[32]); 2784ba371819SOllivier Robert return FALSE; 2785ba371819SOllivier Robert } 2786ba371819SOllivier Robert 27872b15cb3dSCy Schubert short 27882b15cb3dSCy Schubert rpt_Paly0xBB( 27892b15cb3dSCy Schubert TSIPPKT *rpt, 27902b15cb3dSCy Schubert TSIP_RCVR_CFG *TsipxBB 27912b15cb3dSCy Schubert ) 2792ba371819SOllivier Robert { 2793ba371819SOllivier Robert unsigned char *buf; 2794ba371819SOllivier Robert buf = rpt->buf; 2795ba371819SOllivier Robert 27962b15cb3dSCy Schubert /* Palisade is inconsistent with other TSIP, which has a length of 40 */ 2797ba371819SOllivier Robert /* if (rpt->len != 40) return TRUE; */ 2798ba371819SOllivier Robert if (rpt->len != 43) return TRUE; 2799ba371819SOllivier Robert 2800ba371819SOllivier Robert TsipxBB->bSubcode = buf[0]; 2801ba371819SOllivier Robert TsipxBB->operating_mode = buf[1]; 2802ba371819SOllivier Robert TsipxBB->dyn_code = buf[3]; 2803ba371819SOllivier Robert TsipxBB->elev_mask = bGetSingle (&buf[5]); 2804ba371819SOllivier Robert TsipxBB->cno_mask = bGetSingle (&buf[9]); 2805ba371819SOllivier Robert TsipxBB->dop_mask = bGetSingle (&buf[13]); 2806ba371819SOllivier Robert TsipxBB->dop_switch = bGetSingle (&buf[17]); 2807ba371819SOllivier Robert return FALSE; 2808ba371819SOllivier Robert } 2809ba371819SOllivier Robert 28102b15cb3dSCy Schubert /* Receiver serial port configuration */ 28112b15cb3dSCy Schubert short 28122b15cb3dSCy Schubert rpt_0xBC( 28132b15cb3dSCy Schubert TSIPPKT *rpt, 2814ba371819SOllivier Robert unsigned char *port_num, 2815ba371819SOllivier Robert unsigned char *in_baud, 2816ba371819SOllivier Robert unsigned char *out_baud, 2817ba371819SOllivier Robert unsigned char *data_bits, 2818ba371819SOllivier Robert unsigned char *parity, 2819ba371819SOllivier Robert unsigned char *stop_bits, 2820ba371819SOllivier Robert unsigned char *flow_control, 2821ba371819SOllivier Robert unsigned char *protocols_in, 2822ba371819SOllivier Robert unsigned char *protocols_out, 28232b15cb3dSCy Schubert unsigned char *reserved 28242b15cb3dSCy Schubert ) 2825ba371819SOllivier Robert { 2826ba371819SOllivier Robert unsigned char *buf; 2827ba371819SOllivier Robert buf = rpt->buf; 2828ba371819SOllivier Robert 2829ba371819SOllivier Robert if (rpt->len != 10) return TRUE; 2830ba371819SOllivier Robert *port_num = buf[0]; 2831ba371819SOllivier Robert *in_baud = buf[1]; 2832ba371819SOllivier Robert *out_baud = buf[2]; 2833ba371819SOllivier Robert *data_bits = buf[3]; 2834ba371819SOllivier Robert *parity = buf[4]; 2835ba371819SOllivier Robert *stop_bits = buf[5]; 2836ba371819SOllivier Robert *flow_control = buf[6]; 2837ba371819SOllivier Robert *protocols_in = buf[7]; 2838ba371819SOllivier Robert *protocols_out = buf[8]; 2839ba371819SOllivier Robert *reserved = buf[9]; 2840ba371819SOllivier Robert 2841ba371819SOllivier Robert return FALSE; 2842ba371819SOllivier Robert } 2843ba371819SOllivier Robert 2844ba371819SOllivier Robert /**** Superpackets ****/ 2845ba371819SOllivier Robert 28462b15cb3dSCy Schubert short 28472b15cb3dSCy Schubert rpt_0x8F0B( 28482b15cb3dSCy Schubert TSIPPKT *rpt, 2849ba371819SOllivier Robert unsigned short *event, 2850ba371819SOllivier Robert double *tow, 2851ba371819SOllivier Robert unsigned char *date, 2852ba371819SOllivier Robert unsigned char *month, 2853ba371819SOllivier Robert short *year, 2854ba371819SOllivier Robert unsigned char *dim_mode, 2855ba371819SOllivier Robert short *utc_offset, 2856ba371819SOllivier Robert double *bias, 2857ba371819SOllivier Robert double *drift, 2858ba371819SOllivier Robert float *bias_unc, 2859ba371819SOllivier Robert float *dr_unc, 2860ba371819SOllivier Robert double *lat, 2861ba371819SOllivier Robert double *lon, 2862ba371819SOllivier Robert double *alt, 28632b15cb3dSCy Schubert char sv_id[8] 28642b15cb3dSCy Schubert ) 2865ba371819SOllivier Robert { 2866ba371819SOllivier Robert short local_index; 2867ba371819SOllivier Robert unsigned char *buf; 2868ba371819SOllivier Robert 2869ba371819SOllivier Robert buf = rpt->buf; 2870ba371819SOllivier Robert if (rpt->len != 74) return TRUE; 2871ba371819SOllivier Robert *event = bGetShort(&buf[1]); 2872ba371819SOllivier Robert *tow = bGetDouble(&buf[3]); 2873ba371819SOllivier Robert *date = buf[11]; 2874ba371819SOllivier Robert *month = buf[12]; 2875ba371819SOllivier Robert *year = bGetShort(&buf[13]); 2876ba371819SOllivier Robert *dim_mode = buf[15]; 2877ba371819SOllivier Robert *utc_offset = bGetShort(&buf[16]); 2878ba371819SOllivier Robert *bias = bGetDouble(&buf[18]); 2879ba371819SOllivier Robert *drift = bGetDouble(&buf[26]); 2880ba371819SOllivier Robert *bias_unc = bGetSingle(&buf[34]); 2881ba371819SOllivier Robert *dr_unc = bGetSingle(&buf[38]); 2882ba371819SOllivier Robert *lat = bGetDouble(&buf[42]); 2883ba371819SOllivier Robert *lon = bGetDouble(&buf[50]); 2884ba371819SOllivier Robert *alt = bGetDouble(&buf[58]); 2885ba371819SOllivier Robert 2886ba371819SOllivier Robert for (local_index=0; local_index<8; local_index++) sv_id[local_index] = buf[local_index + 66]; 2887ba371819SOllivier Robert return FALSE; 2888ba371819SOllivier Robert } 2889ba371819SOllivier Robert 2890ba371819SOllivier Robert /* datum index and coefficients */ 28912b15cb3dSCy Schubert short 28922b15cb3dSCy Schubert rpt_0x8F14( 28932b15cb3dSCy Schubert TSIPPKT *rpt, 28942b15cb3dSCy Schubert short *datum_idx, 28952b15cb3dSCy Schubert double datum_coeffs[5] 28962b15cb3dSCy Schubert ) 2897ba371819SOllivier Robert { 2898ba371819SOllivier Robert unsigned char *buf; 2899ba371819SOllivier Robert buf = rpt->buf; 2900ba371819SOllivier Robert 2901ba371819SOllivier Robert if (rpt->len != 43) return TRUE; 2902ba371819SOllivier Robert *datum_idx = bGetShort(&buf[1]); 2903ba371819SOllivier Robert datum_coeffs[0] = bGetDouble (&buf[3]); 2904ba371819SOllivier Robert datum_coeffs[1] = bGetDouble (&buf[11]); 2905ba371819SOllivier Robert datum_coeffs[2] = bGetDouble (&buf[19]); 2906ba371819SOllivier Robert datum_coeffs[3] = bGetDouble (&buf[27]); 2907ba371819SOllivier Robert datum_coeffs[4] = bGetDouble (&buf[35]); 2908ba371819SOllivier Robert return FALSE; 2909ba371819SOllivier Robert } 2910ba371819SOllivier Robert 2911ba371819SOllivier Robert 2912ba371819SOllivier Robert /* datum index and coefficients */ 29132b15cb3dSCy Schubert short 29142b15cb3dSCy Schubert rpt_0x8F15( 29152b15cb3dSCy Schubert TSIPPKT *rpt, 29162b15cb3dSCy Schubert short *datum_idx, 29172b15cb3dSCy Schubert double datum_coeffs[5] 29182b15cb3dSCy Schubert ) 2919ba371819SOllivier Robert { 2920ba371819SOllivier Robert unsigned char *buf; 2921ba371819SOllivier Robert buf = rpt->buf; 2922ba371819SOllivier Robert 2923ba371819SOllivier Robert if (rpt->len != 43) return TRUE; 2924ba371819SOllivier Robert *datum_idx = bGetShort(&buf[1]); 2925ba371819SOllivier Robert datum_coeffs[0] = bGetDouble (&buf[3]); 2926ba371819SOllivier Robert datum_coeffs[1] = bGetDouble (&buf[11]); 2927ba371819SOllivier Robert datum_coeffs[2] = bGetDouble (&buf[19]); 2928ba371819SOllivier Robert datum_coeffs[3] = bGetDouble (&buf[27]); 2929ba371819SOllivier Robert datum_coeffs[4] = bGetDouble (&buf[35]); 2930ba371819SOllivier Robert return FALSE; 2931ba371819SOllivier Robert } 2932ba371819SOllivier Robert 2933ba371819SOllivier Robert 2934ba371819SOllivier Robert #define MAX_LONG (2147483648.) /* 2**31 */ 2935ba371819SOllivier Robert 29362b15cb3dSCy Schubert short 29372b15cb3dSCy Schubert rpt_0x8F20( 29382b15cb3dSCy Schubert TSIPPKT *rpt, 2939ba371819SOllivier Robert unsigned char *info, 2940ba371819SOllivier Robert double *lat, 2941ba371819SOllivier Robert double *lon, 2942ba371819SOllivier Robert double *alt, 2943ba371819SOllivier Robert double vel_enu[], 2944ba371819SOllivier Robert double *time_of_fix, 2945ba371819SOllivier Robert short *week_num, 2946ba371819SOllivier Robert unsigned char *nsvs, 2947ba371819SOllivier Robert unsigned char sv_prn[], 2948ba371819SOllivier Robert short sv_IODC[], 29492b15cb3dSCy Schubert short *datum_index 29502b15cb3dSCy Schubert ) 2951ba371819SOllivier Robert { 2952ba371819SOllivier Robert short 2953ba371819SOllivier Robert isv; 2954ba371819SOllivier Robert unsigned char 2955ba371819SOllivier Robert *buf, prnx, iode; 2956ba371819SOllivier Robert unsigned long 2957ba371819SOllivier Robert ulongtemp; 2958ba371819SOllivier Robert long 2959ba371819SOllivier Robert longtemp; 2960ba371819SOllivier Robert double 2961ba371819SOllivier Robert vel_scale; 2962ba371819SOllivier Robert 2963ba371819SOllivier Robert buf = rpt->buf; 2964ba371819SOllivier Robert 2965ba371819SOllivier Robert if (rpt->len != 56) return TRUE; 2966ba371819SOllivier Robert 2967ba371819SOllivier Robert vel_scale = (buf[24]&1)? 0.020 : 0.005; 2968ba371819SOllivier Robert vel_enu[0] = bGetShort (buf+2)*vel_scale; 2969ba371819SOllivier Robert vel_enu[1] = bGetShort (buf+4)*vel_scale; 2970ba371819SOllivier Robert vel_enu[2] = bGetShort (buf+6)*vel_scale; 2971ba371819SOllivier Robert 2972ba371819SOllivier Robert *time_of_fix = bGetULong (buf+8)*.001; 2973ba371819SOllivier Robert 2974ba371819SOllivier Robert longtemp = bGetLong (buf+12); 2975ba371819SOllivier Robert *lat = longtemp*(GPS_PI/MAX_LONG); 2976ba371819SOllivier Robert 2977ba371819SOllivier Robert ulongtemp = bGetULong (buf+16); 2978ba371819SOllivier Robert *lon = ulongtemp*(GPS_PI/MAX_LONG); 2979ba371819SOllivier Robert if (*lon > GPS_PI) *lon -= 2.0*GPS_PI; 2980ba371819SOllivier Robert 2981ba371819SOllivier Robert *alt = bGetLong (buf+20)*.001; 2982ba371819SOllivier Robert /* 25 blank; 29 = UTC */ 2983ba371819SOllivier Robert (*datum_index) = (short)((short)buf[26]-1); 2984ba371819SOllivier Robert *info = buf[27]; 2985ba371819SOllivier Robert *nsvs = buf[28]; 2986ba371819SOllivier Robert *week_num = bGetShort (&buf[30]); 2987ba371819SOllivier Robert for (isv = 0; isv < 8; isv++) { 2988ba371819SOllivier Robert prnx = buf[32+2*isv]; 2989ba371819SOllivier Robert sv_prn[isv] = (unsigned char)(prnx&0x3F); 2990ba371819SOllivier Robert iode = buf[33+2*isv]; 2991ba371819SOllivier Robert sv_IODC[isv] = (short)(iode | ((prnx>>6)<<8)); 2992ba371819SOllivier Robert } 2993ba371819SOllivier Robert return FALSE; 2994ba371819SOllivier Robert } 2995ba371819SOllivier Robert 29962b15cb3dSCy Schubert short 29972b15cb3dSCy Schubert rpt_0x8F41( 29982b15cb3dSCy Schubert TSIPPKT *rpt, 2999ba371819SOllivier Robert unsigned char *bSearchRange, 3000ba371819SOllivier Robert unsigned char *bBoardOptions, 3001ba371819SOllivier Robert unsigned long *iiSerialNumber, 3002ba371819SOllivier Robert unsigned char *bBuildYear, 3003ba371819SOllivier Robert unsigned char *bBuildMonth, 3004ba371819SOllivier Robert unsigned char *bBuildDay, 3005ba371819SOllivier Robert unsigned char *bBuildHour, 3006ba371819SOllivier Robert float *fOscOffset, 30072b15cb3dSCy Schubert unsigned short *iTestCodeId 30082b15cb3dSCy Schubert ) 3009ba371819SOllivier Robert { 3010ba371819SOllivier Robert if (rpt->len != 17) return FALSE; 3011ba371819SOllivier Robert *bSearchRange = rpt->buf[1]; 3012ba371819SOllivier Robert *bBoardOptions = rpt->buf[2]; 3013ba371819SOllivier Robert *iiSerialNumber = bGetLong(&rpt->buf[3]); 3014ba371819SOllivier Robert *bBuildYear = rpt->buf[7]; 3015ba371819SOllivier Robert *bBuildMonth = rpt->buf[8]; 3016ba371819SOllivier Robert *bBuildDay = rpt->buf[9]; 3017ba371819SOllivier Robert *bBuildHour = rpt->buf[10]; 3018ba371819SOllivier Robert *fOscOffset = bGetSingle(&rpt->buf[11]); 3019ba371819SOllivier Robert *iTestCodeId = bGetShort(&rpt->buf[15]); 3020ba371819SOllivier Robert /* Tsipx8E41Data = *Tsipx8E41; */ 3021ba371819SOllivier Robert return TRUE; 3022ba371819SOllivier Robert } 3023ba371819SOllivier Robert 30242b15cb3dSCy Schubert short 30252b15cb3dSCy Schubert rpt_0x8F42( 30262b15cb3dSCy Schubert TSIPPKT *rpt, 3027ba371819SOllivier Robert unsigned char *bProdOptionsPre, 3028ba371819SOllivier Robert unsigned char *bProdNumberExt, 3029ba371819SOllivier Robert unsigned short *iCaseSerialNumberPre, 3030ba371819SOllivier Robert unsigned long *iiCaseSerialNumber, 3031ba371819SOllivier Robert unsigned long *iiProdNumber, 3032ba371819SOllivier Robert unsigned short *iPremiumOptions, 3033ba371819SOllivier Robert unsigned short *iMachineID, 30342b15cb3dSCy Schubert unsigned short *iKey 30352b15cb3dSCy Schubert ) 3036ba371819SOllivier Robert { 3037ba371819SOllivier Robert if (rpt->len != 19) return FALSE; 3038ba371819SOllivier Robert *bProdOptionsPre = rpt->buf[1]; 3039ba371819SOllivier Robert *bProdNumberExt = rpt->buf[2]; 3040ba371819SOllivier Robert *iCaseSerialNumberPre = bGetShort(&rpt->buf[3]); 3041ba371819SOllivier Robert *iiCaseSerialNumber = bGetLong(&rpt->buf[5]); 3042ba371819SOllivier Robert *iiProdNumber = bGetLong(&rpt->buf[9]); 3043ba371819SOllivier Robert *iPremiumOptions = bGetShort(&rpt->buf[13]); 3044ba371819SOllivier Robert *iMachineID = bGetShort(&rpt->buf[15]); 3045ba371819SOllivier Robert *iKey = bGetShort(&rpt->buf[17]); 3046ba371819SOllivier Robert return TRUE; 3047ba371819SOllivier Robert } 3048ba371819SOllivier Robert 30492b15cb3dSCy Schubert short 30502b15cb3dSCy Schubert rpt_0x8F45( 30512b15cb3dSCy Schubert TSIPPKT *rpt, 30522b15cb3dSCy Schubert unsigned char *bSegMask 30532b15cb3dSCy Schubert ) 3054ba371819SOllivier Robert { 3055ba371819SOllivier Robert if (rpt->len != 2) return FALSE; 3056ba371819SOllivier Robert *bSegMask = rpt->buf[1]; 3057ba371819SOllivier Robert return TRUE; 3058ba371819SOllivier Robert } 3059ba371819SOllivier Robert 30602b15cb3dSCy Schubert /* Stinger PPS definition */ 30612b15cb3dSCy Schubert short 30622b15cb3dSCy Schubert rpt_0x8F4A_16( 30632b15cb3dSCy Schubert TSIPPKT *rpt, 3064ba371819SOllivier Robert unsigned char *pps_enabled, 3065ba371819SOllivier Robert unsigned char *pps_timebase, 3066ba371819SOllivier Robert unsigned char *pos_polarity, 3067ba371819SOllivier Robert double *pps_offset, 30682b15cb3dSCy Schubert float *bias_unc_threshold 30692b15cb3dSCy Schubert ) 3070ba371819SOllivier Robert { 3071ba371819SOllivier Robert unsigned char 3072ba371819SOllivier Robert *buf; 3073ba371819SOllivier Robert 3074ba371819SOllivier Robert buf = rpt->buf; 3075ba371819SOllivier Robert if (rpt->len != 16) return TRUE; 3076ba371819SOllivier Robert *pps_enabled = buf[1]; 3077ba371819SOllivier Robert *pps_timebase = buf[2]; 3078ba371819SOllivier Robert *pos_polarity = buf[3]; 3079ba371819SOllivier Robert *pps_offset = bGetDouble(&buf[4]); 3080ba371819SOllivier Robert *bias_unc_threshold = bGetSingle(&buf[12]); 3081ba371819SOllivier Robert return FALSE; 3082ba371819SOllivier Robert } 3083ba371819SOllivier Robert 30842b15cb3dSCy Schubert short 30852b15cb3dSCy Schubert rpt_0x8F4B( 30862b15cb3dSCy Schubert TSIPPKT *rpt, 30872b15cb3dSCy Schubert unsigned long *decorr_max 30882b15cb3dSCy Schubert ) 3089ba371819SOllivier Robert { 3090ba371819SOllivier Robert unsigned char 3091ba371819SOllivier Robert *buf; 3092ba371819SOllivier Robert 3093ba371819SOllivier Robert buf = rpt->buf; 3094ba371819SOllivier Robert if (rpt->len != 5) return TRUE; 3095ba371819SOllivier Robert *decorr_max = bGetLong(&buf[1]); 3096ba371819SOllivier Robert return FALSE; 3097ba371819SOllivier Robert } 3098ba371819SOllivier Robert 30992b15cb3dSCy Schubert short 31002b15cb3dSCy Schubert rpt_0x8F4D( 31012b15cb3dSCy Schubert TSIPPKT *rpt, 31022b15cb3dSCy Schubert unsigned long *event_mask 31032b15cb3dSCy Schubert ) 3104ba371819SOllivier Robert { 3105ba371819SOllivier Robert unsigned char 3106ba371819SOllivier Robert *buf; 3107ba371819SOllivier Robert 3108ba371819SOllivier Robert buf = rpt->buf; 3109ba371819SOllivier Robert if (rpt->len != 5) return TRUE; 3110ba371819SOllivier Robert *event_mask = bGetULong (&buf[1]); 3111ba371819SOllivier Robert return FALSE; 3112ba371819SOllivier Robert } 3113ba371819SOllivier Robert 31142b15cb3dSCy Schubert short 31152b15cb3dSCy Schubert rpt_0x8FA5( 31162b15cb3dSCy Schubert TSIPPKT *rpt, 31172b15cb3dSCy Schubert unsigned char *spktmask 31182b15cb3dSCy Schubert ) 3119ba371819SOllivier Robert { 3120ba371819SOllivier Robert unsigned char 3121ba371819SOllivier Robert *buf; 3122ba371819SOllivier Robert 3123ba371819SOllivier Robert buf = rpt->buf; 3124ba371819SOllivier Robert if (rpt->len != 5) return TRUE; 3125ba371819SOllivier Robert spktmask[0] = buf[1]; 3126ba371819SOllivier Robert spktmask[1] = buf[2]; 3127ba371819SOllivier Robert spktmask[2] = buf[3]; 3128ba371819SOllivier Robert spktmask[3] = buf[4]; 3129ba371819SOllivier Robert return FALSE; 3130ba371819SOllivier Robert } 3131ba371819SOllivier Robert 31322b15cb3dSCy Schubert short 31332b15cb3dSCy Schubert rpt_0x8FAD( 31342b15cb3dSCy Schubert TSIPPKT *rpt, 3135ba371819SOllivier Robert unsigned short *COUNT, 3136ba371819SOllivier Robert double *FracSec, 3137ba371819SOllivier Robert unsigned char *Hour, 3138ba371819SOllivier Robert unsigned char *Minute, 3139ba371819SOllivier Robert unsigned char *Second, 3140ba371819SOllivier Robert unsigned char *Day, 3141ba371819SOllivier Robert unsigned char *Month, 3142ba371819SOllivier Robert unsigned short *Year, 3143ba371819SOllivier Robert unsigned char *Status, 31442b15cb3dSCy Schubert unsigned char *Flags 31452b15cb3dSCy Schubert ) 3146ba371819SOllivier Robert { 3147ba371819SOllivier Robert if (rpt->len != 22) return TRUE; 3148ba371819SOllivier Robert 3149ba371819SOllivier Robert *COUNT = bGetUShort(&rpt->buf[1]); 3150ba371819SOllivier Robert *FracSec = bGetDouble(&rpt->buf[3]); 3151ba371819SOllivier Robert *Hour = rpt->buf[11]; 3152ba371819SOllivier Robert *Minute = rpt->buf[12]; 3153ba371819SOllivier Robert *Second = rpt->buf[13]; 3154ba371819SOllivier Robert *Day = rpt->buf[14]; 3155ba371819SOllivier Robert *Month = rpt->buf[15]; 3156ba371819SOllivier Robert *Year = bGetUShort(&rpt->buf[16]); 3157ba371819SOllivier Robert *Status = rpt->buf[18]; 3158ba371819SOllivier Robert *Flags = rpt->buf[19]; 3159ba371819SOllivier Robert return FALSE; 3160ba371819SOllivier Robert } 3161ba371819SOllivier Robert 3162ba371819SOllivier Robert 3163ba371819SOllivier Robert /* 3164ba371819SOllivier Robert * ************************************************************************* 3165ba371819SOllivier Robert * 3166ba371819SOllivier Robert * Trimble Navigation, Ltd. 3167ba371819SOllivier Robert * OEM Products Development Group 3168ba371819SOllivier Robert * P.O. Box 3642 3169ba371819SOllivier Robert * 645 North Mary Avenue 3170ba371819SOllivier Robert * Sunnyvale, California 94088-3642 3171ba371819SOllivier Robert * 3172ba371819SOllivier Robert * Corporate Headquarter: 3173ba371819SOllivier Robert * Telephone: (408) 481-8000 3174ba371819SOllivier Robert * Fax: (408) 481-6005 3175ba371819SOllivier Robert * 3176ba371819SOllivier Robert * Technical Support Center: 3177ba371819SOllivier Robert * Telephone: (800) 767-4822 (U.S. and Canada) 3178ba371819SOllivier Robert * (408) 481-6940 (outside U.S. and Canada) 3179ba371819SOllivier Robert * Fax: (408) 481-6020 3180ba371819SOllivier Robert * BBS: (408) 481-7800 3181ba371819SOllivier Robert * e-mail: trimble_support@trimble.com 3182ba371819SOllivier Robert * ftp://ftp.trimble.com/pub/sct/embedded/bin 3183ba371819SOllivier Robert * 3184ba371819SOllivier Robert * ************************************************************************* 3185ba371819SOllivier Robert * 3186ba371819SOllivier Robert * T_REPORT.C consists of a primary function TranslateTSIPReportToText() 3187ba371819SOllivier Robert * called by main(). 3188ba371819SOllivier Robert * 3189ba371819SOllivier Robert * This function takes a character buffer that has been received as a report 3190ba371819SOllivier Robert * from a TSIP device and interprets it. The character buffer has been 3191ba371819SOllivier Robert * assembled using tsip_input_proc() in T_PARSER.C. 3192ba371819SOllivier Robert * 3193ba371819SOllivier Robert * A large case statement directs processing to one of many mid-level 3194ba371819SOllivier Robert * functions. The mid-level functions specific to the current report 3195ba371819SOllivier Robert * code passes the report buffer to the appropriate report decoder 3196ba371819SOllivier Robert * rpt_0x?? () in T_PARSER.C, which converts the byte stream in rpt.buf 3197ba371819SOllivier Robert * to data values approporaite for use. 3198ba371819SOllivier Robert * 3199ba371819SOllivier Robert * ************************************************************************* 3200ba371819SOllivier Robert * 3201ba371819SOllivier Robert */ 3202ba371819SOllivier Robert 3203ba371819SOllivier Robert 3204ba371819SOllivier Robert #define GOOD_PARSE 0 3205ba371819SOllivier Robert #define BADID_PARSE 1 3206ba371819SOllivier Robert #define BADLEN_PARSE 2 3207ba371819SOllivier Robert #define BADDATA_PARSE 3 3208ba371819SOllivier Robert 3209ba371819SOllivier Robert #define B_TSIP 0x02 3210ba371819SOllivier Robert #define B_NMEA 0x04 3211ba371819SOllivier Robert 3212ba371819SOllivier Robert 3213ba371819SOllivier Robert /* pbuf is the pointer to the current location of the text output */ 3214ba371819SOllivier Robert static char 3215ba371819SOllivier Robert *pbuf; 3216ba371819SOllivier Robert 3217ba371819SOllivier Robert /* keep track of whether the message has been successfully parsed */ 3218ba371819SOllivier Robert static short 3219ba371819SOllivier Robert parsed; 3220ba371819SOllivier Robert 3221ba371819SOllivier Robert 3222ba371819SOllivier Robert /* convert time of week into day-hour-minute-second and print */ 32232b15cb3dSCy Schubert char * 32242b15cb3dSCy Schubert show_time( 32252b15cb3dSCy Schubert float time_of_week 32262b15cb3dSCy Schubert ) 3227ba371819SOllivier Robert { 3228ba371819SOllivier Robert short days, hours, minutes; 3229ba371819SOllivier Robert float seconds; 3230ba371819SOllivier Robert double tow = 0; 3231ba371819SOllivier Robert static char timestring [80]; 3232ba371819SOllivier Robert 3233ba371819SOllivier Robert if (time_of_week == -1.0) 3234ba371819SOllivier Robert { 3235ba371819SOllivier Robert sprintf(timestring, " <No time yet> "); 3236ba371819SOllivier Robert } 3237ba371819SOllivier Robert else if ((time_of_week >= 604800.0) || (time_of_week < 0.0)) 3238ba371819SOllivier Robert { 3239ba371819SOllivier Robert sprintf(timestring, " <Bad time> "); 3240ba371819SOllivier Robert } 3241ba371819SOllivier Robert else 3242ba371819SOllivier Robert { 3243ba371819SOllivier Robert if (time_of_week < 604799.9) 3244ba371819SOllivier Robert tow = time_of_week + .00000001; 3245ba371819SOllivier Robert seconds = (float)fmod(tow, 60.); 3246ba371819SOllivier Robert minutes = (short) fmod(tow/60., 60.); 3247ba371819SOllivier Robert hours = (short)fmod(tow / 3600., 24.); 3248ba371819SOllivier Robert days = (short)(tow / 86400.0); 3249ba371819SOllivier Robert sprintf(timestring, " %s %02d:%02d:%05.2f ", 3250ba371819SOllivier Robert dayname[days], hours, minutes, seconds); 3251ba371819SOllivier Robert } 3252ba371819SOllivier Robert return timestring; 3253ba371819SOllivier Robert } 3254ba371819SOllivier Robert 3255ba371819SOllivier Robert /**/ 3256ba371819SOllivier Robert /* 0x3D */ 32572b15cb3dSCy Schubert static void 32582b15cb3dSCy Schubert rpt_chan_A_config( 32592b15cb3dSCy Schubert TSIPPKT *rpt 32602b15cb3dSCy Schubert ) 3261ba371819SOllivier Robert { 3262ba371819SOllivier Robert unsigned char 3263ba371819SOllivier Robert tx_baud_index, rx_baud_index, 3264ba371819SOllivier Robert char_format_index, stop_bits, 3265ba371819SOllivier Robert tx_mode_index, rx_mode_index, 3266ba371819SOllivier Robert databits, parity; 3267ba371819SOllivier Robert int 3268ba371819SOllivier Robert i, nbaud; 3269ba371819SOllivier Robert 3270ba371819SOllivier Robert /* unload rptbuf */ 3271ba371819SOllivier Robert if (rpt_0x3D (rpt, 3272ba371819SOllivier Robert &tx_baud_index, &rx_baud_index, &char_format_index, 3273ba371819SOllivier Robert &stop_bits, &tx_mode_index, &rx_mode_index)) { 3274ba371819SOllivier Robert parsed = BADLEN_PARSE; 3275ba371819SOllivier Robert return; 3276ba371819SOllivier Robert } 3277ba371819SOllivier Robert 3278ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nChannel A Configuration"); 3279ba371819SOllivier Robert 3280ba371819SOllivier Robert nbaud = sizeof(old_baudnum); 3281ba371819SOllivier Robert 3282ba371819SOllivier Robert for (i = 0; i < nbaud; ++i) if (tx_baud_index == old_baudnum[i]) break; 3283ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Transmit speed: %s at %s", 3284ba371819SOllivier Robert old_output_ch[tx_mode_index], st_baud_text_app[i]); 3285ba371819SOllivier Robert 3286ba371819SOllivier Robert for (i = 0; i < nbaud; ++i) if (rx_baud_index == old_baudnum[i]) break; 3287ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Receive speed: %s at %s", 3288ba371819SOllivier Robert old_input_ch[rx_mode_index], st_baud_text_app[i]); 3289ba371819SOllivier Robert 3290ba371819SOllivier Robert databits = (unsigned char)((char_format_index & 0x03) + 5); 3291ba371819SOllivier Robert 3292ba371819SOllivier Robert parity = (unsigned char)(char_format_index >> 2); 3293ba371819SOllivier Robert if (parity > 4) parity = 2; 3294ba371819SOllivier Robert 3295ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Character format (bits/char, parity, stop bits): %d-%s-%d", 3296ba371819SOllivier Robert databits, old_parity_text[parity], stop_bits); 3297ba371819SOllivier Robert } 3298ba371819SOllivier Robert 3299ba371819SOllivier Robert /**/ 3300ba371819SOllivier Robert /* 0x40 */ 33012b15cb3dSCy Schubert static void 33022b15cb3dSCy Schubert rpt_almanac_data_page( 33032b15cb3dSCy Schubert TSIPPKT *rpt 33042b15cb3dSCy Schubert ) 3305ba371819SOllivier Robert { 3306ba371819SOllivier Robert unsigned char 3307ba371819SOllivier Robert sv_prn; 3308ba371819SOllivier Robert short 3309ba371819SOllivier Robert week_num; 3310ba371819SOllivier Robert float 3311ba371819SOllivier Robert t_zc, 3312ba371819SOllivier Robert eccentricity, 3313ba371819SOllivier Robert t_oa, 3314ba371819SOllivier Robert i_0, 3315ba371819SOllivier Robert OMEGA_dot, 3316ba371819SOllivier Robert sqrt_A, 3317ba371819SOllivier Robert OMEGA_0, 3318ba371819SOllivier Robert omega, 3319ba371819SOllivier Robert M_0; 3320ba371819SOllivier Robert 3321ba371819SOllivier Robert /* unload rptbuf */ 3322ba371819SOllivier Robert if (rpt_0x40 (rpt, 3323ba371819SOllivier Robert &sv_prn, &week_num, &t_zc, &eccentricity, &t_oa, 3324ba371819SOllivier Robert &i_0, &OMEGA_dot, &sqrt_A, &OMEGA_0, &omega, &M_0)) { 3325ba371819SOllivier Robert parsed = BADLEN_PARSE; 3326ba371819SOllivier Robert return; 3327ba371819SOllivier Robert } 3328ba371819SOllivier Robert 3329ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nAlmanac for SV %02d", sv_prn); 3330ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Captured:%15.0f %s", 3331ba371819SOllivier Robert t_zc, show_time (t_zc)); 3332ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n week:%15d", week_num); 3333ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Eccentricity:%15g", eccentricity); 3334ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n T_oa:%15.0f %s", 3335ba371819SOllivier Robert t_oa, show_time (t_oa)); 3336ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n i 0:%15g", i_0); 3337ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n OMEGA dot:%15g", OMEGA_dot); 3338ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n sqrt A:%15g", sqrt_A); 3339ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n OMEGA 0:%15g", OMEGA_0); 3340ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n omega:%15g", omega); 3341ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n M 0:%15g", M_0); 3342ba371819SOllivier Robert } 3343ba371819SOllivier Robert 3344ba371819SOllivier Robert /* 0x41 */ 33452b15cb3dSCy Schubert static void 33462b15cb3dSCy Schubert rpt_GPS_time( 33472b15cb3dSCy Schubert TSIPPKT *rpt 33482b15cb3dSCy Schubert ) 3349ba371819SOllivier Robert { 3350ba371819SOllivier Robert float 3351ba371819SOllivier Robert time_of_week, UTC_offset; 3352ba371819SOllivier Robert short 3353ba371819SOllivier Robert week_num; 3354ba371819SOllivier Robert 3355ba371819SOllivier Robert /* unload rptbuf */ 3356ba371819SOllivier Robert if (rpt_0x41 (rpt, &time_of_week, &UTC_offset, &week_num)) { 3357ba371819SOllivier Robert parsed = BADLEN_PARSE; 3358ba371819SOllivier Robert return; 3359ba371819SOllivier Robert } 3360ba371819SOllivier Robert 3361ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nGPS time:%s GPS week: %d UTC offset %.1f", 3362ba371819SOllivier Robert show_time(time_of_week), week_num, UTC_offset); 3363ba371819SOllivier Robert 3364ba371819SOllivier Robert } 3365ba371819SOllivier Robert 3366ba371819SOllivier Robert /* 0x42 */ 33672b15cb3dSCy Schubert static void 33682b15cb3dSCy Schubert rpt_single_ECEF_position( 33692b15cb3dSCy Schubert TSIPPKT *rpt 33702b15cb3dSCy Schubert ) 3371ba371819SOllivier Robert { 3372ba371819SOllivier Robert float 3373ba371819SOllivier Robert ECEF_pos[3], time_of_fix; 3374ba371819SOllivier Robert 3375ba371819SOllivier Robert /* unload rptbuf */ 3376ba371819SOllivier Robert if (rpt_0x42 (rpt, ECEF_pos, &time_of_fix)) { 3377ba371819SOllivier Robert parsed = BADLEN_PARSE; 3378ba371819SOllivier Robert return; 3379ba371819SOllivier Robert } 3380ba371819SOllivier Robert 3381ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nSXYZ: %15.0f %15.0f %15.0f %s", 3382ba371819SOllivier Robert ECEF_pos[0], ECEF_pos[1], ECEF_pos[2], 3383ba371819SOllivier Robert show_time(time_of_fix)); 3384ba371819SOllivier Robert } 3385ba371819SOllivier Robert 3386ba371819SOllivier Robert /* 0x43 */ 33872b15cb3dSCy Schubert static void 33882b15cb3dSCy Schubert rpt_single_ECEF_velocity( 33892b15cb3dSCy Schubert TSIPPKT *rpt 33902b15cb3dSCy Schubert ) 3391ba371819SOllivier Robert { 3392ba371819SOllivier Robert 3393ba371819SOllivier Robert float 3394ba371819SOllivier Robert ECEF_vel[3], freq_offset, time_of_fix; 3395ba371819SOllivier Robert 3396ba371819SOllivier Robert /* unload rptbuf */ 3397ba371819SOllivier Robert if (rpt_0x43 (rpt, ECEF_vel, &freq_offset, &time_of_fix)) { 3398ba371819SOllivier Robert parsed = BADLEN_PARSE; 3399ba371819SOllivier Robert return; 3400ba371819SOllivier Robert } 3401ba371819SOllivier Robert 3402ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nVelECEF: %11.3f %11.3f %11.3f %12.3f%s", 3403ba371819SOllivier Robert ECEF_vel[0], ECEF_vel[1], ECEF_vel[2], freq_offset, 3404ba371819SOllivier Robert show_time(time_of_fix)); 3405ba371819SOllivier Robert } 3406ba371819SOllivier Robert 3407ba371819SOllivier Robert /* 0x45 */ 34082b15cb3dSCy Schubert static void 34092b15cb3dSCy Schubert rpt_SW_version( 34102b15cb3dSCy Schubert TSIPPKT *rpt 34112b15cb3dSCy Schubert ) 34122b15cb3dSCy Schubert { 3413ba371819SOllivier Robert unsigned char 3414ba371819SOllivier Robert major_nav_version, minor_nav_version, 3415ba371819SOllivier Robert nav_day, nav_month, nav_year, 3416ba371819SOllivier Robert major_dsp_version, minor_dsp_version, 3417ba371819SOllivier Robert dsp_day, dsp_month, dsp_year; 3418ba371819SOllivier Robert 3419ba371819SOllivier Robert /* unload rptbuf */ 3420ba371819SOllivier Robert if (rpt_0x45 (rpt, 3421ba371819SOllivier Robert &major_nav_version, &minor_nav_version, 3422ba371819SOllivier Robert &nav_day, &nav_month, &nav_year, 3423ba371819SOllivier Robert &major_dsp_version, &minor_dsp_version, 3424ba371819SOllivier Robert &dsp_day, &dsp_month, &dsp_year)) { 3425ba371819SOllivier Robert parsed = BADLEN_PARSE; 3426ba371819SOllivier Robert return; 3427ba371819SOllivier Robert } 3428ba371819SOllivier Robert 3429ba371819SOllivier Robert pbuf += sprintf(pbuf, 3430ba371819SOllivier Robert "\nFW Versions: Nav Proc %2d.%02d %2d/%2d/%2d Sig Proc %2d.%02d %2d/%2d/%2d", 3431ba371819SOllivier Robert major_nav_version, minor_nav_version, nav_day, nav_month, nav_year, 3432ba371819SOllivier Robert major_dsp_version, minor_dsp_version, dsp_day, dsp_month, dsp_year); 3433ba371819SOllivier Robert } 3434ba371819SOllivier Robert 3435ba371819SOllivier Robert /* 0x46 */ 34362b15cb3dSCy Schubert static void 34372b15cb3dSCy Schubert rpt_rcvr_health( 34382b15cb3dSCy Schubert TSIPPKT *rpt 34392b15cb3dSCy Schubert ) 3440ba371819SOllivier Robert { 3441ba371819SOllivier Robert unsigned char 3442ba371819SOllivier Robert status1, status2; 34432b15cb3dSCy Schubert const char 34442b15cb3dSCy Schubert *text; 34452b15cb3dSCy Schubert static const char const 3446ba371819SOllivier Robert *sc_text[] = { 3447ba371819SOllivier Robert "Doing position fixes", 3448ba371819SOllivier Robert "Don't have GPS time yet", 3449ba371819SOllivier Robert "Waiting for almanac collection", 3450ba371819SOllivier Robert "DOP too high ", 3451ba371819SOllivier Robert "No satellites available", 3452ba371819SOllivier Robert "Only 1 satellite available", 3453ba371819SOllivier Robert "Only 2 satellites available", 3454ba371819SOllivier Robert "Only 3 satellites available", 3455ba371819SOllivier Robert "No satellites usable ", 3456ba371819SOllivier Robert "Only 1 satellite usable", 3457ba371819SOllivier Robert "Only 2 satellites usable", 3458ba371819SOllivier Robert "Only 3 satellites usable", 3459ba371819SOllivier Robert "Chosen satellite unusable"}; 3460ba371819SOllivier Robert 3461ba371819SOllivier Robert 3462ba371819SOllivier Robert /* unload rptbuf */ 3463ba371819SOllivier Robert if (rpt_0x46 (rpt, &status1, &status2)) 3464ba371819SOllivier Robert { 3465ba371819SOllivier Robert parsed = BADLEN_PARSE; 3466ba371819SOllivier Robert return; 3467ba371819SOllivier Robert } 3468ba371819SOllivier Robert 34692b15cb3dSCy Schubert text = (status1 < COUNTOF(sc_text)) 34702b15cb3dSCy Schubert ? sc_text[status1] 34712b15cb3dSCy Schubert : "(out of range)"; 3472ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nRcvr status1: %s (%02Xh); ", 34732b15cb3dSCy Schubert text, status1); 3474ba371819SOllivier Robert 3475ba371819SOllivier Robert pbuf += sprintf(pbuf, "status2: %s, %s (%02Xh)", 3476ba371819SOllivier Robert (status2 & 0x01)?"No BBRAM":"BBRAM OK", 3477ba371819SOllivier Robert (status2 & 0x10)?"No Ant":"Ant OK", 3478ba371819SOllivier Robert status2); 3479ba371819SOllivier Robert } 3480ba371819SOllivier Robert 3481ba371819SOllivier Robert /* 0x47 */ 34822b15cb3dSCy Schubert static void 34832b15cb3dSCy Schubert rpt_SNR_all_SVs( 34842b15cb3dSCy Schubert TSIPPKT *rpt 34852b15cb3dSCy Schubert ) 3486ba371819SOllivier Robert { 3487ba371819SOllivier Robert unsigned char 3488ba371819SOllivier Robert nsvs, sv_prn[12]; 3489ba371819SOllivier Robert short 3490ba371819SOllivier Robert isv; 3491ba371819SOllivier Robert float 3492ba371819SOllivier Robert snr[12]; 3493ba371819SOllivier Robert 3494ba371819SOllivier Robert /* unload rptbuf */ 3495ba371819SOllivier Robert if (rpt_0x47 (rpt, &nsvs, sv_prn, snr)) 3496ba371819SOllivier Robert { 3497ba371819SOllivier Robert parsed = BADLEN_PARSE; 3498ba371819SOllivier Robert return; 3499ba371819SOllivier Robert } 3500ba371819SOllivier Robert 3501ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nSNR for satellites: %d", nsvs); 3502ba371819SOllivier Robert for (isv = 0; isv < nsvs; isv++) 3503ba371819SOllivier Robert { 3504ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n SV %02d %6.2f", 3505ba371819SOllivier Robert sv_prn[isv], snr[isv]); 3506ba371819SOllivier Robert } 3507ba371819SOllivier Robert } 3508ba371819SOllivier Robert 3509ba371819SOllivier Robert /* 0x48 */ 35102b15cb3dSCy Schubert static void 35112b15cb3dSCy Schubert rpt_GPS_system_message( 35122b15cb3dSCy Schubert TSIPPKT *rpt 35132b15cb3dSCy Schubert ) 3514ba371819SOllivier Robert { 3515ba371819SOllivier Robert unsigned char 3516ba371819SOllivier Robert message[23]; 3517ba371819SOllivier Robert 3518ba371819SOllivier Robert /* unload rptbuf */ 3519ba371819SOllivier Robert if (rpt_0x48 (rpt, message)) 3520ba371819SOllivier Robert { 3521ba371819SOllivier Robert parsed = BADLEN_PARSE; 3522ba371819SOllivier Robert return; 3523ba371819SOllivier Robert } 3524ba371819SOllivier Robert 3525ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nGPS message: %s", message); 3526ba371819SOllivier Robert } 3527ba371819SOllivier Robert 3528ba371819SOllivier Robert /* 0x49 */ 35292b15cb3dSCy Schubert static void 35302b15cb3dSCy Schubert rpt_almanac_health_page( 35312b15cb3dSCy Schubert TSIPPKT *rpt 35322b15cb3dSCy Schubert ) 3533ba371819SOllivier Robert { 3534ba371819SOllivier Robert short 3535ba371819SOllivier Robert iprn; 3536ba371819SOllivier Robert unsigned char 3537ba371819SOllivier Robert sv_health [32]; 3538ba371819SOllivier Robert 3539ba371819SOllivier Robert /* unload rptbuf */ 3540ba371819SOllivier Robert if (rpt_0x49 (rpt, sv_health)) 3541ba371819SOllivier Robert { 3542ba371819SOllivier Robert parsed = BADLEN_PARSE; 3543ba371819SOllivier Robert return; 3544ba371819SOllivier Robert } 3545ba371819SOllivier Robert 3546ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nAlmanac health page:"); 3547ba371819SOllivier Robert for (iprn = 0; iprn < 32; iprn++) 3548ba371819SOllivier Robert { 3549ba371819SOllivier Robert if (!(iprn%5)) *pbuf++ = '\n'; 3550ba371819SOllivier Robert pbuf += sprintf(pbuf, " SV%02d %2X", 3551ba371819SOllivier Robert (iprn+1) , sv_health[iprn]); 3552ba371819SOllivier Robert } 3553ba371819SOllivier Robert } 3554ba371819SOllivier Robert 3555ba371819SOllivier Robert /* 0x4A */ 35562b15cb3dSCy Schubert static void 35572b15cb3dSCy Schubert rpt_single_lla_position( 35582b15cb3dSCy Schubert TSIPPKT *rpt 35592b15cb3dSCy Schubert ) 35602b15cb3dSCy Schubert { 3561ba371819SOllivier Robert short 3562ba371819SOllivier Robert lat_deg, lon_deg; 3563ba371819SOllivier Robert float 3564ba371819SOllivier Robert lat, lon, 3565ba371819SOllivier Robert alt, clock_bias, time_of_fix; 3566ba371819SOllivier Robert double lat_min, lon_min; 3567ba371819SOllivier Robert unsigned char 3568ba371819SOllivier Robert north_south, east_west; 3569ba371819SOllivier Robert 3570ba371819SOllivier Robert if (rpt_0x4A (rpt, 3571ba371819SOllivier Robert &lat, &lon, &alt, &clock_bias, &time_of_fix)) 3572ba371819SOllivier Robert { 3573ba371819SOllivier Robert parsed = BADLEN_PARSE; 3574ba371819SOllivier Robert return; 3575ba371819SOllivier Robert } 3576ba371819SOllivier Robert 3577ba371819SOllivier Robert /* convert from radians to degrees */ 3578ba371819SOllivier Robert lat *= (float)R2D; 3579ba371819SOllivier Robert north_south = 'N'; 3580ba371819SOllivier Robert if (lat < 0.0) 3581ba371819SOllivier Robert { 3582ba371819SOllivier Robert north_south = 'S'; 3583ba371819SOllivier Robert lat = -lat; 3584ba371819SOllivier Robert } 3585ba371819SOllivier Robert lat_deg = (short)lat; 3586ba371819SOllivier Robert lat_min = (lat - lat_deg) * 60.0; 3587ba371819SOllivier Robert 3588ba371819SOllivier Robert lon *= (float)R2D; 3589ba371819SOllivier Robert east_west = 'E'; 3590ba371819SOllivier Robert if (lon < 0.0) 3591ba371819SOllivier Robert { 3592ba371819SOllivier Robert east_west = 'W'; 3593ba371819SOllivier Robert lon = -lon; 3594ba371819SOllivier Robert } 3595ba371819SOllivier Robert lon_deg = (short)lon; 3596ba371819SOllivier Robert lon_min = (lon - lon_deg) * 60.0; 3597ba371819SOllivier Robert 3598ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nSLLA: %4d: %06.3f %c%5d:%06.3f %c%10.2f %12.2f%s", 3599ba371819SOllivier Robert lat_deg, lat_min, north_south, 3600ba371819SOllivier Robert lon_deg, lon_min, east_west, 3601ba371819SOllivier Robert alt, clock_bias, 3602ba371819SOllivier Robert show_time(time_of_fix)); 3603ba371819SOllivier Robert } 3604ba371819SOllivier Robert 3605ba371819SOllivier Robert /* 0x4A */ 36062b15cb3dSCy Schubert static void 36072b15cb3dSCy Schubert rpt_ref_alt( 36082b15cb3dSCy Schubert TSIPPKT *rpt 36092b15cb3dSCy Schubert ) 36102b15cb3dSCy Schubert { 3611ba371819SOllivier Robert float 3612ba371819SOllivier Robert alt, dummy; 3613ba371819SOllivier Robert unsigned char 3614ba371819SOllivier Robert alt_flag; 3615ba371819SOllivier Robert 36162b15cb3dSCy Schubert if (rpt_0x4A_2 (rpt, &alt, &dummy, &alt_flag)) 3617ba371819SOllivier Robert { 3618ba371819SOllivier Robert parsed = BADLEN_PARSE; 3619ba371819SOllivier Robert return; 3620ba371819SOllivier Robert } 3621ba371819SOllivier Robert 3622ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nReference Alt: %.1f m; %s", 3623ba371819SOllivier Robert alt, alt_flag?"ON":"OFF"); 3624ba371819SOllivier Robert } 3625ba371819SOllivier Robert 3626ba371819SOllivier Robert /* 0x4B */ 36272b15cb3dSCy Schubert static void 36282b15cb3dSCy Schubert rpt_rcvr_id_and_status( 36292b15cb3dSCy Schubert TSIPPKT *rpt 36302b15cb3dSCy Schubert ) 3631ba371819SOllivier Robert { 3632ba371819SOllivier Robert 3633ba371819SOllivier Robert unsigned char 3634ba371819SOllivier Robert machine_id, status3, status4; 3635ba371819SOllivier Robert 3636ba371819SOllivier Robert /* unload rptbuf */ 3637ba371819SOllivier Robert if (rpt_0x4B (rpt, &machine_id, &status3, &status4)) 3638ba371819SOllivier Robert { 3639ba371819SOllivier Robert parsed = BADLEN_PARSE; 3640ba371819SOllivier Robert return; 3641ba371819SOllivier Robert } 3642ba371819SOllivier Robert 3643ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nRcvr Machine ID: %d; Status3 = %s, %s (%02Xh)", 3644ba371819SOllivier Robert machine_id, 3645ba371819SOllivier Robert (status3 & 0x02)?"No RTC":"RTC OK", 3646ba371819SOllivier Robert (status3 & 0x08)?"No Alm":"Alm OK", 3647ba371819SOllivier Robert status3); 3648ba371819SOllivier Robert } 3649ba371819SOllivier Robert 3650ba371819SOllivier Robert /* 0x4C */ 36512b15cb3dSCy Schubert static void 36522b15cb3dSCy Schubert rpt_operating_parameters( 36532b15cb3dSCy Schubert TSIPPKT *rpt 36542b15cb3dSCy Schubert ) 3655ba371819SOllivier Robert { 3656ba371819SOllivier Robert unsigned char 3657ba371819SOllivier Robert dyn_code; 3658ba371819SOllivier Robert float 3659ba371819SOllivier Robert el_mask, snr_mask, dop_mask, dop_switch; 3660ba371819SOllivier Robert 3661ba371819SOllivier Robert /* unload rptbuf */ 3662ba371819SOllivier Robert if (rpt_0x4C (rpt, &dyn_code, &el_mask, 3663ba371819SOllivier Robert &snr_mask, &dop_mask, &dop_switch)) 3664ba371819SOllivier Robert { 3665ba371819SOllivier Robert parsed = BADLEN_PARSE; 3666ba371819SOllivier Robert return; 3667ba371819SOllivier Robert } 3668ba371819SOllivier Robert 3669ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nOperating Parameters:"); 3670ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Dynamics code = %d %s", 3671ba371819SOllivier Robert dyn_code, dyn_text[dyn_code]); 36722b15cb3dSCy Schubert pbuf += sprintf(pbuf, "\n Elevation mask = %.2f", el_mask * R2D); 3673ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n SNR mask = %.2f", snr_mask); 3674ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n DOP mask = %.2f", dop_mask); 3675ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n DOP switch = %.2f", dop_switch); 3676ba371819SOllivier Robert } 3677ba371819SOllivier Robert 3678ba371819SOllivier Robert /* 0x4D */ 36792b15cb3dSCy Schubert static void 36802b15cb3dSCy Schubert rpt_oscillator_offset( 36812b15cb3dSCy Schubert TSIPPKT *rpt 36822b15cb3dSCy Schubert ) 3683ba371819SOllivier Robert { 3684ba371819SOllivier Robert float 3685ba371819SOllivier Robert osc_offset; 3686ba371819SOllivier Robert 3687ba371819SOllivier Robert /* unload rptbuf */ 3688ba371819SOllivier Robert if (rpt_0x4D (rpt, &osc_offset)) 3689ba371819SOllivier Robert { 3690ba371819SOllivier Robert parsed = BADLEN_PARSE; 3691ba371819SOllivier Robert return; 3692ba371819SOllivier Robert } 3693ba371819SOllivier Robert 3694ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nOscillator offset: %.2f Hz = %.3f PPM", 3695ba371819SOllivier Robert osc_offset, osc_offset/1575.42); 3696ba371819SOllivier Robert } 3697ba371819SOllivier Robert 3698ba371819SOllivier Robert /* 0x4E */ 36992b15cb3dSCy Schubert static void 37002b15cb3dSCy Schubert rpt_GPS_time_set_response( 37012b15cb3dSCy Schubert TSIPPKT *rpt 37022b15cb3dSCy Schubert ) 3703ba371819SOllivier Robert { 3704ba371819SOllivier Robert unsigned char 3705ba371819SOllivier Robert response; 3706ba371819SOllivier Robert 3707ba371819SOllivier Robert /* unload rptbuf */ 3708ba371819SOllivier Robert if (rpt_0x4E (rpt, &response)) 3709ba371819SOllivier Robert { 3710ba371819SOllivier Robert parsed = BADLEN_PARSE; 3711ba371819SOllivier Robert return; 3712ba371819SOllivier Robert } 3713ba371819SOllivier Robert 3714ba371819SOllivier Robert switch (response) 3715ba371819SOllivier Robert { 3716ba371819SOllivier Robert case 'Y': 3717ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nTime set accepted"); 3718ba371819SOllivier Robert break; 3719ba371819SOllivier Robert 3720ba371819SOllivier Robert case 'N': 3721ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nTime set rejected or not required"); 3722ba371819SOllivier Robert break; 3723ba371819SOllivier Robert 3724ba371819SOllivier Robert default: 3725ba371819SOllivier Robert parsed = BADDATA_PARSE; 3726ba371819SOllivier Robert } 3727ba371819SOllivier Robert } 3728ba371819SOllivier Robert 3729ba371819SOllivier Robert /* 0x4F */ 37302b15cb3dSCy Schubert static void 37312b15cb3dSCy Schubert rpt_UTC_offset( 37322b15cb3dSCy Schubert TSIPPKT *rpt 37332b15cb3dSCy Schubert ) 3734ba371819SOllivier Robert { 3735ba371819SOllivier Robert double 3736ba371819SOllivier Robert a0; 3737ba371819SOllivier Robert float 3738ba371819SOllivier Robert a1, time_of_data; 3739ba371819SOllivier Robert short 3740ba371819SOllivier Robert dt_ls, wn_t, wn_lsf, dn, dt_lsf; 3741ba371819SOllivier Robert 3742ba371819SOllivier Robert /* unload rptbuf */ 3743ba371819SOllivier Robert if (rpt_0x4F (rpt, &a0, &a1, &time_of_data, 3744ba371819SOllivier Robert &dt_ls, &wn_t, &wn_lsf, &dn, &dt_lsf)) { 3745ba371819SOllivier Robert parsed = BADLEN_PARSE; 3746ba371819SOllivier Robert return; 3747ba371819SOllivier Robert } 3748ba371819SOllivier Robert 3749ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nUTC Correction Data"); 3750ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n A_0 = %g ", a0); 3751ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n A_1 = %g ", a1); 3752ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n delta_t_LS = %d ", dt_ls); 3753ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n t_ot = %.0f ", time_of_data); 3754ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n WN_t = %d ", wn_t ); 3755ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n WN_LSF = %d ", wn_lsf ); 3756ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n DN = %d ", dn ); 3757ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n delta_t_LSF = %d ", dt_lsf ); 3758ba371819SOllivier Robert } 3759ba371819SOllivier Robert 3760ba371819SOllivier Robert /**/ 3761ba371819SOllivier Robert /* 0x54 */ 37622b15cb3dSCy Schubert static void 37632b15cb3dSCy Schubert rpt_1SV_bias( 37642b15cb3dSCy Schubert TSIPPKT *rpt 37652b15cb3dSCy Schubert ) 3766ba371819SOllivier Robert { 3767ba371819SOllivier Robert float 3768ba371819SOllivier Robert clock_bias, freq_offset, time_of_fix; 3769ba371819SOllivier Robert 3770ba371819SOllivier Robert /* unload rptbuf */ 3771ba371819SOllivier Robert if (rpt_0x54 (rpt, &clock_bias, &freq_offset, &time_of_fix)) { 3772ba371819SOllivier Robert parsed = BADLEN_PARSE; 3773ba371819SOllivier Robert return; 3774ba371819SOllivier Robert } 3775ba371819SOllivier Robert 3776ba371819SOllivier Robert pbuf += sprintf (pbuf, "\nTime Fix Clock Bias: %6.2f m Freq Bias: %6.2f m/s%s", 3777ba371819SOllivier Robert clock_bias, freq_offset, show_time (time_of_fix)); 3778ba371819SOllivier Robert } 3779ba371819SOllivier Robert 3780ba371819SOllivier Robert /* 0x55 */ 37812b15cb3dSCy Schubert static void 37822b15cb3dSCy Schubert rpt_io_opt( 37832b15cb3dSCy Schubert TSIPPKT *rpt 37842b15cb3dSCy Schubert ) 3785ba371819SOllivier Robert { 3786ba371819SOllivier Robert unsigned char 3787ba371819SOllivier Robert pos_code, vel_code, time_code, aux_code; 3788ba371819SOllivier Robert 3789ba371819SOllivier Robert /* unload rptbuf */ 3790ba371819SOllivier Robert if (rpt_0x55 (rpt, 3791ba371819SOllivier Robert &pos_code, &vel_code, &time_code, &aux_code)) { 3792ba371819SOllivier Robert parsed = BADLEN_PARSE; 3793ba371819SOllivier Robert return; 3794ba371819SOllivier Robert } 3795ba371819SOllivier Robert /* rptbuf unloaded */ 3796ba371819SOllivier Robert 3797ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nI/O Options: %2X %2X %2X %2X", 3798ba371819SOllivier Robert pos_code, vel_code, time_code, aux_code); 3799ba371819SOllivier Robert 3800ba371819SOllivier Robert if (pos_code & 0x01) { 3801ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n ECEF XYZ position output"); 3802ba371819SOllivier Robert } 3803ba371819SOllivier Robert 3804ba371819SOllivier Robert if (pos_code & 0x02) { 3805ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n LLA position output"); 3806ba371819SOllivier Robert } 3807ba371819SOllivier Robert 3808ba371819SOllivier Robert pbuf += sprintf(pbuf, (pos_code & 0x04)? 3809ba371819SOllivier Robert "\n MSL altitude output (Geoid height) ": 3810ba371819SOllivier Robert "\n WGS-84 altitude output"); 3811ba371819SOllivier Robert 3812ba371819SOllivier Robert pbuf += sprintf(pbuf, (pos_code & 0x08)? 3813ba371819SOllivier Robert "\n MSL altitude input": 3814ba371819SOllivier Robert "\n WGS-84 altitude input"); 3815ba371819SOllivier Robert 3816ba371819SOllivier Robert pbuf += sprintf(pbuf, (pos_code & 0x10)? 3817ba371819SOllivier Robert "\n Double precision": 3818ba371819SOllivier Robert "\n Single precision"); 3819ba371819SOllivier Robert 3820ba371819SOllivier Robert if (pos_code & 0x20) { 3821ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n All Enabled Superpackets"); 3822ba371819SOllivier Robert } 3823ba371819SOllivier Robert 3824ba371819SOllivier Robert if (vel_code & 0x01) { 3825ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n ECEF XYZ velocity output"); 3826ba371819SOllivier Robert } 3827ba371819SOllivier Robert 3828ba371819SOllivier Robert if (vel_code & 0x02) { 3829ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n ENU velocity output"); 3830ba371819SOllivier Robert } 3831ba371819SOllivier Robert 3832ba371819SOllivier Robert pbuf += sprintf(pbuf, (time_code & 0x01)? 3833ba371819SOllivier Robert "\n Time tags in UTC": 3834ba371819SOllivier Robert "\n Time tags in GPS time"); 3835ba371819SOllivier Robert 3836ba371819SOllivier Robert if (time_code & 0x02) { 3837ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Fixes delayed to integer seconds"); 3838ba371819SOllivier Robert } 3839ba371819SOllivier Robert 3840ba371819SOllivier Robert if (time_code & 0x04) { 3841ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Fixes sent only on request"); 3842ba371819SOllivier Robert } 3843ba371819SOllivier Robert 3844ba371819SOllivier Robert if (time_code & 0x08) { 3845ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Synchronized measurements"); 3846ba371819SOllivier Robert } 3847ba371819SOllivier Robert 3848ba371819SOllivier Robert if (time_code & 0x10) { 3849ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Minimize measurement propagation"); 3850ba371819SOllivier Robert } 3851ba371819SOllivier Robert 3852ba371819SOllivier Robert pbuf += sprintf(pbuf, (time_code & 0x20) ? 3853ba371819SOllivier Robert "\n PPS output at all times" : 3854ba371819SOllivier Robert "\n PPS output during fixes"); 3855ba371819SOllivier Robert 3856ba371819SOllivier Robert if (aux_code & 0x01) { 3857ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Raw measurement output"); 3858ba371819SOllivier Robert } 3859ba371819SOllivier Robert 3860ba371819SOllivier Robert if (aux_code & 0x02) { 3861ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Code-phase smoothed before output"); 3862ba371819SOllivier Robert } 3863ba371819SOllivier Robert 3864ba371819SOllivier Robert if (aux_code & 0x04) { 3865ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Additional fix status"); 3866ba371819SOllivier Robert } 3867ba371819SOllivier Robert 3868ba371819SOllivier Robert pbuf += sprintf(pbuf, (aux_code & 0x08)? 3869ba371819SOllivier Robert "\n Signal Strength Output as dBHz" : 3870ba371819SOllivier Robert "\n Signal Strength Output as AMU"); 3871ba371819SOllivier Robert } 3872ba371819SOllivier Robert 3873ba371819SOllivier Robert /* 0x56 */ 38742b15cb3dSCy Schubert static void 38752b15cb3dSCy Schubert rpt_ENU_velocity( 38762b15cb3dSCy Schubert TSIPPKT *rpt 38772b15cb3dSCy Schubert ) 3878ba371819SOllivier Robert { 3879ba371819SOllivier Robert float 3880ba371819SOllivier Robert vel_ENU[3], freq_offset, time_of_fix; 3881ba371819SOllivier Robert 3882ba371819SOllivier Robert /* unload rptbuf */ 3883ba371819SOllivier Robert if (rpt_0x56 (rpt, vel_ENU, &freq_offset, &time_of_fix)) { 3884ba371819SOllivier Robert parsed = BADLEN_PARSE; 3885ba371819SOllivier Robert return; 3886ba371819SOllivier Robert } 3887ba371819SOllivier Robert 3888ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nVel ENU: %11.3f %11.3f %11.3f %12.3f%s", 3889ba371819SOllivier Robert vel_ENU[0], vel_ENU[1], vel_ENU[2], freq_offset, 3890ba371819SOllivier Robert show_time (time_of_fix)); 3891ba371819SOllivier Robert } 3892ba371819SOllivier Robert 3893ba371819SOllivier Robert /* 0x57 */ 38942b15cb3dSCy Schubert static void 38952b15cb3dSCy Schubert rpt_last_fix_info( 38962b15cb3dSCy Schubert TSIPPKT *rpt 38972b15cb3dSCy Schubert ) 3898ba371819SOllivier Robert { 3899ba371819SOllivier Robert unsigned char 3900ba371819SOllivier Robert source_code, diag_code; 3901ba371819SOllivier Robert short 3902ba371819SOllivier Robert week_num; 3903ba371819SOllivier Robert float 3904ba371819SOllivier Robert time_of_fix; 3905ba371819SOllivier Robert 3906ba371819SOllivier Robert /* unload rptbuf */ 3907ba371819SOllivier Robert if (rpt_0x57 (rpt, &source_code, &diag_code, &week_num, &time_of_fix)) { 3908ba371819SOllivier Robert parsed = BADLEN_PARSE; 3909ba371819SOllivier Robert return; 3910ba371819SOllivier Robert } 3911ba371819SOllivier Robert 3912ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n source code %d; diag code: %2Xh", 3913ba371819SOllivier Robert source_code, diag_code); 3914ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Time of last fix:%s", show_time(time_of_fix)); 3915ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Week of last fix: %d", week_num); 3916ba371819SOllivier Robert } 3917ba371819SOllivier Robert 3918ba371819SOllivier Robert /* 0x58 */ 39192b15cb3dSCy Schubert static void 39202b15cb3dSCy Schubert rpt_GPS_system_data( 39212b15cb3dSCy Schubert TSIPPKT *rpt 39222b15cb3dSCy Schubert ) 3923ba371819SOllivier Robert { 3924ba371819SOllivier Robert unsigned char 3925ba371819SOllivier Robert iprn, 3926ba371819SOllivier Robert op_code, data_type, sv_prn, 3927ba371819SOllivier Robert data_length, data_packet[250]; 3928ba371819SOllivier Robert ALM_INFO 3929ba371819SOllivier Robert *almanac; 3930ba371819SOllivier Robert ALH_PARMS 3931ba371819SOllivier Robert *almh; 3932ba371819SOllivier Robert UTC_INFO 3933ba371819SOllivier Robert *utc; 3934ba371819SOllivier Robert ION_INFO 3935ba371819SOllivier Robert *ionosphere; 3936ba371819SOllivier Robert EPHEM_CLOCK 3937ba371819SOllivier Robert *cdata; 3938ba371819SOllivier Robert EPHEM_ORBIT 3939ba371819SOllivier Robert *edata; 3940ba371819SOllivier Robert NAV_INFO 3941ba371819SOllivier Robert *nav_data; 3942ba371819SOllivier Robert unsigned char 3943ba371819SOllivier Robert curr_t_oa; 3944ba371819SOllivier Robert unsigned short 3945ba371819SOllivier Robert curr_wn_oa; 3946ba371819SOllivier Robert static char 3947ba371819SOllivier Robert *datname[] = 3948ba371819SOllivier Robert {"", "", "Almanac Orbit", 3949ba371819SOllivier Robert "Health Page & Ref Time", "Ionosphere", "UTC ", 3950ba371819SOllivier Robert "Ephemeris"}; 3951ba371819SOllivier Robert 3952ba371819SOllivier Robert /* unload rptbuf */ 3953ba371819SOllivier Robert if (rpt_0x58 (rpt, &op_code, &data_type, &sv_prn, 3954ba371819SOllivier Robert &data_length, data_packet)) 3955ba371819SOllivier Robert { 3956ba371819SOllivier Robert parsed = BADLEN_PARSE; 3957ba371819SOllivier Robert return; 3958ba371819SOllivier Robert } 3959ba371819SOllivier Robert 3960ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nSystem data [%d]: %s SV%02d", 3961ba371819SOllivier Robert data_type, datname[data_type], sv_prn); 3962ba371819SOllivier Robert switch (op_code) 3963ba371819SOllivier Robert { 3964ba371819SOllivier Robert case 1: 3965ba371819SOllivier Robert pbuf += sprintf(pbuf, " Acknowledgment"); 3966ba371819SOllivier Robert break; 3967ba371819SOllivier Robert case 2: 3968ba371819SOllivier Robert pbuf += sprintf(pbuf, " length = %d bytes", data_length); 3969ba371819SOllivier Robert switch (data_type) { 3970ba371819SOllivier Robert case 2: 3971ba371819SOllivier Robert /* Almanac */ 3972ba371819SOllivier Robert if (sv_prn == 0 || sv_prn > 32) { 3973ba371819SOllivier Robert pbuf += sprintf(pbuf, " Binary PRN invalid"); 3974ba371819SOllivier Robert return; 3975ba371819SOllivier Robert } 3976ba371819SOllivier Robert almanac = (ALM_INFO*)data_packet; 3977ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n t_oa_raw = % -12d SV_hlth = % -12d ", 3978ba371819SOllivier Robert almanac->t_oa_raw , almanac->SV_health ); 3979ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n e = % -12g t_oa = % -12g ", 3980ba371819SOllivier Robert almanac->e , almanac->t_oa ); 3981ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n i_0 = % -12g OMEGADOT = % -12g ", 3982ba371819SOllivier Robert almanac->i_0 , almanac->OMEGADOT ); 3983ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n sqrt_A = % -12g OMEGA_0 = % -12g ", 3984ba371819SOllivier Robert almanac->sqrt_A , almanac->OMEGA_0 ); 3985ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n omega = % -12g M_0 = % -12g ", 3986ba371819SOllivier Robert almanac->omega , almanac->M_0 ); 3987ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n a_f0 = % -12g a_f1 = % -12g ", 3988ba371819SOllivier Robert almanac->a_f0 , almanac->a_f1 ); 3989ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Axis = % -12g n = % -12g ", 3990ba371819SOllivier Robert almanac->Axis , almanac->n ); 3991ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n OMEGA_n = % -12g ODOT_n = % -12g ", 3992ba371819SOllivier Robert almanac->OMEGA_n , almanac->ODOT_n ); 3993ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n t_zc = % -12g weeknum = % -12d ", 3994ba371819SOllivier Robert almanac->t_zc , almanac->weeknum ); 3995ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n wn_oa = % -12d", almanac->wn_oa ); 3996ba371819SOllivier Robert break; 3997ba371819SOllivier Robert 3998ba371819SOllivier Robert case 3: 3999ba371819SOllivier Robert /* Almanac health page */ 4000ba371819SOllivier Robert almh = (ALH_PARMS*)data_packet; 4001ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n t_oa = %d, wn_oa&0xFF = %d ", 4002ba371819SOllivier Robert almh->t_oa, almh->WN_a); 4003ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nAlmanac health page:"); 4004ba371819SOllivier Robert for (iprn = 0; iprn < 32; iprn++) { 4005ba371819SOllivier Robert if (!(iprn%5)) *pbuf++ = '\n'; 4006ba371819SOllivier Robert pbuf += sprintf(pbuf, " SV%02d %2X", 4007ba371819SOllivier Robert (iprn+1) , almh->SV_health[iprn]); 4008ba371819SOllivier Robert } 4009ba371819SOllivier Robert curr_t_oa = data_packet[34]; 4010ba371819SOllivier Robert curr_wn_oa = (unsigned short)((data_packet[35]<<8) + data_packet[36]); 4011ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n current t_oa = %d, wn_oa = %d ", 4012ba371819SOllivier Robert curr_t_oa, curr_wn_oa); 4013ba371819SOllivier Robert break; 4014ba371819SOllivier Robert 4015ba371819SOllivier Robert case 4: 4016ba371819SOllivier Robert /* Ionosphere */ 4017ba371819SOllivier Robert ionosphere = (ION_INFO*)data_packet; 4018ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n alpha_0 = % -12g alpha_1 = % -12g ", 4019ba371819SOllivier Robert ionosphere->alpha_0, ionosphere->alpha_1); 4020ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n alpha_2 = % -12g alpha_3 = % -12g ", 4021ba371819SOllivier Robert ionosphere->alpha_2, ionosphere->alpha_3); 4022ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n beta_0 = % -12g beta_1 = % -12g ", 4023ba371819SOllivier Robert ionosphere->beta_0, ionosphere->beta_1); 4024ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n beta_2 = % -12g beta_3 = % -12g ", 4025ba371819SOllivier Robert ionosphere->beta_2, ionosphere->beta_3); 4026ba371819SOllivier Robert break; 4027ba371819SOllivier Robert 4028ba371819SOllivier Robert case 5: 4029ba371819SOllivier Robert /* UTC */ 4030ba371819SOllivier Robert utc = (UTC_INFO*)data_packet; 4031ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n A_0 = %g ", utc->A_0); 4032ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n A_1 = %g ", utc->A_1); 4033ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n delta_t_LS = %d ", utc->delta_t_LS); 4034ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n t_ot = %.0f ", utc->t_ot ); 4035ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n WN_t = %d ", utc->WN_t ); 4036ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n WN_LSF = %d ", utc->WN_LSF ); 4037ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n DN = %d ", utc->DN ); 4038ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n delta_t_LSF = %d ", utc->delta_t_LSF ); 4039ba371819SOllivier Robert break; 4040ba371819SOllivier Robert 4041ba371819SOllivier Robert case 6: /* Ephemeris */ 4042ba371819SOllivier Robert if (sv_prn == 0 || sv_prn > 32) { 4043ba371819SOllivier Robert pbuf += sprintf(pbuf, " Binary PRN invalid"); 4044ba371819SOllivier Robert return; 4045ba371819SOllivier Robert } 4046ba371819SOllivier Robert nav_data = (NAV_INFO*)data_packet; 4047ba371819SOllivier Robert 4048ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n SV_PRN = % -12d . t_ephem = % -12g . ", 4049ba371819SOllivier Robert nav_data->sv_number , nav_data->t_ephem ); 4050ba371819SOllivier Robert cdata = &(nav_data->ephclk); 4051ba371819SOllivier Robert pbuf += sprintf(pbuf, 4052ba371819SOllivier Robert "\n weeknum = % -12d . codeL2 = % -12d . L2Pdata = % -12d", 4053ba371819SOllivier Robert cdata->weeknum , cdata->codeL2 , cdata->L2Pdata ); 4054ba371819SOllivier Robert pbuf += sprintf(pbuf, 4055ba371819SOllivier Robert "\n SVacc_raw = % -12d .SV_health = % -12d . IODC = % -12d", 4056ba371819SOllivier Robert cdata->SVacc_raw, cdata->SV_health, cdata->IODC ); 4057ba371819SOllivier Robert pbuf += sprintf(pbuf, 4058ba371819SOllivier Robert "\n T_GD = % -12g . t_oc = % -12g . a_f2 = % -12g", 4059ba371819SOllivier Robert cdata->T_GD, cdata->t_oc, cdata->a_f2 ); 4060ba371819SOllivier Robert pbuf += sprintf(pbuf, 4061ba371819SOllivier Robert "\n a_f1 = % -12g . a_f0 = % -12g . SVacc = % -12g", 4062ba371819SOllivier Robert cdata->a_f1, cdata->a_f0, cdata->SVacc ); 4063ba371819SOllivier Robert edata = &(nav_data->ephorb); 4064ba371819SOllivier Robert pbuf += sprintf(pbuf, 4065ba371819SOllivier Robert "\n IODE = % -12d .fit_intvl = % -12d . C_rs = % -12g", 4066ba371819SOllivier Robert edata->IODE, edata->fit_interval, edata->C_rs ); 4067ba371819SOllivier Robert pbuf += sprintf(pbuf, 4068ba371819SOllivier Robert "\n delta_n = % -12g . M_0 = % -12g . C_uc = % -12g", 4069ba371819SOllivier Robert edata->delta_n, edata->M_0, edata->C_uc ); 4070ba371819SOllivier Robert pbuf += sprintf(pbuf, 4071ba371819SOllivier Robert "\n ecc = % -12g . C_us = % -12g . sqrt_A = % -12g", 4072ba371819SOllivier Robert edata->e, edata->C_us, edata->sqrt_A ); 4073ba371819SOllivier Robert pbuf += sprintf(pbuf, 4074ba371819SOllivier Robert "\n t_oe = % -12g . C_ic = % -12g . OMEGA_0 = % -12g", 4075ba371819SOllivier Robert edata->t_oe, edata->C_ic, edata->OMEGA_0 ); 4076ba371819SOllivier Robert pbuf += sprintf(pbuf, 4077ba371819SOllivier Robert "\n C_is = % -12g . i_0 = % -12g . C_rc = % -12g", 4078ba371819SOllivier Robert edata->C_is, edata->i_0, edata->C_rc ); 4079ba371819SOllivier Robert pbuf += sprintf(pbuf, 4080ba371819SOllivier Robert "\n omega = % -12g . OMEGADOT = % -12g . IDOT = % -12g", 4081ba371819SOllivier Robert edata->omega, edata->OMEGADOT, edata->IDOT ); 4082ba371819SOllivier Robert pbuf += sprintf(pbuf, 4083ba371819SOllivier Robert "\n Axis = % -12g . n = % -12g . r1me2 = % -12g", 4084ba371819SOllivier Robert edata->Axis, edata->n, edata->r1me2 ); 4085ba371819SOllivier Robert pbuf += sprintf(pbuf, 4086ba371819SOllivier Robert "\n OMEGA_n = % -12g . ODOT_n = % -12g", 4087ba371819SOllivier Robert edata->OMEGA_n, edata->ODOT_n ); 4088ba371819SOllivier Robert break; 4089ba371819SOllivier Robert } 4090ba371819SOllivier Robert } 4091ba371819SOllivier Robert } 4092ba371819SOllivier Robert 4093ba371819SOllivier Robert 4094ba371819SOllivier Robert /* 0x59: */ 40952b15cb3dSCy Schubert static void 40962b15cb3dSCy Schubert rpt_SVs_enabled( 40972b15cb3dSCy Schubert TSIPPKT *rpt 40982b15cb3dSCy Schubert ) 4099ba371819SOllivier Robert { 4100ba371819SOllivier Robert unsigned char 4101ba371819SOllivier Robert numsvs, 4102ba371819SOllivier Robert code_type, 4103ba371819SOllivier Robert status_code[32]; 4104ba371819SOllivier Robert short 4105ba371819SOllivier Robert iprn; 4106ba371819SOllivier Robert 4107ba371819SOllivier Robert /* unload rptbuf */ 4108ba371819SOllivier Robert if (rpt_0x59 (rpt, &code_type, status_code)) 4109ba371819SOllivier Robert { 4110ba371819SOllivier Robert parsed = BADLEN_PARSE; 4111ba371819SOllivier Robert return; 4112ba371819SOllivier Robert } 4113ba371819SOllivier Robert switch (code_type) 4114ba371819SOllivier Robert { 4115ba371819SOllivier Robert case 3: pbuf += sprintf(pbuf, "\nSVs Disabled:\n"); break; 4116ba371819SOllivier Robert case 6: pbuf += sprintf(pbuf, "\nSVs with Health Ignored:\n"); break; 4117ba371819SOllivier Robert default: return; 4118ba371819SOllivier Robert } 4119ba371819SOllivier Robert numsvs = 0; 4120ba371819SOllivier Robert for (iprn = 0; iprn < 32; iprn++) 4121ba371819SOllivier Robert { 4122ba371819SOllivier Robert if (status_code[iprn]) 4123ba371819SOllivier Robert { 4124ba371819SOllivier Robert pbuf += sprintf(pbuf, " %02d", iprn+1); 4125ba371819SOllivier Robert numsvs++; 4126ba371819SOllivier Robert } 4127ba371819SOllivier Robert } 4128ba371819SOllivier Robert if (numsvs == 0) pbuf += sprintf(pbuf, "None"); 4129ba371819SOllivier Robert } 4130ba371819SOllivier Robert 4131ba371819SOllivier Robert 4132ba371819SOllivier Robert /* 0x5A */ 41332b15cb3dSCy Schubert static void 41342b15cb3dSCy Schubert rpt_raw_msmt( 41352b15cb3dSCy Schubert TSIPPKT *rpt 41362b15cb3dSCy Schubert ) 4137ba371819SOllivier Robert { 4138ba371819SOllivier Robert unsigned char 4139ba371819SOllivier Robert sv_prn; 4140ba371819SOllivier Robert float 4141ba371819SOllivier Robert sample_length, signal_level, code_phase, Doppler; 4142ba371819SOllivier Robert double 4143ba371819SOllivier Robert time_of_fix; 4144ba371819SOllivier Robert 4145ba371819SOllivier Robert /* unload rptbuf */ 4146ba371819SOllivier Robert if (rpt_0x5A (rpt, &sv_prn, &sample_length, &signal_level, 4147ba371819SOllivier Robert &code_phase, &Doppler, &time_of_fix)) 4148ba371819SOllivier Robert { 4149ba371819SOllivier Robert parsed = BADLEN_PARSE; 4150ba371819SOllivier Robert return; 4151ba371819SOllivier Robert } 4152ba371819SOllivier Robert 4153ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n %02d %5.0f %7.1f %10.2f %10.2f %12.3f %s", 4154ba371819SOllivier Robert sv_prn, sample_length, signal_level, code_phase, Doppler, time_of_fix, 4155ba371819SOllivier Robert show_time ((float)time_of_fix)); 4156ba371819SOllivier Robert } 4157ba371819SOllivier Robert 4158ba371819SOllivier Robert /* 0x5B */ 41592b15cb3dSCy Schubert static void 41602b15cb3dSCy Schubert rpt_SV_ephemeris_status( 41612b15cb3dSCy Schubert TSIPPKT *rpt 41622b15cb3dSCy Schubert ) 4163ba371819SOllivier Robert { 4164ba371819SOllivier Robert unsigned char 4165ba371819SOllivier Robert sv_prn, sv_health, sv_iode, fit_interval_flag; 4166ba371819SOllivier Robert float 4167ba371819SOllivier Robert time_of_collection, time_of_eph, sv_accy; 4168ba371819SOllivier Robert 4169ba371819SOllivier Robert /* unload rptbuf */ 4170ba371819SOllivier Robert if (rpt_0x5B (rpt, &sv_prn, &sv_health, &sv_iode, &fit_interval_flag, 4171ba371819SOllivier Robert &time_of_collection, &time_of_eph, &sv_accy)) 4172ba371819SOllivier Robert { 4173ba371819SOllivier Robert parsed = BADLEN_PARSE; 4174ba371819SOllivier Robert return; 4175ba371819SOllivier Robert } 4176ba371819SOllivier Robert 4177ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n SV%02d %s %2Xh %2Xh ", 4178ba371819SOllivier Robert sv_prn, show_time (time_of_collection), sv_health, sv_iode); 4179ba371819SOllivier Robert /* note: cannot use show_time twice in same call */ 4180ba371819SOllivier Robert pbuf += sprintf(pbuf, "%s %1d %4.1f", 4181ba371819SOllivier Robert show_time (time_of_eph), fit_interval_flag, sv_accy); 4182ba371819SOllivier Robert } 4183ba371819SOllivier Robert 4184ba371819SOllivier Robert /* 0x5C */ 41852b15cb3dSCy Schubert static void 41862b15cb3dSCy Schubert rpt_SV_tracking_status( 41872b15cb3dSCy Schubert TSIPPKT *rpt 41882b15cb3dSCy Schubert ) 4189ba371819SOllivier Robert { 4190ba371819SOllivier Robert unsigned char 4191ba371819SOllivier Robert sv_prn, chan, slot, acq_flag, eph_flag, 4192ba371819SOllivier Robert old_msmt_flag, integer_msec_flag, bad_data_flag, 4193ba371819SOllivier Robert data_collect_flag; 4194ba371819SOllivier Robert float 4195ba371819SOllivier Robert signal_level, time_of_last_msmt, 4196ba371819SOllivier Robert elev, azim; 4197ba371819SOllivier Robert 4198ba371819SOllivier Robert /* unload rptbuf */ 4199ba371819SOllivier Robert if (rpt_0x5C (rpt, 4200ba371819SOllivier Robert &sv_prn, &slot, &chan, &acq_flag, &eph_flag, 4201ba371819SOllivier Robert &signal_level, &time_of_last_msmt, &elev, &azim, 4202ba371819SOllivier Robert &old_msmt_flag, &integer_msec_flag, &bad_data_flag, 4203ba371819SOllivier Robert &data_collect_flag)) 4204ba371819SOllivier Robert { 4205ba371819SOllivier Robert parsed = BADLEN_PARSE; 4206ba371819SOllivier Robert return; 4207ba371819SOllivier Robert } 4208ba371819SOllivier Robert 4209ba371819SOllivier Robert pbuf += sprintf(pbuf, 4210ba371819SOllivier Robert "\n SV%2d %1d %1d %1d %4.1f %s %5.1f %5.1f", 4211ba371819SOllivier Robert sv_prn, chan, 4212ba371819SOllivier Robert acq_flag, eph_flag, signal_level, 4213ba371819SOllivier Robert show_time(time_of_last_msmt), 4214ba371819SOllivier Robert elev*R2D, azim*R2D); 4215ba371819SOllivier Robert } 4216ba371819SOllivier Robert 4217ba371819SOllivier Robert /**/ 4218ba371819SOllivier Robert /* 0x6D */ 42192b15cb3dSCy Schubert static void 42202b15cb3dSCy Schubert rpt_allSV_selection( 42212b15cb3dSCy Schubert TSIPPKT *rpt 42222b15cb3dSCy Schubert ) 4223ba371819SOllivier Robert { 4224ba371819SOllivier Robert unsigned char 4225ba371819SOllivier Robert manual_mode, nsvs, sv_prn[8], ndim; 4226ba371819SOllivier Robert short 4227ba371819SOllivier Robert islot; 4228ba371819SOllivier Robert float 4229ba371819SOllivier Robert pdop, hdop, vdop, tdop; 4230ba371819SOllivier Robert 4231ba371819SOllivier Robert /* unload rptbuf */ 4232ba371819SOllivier Robert if (rpt_0x6D (rpt, 4233ba371819SOllivier Robert &manual_mode, &nsvs, &ndim, sv_prn, 4234ba371819SOllivier Robert &pdop, &hdop, &vdop, &tdop)) 4235ba371819SOllivier Robert { 4236ba371819SOllivier Robert parsed = BADLEN_PARSE; 4237ba371819SOllivier Robert return; 4238ba371819SOllivier Robert } 4239ba371819SOllivier Robert 4240ba371819SOllivier Robert switch (ndim) 4241ba371819SOllivier Robert { 4242ba371819SOllivier Robert case 0: 4243ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nMode: Searching, %d-SV:", nsvs); 4244ba371819SOllivier Robert break; 4245ba371819SOllivier Robert case 1: 4246ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nMode: One-SV Timing:"); 4247ba371819SOllivier Robert break; 4248ba371819SOllivier Robert case 3: case 4: 4249ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nMode: %c-%dD, %d-SV:", 4250ba371819SOllivier Robert manual_mode ? 'M' : 'A', ndim - 1, nsvs); 4251ba371819SOllivier Robert break; 4252ba371819SOllivier Robert case 5: 4253ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nMode: Timing, %d-SV:", nsvs); 4254ba371819SOllivier Robert break; 4255ba371819SOllivier Robert default: 4256ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nMode: Unknown = %d:", ndim); 4257ba371819SOllivier Robert break; 4258ba371819SOllivier Robert } 4259ba371819SOllivier Robert 4260ba371819SOllivier Robert for (islot = 0; islot < nsvs; islot++) 4261ba371819SOllivier Robert { 4262ba371819SOllivier Robert if (sv_prn[islot]) pbuf += sprintf(pbuf, " %02d", sv_prn[islot]); 4263ba371819SOllivier Robert } 4264ba371819SOllivier Robert if (ndim == 3 || ndim == 4) 4265ba371819SOllivier Robert { 4266ba371819SOllivier Robert pbuf += sprintf(pbuf, "; DOPs: P %.1f H %.1f V %.1f T %.1f", 4267ba371819SOllivier Robert pdop, hdop, vdop, tdop); 4268ba371819SOllivier Robert } 4269ba371819SOllivier Robert } 4270ba371819SOllivier Robert 4271ba371819SOllivier Robert /**/ 4272ba371819SOllivier Robert /* 0x82 */ 42732b15cb3dSCy Schubert static void 42742b15cb3dSCy Schubert rpt_DGPS_position_mode( 42752b15cb3dSCy Schubert TSIPPKT *rpt 42762b15cb3dSCy Schubert ) 4277ba371819SOllivier Robert { 4278ba371819SOllivier Robert unsigned char 4279ba371819SOllivier Robert diff_mode; 4280ba371819SOllivier Robert 4281ba371819SOllivier Robert /* unload rptbuf */ 4282ba371819SOllivier Robert if (rpt_0x82 (rpt, &diff_mode)) { 4283ba371819SOllivier Robert parsed = BADLEN_PARSE; 4284ba371819SOllivier Robert return; 4285ba371819SOllivier Robert } 4286ba371819SOllivier Robert 4287ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nFix is%s DGPS-corrected (%s mode) (%d)", 4288ba371819SOllivier Robert (diff_mode&1) ? "" : " not", 4289ba371819SOllivier Robert (diff_mode&2) ? "auto" : "manual", 4290ba371819SOllivier Robert diff_mode); 4291ba371819SOllivier Robert } 4292ba371819SOllivier Robert 4293ba371819SOllivier Robert /* 0x83 */ 42942b15cb3dSCy Schubert static void 42952b15cb3dSCy Schubert rpt_double_ECEF_position( 42962b15cb3dSCy Schubert TSIPPKT *rpt 42972b15cb3dSCy Schubert ) 4298ba371819SOllivier Robert { 4299ba371819SOllivier Robert double 4300ba371819SOllivier Robert ECEF_pos[3], clock_bias; 4301ba371819SOllivier Robert float 4302ba371819SOllivier Robert time_of_fix; 4303ba371819SOllivier Robert 4304ba371819SOllivier Robert /* unload rptbuf */ 4305ba371819SOllivier Robert if (rpt_0x83 (rpt, ECEF_pos, &clock_bias, &time_of_fix)) 4306ba371819SOllivier Robert { 4307ba371819SOllivier Robert parsed = BADLEN_PARSE; 4308ba371819SOllivier Robert return; 4309ba371819SOllivier Robert } 4310ba371819SOllivier Robert 4311ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nDXYZ:%12.2f %13.2f %13.2f %12.2f%s", 4312ba371819SOllivier Robert ECEF_pos[0], ECEF_pos[1], ECEF_pos[2], clock_bias, 4313ba371819SOllivier Robert show_time(time_of_fix)); 4314ba371819SOllivier Robert } 4315ba371819SOllivier Robert 4316ba371819SOllivier Robert /* 0x84 */ 43172b15cb3dSCy Schubert static void 43182b15cb3dSCy Schubert rpt_double_lla_position( 43192b15cb3dSCy Schubert TSIPPKT *rpt 43202b15cb3dSCy Schubert ) 4321ba371819SOllivier Robert { 4322ba371819SOllivier Robert short 4323ba371819SOllivier Robert lat_deg, lon_deg; 4324ba371819SOllivier Robert double 4325ba371819SOllivier Robert lat, lon, lat_min, lon_min, 4326ba371819SOllivier Robert alt, clock_bias; 4327ba371819SOllivier Robert float 4328ba371819SOllivier Robert time_of_fix; 4329ba371819SOllivier Robert unsigned char 4330ba371819SOllivier Robert north_south, east_west; 4331ba371819SOllivier Robert 4332ba371819SOllivier Robert /* unload rptbuf */ 4333ba371819SOllivier Robert if (rpt_0x84 (rpt, 4334ba371819SOllivier Robert &lat, &lon, &alt, &clock_bias, &time_of_fix)) 4335ba371819SOllivier Robert { 4336ba371819SOllivier Robert parsed = BADLEN_PARSE; 4337ba371819SOllivier Robert return; 4338ba371819SOllivier Robert } 4339ba371819SOllivier Robert 4340ba371819SOllivier Robert lat *= R2D; 4341ba371819SOllivier Robert lon *= R2D; 4342ba371819SOllivier Robert if (lat < 0.0) { 4343ba371819SOllivier Robert north_south = 'S'; 4344ba371819SOllivier Robert lat = -lat; 4345ba371819SOllivier Robert } else { 4346ba371819SOllivier Robert north_south = 'N'; 4347ba371819SOllivier Robert } 4348ba371819SOllivier Robert lat_deg = (short)lat; 4349ba371819SOllivier Robert lat_min = (lat - lat_deg) * 60.0; 4350ba371819SOllivier Robert 4351ba371819SOllivier Robert if (lon < 0.0) { 4352ba371819SOllivier Robert east_west = 'W'; 4353ba371819SOllivier Robert lon = -lon; 4354ba371819SOllivier Robert } else { 4355ba371819SOllivier Robert east_west = 'E'; 4356ba371819SOllivier Robert } 4357ba371819SOllivier Robert lon_deg = (short)lon; 4358ba371819SOllivier Robert lon_min = (lon - lon_deg) * 60.0; 4359ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nDLLA: %2d:%08.5f %c; %3d:%08.5f %c; %10.2f %12.2f%s", 4360ba371819SOllivier Robert lat_deg, lat_min, north_south, 4361ba371819SOllivier Robert lon_deg, lon_min, east_west, 4362ba371819SOllivier Robert alt, clock_bias, 4363ba371819SOllivier Robert show_time(time_of_fix)); 4364ba371819SOllivier Robert } 4365ba371819SOllivier Robert 4366ba371819SOllivier Robert /* 0xBB */ 43672b15cb3dSCy Schubert static void 43682b15cb3dSCy Schubert rpt_complete_rcvr_config( 43692b15cb3dSCy Schubert TSIPPKT *rpt 43702b15cb3dSCy Schubert ) 4371ba371819SOllivier Robert { 4372ba371819SOllivier Robert TSIP_RCVR_CFG TsipxBB ; 4373ba371819SOllivier Robert /* unload rptbuf */ 4374ba371819SOllivier Robert if (rpt_Paly0xBB (rpt, &TsipxBB)) 4375ba371819SOllivier Robert { 4376ba371819SOllivier Robert parsed = BADLEN_PARSE; 4377ba371819SOllivier Robert return; 4378ba371819SOllivier Robert } 4379ba371819SOllivier Robert 4380ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n operating mode: %s", 4381ba371819SOllivier Robert NavModeText0xBB[TsipxBB.operating_mode]); 4382ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dynamics: %s", 4383ba371819SOllivier Robert dyn_text[TsipxBB.dyn_code]); 4384ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n elev angle mask: %g deg", 4385ba371819SOllivier Robert TsipxBB.elev_mask * R2D); 4386ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n SNR mask: %g AMU", 4387ba371819SOllivier Robert TsipxBB.cno_mask); 4388ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n DOP mask: %g", 4389ba371819SOllivier Robert TsipxBB.dop_mask); 4390ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n DOP switch: %g", 4391ba371819SOllivier Robert TsipxBB.dop_switch); 4392ba371819SOllivier Robert return ; 4393ba371819SOllivier Robert } 4394ba371819SOllivier Robert 4395ba371819SOllivier Robert /* 0xBC */ 43962b15cb3dSCy Schubert static void 43972b15cb3dSCy Schubert rpt_rcvr_serial_port_config( 43982b15cb3dSCy Schubert TSIPPKT *rpt 43992b15cb3dSCy Schubert ) 4400ba371819SOllivier Robert { 4401ba371819SOllivier Robert unsigned char 4402ba371819SOllivier Robert port_num, in_baud, out_baud, data_bits, parity, stop_bits, flow_control, 4403ba371819SOllivier Robert protocols_in, protocols_out, reserved; 4404ba371819SOllivier Robert unsigned char known; 4405ba371819SOllivier Robert 4406ba371819SOllivier Robert /* unload rptbuf */ 4407ba371819SOllivier Robert if (rpt_0xBC (rpt, &port_num, &in_baud, &out_baud, &data_bits, &parity, 4408ba371819SOllivier Robert &stop_bits, &flow_control, &protocols_in, &protocols_out, &reserved)) { 4409ba371819SOllivier Robert parsed = BADLEN_PARSE; 4410ba371819SOllivier Robert return; 4411ba371819SOllivier Robert } 4412ba371819SOllivier Robert /* rptbuf unloaded */ 4413ba371819SOllivier Robert 4414ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n RECEIVER serial port %s config:", 4415ba371819SOllivier Robert rcvr_port_text[port_num]); 4416ba371819SOllivier Robert 4417ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n I/O Baud %s/%s, %d - %s - %d", 4418ba371819SOllivier Robert st_baud_text_app[in_baud], 4419ba371819SOllivier Robert st_baud_text_app[out_baud], 4420ba371819SOllivier Robert data_bits+5, 4421ba371819SOllivier Robert parity_text[parity], 4422ba371819SOllivier Robert stop_bits=1); 4423ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Input protocols: "); 4424ba371819SOllivier Robert known = FALSE; 4425ba371819SOllivier Robert if (protocols_in&B_TSIP) 4426ba371819SOllivier Robert { 4427ba371819SOllivier Robert pbuf += sprintf(pbuf, "%s ", protocols_in_text[1]); 4428ba371819SOllivier Robert known = TRUE; 4429ba371819SOllivier Robert } 4430ba371819SOllivier Robert if (known == FALSE) pbuf += sprintf(pbuf, "No known"); 4431ba371819SOllivier Robert 4432ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Output protocols: "); 4433ba371819SOllivier Robert known = FALSE; 4434ba371819SOllivier Robert if (protocols_out&B_TSIP) 4435ba371819SOllivier Robert { 4436ba371819SOllivier Robert pbuf += sprintf(pbuf, "%s ", protocols_out_text[1]); 4437ba371819SOllivier Robert known = TRUE; 4438ba371819SOllivier Robert } 4439ba371819SOllivier Robert if (protocols_out&B_NMEA) 4440ba371819SOllivier Robert { 4441ba371819SOllivier Robert pbuf += sprintf(pbuf, "%s ", protocols_out_text[2]); 4442ba371819SOllivier Robert known = TRUE; 4443ba371819SOllivier Robert } 4444ba371819SOllivier Robert if (known == FALSE) pbuf += sprintf(pbuf, "No known"); 4445ba371819SOllivier Robert reserved = reserved; 4446ba371819SOllivier Robert 4447ba371819SOllivier Robert } 4448ba371819SOllivier Robert 4449ba371819SOllivier Robert /* 0x8F */ 4450ba371819SOllivier Robert /* 8F0B */ 44512b15cb3dSCy Schubert static void 44522b15cb3dSCy Schubert rpt_8F0B( 44532b15cb3dSCy Schubert TSIPPKT *rpt 44542b15cb3dSCy Schubert ) 4455ba371819SOllivier Robert { 4456ba371819SOllivier Robert const char 4457ba371819SOllivier Robert *oprtng_dim[7] = { 4458ba371819SOllivier Robert "horizontal (2-D)", 4459ba371819SOllivier Robert "full position (3-D)", 4460ba371819SOllivier Robert "single satellite (0-D)", 4461ba371819SOllivier Robert "automatic", 4462ba371819SOllivier Robert "N/A", 4463ba371819SOllivier Robert "N/A", 4464ba371819SOllivier Robert "overdetermined clock"}; 4465ba371819SOllivier Robert char 4466ba371819SOllivier Robert sv_id[8]; 4467ba371819SOllivier Robert unsigned char 4468ba371819SOllivier Robert month, 4469ba371819SOllivier Robert date, 4470ba371819SOllivier Robert dim_mode, 4471ba371819SOllivier Robert north_south, 4472ba371819SOllivier Robert east_west; 4473ba371819SOllivier Robert unsigned short 4474ba371819SOllivier Robert event; 4475ba371819SOllivier Robert short 4476ba371819SOllivier Robert utc_offset, 4477ba371819SOllivier Robert year, 4478ba371819SOllivier Robert local_index; 4479ba371819SOllivier Robert short 4480ba371819SOllivier Robert lat_deg, 4481ba371819SOllivier Robert lon_deg; 4482ba371819SOllivier Robert float 4483ba371819SOllivier Robert bias_unc, 4484ba371819SOllivier Robert dr_unc; 4485ba371819SOllivier Robert double 4486ba371819SOllivier Robert tow, 4487ba371819SOllivier Robert bias, 4488ba371819SOllivier Robert drift, 4489ba371819SOllivier Robert lat, 4490ba371819SOllivier Robert lon, 4491ba371819SOllivier Robert alt, 4492ba371819SOllivier Robert lat_min, 4493ba371819SOllivier Robert lon_min; 4494ba371819SOllivier Robert int 4495ba371819SOllivier Robert numfix, 4496ba371819SOllivier Robert numnotfix; 4497ba371819SOllivier Robert 4498ba371819SOllivier Robert if (rpt_0x8F0B(rpt, 4499ba371819SOllivier Robert &event, 4500ba371819SOllivier Robert &tow, 4501ba371819SOllivier Robert &date, 4502ba371819SOllivier Robert &month, 4503ba371819SOllivier Robert &year, 4504ba371819SOllivier Robert &dim_mode, 4505ba371819SOllivier Robert &utc_offset, 4506ba371819SOllivier Robert &bias, 4507ba371819SOllivier Robert &drift, 4508ba371819SOllivier Robert &bias_unc, 4509ba371819SOllivier Robert &dr_unc, 4510ba371819SOllivier Robert &lat, 4511ba371819SOllivier Robert &lon, 4512ba371819SOllivier Robert &alt, 4513ba371819SOllivier Robert sv_id)) 4514ba371819SOllivier Robert { 4515ba371819SOllivier Robert parsed = BADLEN_PARSE; 4516ba371819SOllivier Robert return; 4517ba371819SOllivier Robert } 4518ba371819SOllivier Robert 4519ba371819SOllivier Robert if (event == 0) 4520ba371819SOllivier Robert { 4521ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nNew partial+full meas"); 4522ba371819SOllivier Robert } 4523ba371819SOllivier Robert else 4524ba371819SOllivier Robert { 4525ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nEvent count: %5d", event); 4526ba371819SOllivier Robert } 4527ba371819SOllivier Robert 4528ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nGPS time : %s %2d/%2d/%2d (DMY)", 4529ba371819SOllivier Robert show_time(tow), date, month, year); 4530ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nMode : %s", oprtng_dim[dim_mode]); 4531ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nUTC offset: %2d", utc_offset); 4532ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nClock Bias: %6.2f m", bias); 4533ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nFreq bias : %6.2f m/s", drift); 4534ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nBias unc : %6.2f m", bias_unc); 4535ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nFreq unc : %6.2f m/s", dr_unc); 4536ba371819SOllivier Robert 4537ba371819SOllivier Robert lat *= R2D; /* convert from radians to degrees */ 4538ba371819SOllivier Robert lon *= R2D; 4539ba371819SOllivier Robert if (lat < 0.0) 4540ba371819SOllivier Robert { 4541ba371819SOllivier Robert north_south = 'S'; 4542ba371819SOllivier Robert lat = -lat; 4543ba371819SOllivier Robert } 4544ba371819SOllivier Robert else 4545ba371819SOllivier Robert { 4546ba371819SOllivier Robert north_south = 'N'; 4547ba371819SOllivier Robert } 4548ba371819SOllivier Robert 4549ba371819SOllivier Robert lat_deg = (short)lat; 4550ba371819SOllivier Robert lat_min = (lat - lat_deg) * 60.0; 4551ba371819SOllivier Robert if (lon < 0.0) 4552ba371819SOllivier Robert { 4553ba371819SOllivier Robert east_west = 'W'; 4554ba371819SOllivier Robert lon = -lon; 4555ba371819SOllivier Robert } 4556ba371819SOllivier Robert else 4557ba371819SOllivier Robert { 4558ba371819SOllivier Robert east_west = 'E'; 4559ba371819SOllivier Robert } 4560ba371819SOllivier Robert 4561ba371819SOllivier Robert lon_deg = (short)lon; 4562ba371819SOllivier Robert lon_min = (lon - lon_deg) * 60.0; 4563ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nPosition :"); 4564ba371819SOllivier Robert pbuf += sprintf(pbuf, " %4d %6.3f %c", lat_deg, lat_min, north_south); 4565ba371819SOllivier Robert pbuf += sprintf(pbuf, " %5d %6.3f %c", lon_deg, lon_min, east_west); 4566ba371819SOllivier Robert pbuf += sprintf(pbuf, " %10.2f", alt); 4567ba371819SOllivier Robert 4568ba371819SOllivier Robert numfix = numnotfix = 0; 4569ba371819SOllivier Robert for (local_index=0; local_index<8; local_index++) 4570ba371819SOllivier Robert { 4571ba371819SOllivier Robert if (sv_id[local_index] < 0) numnotfix++; 4572ba371819SOllivier Robert if (sv_id[local_index] > 0) numfix++; 4573ba371819SOllivier Robert } 4574ba371819SOllivier Robert if (numfix > 0) 4575ba371819SOllivier Robert { 4576ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nSVs used in fix : "); 4577ba371819SOllivier Robert for (local_index=0; local_index<8; local_index++) 4578ba371819SOllivier Robert { 4579ba371819SOllivier Robert if (sv_id[local_index] > 0) 4580ba371819SOllivier Robert { 4581ba371819SOllivier Robert pbuf += sprintf(pbuf, "%2d ", sv_id[local_index]); 4582ba371819SOllivier Robert } 4583ba371819SOllivier Robert } 4584ba371819SOllivier Robert } 4585ba371819SOllivier Robert if (numnotfix > 0) 4586ba371819SOllivier Robert { 4587ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nOther SVs tracked: "); 4588ba371819SOllivier Robert for (local_index=0; local_index<8; local_index++) 4589ba371819SOllivier Robert { 4590ba371819SOllivier Robert if (sv_id[local_index] < 0) 4591ba371819SOllivier Robert { 4592ba371819SOllivier Robert pbuf += sprintf(pbuf, "%2d ", sv_id[local_index]); 4593ba371819SOllivier Robert } 4594ba371819SOllivier Robert } 4595ba371819SOllivier Robert } 4596ba371819SOllivier Robert } 4597ba371819SOllivier Robert 4598ba371819SOllivier Robert /* 0x8F14 */ 4599ba371819SOllivier Robert /* Datum parameters */ 46002b15cb3dSCy Schubert static void 46012b15cb3dSCy Schubert rpt_8F14( 46022b15cb3dSCy Schubert TSIPPKT *rpt 46032b15cb3dSCy Schubert ) 4604ba371819SOllivier Robert { 4605ba371819SOllivier Robert double 4606ba371819SOllivier Robert datum_coeffs[5]; 4607ba371819SOllivier Robert short 4608ba371819SOllivier Robert datum_idx; 4609ba371819SOllivier Robert 4610ba371819SOllivier Robert /* unload rptbuf */ 4611ba371819SOllivier Robert if (rpt_0x8F14 (rpt, &datum_idx, datum_coeffs)) 4612ba371819SOllivier Robert { 4613ba371819SOllivier Robert parsed = BADLEN_PARSE; 4614ba371819SOllivier Robert return; 4615ba371819SOllivier Robert } 4616ba371819SOllivier Robert 4617ba371819SOllivier Robert if (datum_idx == -1) 4618ba371819SOllivier Robert { 4619ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nUser-Entered Datum:"); 4620ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dx = %6.1f", datum_coeffs[0]); 4621ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dy = %6.1f", datum_coeffs[1]); 4622ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dz = %6.1f", datum_coeffs[2]); 4623ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n a-axis = %10.3f", datum_coeffs[3]); 4624ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n e-squared = %16.14f", datum_coeffs[4]); 4625ba371819SOllivier Robert } 4626ba371819SOllivier Robert else if (datum_idx == 0) 4627ba371819SOllivier Robert { 4628ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nWGS-84 datum, Index 0 "); 4629ba371819SOllivier Robert } 4630ba371819SOllivier Robert else 4631ba371819SOllivier Robert { 4632ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nStandard Datum, Index %3d ", datum_idx); 4633ba371819SOllivier Robert } 4634ba371819SOllivier Robert } 4635ba371819SOllivier Robert 4636ba371819SOllivier Robert /* 0x8F15 */ 4637ba371819SOllivier Robert /* Datum parameters */ 46382b15cb3dSCy Schubert static void 46392b15cb3dSCy Schubert rpt_8F15( 46402b15cb3dSCy Schubert TSIPPKT *rpt 46412b15cb3dSCy Schubert ) 4642ba371819SOllivier Robert { 4643ba371819SOllivier Robert double 4644ba371819SOllivier Robert datum_coeffs[5]; 4645ba371819SOllivier Robert short 4646ba371819SOllivier Robert datum_idx; 4647ba371819SOllivier Robert 4648ba371819SOllivier Robert /* unload rptbuf */ 4649ba371819SOllivier Robert if (rpt_0x8F15 (rpt, &datum_idx, datum_coeffs)) { 4650ba371819SOllivier Robert parsed = BADLEN_PARSE; 4651ba371819SOllivier Robert return; 4652ba371819SOllivier Robert } 4653ba371819SOllivier Robert 4654ba371819SOllivier Robert if (datum_idx == -1) 4655ba371819SOllivier Robert { 4656ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nUser-Entered Datum:"); 4657ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dx = %6.1f", datum_coeffs[0]); 4658ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dy = %6.1f", datum_coeffs[1]); 4659ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n dz = %6.1f", datum_coeffs[2]); 4660ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n a-axis = %10.3f", datum_coeffs[3]); 4661ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n e-squared = %16.14f", datum_coeffs[4]); 4662ba371819SOllivier Robert } 4663ba371819SOllivier Robert else if (datum_idx == 0) 4664ba371819SOllivier Robert { 4665ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nWGS-84 datum, Index 0 "); 4666ba371819SOllivier Robert } 4667ba371819SOllivier Robert else 4668ba371819SOllivier Robert { 4669ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nStandard Datum, Index %3d ", datum_idx); 4670ba371819SOllivier Robert } 4671ba371819SOllivier Robert } 4672ba371819SOllivier Robert 4673ba371819SOllivier Robert /* 0x8F20 */ 4674ba371819SOllivier Robert #define INFO_DGPS 0x02 4675ba371819SOllivier Robert #define INFO_2D 0x04 4676ba371819SOllivier Robert #define INFO_ALTSET 0x08 4677ba371819SOllivier Robert #define INFO_FILTERED 0x10 46782b15cb3dSCy Schubert static void 46792b15cb3dSCy Schubert rpt_8F20( 46802b15cb3dSCy Schubert TSIPPKT *rpt 46812b15cb3dSCy Schubert ) 4682ba371819SOllivier Robert { 4683ba371819SOllivier Robert unsigned char 4684ba371819SOllivier Robert info, nsvs, sv_prn[32]; 4685ba371819SOllivier Robert short 4686ba371819SOllivier Robert week_num, datum_index, sv_IODC[32]; 4687ba371819SOllivier Robert double 4688ba371819SOllivier Robert lat, lon, alt, time_of_fix; 4689ba371819SOllivier Robert double 4690ba371819SOllivier Robert londeg, latdeg, vel[3]; 4691ba371819SOllivier Robert short 4692ba371819SOllivier Robert isv; 4693ba371819SOllivier Robert char 4694ba371819SOllivier Robert datum_string[20]; 4695ba371819SOllivier Robert 4696ba371819SOllivier Robert /* unload rptbuf */ 4697ba371819SOllivier Robert if (rpt_0x8F20 (rpt, 4698ba371819SOllivier Robert &info, &lat, &lon, &alt, vel, 4699ba371819SOllivier Robert &time_of_fix, 4700ba371819SOllivier Robert &week_num, &nsvs, sv_prn, sv_IODC, &datum_index)) 4701ba371819SOllivier Robert { 4702ba371819SOllivier Robert parsed = BADLEN_PARSE; 4703ba371819SOllivier Robert return; 4704ba371819SOllivier Robert } 4705ba371819SOllivier Robert pbuf += sprintf(pbuf, 4706ba371819SOllivier Robert "\nFix at: %04d:%3s:%02d:%02d:%06.3f GPS (=UTC+%2ds) FixType: %s%s%s", 4707ba371819SOllivier Robert week_num, 4708ba371819SOllivier Robert dayname[(short)(time_of_fix/86400.0)], 4709ba371819SOllivier Robert (short)fmod(time_of_fix/3600., 24.), 4710ba371819SOllivier Robert (short)fmod(time_of_fix/60., 60.), 4711ba371819SOllivier Robert fmod(time_of_fix, 60.), 4712ba371819SOllivier Robert (char)rpt->buf[29], /* UTC offset */ 4713ba371819SOllivier Robert (info & INFO_DGPS)?"Diff":"", 4714ba371819SOllivier Robert (info & INFO_2D)?"2D":"3D", 4715ba371819SOllivier Robert (info & INFO_FILTERED)?"-Filtrd":""); 4716ba371819SOllivier Robert 4717ba371819SOllivier Robert if (datum_index > 0) 4718ba371819SOllivier Robert { 4719ba371819SOllivier Robert sprintf(datum_string, "Datum%3d", datum_index); 4720ba371819SOllivier Robert } 4721ba371819SOllivier Robert else if (datum_index) 4722ba371819SOllivier Robert { 4723ba371819SOllivier Robert sprintf(datum_string, "Unknown "); 4724ba371819SOllivier Robert } 4725ba371819SOllivier Robert else 4726ba371819SOllivier Robert { 4727ba371819SOllivier Robert sprintf(datum_string, "WGS-84"); 4728ba371819SOllivier Robert } 4729ba371819SOllivier Robert 4730ba371819SOllivier Robert /* convert from radians to degrees */ 4731ba371819SOllivier Robert latdeg = R2D * fabs(lat); 4732ba371819SOllivier Robert londeg = R2D * fabs(lon); 4733ba371819SOllivier Robert pbuf += sprintf(pbuf, 4734ba371819SOllivier Robert "\n Pos: %4d:%09.6f %c %5d:%09.6f %c %10.2f m HAE (%s)", 4735ba371819SOllivier Robert (short)latdeg, fmod (latdeg, 1.)*60.0, 4736ba371819SOllivier Robert (lat<0.0)?'S':'N', 4737ba371819SOllivier Robert (short)londeg, fmod (londeg, 1.)*60.0, 4738ba371819SOllivier Robert (lon<0.0)?'W':'E', 4739ba371819SOllivier Robert alt, 4740ba371819SOllivier Robert datum_string); 4741ba371819SOllivier Robert pbuf += sprintf(pbuf, 4742ba371819SOllivier Robert "\n Vel: %9.3f E %9.3f N %9.3f U (m/sec)", 4743ba371819SOllivier Robert vel[0], vel[1], vel[2]); 4744ba371819SOllivier Robert 4745ba371819SOllivier Robert pbuf += sprintf(pbuf, 4746ba371819SOllivier Robert "\n SVs: "); 4747ba371819SOllivier Robert for (isv = 0; isv < nsvs; isv++) { 4748ba371819SOllivier Robert pbuf += sprintf(pbuf, " %02d", sv_prn[isv]); 4749ba371819SOllivier Robert } 4750ba371819SOllivier Robert pbuf += sprintf(pbuf, " (IODEs:"); 4751ba371819SOllivier Robert for (isv = 0; isv < nsvs; isv++) { 4752ba371819SOllivier Robert pbuf += sprintf(pbuf, " %02X", sv_IODC[isv]&0xFF); 4753ba371819SOllivier Robert } 4754ba371819SOllivier Robert pbuf += sprintf(pbuf, ")"); 4755ba371819SOllivier Robert } 4756ba371819SOllivier Robert 4757ba371819SOllivier Robert /* 0x8F41 */ 47582b15cb3dSCy Schubert static void 47592b15cb3dSCy Schubert rpt_8F41( 47602b15cb3dSCy Schubert TSIPPKT *rpt 47612b15cb3dSCy Schubert ) 4762ba371819SOllivier Robert { 4763ba371819SOllivier Robert unsigned char 4764ba371819SOllivier Robert bSearchRange, 4765ba371819SOllivier Robert bBoardOptions, 4766ba371819SOllivier Robert bBuildYear, 4767ba371819SOllivier Robert bBuildMonth, 4768ba371819SOllivier Robert bBuildDay, 4769ba371819SOllivier Robert bBuildHour; 4770ba371819SOllivier Robert float 4771ba371819SOllivier Robert fOscOffset; 4772ba371819SOllivier Robert unsigned short 4773ba371819SOllivier Robert iTestCodeId; 4774ba371819SOllivier Robert unsigned long 4775ba371819SOllivier Robert iiSerialNumber; 4776ba371819SOllivier Robert 4777ba371819SOllivier Robert if (!rpt_0x8F41(rpt, 4778ba371819SOllivier Robert &bSearchRange, 4779ba371819SOllivier Robert &bBoardOptions, 4780ba371819SOllivier Robert &iiSerialNumber, 4781ba371819SOllivier Robert &bBuildYear, 4782ba371819SOllivier Robert &bBuildMonth, 4783ba371819SOllivier Robert &bBuildDay, 4784ba371819SOllivier Robert &bBuildHour, 4785ba371819SOllivier Robert &fOscOffset, 4786ba371819SOllivier Robert &iTestCodeId)) 4787ba371819SOllivier Robert { 4788ba371819SOllivier Robert parsed = BADLEN_PARSE; 4789ba371819SOllivier Robert return; 4790ba371819SOllivier Robert } 4791ba371819SOllivier Robert 4792ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n search range: %d", 4793ba371819SOllivier Robert bSearchRange); 4794ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n board options: %d", 4795ba371819SOllivier Robert bBoardOptions); 4796ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n board serial #: %ld", 4797ba371819SOllivier Robert iiSerialNumber); 4798ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n build date/hour: %02d/%02d/%02d %02d:00", 4799ba371819SOllivier Robert bBuildDay, bBuildMonth, bBuildYear, bBuildHour); 4800ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n osc offset: %.3f PPM (%.0f Hz)", 4801ba371819SOllivier Robert fOscOffset/1575.42, fOscOffset); 4802ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n test code: %d", 4803ba371819SOllivier Robert iTestCodeId); 4804ba371819SOllivier Robert } 4805ba371819SOllivier Robert 4806ba371819SOllivier Robert /* 0x8F42 */ 48072b15cb3dSCy Schubert static void 48082b15cb3dSCy Schubert rpt_8F42( 48092b15cb3dSCy Schubert TSIPPKT *rpt 48102b15cb3dSCy Schubert ) 4811ba371819SOllivier Robert { 4812ba371819SOllivier Robert unsigned char 4813ba371819SOllivier Robert bProdOptionsPre, 4814ba371819SOllivier Robert bProdNumberExt; 4815ba371819SOllivier Robert unsigned short 4816ba371819SOllivier Robert iCaseSerialNumberPre, 4817ba371819SOllivier Robert iPremiumOptions, 4818ba371819SOllivier Robert iMachineID, 4819ba371819SOllivier Robert iKey; 4820ba371819SOllivier Robert unsigned long 4821ba371819SOllivier Robert iiCaseSerialNumber, 4822ba371819SOllivier Robert iiProdNumber; 4823ba371819SOllivier Robert 4824ba371819SOllivier Robert if (!rpt_0x8F42(rpt, 4825ba371819SOllivier Robert &bProdOptionsPre, 4826ba371819SOllivier Robert &bProdNumberExt, 4827ba371819SOllivier Robert &iCaseSerialNumberPre, 4828ba371819SOllivier Robert &iiCaseSerialNumber, 4829ba371819SOllivier Robert &iiProdNumber, 4830ba371819SOllivier Robert &iPremiumOptions, 4831ba371819SOllivier Robert &iMachineID, 4832ba371819SOllivier Robert &iKey)) 4833ba371819SOllivier Robert { 4834ba371819SOllivier Robert parsed = BADLEN_PARSE; 4835ba371819SOllivier Robert return; 4836ba371819SOllivier Robert } 4837ba371819SOllivier Robert 4838ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nProduct ID 8F42"); 4839ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n extension: %d", bProdNumberExt); 4840ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n case serial # prefix: %d", iCaseSerialNumberPre); 4841ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n case serial #: %ld", iiCaseSerialNumber); 4842ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n prod. #: %ld", iiProdNumber); 4843ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n premium options: %Xh", iPremiumOptions); 4844ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n machine ID: %d", iMachineID); 4845ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n key: %Xh", iKey); 4846ba371819SOllivier Robert } 4847ba371819SOllivier Robert 4848ba371819SOllivier Robert /* 0x8F45 */ 48492b15cb3dSCy Schubert static void 48502b15cb3dSCy Schubert rpt_8F45( 48512b15cb3dSCy Schubert TSIPPKT *rpt 48522b15cb3dSCy Schubert ) 4853ba371819SOllivier Robert { 4854ba371819SOllivier Robert unsigned char bSegMask; 4855ba371819SOllivier Robert 4856ba371819SOllivier Robert if (!rpt_0x8F45(rpt, 4857ba371819SOllivier Robert &bSegMask)) 4858ba371819SOllivier Robert { 4859ba371819SOllivier Robert parsed = BADLEN_PARSE; 4860ba371819SOllivier Robert return; 4861ba371819SOllivier Robert } 4862ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nCleared Segment Mask: %Xh", bSegMask); 4863ba371819SOllivier Robert } 4864ba371819SOllivier Robert 4865ba371819SOllivier Robert /* Stinger PPS def */ 48662b15cb3dSCy Schubert static void 48672b15cb3dSCy Schubert rpt_8F4A( 48682b15cb3dSCy Schubert TSIPPKT *rpt 48692b15cb3dSCy Schubert ) 4870ba371819SOllivier Robert { 4871ba371819SOllivier Robert unsigned char 4872ba371819SOllivier Robert pps_enabled, 4873ba371819SOllivier Robert pps_timebase, 4874ba371819SOllivier Robert pps_polarity; 4875ba371819SOllivier Robert float 4876ba371819SOllivier Robert bias_unc_threshold; 4877ba371819SOllivier Robert double 4878ba371819SOllivier Robert pps_offset; 4879ba371819SOllivier Robert 4880ba371819SOllivier Robert if (rpt_0x8F4A_16 (rpt, 4881ba371819SOllivier Robert &pps_enabled, 4882ba371819SOllivier Robert &pps_timebase, 4883ba371819SOllivier Robert &pps_polarity, 4884ba371819SOllivier Robert &pps_offset, 4885ba371819SOllivier Robert &bias_unc_threshold)) 4886ba371819SOllivier Robert { 4887ba371819SOllivier Robert parsed = BADLEN_PARSE; 4888ba371819SOllivier Robert return; 4889ba371819SOllivier Robert } 4890ba371819SOllivier Robert 4891ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nPPS is %s", pps_enabled?"enabled":"disabled"); 4892ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n timebase: %s", PPSTimeBaseText[pps_timebase]); 4893ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n polarity: %s", PPSPolarityText[pps_polarity]); 4894ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n offset: %.1f ns, ", pps_offset*1.e9); 4895ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n biasunc: %.1f ns", bias_unc_threshold/GPS_C*1.e9); 4896ba371819SOllivier Robert } 4897ba371819SOllivier Robert 4898ba371819SOllivier Robert /* fast-SA decorrolation time for self-survey */ 48992b15cb3dSCy Schubert static void 49002b15cb3dSCy Schubert rpt_8F4B( 49012b15cb3dSCy Schubert TSIPPKT *rpt 49022b15cb3dSCy Schubert ) 4903ba371819SOllivier Robert { 4904ba371819SOllivier Robert unsigned long 4905ba371819SOllivier Robert decorr_max; 4906ba371819SOllivier Robert 4907ba371819SOllivier Robert if (rpt_0x8F4B(rpt, &decorr_max)) 4908ba371819SOllivier Robert { 4909ba371819SOllivier Robert parsed = BADLEN_PARSE; 4910ba371819SOllivier Robert return; 4911ba371819SOllivier Robert } 4912ba371819SOllivier Robert 4913ba371819SOllivier Robert pbuf += sprintf(pbuf, 4914ba371819SOllivier Robert "\nMax # of position fixes for self-survey : %ld", 4915ba371819SOllivier Robert decorr_max); 4916ba371819SOllivier Robert } 4917ba371819SOllivier Robert 49182b15cb3dSCy Schubert static void 49192b15cb3dSCy Schubert rpt_8F4D( 49202b15cb3dSCy Schubert TSIPPKT *rpt 49212b15cb3dSCy Schubert ) 4922ba371819SOllivier Robert { 4923ba371819SOllivier Robert static char 4924ba371819SOllivier Robert *linestart; 4925ba371819SOllivier Robert unsigned long 4926ba371819SOllivier Robert OutputMask; 4927ba371819SOllivier Robert static unsigned long 4928ba371819SOllivier Robert MaskBit[] = { 49292b15cb3dSCy Schubert 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 49302b15cb3dSCy Schubert 0x00000020, 4931ba371819SOllivier Robert 0x00000100L, 0x00000800L, 0x00001000L, 4932ba371819SOllivier Robert 0x40000000L, 0x80000000L}; 4933ba371819SOllivier Robert int 4934ba371819SOllivier Robert ichoice, 4935ba371819SOllivier Robert numchoices; 4936ba371819SOllivier Robert 4937ba371819SOllivier Robert if (rpt_0x8F4D(rpt, &OutputMask)) 4938ba371819SOllivier Robert { 4939ba371819SOllivier Robert parsed = BADLEN_PARSE; 4940ba371819SOllivier Robert return; 4941ba371819SOllivier Robert } 4942ba371819SOllivier Robert 4943ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nAuto-Report Mask: %02X %02X %02X %02X", 4944ba371819SOllivier Robert (unsigned char)(OutputMask>>24), 4945ba371819SOllivier Robert (unsigned char)(OutputMask>>16), 4946ba371819SOllivier Robert (unsigned char)(OutputMask>>8), 4947ba371819SOllivier Robert (unsigned char)OutputMask); 4948ba371819SOllivier Robert 4949ba371819SOllivier Robert numchoices = sizeof(MaskText)/sizeof(char*); 4950ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nAuto-Reports scheduled for Output:"); 4951ba371819SOllivier Robert linestart = pbuf; 4952ba371819SOllivier Robert for (ichoice = 0; ichoice < numchoices; ichoice++) 4953ba371819SOllivier Robert { 4954ba371819SOllivier Robert if (OutputMask&MaskBit[ichoice]) 4955ba371819SOllivier Robert { 4956ba371819SOllivier Robert pbuf += sprintf(pbuf, "%s %s", 4957ba371819SOllivier Robert (pbuf==linestart)?"\n ":",", 4958ba371819SOllivier Robert MaskText[ichoice]); 4959ba371819SOllivier Robert if (pbuf-linestart > 60) linestart = pbuf; 4960ba371819SOllivier Robert } 4961ba371819SOllivier Robert } 4962ba371819SOllivier Robert 4963ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nAuto-Reports NOT scheduled for Output:"); 4964ba371819SOllivier Robert linestart = pbuf; 4965ba371819SOllivier Robert for (ichoice = 0; ichoice < numchoices; ichoice++) 4966ba371819SOllivier Robert { 4967ba371819SOllivier Robert if (OutputMask&MaskBit[ichoice]) continue; 4968ba371819SOllivier Robert pbuf += sprintf(pbuf, "%s %s", 4969ba371819SOllivier Robert (pbuf==linestart)?"\n ":",", 4970ba371819SOllivier Robert MaskText[ichoice]); 4971ba371819SOllivier Robert if (pbuf-linestart > 60) linestart = pbuf; 4972ba371819SOllivier Robert } 4973ba371819SOllivier Robert } 4974ba371819SOllivier Robert 49752b15cb3dSCy Schubert static void 49762b15cb3dSCy Schubert rpt_8FA5( 49772b15cb3dSCy Schubert TSIPPKT *rpt 49782b15cb3dSCy Schubert ) 4979ba371819SOllivier Robert { 4980ba371819SOllivier Robert unsigned char 4981ba371819SOllivier Robert spktmask[4]; 4982ba371819SOllivier Robert 4983ba371819SOllivier Robert if (rpt_0x8FA5(rpt, spktmask)) 4984ba371819SOllivier Robert { 4985ba371819SOllivier Robert parsed = BADLEN_PARSE; 4986ba371819SOllivier Robert return; 4987ba371819SOllivier Robert } 4988ba371819SOllivier Robert 4989ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nSuperpacket auto-output mask: %02X %02X %02X %02X", 4990ba371819SOllivier Robert spktmask[0], spktmask[1], spktmask[2], spktmask[3]); 4991ba371819SOllivier Robert 4992ba371819SOllivier Robert if (spktmask[0]&0x01) pbuf+= sprintf (pbuf, "\n PPS 8F-0B"); 4993ba371819SOllivier Robert if (spktmask[0]&0x02) pbuf+= sprintf (pbuf, "\n Event 8F-0B"); 4994ba371819SOllivier Robert if (spktmask[0]&0x10) pbuf+= sprintf (pbuf, "\n PPS 8F-AD"); 4995ba371819SOllivier Robert if (spktmask[0]&0x20) pbuf+= sprintf (pbuf, "\n Event 8F-AD"); 4996ba371819SOllivier Robert if (spktmask[2]&0x01) pbuf+= sprintf (pbuf, "\n ppos Fix 8F-20"); 4997ba371819SOllivier Robert } 4998ba371819SOllivier Robert 49992b15cb3dSCy Schubert static void 50002b15cb3dSCy Schubert rpt_8FAD( 50012b15cb3dSCy Schubert TSIPPKT *rpt 50022b15cb3dSCy Schubert ) 5003ba371819SOllivier Robert { 5004ba371819SOllivier Robert unsigned short 5005ba371819SOllivier Robert Count, 5006ba371819SOllivier Robert Year; 5007ba371819SOllivier Robert double 5008ba371819SOllivier Robert FracSec; 5009ba371819SOllivier Robert unsigned char 5010ba371819SOllivier Robert Hour, 5011ba371819SOllivier Robert Minute, 5012ba371819SOllivier Robert Second, 5013ba371819SOllivier Robert Day, 5014ba371819SOllivier Robert Month, 5015ba371819SOllivier Robert Status, 5016ba371819SOllivier Robert Flags; 5017ba371819SOllivier Robert static char* Status8FADText[] = { 5018ba371819SOllivier Robert "CODE_DOING_FIXES", 5019ba371819SOllivier Robert "CODE_GOOD_1_SV", 5020ba371819SOllivier Robert "CODE_APPX_1SV", 5021ba371819SOllivier Robert "CODE_NEED_TIME", 5022ba371819SOllivier Robert "CODE_NEED_INITIALIZATION", 5023ba371819SOllivier Robert "CODE_PDOP_HIGH", 5024ba371819SOllivier Robert "CODE_BAD_1SV", 5025ba371819SOllivier Robert "CODE_0SVS", 5026ba371819SOllivier Robert "CODE_1SV", 5027ba371819SOllivier Robert "CODE_2SVS", 5028ba371819SOllivier Robert "CODE_3SVS", 5029ba371819SOllivier Robert "CODE_NO_INTEGRITY", 5030ba371819SOllivier Robert "CODE_DCORR_GEN", 5031ba371819SOllivier Robert "CODE_OVERDET_CLK", 5032ba371819SOllivier Robert "Invalid Status"}, 5033ba371819SOllivier Robert *LeapStatusText[] = { 5034ba371819SOllivier Robert " UTC Avail", " ", " ", " ", 5035ba371819SOllivier Robert " Scheduled", " Pending", " Warning", " In Progress"}; 5036ba371819SOllivier Robert int i; 5037ba371819SOllivier Robert 5038ba371819SOllivier Robert if (rpt_0x8FAD (rpt, 5039ba371819SOllivier Robert &Count, 5040ba371819SOllivier Robert &FracSec, 5041ba371819SOllivier Robert &Hour, 5042ba371819SOllivier Robert &Minute, 5043ba371819SOllivier Robert &Second, 5044ba371819SOllivier Robert &Day, 5045ba371819SOllivier Robert &Month, 5046ba371819SOllivier Robert &Year, 5047ba371819SOllivier Robert &Status, 5048ba371819SOllivier Robert &Flags)) 5049ba371819SOllivier Robert { 5050ba371819SOllivier Robert parsed = BADLEN_PARSE; 5051ba371819SOllivier Robert return; 5052ba371819SOllivier Robert } 5053ba371819SOllivier Robert 5054ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n8FAD Count: %d Status: %s", 5055ba371819SOllivier Robert Count, Status8FADText[Status]); 5056ba371819SOllivier Robert 5057ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n Leap Flags:"); 5058ba371819SOllivier Robert if (Flags) 5059ba371819SOllivier Robert { 5060ba371819SOllivier Robert for (i=0; i<8; i++) 5061ba371819SOllivier Robert { 5062ba371819SOllivier Robert if (Flags&(1<<i)) pbuf += sprintf(pbuf, LeapStatusText[i]); 5063ba371819SOllivier Robert } 5064ba371819SOllivier Robert } 5065ba371819SOllivier Robert else 5066ba371819SOllivier Robert { 5067ba371819SOllivier Robert pbuf += sprintf(pbuf, " UTC info not available"); 5068ba371819SOllivier Robert } 5069ba371819SOllivier Robert 5070ba371819SOllivier Robert pbuf += sprintf(pbuf, "\n %02d/%02d/%04d (DMY) %02d:%02d:%02d.%09ld UTC", 5071ba371819SOllivier Robert Day, Month, Year, Hour, Minute, Second, (long)(FracSec*1.e9)); 5072ba371819SOllivier Robert } 5073ba371819SOllivier Robert 5074ba371819SOllivier Robert 50752b15cb3dSCy Schubert int 50762b15cb3dSCy Schubert print_msg_table_header( 50772b15cb3dSCy Schubert int rptcode, 50782b15cb3dSCy Schubert char *HdrStr, 50792b15cb3dSCy Schubert int force 50802b15cb3dSCy Schubert ) 5081ba371819SOllivier Robert { 5082ba371819SOllivier Robert /* force header is to help auto-output function */ 5083ba371819SOllivier Robert /* last_rptcode is to determine whether to print a header */ 50849c2daa00SOllivier Robert /* for the first occurrence of a series of reports */ 5085ba371819SOllivier Robert static int 5086ba371819SOllivier Robert last_rptcode = 0; 5087ba371819SOllivier Robert int 5088ba371819SOllivier Robert numchars; 5089ba371819SOllivier Robert 5090ba371819SOllivier Robert numchars = 0; 5091ba371819SOllivier Robert if (force || rptcode!=last_rptcode) 5092ba371819SOllivier Robert { 5093ba371819SOllivier Robert /* supply a header in console output */ 5094ba371819SOllivier Robert switch (rptcode) 5095ba371819SOllivier Robert { 5096ba371819SOllivier Robert case 0x5A: 5097ba371819SOllivier Robert numchars = sprintf(HdrStr, "\nRaw Measurement Data"); 5098ba371819SOllivier Robert numchars += sprintf(HdrStr+numchars, 5099ba371819SOllivier Robert "\n SV Sample SNR Code Phase Doppler Seconds Time of Meas"); 5100ba371819SOllivier Robert break; 5101ba371819SOllivier Robert 5102ba371819SOllivier Robert case 0x5B: 5103ba371819SOllivier Robert numchars = sprintf(HdrStr, "\nEphemeris Status"); 5104ba371819SOllivier Robert numchars += sprintf(HdrStr+numchars, 5105ba371819SOllivier Robert "\n SV Time collected Health IODE t oe Fit URA"); 5106ba371819SOllivier Robert break; 5107ba371819SOllivier Robert 5108ba371819SOllivier Robert case 0x5C: 5109ba371819SOllivier Robert numchars = sprintf(HdrStr, "\nTracking Info"); 5110ba371819SOllivier Robert numchars += sprintf(HdrStr+numchars, 5111ba371819SOllivier Robert "\n SV C Acq Eph SNR Time of Meas Elev Azim "); 5112ba371819SOllivier Robert break; 5113ba371819SOllivier Robert 5114ba371819SOllivier Robert } 5115ba371819SOllivier Robert } 5116ba371819SOllivier Robert last_rptcode = rptcode; 5117ba371819SOllivier Robert return (short)numchars; 5118ba371819SOllivier Robert } 5119ba371819SOllivier Robert 51202b15cb3dSCy Schubert static void 51212b15cb3dSCy Schubert unknown_rpt( 51222b15cb3dSCy Schubert TSIPPKT *rpt 51232b15cb3dSCy Schubert ) 5124ba371819SOllivier Robert { 5125ba371819SOllivier Robert int i; 5126ba371819SOllivier Robert 5127ba371819SOllivier Robert /* app-specific rpt packets */ 5128ba371819SOllivier Robert if (parsed == BADLEN_PARSE) 5129ba371819SOllivier Robert { 5130ba371819SOllivier Robert pbuf += sprintf(pbuf, "\nTSIP report packet ID %2Xh, length %d: Bad length", 5131ba371819SOllivier Robert rpt->code, rpt->len); 5132ba371819SOllivier Robert } 5133ba371819SOllivier Robert if (parsed == BADID_PARSE) 5134ba371819SOllivier Robert { 5135ba371819SOllivier Robert pbuf += sprintf(pbuf, 5136ba371819SOllivier Robert "\nTSIP report packet ID %2Xh, length %d: translation not supported", 5137ba371819SOllivier Robert rpt->code, rpt->len); 5138ba371819SOllivier Robert } 5139ba371819SOllivier Robert 5140ba371819SOllivier Robert if (parsed == BADDATA_PARSE) 5141ba371819SOllivier Robert { 5142ba371819SOllivier Robert pbuf += sprintf(pbuf, 5143ba371819SOllivier Robert "\nTSIP report packet ID %2Xh, length %d: data content incorrect", 5144ba371819SOllivier Robert rpt->code, rpt->len); 5145ba371819SOllivier Robert } 5146ba371819SOllivier Robert 5147ba371819SOllivier Robert for (i = 0; i < rpt->len; i++) { 5148ba371819SOllivier Robert if ((i % 20) == 0) *pbuf++ = '\n'; 5149ba371819SOllivier Robert pbuf += sprintf(pbuf, " %02X", rpt->buf[i]); 5150ba371819SOllivier Robert } 5151ba371819SOllivier Robert } 5152ba371819SOllivier Robert /**/ 51532b15cb3dSCy Schubert 5154ba371819SOllivier Robert /* 5155ba371819SOllivier Robert ** main subroutine, called from ProcessInputBytesWhileWaitingForKBHit() 5156ba371819SOllivier Robert */ 51572b15cb3dSCy Schubert void 51582b15cb3dSCy Schubert TranslateTSIPReportToText( 51592b15cb3dSCy Schubert TSIPPKT *rpt, 51602b15cb3dSCy Schubert char *TextOutputBuffer 51612b15cb3dSCy Schubert ) 5162ba371819SOllivier Robert { 5163ba371819SOllivier Robert 5164ba371819SOllivier Robert /* pbuf is the pointer to the current location of the text output */ 5165ba371819SOllivier Robert pbuf = TextOutputBuffer; 5166ba371819SOllivier Robert 5167ba371819SOllivier Robert /* keep track of whether the message has been successfully parsed */ 5168ba371819SOllivier Robert parsed = GOOD_PARSE; 5169ba371819SOllivier Robert 5170ba371819SOllivier Robert /* print a header if this is the first of a series of messages */ 5171ba371819SOllivier Robert pbuf += print_msg_table_header (rpt->code, pbuf, FALSE); 5172ba371819SOllivier Robert 5173ba371819SOllivier Robert /* process incoming TSIP report according to code */ 5174ba371819SOllivier Robert switch (rpt->code) 5175ba371819SOllivier Robert { 5176ba371819SOllivier Robert case 0x3D: rpt_chan_A_config (rpt); break; 5177ba371819SOllivier Robert case 0x40: rpt_almanac_data_page (rpt); break; 5178ba371819SOllivier Robert case 0x41: rpt_GPS_time (rpt); break; 5179ba371819SOllivier Robert case 0x42: rpt_single_ECEF_position (rpt); break; 5180ba371819SOllivier Robert case 0x43: rpt_single_ECEF_velocity (rpt); break; 5181ba371819SOllivier Robert case 0x45: rpt_SW_version (rpt); break; 5182ba371819SOllivier Robert case 0x46: rpt_rcvr_health (rpt); break; 5183ba371819SOllivier Robert case 0x47: rpt_SNR_all_SVs (rpt); break; 5184ba371819SOllivier Robert case 0x48: rpt_GPS_system_message (rpt); break; 5185ba371819SOllivier Robert case 0x49: rpt_almanac_health_page (rpt); break; 5186ba371819SOllivier Robert case 0x4A: switch (rpt->len) { 5187ba371819SOllivier Robert /* 5188ba371819SOllivier Robert ** special case (=slip-up) in the TSIP protocol; 5189ba371819SOllivier Robert ** parsing method depends on length 5190ba371819SOllivier Robert */ 5191ba371819SOllivier Robert case 20: rpt_single_lla_position (rpt); break; 5192ba371819SOllivier Robert case 9: rpt_ref_alt (rpt); break; 5193ba371819SOllivier Robert } break; 5194ba371819SOllivier Robert case 0x4B: rpt_rcvr_id_and_status (rpt);break; 5195ba371819SOllivier Robert case 0x4C: rpt_operating_parameters (rpt); break; 5196ba371819SOllivier Robert case 0x4D: rpt_oscillator_offset (rpt); break; 5197ba371819SOllivier Robert case 0x4E: rpt_GPS_time_set_response (rpt); break; 5198ba371819SOllivier Robert case 0x4F: rpt_UTC_offset (rpt); break; 5199ba371819SOllivier Robert case 0x54: rpt_1SV_bias (rpt); break; 5200ba371819SOllivier Robert case 0x55: rpt_io_opt (rpt); break; 5201ba371819SOllivier Robert case 0x56: rpt_ENU_velocity (rpt); break; 5202ba371819SOllivier Robert case 0x57: rpt_last_fix_info (rpt); break; 5203ba371819SOllivier Robert case 0x58: rpt_GPS_system_data (rpt); break; 5204ba371819SOllivier Robert case 0x59: rpt_SVs_enabled (rpt); break; 5205ba371819SOllivier Robert case 0x5A: rpt_raw_msmt (rpt); break; 5206ba371819SOllivier Robert case 0x5B: rpt_SV_ephemeris_status (rpt); break; 5207ba371819SOllivier Robert case 0x5C: rpt_SV_tracking_status (rpt); break; 5208ba371819SOllivier Robert case 0x6D: rpt_allSV_selection (rpt); break; 5209ba371819SOllivier Robert case 0x82: rpt_DGPS_position_mode (rpt); break; 5210ba371819SOllivier Robert case 0x83: rpt_double_ECEF_position (rpt); break; 5211ba371819SOllivier Robert case 0x84: rpt_double_lla_position (rpt); break; 5212ba371819SOllivier Robert case 0xBB: rpt_complete_rcvr_config (rpt); break; 5213ba371819SOllivier Robert case 0xBC: rpt_rcvr_serial_port_config (rpt); break; 5214ba371819SOllivier Robert 5215ba371819SOllivier Robert case 0x8F: switch (rpt->buf[0]) 5216ba371819SOllivier Robert { 5217ba371819SOllivier Robert /* superpackets; parsed according to subcodes */ 5218ba371819SOllivier Robert case 0x0B: rpt_8F0B(rpt); break; 5219ba371819SOllivier Robert case 0x14: rpt_8F14(rpt); break; 5220ba371819SOllivier Robert case 0x15: rpt_8F15(rpt); break; 5221ba371819SOllivier Robert case 0x20: rpt_8F20(rpt); break; 5222ba371819SOllivier Robert case 0x41: rpt_8F41(rpt); break; 5223ba371819SOllivier Robert case 0x42: rpt_8F42(rpt); break; 5224ba371819SOllivier Robert case 0x45: rpt_8F45(rpt); break; 5225ba371819SOllivier Robert case 0x4A: rpt_8F4A(rpt); break; 5226ba371819SOllivier Robert case 0x4B: rpt_8F4B(rpt); break; 5227ba371819SOllivier Robert case 0x4D: rpt_8F4D(rpt); break; 5228ba371819SOllivier Robert case 0xA5: rpt_8FA5(rpt); break; 5229ba371819SOllivier Robert case 0xAD: rpt_8FAD(rpt); break; 5230ba371819SOllivier Robert default: parsed = BADID_PARSE; break; 5231ba371819SOllivier Robert } 5232ba371819SOllivier Robert break; 5233ba371819SOllivier Robert 5234ba371819SOllivier Robert default: parsed = BADID_PARSE; break; 5235ba371819SOllivier Robert } 5236ba371819SOllivier Robert 5237ba371819SOllivier Robert if (parsed != GOOD_PARSE) 5238ba371819SOllivier Robert { 5239ba371819SOllivier Robert /* 5240ba371819SOllivier Robert **The message has TSIP structure (DLEs, etc.) 5241ba371819SOllivier Robert ** but could not be parsed by above routines 5242ba371819SOllivier Robert */ 5243ba371819SOllivier Robert unknown_rpt (rpt); 5244ba371819SOllivier Robert } 5245ba371819SOllivier Robert 5246ba371819SOllivier Robert /* close TextOutputBuffer */ 5247ba371819SOllivier Robert pbuf = '\0'; 5248ba371819SOllivier Robert } 5249ba371819SOllivier Robert 5250ba371819SOllivier Robert #endif /* TRIMBLE_OUTPUT_FUNC */ 5251ba371819SOllivier Robert 5252ba371819SOllivier Robert #else /* defined(REFCLOCK) && defined(CLOCK_RIPENCC) */ 5253*f5f40dd6SCy Schubert NONEMPTY_TRANSLATION_UNIT 5254ba371819SOllivier Robert #endif /* defined(REFCLOCK) && defined(CLOCK_RIPENCC) */ 5255ba371819SOllivier Robert 5256