📄 refclock_ripencc.c
字号:
/* * $Id: refclock_ripencc.c,v 1.13 2002/06/18 14:20:55 marks Exp marks $ * * Copyright (c) 2002 RIPE NCC * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of the author not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * * * This driver was developed for use with the RIPE NCC TTM project. * * * The initial driver was developed by Daniel Karrenberg <dfk@ripe.net> * using the code made available by Trimble. This was for xntpd-3.x.x * * Rewrite of the driver for ntpd-4.x.x by Mark Santcroos <marks@ripe.net> * */#ifdef HAVE_CONFIG_H#include <config.h>#endif /* HAVE_CONFIG_H */#if defined(REFCLOCK) && defined(CLOCK_RIPENCC)#include "ntp_stdlib.h"#include "ntpd.h"#include "ntp_refclock.h"#include "ntp_unixtime.h"#include "ntp_io.h"#ifdef HAVE_PPSAPI# include "ppsapi_timepps.h"#endif/* * Definitions *//* we are on little endian */#define BYTESWAP/* * DEBUG statements: uncomment if necessary *//* #define DEBUG_NCC */ /* general debug statements *//* #define DEBUG_PPS */ /* debug pps *//* #define DEBUG_RAW */ /* print raw packets */#define TRIMBLE_OUTPUT_FUNC#define TSIP_VERNUM "7.12a"#ifndef FALSE#define FALSE (0)#define TRUE (!FALSE)#endif /* FALSE */#define GPS_PI (3.1415926535898)#define GPS_C (299792458.)#define D2R (GPS_PI/180.0)#define R2D (180.0/GPS_PI)#define WEEK (604800.)#define MAXCHAN (8)/* control characters for TSIP packets */#define DLE (0x10)#define ETX (0x03)#define MAX_RPTBUF (256)/* values of TSIPPKT.status */#define TSIP_PARSED_EMPTY 0#define TSIP_PARSED_FULL 1#define TSIP_PARSED_DLE_1 2#define TSIP_PARSED_DATA 3#define TSIP_PARSED_DLE_2 4#define UTCF_UTC_AVAIL (unsigned char) (1) /* UTC available */#define UTCF_LEAP_SCHD (unsigned char) (1<<4) /* Leap scheduled */#define UTCF_LEAP_PNDG (unsigned char) (1<<5) /* Leap pending, will occur at end of day */#define DEVICE "/dev/gps%d" /* name of radio device */#define PRECISION (-9) /* precision assumed (about 2 ms) */#define PPS_PRECISION (-20) /* precision assumed (about 1 us) */#define REFID "GPS\0" /* reference id */#define REFID_LEN 4#define DESCRIPTION "RIPE NCC GPS (Palisade)" /* Description */#define SPEED232 B9600 /* 9600 baud */#define NSAMPLES 3 /* stages of median filter *//* Structures *//* TSIP packets have the following structure, whether report or command. */typedef struct { short counter, /* counter */ len; /* size of buf; < MAX_RPTBUF unsigned chars */ unsigned char status, /* TSIP packet format/parse status */ code, /* TSIP code */ buf[MAX_RPTBUF];/* report or command string */} TSIPPKT;/* TSIP binary data structures */typedef struct { unsigned char t_oa_raw, SV_health; float e, t_oa, i_0, OMEGADOT, sqrt_A, OMEGA_0, omega, M_0, a_f0, a_f1, Axis, n, OMEGA_n, ODOT_n, t_zc; short weeknum, wn_oa;} ALM_INFO;typedef struct { /* Almanac health page (25) parameters */ unsigned char WN_a, SV_health[32], t_oa;} ALH_PARMS;typedef struct { /* Universal Coordinated Time (UTC) parms */ double A_0; float A_1; short delta_t_LS; float t_ot; short WN_t, WN_LSF, DN, delta_t_LSF;} UTC_INFO;typedef struct { /* Ionospheric info (float) */ float alpha_0, alpha_1, alpha_2, alpha_3, beta_0, beta_1, beta_2, beta_3;} ION_INFO;typedef struct { /* Subframe 1 info (float) */ short weeknum; unsigned char codeL2, L2Pdata, SVacc_raw, SV_health; short IODC; float T_GD, t_oc, a_f2, a_f1, a_f0, SVacc;} EPHEM_CLOCK;typedef struct { /* Ephemeris info (float) */ unsigned char IODE, fit_interval; float C_rs, delta_n; double M_0; float C_uc; double e; float C_us; double sqrt_A; float t_oe, C_ic; double OMEGA_0; float C_is; double i_0; float C_rc; double omega; float OMEGADOT, IDOT; double Axis, n, r1me2, OMEGA_n, ODOT_n;} EPHEM_ORBIT;typedef struct { /* Navigation data structure */ short sv_number; /* SV number (0 = no entry) */ float t_ephem; /* time of ephemeris collection */ EPHEM_CLOCK ephclk; /* subframe 1 data */ EPHEM_ORBIT ephorb; /* ephemeris data */} NAV_INFO;typedef struct { unsigned char bSubcode, operating_mode, dgps_mode, dyn_code, trackmode; float elev_mask, cno_mask, dop_mask, dop_switch; unsigned char dgps_age_limit;} TSIP_RCVR_CFG;#ifdef TRIMBLE_OUTPUT_FUNCstatic char *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, old_baudnum[] = {0, 1, 4, 5, 6, 8, 9, 11, 28, 12}, *st_baud_text_app [] = {"", "", " 300", " 600", " 1200", " 2400", " 4800", " 9600", "19200", "38400"}, *old_parity_text[] = {"EVEN", "ODD", "", "", "NONE"}, *parity_text [] = {"NONE", "ODD", "EVEN"}, *old_input_ch[] = { "TSIP", "RTCM (6 of 8 bits)"}, *old_output_ch[] = { "TSIP", "No output", "", "", "", "NMEA 0183"}, *protocols_in_text[] = { "", "TSIP", "", ""}, *protocols_out_text[] = { "", "TSIP", "NMEA"}, *rcvr_port_text [] = { "Port A ", "Port B ", "Current Port"}, *dyn_text [] = {"Unchanged", "Land", "Sea", "Air", "Static"}, *NavModeText0xBB[] = {"automatic", "time only (0-D)", "", "2-D", "3-D", "", "", "OverDetermined Time"}, *PPSTimeBaseText[] = {"GPS", "UTC", "USER"}, *PPSPolarityText[] = {"Positive", "Negative"}, *MaskText[] = { "Almanac ", "Ephemeris", "UTC ", "Iono ", "GPS Msg ", "Alm Hlth ", "Time Fix ", "SV Select", "Ext Event", "Pos Fix ", "Raw Meas "};#endif /* TRIMBLE_OUTPUT_FUNC *//* * Unit control structure */struct ripencc_unit { int unit; /* unit number */ int pollcnt; /* poll message counter */ int polled; /* Hand in a sample? */ char leapdelta; /* delta of next leap event */ unsigned char utcflags; /* delta of next leap event */ l_fp tstamp; /* timestamp of last poll */ struct timespec ts; /* last timestamp */ pps_params_t pps_params; /* pps parameters */ pps_info_t pps_info; /* last pps data */ pps_handle_t handle; /* pps handlebars */};/******************* PROTOYPES *****************//* prototypes for report parsing primitives */short rpt_0x3D (TSIPPKT *rpt, unsigned char *tx_baud_index, unsigned char *rx_baud_index, unsigned char *char_format_index, unsigned char *stop_bits, unsigned char *tx_mode_index, unsigned char *rx_mode_index);short rpt_0x40 (TSIPPKT *rpt, unsigned char *sv_prn, short *week_num, float *t_zc, float *eccentricity, float *t_oa, float *i_0, float *OMEGA_dot, float *sqrt_A, float *OMEGA_0, float *omega, float *M_0);short rpt_0x41 (TSIPPKT *rpt, float *time_of_week, float *UTC_offset, short *week_num);short rpt_0x42 (TSIPPKT *rpt, float ECEF_pos[3], float *time_of_fix);short rpt_0x43 (TSIPPKT *rpt, float ECEF_vel[3], float *freq_offset, float *time_of_fix);short rpt_0x45 (TSIPPKT *rpt, unsigned char *major_nav_version, unsigned char *minor_nav_version, unsigned char *nav_day, unsigned char *nav_month, unsigned char *nav_year, unsigned char *major_dsp_version, unsigned char *minor_dsp_version, unsigned char *dsp_day, unsigned char *dsp_month, unsigned char *dsp_year);short rpt_0x46 (TSIPPKT *rpt, unsigned char *status1, unsigned char *status2);short rpt_0x47 (TSIPPKT *rpt, unsigned char *nsvs, unsigned char *sv_prn, float *snr);short rpt_0x48 (TSIPPKT *rpt, unsigned char *message);short rpt_0x49 (TSIPPKT *rpt, unsigned char *sv_health);short rpt_0x4A (TSIPPKT *rpt, float *lat, float *lon, float *alt, float *clock_bias, float *time_of_fix);short rpt_0x4A_2 (TSIPPKT *rpt, float *alt, float *dummy, unsigned char *alt_flag);short rpt_0x4B (TSIPPKT *rpt, unsigned char *machine_id, unsigned char *status3, unsigned char *status4);short rpt_0x4C (TSIPPKT *rpt, unsigned char *dyn_code, float *el_mask, float *snr_mask, float *dop_mask, float *dop_switch);short rpt_0x4D (TSIPPKT *rpt, float *osc_offset);short rpt_0x4E (TSIPPKT *rpt, unsigned char *response);short rpt_0x4F (TSIPPKT *rpt, double *a0, float *a1, float *time_of_data, short *dt_ls, short *wn_t, short *wn_lsf, short *dn, short *dt_lsf);short rpt_0x54 (TSIPPKT *rpt, float *clock_bias, float *freq_offset, float *time_of_fix);short rpt_0x55 (TSIPPKT *rpt, unsigned char *pos_code, unsigned char *vel_code, unsigned char *time_code, unsigned char *aux_code);short rpt_0x56 (TSIPPKT *rpt, float vel_ENU[3], float *freq_offset, float *time_of_fix);short rpt_0x57 (TSIPPKT *rpt, unsigned char *source_code, unsigned char *diag_code, short *week_num, float *time_of_fix);short rpt_0x58 (TSIPPKT *rpt, unsigned char *op_code, unsigned char *data_type, unsigned char *sv_prn, unsigned char *data_length, unsigned char *data_packet);short rpt_0x59 (TSIPPKT *rpt, unsigned char *code_type, unsigned char status_code[32]);short rpt_0x5A (TSIPPKT *rpt, unsigned char *sv_prn, float *sample_length, float *signal_level, float *code_phase, float *Doppler, double *time_of_fix);short rpt_0x5B (TSIPPKT *rpt, unsigned char *sv_prn, unsigned char *sv_health, unsigned char *sv_iode, unsigned char *fit_interval_flag, float *time_of_collection, float *time_of_eph, float *sv_accy);short rpt_0x5C (TSIPPKT *rpt, unsigned char *sv_prn, unsigned char *slot, unsigned char *chan, unsigned char *acq_flag, unsigned char *eph_flag, float *signal_level, float *time_of_last_msmt, float *elev, float *azim, unsigned char *old_msmt_flag, unsigned char *integer_msec_flag, unsigned char *bad_data_flag, unsigned char *data_collect_flag);short rpt_0x6D (TSIPPKT *rpt, unsigned char *manual_mode, unsigned char *nsvs, unsigned char *ndim, unsigned char sv_prn[], float *pdop, float *hdop, float *vdop, float *tdop);short rpt_0x82 (TSIPPKT *rpt, unsigned char *diff_mode);short rpt_0x83 (TSIPPKT *rpt, double ECEF_pos[3], double *clock_bias, float *time_of_fix);short rpt_0x84 (TSIPPKT *rpt, double *lat, double *lon, double *alt, double *clock_bias, float *time_of_fix);short rpt_Paly0xBB(TSIPPKT *rpt, TSIP_RCVR_CFG *TsipxBB);short rpt_0xBC (TSIPPKT *rpt, unsigned char *port_num, unsigned char *in_baud, unsigned char *out_baud, unsigned char *data_bits, unsigned char *parity, unsigned char *stop_bits, unsigned char *flow_control, unsigned char *protocols_in, unsigned char *protocols_out, unsigned char *reserved);/* prototypes for superpacket parsers */short rpt_0x8F0B (TSIPPKT *rpt, unsigned short *event, double *tow, unsigned char *date, unsigned char *month, short *year, unsigned char *dim_mode, short *utc_offset, double *bias, double *drift, float *bias_unc, float *dr_unc, double *lat, double *lon, double *alt, char sv_id[8]);short rpt_0x8F14 (TSIPPKT *rpt, short *datum_idx, double datum_coeffs[5]);short rpt_0x8F15 (TSIPPKT *rpt, short *datum_idx, double datum_coeffs[5]);short rpt_0x8F20 (TSIPPKT *rpt, unsigned char *info, double *lat, double *lon, double *alt, double vel_enu[], double *time_of_fix, short *week_num, unsigned char *nsvs, unsigned char sv_prn[], short sv_IODC[], short *datum_index);short rpt_0x8F41 (TSIPPKT *rpt, unsigned char *bSearchRange, unsigned char *bBoardOptions, unsigned long *iiSerialNumber, unsigned char *bBuildYear, unsigned char *bBuildMonth, unsigned char *bBuildDay, unsigned char *bBuildHour, float *fOscOffset, unsigned short *iTestCodeId);short rpt_0x8F42 (TSIPPKT *rpt, unsigned char *bProdOptionsPre, unsigned char *bProdNumberExt, unsigned short *iCaseSerialNumberPre, unsigned long *iiCaseSerialNumber, unsigned long *iiProdNumber, unsigned short *iPremiumOptions, unsigned short *iMachineID, unsigned short *iKey);short rpt_0x8F45 (TSIPPKT *rpt, unsigned char *bSegMask);short rpt_0x8F4A_16 (TSIPPKT *rpt, unsigned char *pps_enabled, unsigned char *pps_timebase, unsigned char *pos_polarity, double *pps_offset, float *bias_unc_threshold);short rpt_0x8F4B (TSIPPKT *rpt, unsigned long *decorr_max);short rpt_0x8F4D (TSIPPKT *rpt, unsigned long *event_mask);short rpt_0x8FA5 (TSIPPKT *rpt, unsigned char *spktmask);short rpt_0x8FAD (TSIPPKT *rpt, unsigned short *COUNT, double *FracSec, unsigned char *Hour, unsigned char *Minute, unsigned char *Second, unsigned char *Day, unsigned char *Month, unsigned short *Year, unsigned char *Status, unsigned char *Flags);/**//* prototypes for command-encode primitives with suffix convention: *//* c = clear, s = set, q = query, e = enable, d = disable */void cmd_0x1F (TSIPPKT *cmd);void cmd_0x26 (TSIPPKT *cmd);void cmd_0x2F (TSIPPKT *cmd);void cmd_0x35s (TSIPPKT *cmd, unsigned char pos_code, unsigned char vel_code, unsigned char time_code, unsigned char opts_code);void cmd_0x3C (TSIPPKT *cmd, unsigned char sv_prn);void cmd_0x3Ds (TSIPPKT *cmd, unsigned char baud_out, unsigned char baud_inp, unsigned char char_code, unsigned char stopbitcode, unsigned char output_mode, unsigned char input_mode);void cmd_0xBBq (TSIPPKT *cmd, unsigned char subcode) ;/* prototypes 8E commands */void cmd_0x8E0Bq (TSIPPKT *cmd);void cmd_0x8E41q (TSIPPKT *cmd);void cmd_0x8E42q (TSIPPKT *cmd);void cmd_0x8E4Aq (TSIPPKT *cmd);void cmd_0x8E4As (TSIPPKT *cmd, unsigned char PPSOnOff, unsigned char TimeBase, unsigned char Polarity, double PPSOffset, float Uncertainty);void cmd_0x8E4Bq (TSIPPKT *cmd);void cmd_0x8E4Ds (TSIPPKT *cmd, unsigned long AutoOutputMask);void cmd_0x8EADq (TSIPPKT *cmd);/* header/source border XXXXXXXXXXXXXXXXXXXXXXXXXX *//* Trimble parse functions */static int parse0x8FAD P((TSIPPKT *, struct peer *));static int parse0x8F0B P((TSIPPKT *, struct peer *));#ifdef TRIMBLE_OUTPUT_FUNCstatic int parseany P((TSIPPKT *, struct peer *));static void TranslateTSIPReportToText P((TSIPPKT *, char *));#endif /* TRIMBLE_OUTPUT_FUNC */static int parse0x5C P((TSIPPKT *, struct peer *));static int parse0x4F P((TSIPPKT *, struct peer *));static void tsip_input_proc P((TSIPPKT *, int));/* Trimble helper functions */static void bPutFloat P((float *, unsigned char *));static void bPutDouble P((double *, unsigned char *));static void bPutULong P((unsigned long *, unsigned char *));static int print_msg_table_header P((int rptcode, char *HdrStr, int force));static char * show_time P((float time_of_week));/* RIPE NCC functions */static void ripencc_control P((int, struct refclockstat *, struct refclockstat *, struct peer *));static int ripencc_ppsapi P((struct peer *, int, int));static int ripencc_get_pps_ts P((struct ripencc_unit *, l_fp *));static int ripencc_start P((int, struct peer *));static void ripencc_shutdown P((int, struct peer *));static void ripencc_poll P((int, struct peer *));static void ripencc_send P((struct peer *, TSIPPKT spt));static void ripencc_receive P((struct recvbuf *));/* fill in reflock structure for our clock */struct refclock refclock_ripencc = { ripencc_start, /* start up driver */ ripencc_shutdown, /* shut down driver */ ripencc_poll, /* transmit poll message */ ripencc_control, /* control function */ noentry, /* initialize driver */ noentry, /* debug info */ NOFLAGS /* clock flags */};/* * Tables to compute the ddd of year form icky dd/mm timecode. Viva la * leap. */static int day1tab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};static int day2tab[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};/* * ripencc_start - open the GPS devices and initialize data for processing */static intripencc_start(int unit, struct peer *peer){ register struct ripencc_unit *up; struct refclockproc *pp; char device[40]; int fd; struct termios tio; TSIPPKT spt; /* * Open serial port */ (void)snprintf(device, sizeof(device), DEVICE, unit); if (!(fd = refclock_open(device, SPEED232, LDISC_RAW))) return (0); /* from refclock_palisade.c */ if (tcgetattr(fd, &tio) < 0) { msyslog(LOG_ERR, "Palisade(%d) tcgetattr(fd, &tio): %m",unit); return (0); } /* * set flags */ tio.c_cflag |= (PARENB|PARODD); tio.c_iflag &= ~ICRNL; if (tcsetattr(fd, TCSANOW, &tio) == -1) { msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit); return (0); } /* * Allocate and initialize unit structure */ if (!(up = (struct ripencc_unit *) emalloc(sizeof(struct ripencc_unit)))) { (void) close(fd); return (0); } memset((char *)up, 0, sizeof(struct ripencc_unit)); pp = peer->procptr; pp->io.clock_recv = ripencc_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { (void) close(fd); free(up); return (0); } pp->unitptr = (caddr_t)up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, REFID_LEN); up->pollcnt = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -