diff options
author | delphij <delphij@FreeBSD.org> | 2015-07-15 19:21:26 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2015-07-15 19:21:26 +0000 |
commit | 2a25cee78ab1d37e7d2bc40ae675646974d99f56 (patch) | |
tree | b0302ac4be59e104f4e1e54014561a1389397192 /contrib/ntp/ntpd/refclock_parse.c | |
parent | a0741a75537b2e0514472ac3b28afc55a7846c30 (diff) | |
download | FreeBSD-src-2a25cee78ab1d37e7d2bc40ae675646974d99f56.zip FreeBSD-src-2a25cee78ab1d37e7d2bc40ae675646974d99f56.tar.gz |
MFC r280849,280915-280916,281015-281016,282097,282408,282415,283542,
284864,285169-285170,285435:
ntp 4.2.8p3.
Relnotes: yes
Approved by: re (?)
Diffstat (limited to 'contrib/ntp/ntpd/refclock_parse.c')
-rw-r--r-- | contrib/ntp/ntpd/refclock_parse.c | 1717 |
1 files changed, 944 insertions, 773 deletions
diff --git a/contrib/ntp/ntpd/refclock_parse.c b/contrib/ntp/ntpd/refclock_parse.c index 0b0109c..147a462 100644 --- a/contrib/ntp/ntpd/refclock_parse.c +++ b/contrib/ntp/ntpd/refclock_parse.c @@ -1,7 +1,7 @@ /* - * /src/NTP/REPOSITORY/ntp4-dev/ntpd/refclock_parse.c,v 4.80 2007/08/11 12:06:29 kardel Exp + * /src/NTP/REPOSITORY/ntp4-dev/ntpd/refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A * - * refclock_parse.c,v 4.80 2007/08/11 12:06:29 kardel Exp + * refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A * * generic reference clock driver for several DCF/GPS/MSF/... receivers * @@ -15,8 +15,8 @@ * Currently the STREAMS module is only available for Suns running * SunOS 4.x and SunOS5.x. * - * Copyright (c) 1995-2007 by Frank Kardel <kardel <AT> ntp.org> - * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany + * Copyright (c) 1995-2015 by Frank Kardel <kardel <AT> ntp.org> + * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -48,40 +48,42 @@ # include "config.h" #endif +#include "ntp_types.h" + #if defined(REFCLOCK) && defined(CLOCK_PARSE) /* * This driver currently provides the support for - * - Meinberg receiver DCF77 PZF 535 (TCXO version) (DCF) - * - Meinberg receiver DCF77 PZF 535 (OCXO version) (DCF) - * - Meinberg receiver DCF77 PZF 509 (DCF) + * - Meinberg receiver DCF77 PZF535 (TCXO version) (DCF) + * - Meinberg receiver DCF77 PZF535 (OCXO version) (DCF) + * - Meinberg receiver DCF77 PZF509 (DCF) * - Meinberg receiver DCF77 AM receivers (e.g. C51) (DCF) * - IGEL CLOCK (DCF) * - ELV DCF7000 (DCF) * - Schmid clock (DCF) * - Conrad DCF77 receiver module (DCF) * - FAU DCF77 NTP receiver (TimeBrick) (DCF) - * - WHARTON 400A Series clock (DCF) + * - WHARTON 400A Series clock (DCF) * - * - Meinberg GPS166/GPS167 (GPS) + * - Meinberg GPS receivers (GPS) * - Trimble (TSIP and TAIP protocol) (GPS) * * - RCC8000 MSF Receiver (MSF) - * - VARITEXT clock (MSF) + * - VARITEXT clock (MSF) */ /* * Meinberg receivers are usually connected via a - * 9600 baud serial line + * 9600/7E1 or 19200/8N1 serial line. * * The Meinberg GPS receivers also have a special NTP time stamp * format. The firmware release is Uni-Erlangen. * * Meinberg generic receiver setup: - * output time code every second - * Baud rate 9600 7E2S + * output time code every second + * Baud rate 9600 7E2S * - * Meinberg GPS16x setup: + * Meinberg GPS receiver setup: * output time code every second * Baudrate 19200 8N1 * @@ -89,14 +91,16 @@ * in Meinberg receivers. * * Special software versions are only sensible for the - * GPS 16x family of receivers. + * oldest GPS receiver, GPS16x. For newer receiver types + * the output string format can be configured at the device, + * and the device name is generally GPSxxx instead of GPS16x. * * Meinberg can be reached via: http://www.meinberg.de/ */ #include "ntpd.h" #include "ntp_refclock.h" -#include "ntp_unixtime.h" /* includes <sys/time.h> */ +#include "timevalops.h" /* includes <sys/time.h> */ #include "ntp_control.h" #include "ntp_string.h" @@ -120,6 +124,7 @@ #endif #ifdef HAVE_TERMIOS +# include <termios.h> # define TTY_GETATTR(_FD_, _ARG_) tcgetattr((_FD_), (_ARG_)) # define TTY_SETATTR(_FD_, _ARG_) tcsetattr((_FD_), TCSANOW, (_ARG_)) # undef HAVE_SYSV_TTYS @@ -141,6 +146,7 @@ #ifdef HAVE_PPSAPI # include "ppsapi_timepps.h" +# include "refclock_atom.h" #endif #ifdef PPS @@ -152,13 +158,13 @@ # endif #endif -#define BUFFER_SIZE(_BUF, _PTR) ((_BUF) + sizeof(_BUF) - (_PTR)) -#define BUFFER_SIZES(_BUF, _PTR, _SZ) ((_BUF) + (_SZ) - (_PTR)) +# define BUFFER_SIZE(_BUF, _PTR) ((int)((_BUF) + sizeof(_BUF) - (_PTR))) +# define BUFFER_SIZES(_BUF, _PTR, _SZ) ((int)((_BUF) + (_SZ) - (_PTR))) /* * document type of PPS interfacing - copy of ifdef mechanism in local_input() */ -#undef PPS_METHOD +#undef PPS_METHOD #ifdef HAVE_PPSAPI #define PPS_METHOD "PPS API" @@ -177,6 +183,18 @@ #endif /* TIOCDCDTIMESTAMP */ #endif /* HAVE_PPSAPI */ +/* + * COND_DEF can be conditionally defined as DEF or 0. If defined as DEF + * then some more parse-specific variables are flagged to be printed with + * "ntpq -c cv <assid>". This can be lengthy, so by default COND_DEF + * should be defined as 0. + */ +#if 0 +# define COND_DEF DEF // enable this for testing +#else +# define COND_DEF 0 // enable this by default +#endif + #include "ntp_io.h" #include "ntp_stdlib.h" @@ -188,16 +206,16 @@ #include "ieee754io.h" #include "recvbuff.h" -static char rcsid[] = "refclock_parse.c,v 4.80 2007/08/11 12:06:29 kardel Exp"; +static char rcsid[] = "refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A+POWERUPTRUST"; /**=========================================================================== ** external interface to ntp mechanism **/ -static int parse_start P((int, struct peer *)); -static void parse_shutdown P((int, struct peer *)); -static void parse_poll P((int, struct peer *)); -static void parse_control P((int, struct refclockstat *, struct refclockstat *, struct peer *)); +static int parse_start (int, struct peer *); +static void parse_shutdown (int, struct peer *); +static void parse_poll (int, struct peer *); +static void parse_control (int, const struct refclockstat *, struct refclockstat *, struct peer *); struct refclock refclock_parse = { parse_start, @@ -231,16 +249,16 @@ struct parseunit; /* to keep inquiring minds happy */ typedef struct bind { const char *bd_description; /* name of type of binding */ - int (*bd_init) P((struct parseunit *)); /* initialize */ - void (*bd_end) P((struct parseunit *)); /* end */ - int (*bd_setcs) P((struct parseunit *, parsectl_t *)); /* set character size */ - int (*bd_disable) P((struct parseunit *)); /* disable */ - int (*bd_enable) P((struct parseunit *)); /* enable */ - int (*bd_getfmt) P((struct parseunit *, parsectl_t *)); /* get format */ - int (*bd_setfmt) P((struct parseunit *, parsectl_t *)); /* setfmt */ - int (*bd_timecode) P((struct parseunit *, parsectl_t *)); /* get time code */ - void (*bd_receive) P((struct recvbuf *)); /* receive operation */ - int (*bd_io_input) P((struct recvbuf *)); /* input operation */ + int (*bd_init) (struct parseunit *); /* initialize */ + void (*bd_end) (struct parseunit *); /* end */ + int (*bd_setcs) (struct parseunit *, parsectl_t *); /* set character size */ + int (*bd_disable) (struct parseunit *); /* disable */ + int (*bd_enable) (struct parseunit *); /* enable */ + int (*bd_getfmt) (struct parseunit *, parsectl_t *); /* get format */ + int (*bd_setfmt) (struct parseunit *, parsectl_t *); /* setfmt */ + int (*bd_timecode) (struct parseunit *, parsectl_t *); /* get time code */ + void (*bd_receive) (struct recvbuf *); /* receive operation */ + int (*bd_io_input) (struct recvbuf *); /* input operation */ } bind_t; #define PARSE_END(_X_) (*(_X_)->binding->bd_end)(_X_) @@ -252,12 +270,11 @@ typedef struct bind #define PARSE_GETTIMECODE(_X_, _DCT_) (*(_X_)->binding->bd_timecode)(_X_, _DCT_) /* - * io modes + * special handling flags */ -#define PARSE_F_PPSPPS 0x0001 /* use loopfilter PPS code (CIOGETEV) */ -#define PARSE_F_PPSONSECOND 0x0002 /* PPS pulses are on second */ - - +#define PARSE_F_PPSONSECOND 0x00000001 /* PPS pulses are on second */ +#define PARSE_F_POWERUPTRUST 0x00000100 /* POWERUP state ist trusted for */ + /* trusttime after SYNC was seen */ /**=========================================================================== ** error message regression handling ** @@ -379,7 +396,7 @@ struct parseunit * PARSE io */ bind_t *binding; /* io handling binding */ - + /* * parse state */ @@ -405,9 +422,8 @@ struct parseunit u_long ppsserial; /* magic cookie for ppsclock serials (avoids stale ppsclock data) */ int ppsfd; /* fd to ise for PPS io */ #ifdef HAVE_PPSAPI - pps_handle_t ppshandle; /* store PPSAPI handle */ - pps_params_t ppsparams; /* current PPS parameters */ int hardppsstate; /* current hard pps state */ + struct refclock_atom atom; /* PPSAPI structure */ #endif parsetime_t timedata; /* last (parse module) data */ void *localdata; /* optional local, receiver-specific data */ @@ -423,9 +439,9 @@ struct parseunit ** includes NTP parameters, TTY parameters and IO handling parameters **/ -static void poll_dpoll P((struct parseunit *)); -static void poll_poll P((struct peer *)); -static int poll_init P((struct parseunit *)); +static void poll_dpoll (struct parseunit *); +static void poll_poll (struct peer *); +static int poll_init (struct parseunit *); typedef struct poll_info { @@ -448,23 +464,23 @@ typedef struct poll_info #define DCF_P_ID "DCFp" /* psuedo random phase shift */ #define GPS_ID "GPS" /* GPS receiver */ -#define NOCLOCK_ROOTDELAY 0.0 -#define NOCLOCK_BASEDELAY 0.0 -#define NOCLOCK_DESCRIPTION 0 +#define NOCLOCK_ROOTDELAY 0.0 +#define NOCLOCK_BASEDELAY 0.0 +#define NOCLOCK_DESCRIPTION 0 #define NOCLOCK_MAXUNSYNC 0 #define NOCLOCK_CFLAG 0 #define NOCLOCK_IFLAG 0 #define NOCLOCK_OFLAG 0 #define NOCLOCK_LFLAG 0 -#define NOCLOCK_ID "TILT" -#define NOCLOCK_POLL NO_POLL -#define NOCLOCK_INIT NO_INIT -#define NOCLOCK_END NO_END -#define NOCLOCK_DATA NO_LCLDATA -#define NOCLOCK_FORMAT "" -#define NOCLOCK_TYPE CTL_SST_TS_UNSPEC -#define NOCLOCK_SAMPLES 0 -#define NOCLOCK_KEEP 0 +#define NOCLOCK_ID "TILT" +#define NOCLOCK_POLL NO_POLL +#define NOCLOCK_INIT NO_INIT +#define NOCLOCK_END NO_END +#define NOCLOCK_DATA NO_LCLDATA +#define NOCLOCK_FORMAT "" +#define NOCLOCK_TYPE CTL_SST_TS_UNSPEC +#define NOCLOCK_SAMPLES 0 +#define NOCLOCK_KEEP 0 #define DCF_TYPE CTL_SST_TS_LF #define GPS_TYPE CTL_SST_TS_UHF @@ -534,14 +550,14 @@ typedef struct poll_info #define DCFPZF535OCXO_FORMAT "Meinberg Standard" /* - * Meinberg GPS16X receiver + * Meinberg GPS receivers */ -static void gps16x_message P((struct parseunit *, parsetime_t *)); -static int gps16x_poll_init P((struct parseunit *)); +static void gps16x_message (struct parseunit *, parsetime_t *); +static int gps16x_poll_init (struct parseunit *); #define GPS16X_ROOTDELAY 0.0 /* nothing here */ #define GPS16X_BASEDELAY 0.001968 /* XXX to be fixed ! 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */ -#define GPS16X_DESCRIPTION "Meinberg GPS16x receiver" +#define GPS16X_DESCRIPTION "Meinberg GPS receiver" #define GPS16X_MAXUNSYNC 60*60*96 /* only trust clock for 4 days * @ 5e-9df/f we have accumulated * at most an error of 1.73 ms @@ -677,16 +693,18 @@ static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE }; * RAWDCF receivers that need to be powered from DTR * (like Expert mouse clock) */ -static int rawdcf_init_1 P((struct parseunit *)); +static int rawdcf_init_1 (struct parseunit *); #define RAWDCFDTRSET_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR)" +#define RAWDCFDTRSET75_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR @ 75 baud)" #define RAWDCFDTRSET_INIT rawdcf_init_1 /* * RAWDCF receivers that need to be powered from * DTR CLR and RTS SET */ -static int rawdcf_init_2 P((struct parseunit *)); +static int rawdcf_init_2 (struct parseunit *); #define RAWDCFDTRCLRRTSSET_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET)" +#define RAWDCFDTRCLRRTSSET75_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET @ 75 baud)" #define RAWDCFDTRCLRRTSSET_INIT rawdcf_init_2 /* @@ -700,17 +718,17 @@ static int rawdcf_init_2 P((struct parseunit *)); #define TRIM_TAIPCMDSIZE (sizeof(TRIM_TAIPPOLLCMD)-1) static poll_info_t trimbletaip_pollinfo = { TRIM_POLLRATE, TRIM_TAIPPOLLCMD, TRIM_TAIPCMDSIZE }; -static int trimbletaip_init P((struct parseunit *)); -static void trimbletaip_event P((struct parseunit *, int)); +static int trimbletaip_init (struct parseunit *); +static void trimbletaip_event (struct parseunit *, int); /* query time & UTC correction data */ static char tsipquery[] = { DLE, 0x21, DLE, ETX, DLE, 0x2F, DLE, ETX }; static poll_info_t trimbletsip_pollinfo = { TRIM_POLLRATE, tsipquery, sizeof(tsipquery) }; -static int trimbletsip_init P((struct parseunit *)); -static void trimbletsip_end P((struct parseunit *)); -static void trimbletsip_message P((struct parseunit *, parsetime_t *)); -static void trimbletsip_event P((struct parseunit *, int)); +static int trimbletsip_init (struct parseunit *); +static void trimbletsip_end (struct parseunit *); +static void trimbletsip_message (struct parseunit *, parsetime_t *); +static void trimbletsip_event (struct parseunit *, int); #define TRIMBLETSIP_IDLE_TIME (300) /* 5 minutes silence at most */ #define TRIMBLE_RESET_HOLDOFF TRIMBLETSIP_IDLE_TIME @@ -741,9 +759,9 @@ static void trimbletsip_event P((struct parseunit *, int)); #define TRIMBLETAIP_INIT trimbletaip_init #define TRIMBLETSIP_INIT trimbletsip_init -#define TRIMBLETAIP_EVENT trimbletaip_event +#define TRIMBLETAIP_EVENT trimbletaip_event -#define TRIMBLETSIP_EVENT trimbletsip_event +#define TRIMBLETSIP_EVENT trimbletsip_event #define TRIMBLETSIP_MESSAGE trimbletsip_message #define TRIMBLETAIP_END 0 @@ -800,7 +818,7 @@ static poll_info_t rcc8000_pollinfo = { RCC_POLLRATE, RCC_POLLCMD, RCC_CMDSIZE } #define RCC8000_KEEP 3 /* - * Hopf Radio clock 6021 Format + * Hopf Radio clock 6021 Format * */ #define HOPF6021_ROOTDELAY 0.0 @@ -855,14 +873,43 @@ static poll_info_t rcc8000_pollinfo = { RCC_POLLRATE, RCC_POLLCMD, RCC_CMDSIZE } #define VARITEXT_SAMPLES 32 #define VARITEXT_KEEP 20 +/* + * SEL240x Satellite Sychronized Clock + */ +#define SEL240X_POLLRATE 0 /* only true direct polling */ +#define SEL240X_POLLCMD "BUB8" +#define SEL240X_CMDSIZE 4 + +static poll_info_t sel240x_pollinfo = { SEL240X_POLLRATE, + SEL240X_POLLCMD, + SEL240X_CMDSIZE }; +#define SEL240X_FLAGS (PARSE_F_PPSONSECOND) +#define SEL240X_POLL poll_dpoll +#define SEL240X_INIT poll_init +#define SEL240X_END 0 +#define SEL240X_DATA ((void *)(&sel240x_pollinfo)) +#define SEL240X_ROOTDELAY 0.0 +#define SEL240X_BASEDELAY 0.0 +#define SEL240X_ID GPS_ID +#define SEL240X_DESCRIPTION "SEL240x Satellite Synchronized Clock" +#define SEL240X_FORMAT "SEL B8" +#define SEL240X_MAXUNSYNC 60*60*12 /* only trust clock for 12 hours */ +#define SEL240X_SPEED (B9600) +#define SEL240X_CFLAG (CS8|CREAD|CLOCAL) +#define SEL240X_IFLAG (IGNBRK|IGNPAR) +#define SEL240X_OFLAG (0) +#define SEL240X_LFLAG (0) +#define SEL240X_SAMPLES 5 +#define SEL240X_KEEP 3 + static struct parse_clockinfo { - u_long cl_flags; /* operation flags (io modes) */ - void (*cl_poll) P((struct parseunit *)); /* active poll routine */ - int (*cl_init) P((struct parseunit *)); /* active poll init routine */ - void (*cl_event) P((struct parseunit *, int)); /* special event handling (e.g. reset clock) */ - void (*cl_end) P((struct parseunit *)); /* active poll end routine */ - void (*cl_message) P((struct parseunit *, parsetime_t *)); /* process a lower layer message */ + u_long cl_flags; /* operation flags (PPS interpretation, trust handling) */ + void (*cl_poll) (struct parseunit *); /* active poll routine */ + int (*cl_init) (struct parseunit *); /* active poll init routine */ + void (*cl_event) (struct parseunit *, int); /* special event handling (e.g. reset clock) */ + void (*cl_end) (struct parseunit *); /* active poll end routine */ + void (*cl_message) (struct parseunit *, parsetime_t *); /* process a lower layer message */ void *cl_data; /* local data area for "poll" mechanism */ double cl_rootdelay; /* rootdelay */ double cl_basedelay; /* current offset by which the RS232 @@ -1167,7 +1214,7 @@ static struct parse_clockinfo }, { /* mode 12 */ HOPF6021_FLAGS, - NO_POLL, + NO_POLL, NO_INIT, NO_EVENT, NO_END, @@ -1351,6 +1398,122 @@ static struct parse_clockinfo RAWDCF_SAMPLES, RAWDCF_KEEP }, + { /* mode 20, like mode 14 but driven by 75 baud */ + RAWDCF_FLAGS, + NO_POLL, + RAWDCFDTRSET_INIT, + NO_EVENT, + NO_END, + NO_MESSAGE, + NO_LCLDATA, + RAWDCF_ROOTDELAY, + RAWDCF_BASEDELAY, + DCF_A_ID, + RAWDCFDTRSET75_DESCRIPTION, + RAWDCF_FORMAT, + DCF_TYPE, + RAWDCF_MAXUNSYNC, + B75, + RAWDCF_CFLAG, + RAWDCF_IFLAG, + RAWDCF_OFLAG, + RAWDCF_LFLAG, + RAWDCF_SAMPLES, + RAWDCF_KEEP + }, + { /* mode 21, like mode 16 but driven by 75 baud + - RAWDCF RTS set, DTR clr */ + RAWDCF_FLAGS, + NO_POLL, + RAWDCFDTRCLRRTSSET_INIT, + NO_EVENT, + NO_END, + NO_MESSAGE, + NO_LCLDATA, + RAWDCF_ROOTDELAY, + RAWDCF_BASEDELAY, + DCF_A_ID, + RAWDCFDTRCLRRTSSET75_DESCRIPTION, + RAWDCF_FORMAT, + DCF_TYPE, + RAWDCF_MAXUNSYNC, + B75, + RAWDCF_CFLAG, + RAWDCF_IFLAG, + RAWDCF_OFLAG, + RAWDCF_LFLAG, + RAWDCF_SAMPLES, + RAWDCF_KEEP + }, + { /* mode 22 - like 2 with POWERUP trust */ + MBG_FLAGS | PARSE_F_POWERUPTRUST, + NO_POLL, + NO_INIT, + NO_EVENT, + NO_END, + NO_MESSAGE, + NO_LCLDATA, + DCFUA31_ROOTDELAY, + DCFUA31_BASEDELAY, + DCF_A_ID, + DCFUA31_DESCRIPTION, + DCFUA31_FORMAT, + DCF_TYPE, + DCFUA31_MAXUNSYNC, + DCFUA31_SPEED, + DCFUA31_CFLAG, + DCFUA31_IFLAG, + DCFUA31_OFLAG, + DCFUA31_LFLAG, + DCFUA31_SAMPLES, + DCFUA31_KEEP + }, + { /* mode 23 - like 7 with POWERUP trust */ + MBG_FLAGS | PARSE_F_POWERUPTRUST, + GPS16X_POLL, + GPS16X_INIT, + NO_EVENT, + GPS16X_END, + GPS16X_MESSAGE, + GPS16X_DATA, + GPS16X_ROOTDELAY, + GPS16X_BASEDELAY, + GPS16X_ID, + GPS16X_DESCRIPTION, + GPS16X_FORMAT, + GPS_TYPE, + GPS16X_MAXUNSYNC, + GPS16X_SPEED, + GPS16X_CFLAG, + GPS16X_IFLAG, + GPS16X_OFLAG, + GPS16X_LFLAG, + GPS16X_SAMPLES, + GPS16X_KEEP + }, + { /* mode 24 */ + SEL240X_FLAGS, + SEL240X_POLL, + SEL240X_INIT, + NO_EVENT, + SEL240X_END, + NO_MESSAGE, + SEL240X_DATA, + SEL240X_ROOTDELAY, + SEL240X_BASEDELAY, + SEL240X_ID, + SEL240X_DESCRIPTION, + SEL240X_FORMAT, + GPS_TYPE, + SEL240X_MAXUNSYNC, + SEL240X_SPEED, + SEL240X_CFLAG, + SEL240X_IFLAG, + SEL240X_OFLAG, + SEL240X_LFLAG, + SEL240X_SAMPLES, + SEL240X_KEEP + }, }; static int ncltypes = sizeof(parse_clockinfo) / sizeof(struct parse_clockinfo); @@ -1371,11 +1534,11 @@ static int notice = 0; #define PARSE_STATETIME(parse, i) ((parse->generic->currentstatus == i) ? parse->statetime[i] + current_time - parse->lastchange : parse->statetime[i]) -static void parse_event P((struct parseunit *, int)); -static void parse_process P((struct parseunit *, parsetime_t *)); -static void clear_err P((struct parseunit *, u_long)); -static int list_err P((struct parseunit *, u_long)); -static char * l_mktime P((u_long)); +static void parse_event (struct parseunit *, int); +static void parse_process (struct parseunit *, parsetime_t *); +static void clear_err (struct parseunit *, u_long); +static int list_err (struct parseunit *, u_long); +static char * l_mktime (u_long); /**=========================================================================== ** implementation error message regression module @@ -1388,7 +1551,7 @@ clear_err( { if (lstate == ERR_ALL) { - int i; + size_t i; for (i = 0; i < ERR_CNT; i++) { @@ -1427,7 +1590,7 @@ list_err( if (do_it) err->err_cnt++; - + if (err->err_stage->err_count && (err->err_cnt >= err->err_stage->err_count)) { @@ -1451,7 +1614,7 @@ list_err( l_mktime(current_time - err->err_started)); err->err_suppressed = 0; } - + return do_it; } @@ -1473,13 +1636,14 @@ mkreadable( int hex ) { + static const char ellipsis[] = "..."; char *b = buffer; - char *endb = (char *)0; + char *endb = NULL; if (blen < 4) - return (char *)0; /* don't bother with mini buffers */ + return NULL; /* don't bother with mini buffers */ - endb = buffer + blen - 4; + endb = buffer + blen - sizeof(ellipsis); blen--; /* account for '\0' */ @@ -1488,7 +1652,7 @@ mkreadable( if (!hex && /* no binary only */ (*src != '\\') && /* no plain \ */ (*src != '"') && /* no " */ - isprint((int)*src)) /* only printables */ + isprint((unsigned char)*src)) /* only printables */ { /* they are easy... */ *buffer++ = *src++; blen--; @@ -1508,21 +1672,21 @@ mkreadable( { if (*src == '\\') { - strcpy(buffer,"\\\\"); + memcpy(buffer, "\\\\", 2); buffer += 2; blen -= 2; src++; } else { - sprintf(buffer, "\\x%02x", *src++); + snprintf(buffer, blen, "\\x%02x", *src++); blen -= 4; buffer += 4; } } } if (srclen && !blen && endb) /* overflow - set last chars to ... */ - strcpy(endb, "..."); + memcpy(endb, ellipsis, sizeof(ellipsis)); } *buffer = '\0'; @@ -1554,27 +1718,27 @@ mkascii( * define possible io handling methods */ #ifdef STREAM -static int ppsclock_init P((struct parseunit *)); -static int stream_init P((struct parseunit *)); -static void stream_end P((struct parseunit *)); -static int stream_enable P((struct parseunit *)); -static int stream_disable P((struct parseunit *)); -static int stream_setcs P((struct parseunit *, parsectl_t *)); -static int stream_getfmt P((struct parseunit *, parsectl_t *)); -static int stream_setfmt P((struct parseunit *, parsectl_t *)); -static int stream_timecode P((struct parseunit *, parsectl_t *)); -static void stream_receive P((struct recvbuf *)); +static int ppsclock_init (struct parseunit *); +static int stream_init (struct parseunit *); +static void stream_end (struct parseunit *); +static int stream_enable (struct parseunit *); +static int stream_disable (struct parseunit *); +static int stream_setcs (struct parseunit *, parsectl_t *); +static int stream_getfmt (struct parseunit *, parsectl_t *); +static int stream_setfmt (struct parseunit *, parsectl_t *); +static int stream_timecode (struct parseunit *, parsectl_t *); +static void stream_receive (struct recvbuf *); #endif - -static int local_init P((struct parseunit *)); -static void local_end P((struct parseunit *)); -static int local_nop P((struct parseunit *)); -static int local_setcs P((struct parseunit *, parsectl_t *)); -static int local_getfmt P((struct parseunit *, parsectl_t *)); -static int local_setfmt P((struct parseunit *, parsectl_t *)); -static int local_timecode P((struct parseunit *, parsectl_t *)); -static void local_receive P((struct recvbuf *)); -static int local_input P((struct recvbuf *)); + +static int local_init (struct parseunit *); +static void local_end (struct parseunit *); +static int local_nop (struct parseunit *); +static int local_setcs (struct parseunit *, parsectl_t *); +static int local_getfmt (struct parseunit *, parsectl_t *); +static int local_setfmt (struct parseunit *, parsectl_t *); +static int local_timecode (struct parseunit *, parsectl_t *); +static void local_receive (struct recvbuf *); +static int local_input (struct recvbuf *); static bind_t io_bindings[] = { @@ -1621,34 +1785,21 @@ static bind_t io_bindings[] = }, { (char *)0, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, } }; #ifdef STREAM -#define fix_ts(_X_) \ - if ((&(_X_))->tv.tv_usec >= 1000000) \ - { \ - (&(_X_))->tv.tv_usec -= 1000000; \ - (&(_X_))->tv.tv_sec += 1; \ - } - -#define cvt_ts(_X_, _Y_) \ - { \ - l_fp ts; \ - fix_ts((_X_)); \ - if (!buftvtots((const char *)&(&(_X_))->tv, &ts)) \ - { \ - ERR(ERR_BADDATA) \ - msyslog(LOG_ERR,"parse: stream_receive: timestamp conversion error (buftvtots) (%s) (%ld.%06ld) ", (_Y_), (long)(&(_X_))->tv.tv_sec, (long)(&(_X_))->tv.tv_usec);\ - return; \ - } \ - else \ - { \ - (&(_X_))->fp = ts; \ - } \ - } - /*-------------------------------------------------- * ppsclock STREAM init */ @@ -1659,7 +1810,7 @@ ppsclock_init( { static char m1[] = "ppsclocd"; static char m2[] = "ppsclock"; - + /* * now push the parse streams module * it will ensure exclusive access to the device @@ -1748,7 +1899,7 @@ stream_setcs( ) { struct strioctl strioc; - + strioc.ic_cmd = PARSEIOC_SETCS; strioc.ic_timout = 0; strioc.ic_dp = (char *)tcl; @@ -1771,7 +1922,7 @@ stream_enable( ) { struct strioctl strioc; - + strioc.ic_cmd = PARSEIOC_ENABLE; strioc.ic_timout = 0; strioc.ic_dp = (char *)0; @@ -1795,7 +1946,7 @@ stream_disable( ) { struct strioctl strioc; - + strioc.ic_cmd = PARSEIOC_DISABLE; strioc.ic_timout = 0; strioc.ic_dp = (char *)0; @@ -1820,7 +1971,7 @@ stream_getfmt( ) { struct strioctl strioc; - + strioc.ic_cmd = PARSEIOC_GETFMT; strioc.ic_timout = 0; strioc.ic_dp = (char *)tcl; @@ -1843,7 +1994,7 @@ stream_setfmt( ) { struct strioctl strioc; - + strioc.ic_cmd = PARSEIOC_SETFMT; strioc.ic_timout = 0; strioc.ic_dp = (char *)tcl; @@ -1868,12 +2019,12 @@ stream_timecode( ) { struct strioctl strioc; - + strioc.ic_cmd = PARSEIOC_TIMECODE; strioc.ic_timout = 0; strioc.ic_dp = (char *)tcl; strioc.ic_len = sizeof (*tcl); - + if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1) { ERR(ERR_INTERNAL) @@ -1892,9 +2043,10 @@ stream_receive( struct recvbuf *rbufp ) { - struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock); + struct parseunit * parse; parsetime_t parsetime; + parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr; if (!parse->peer) return; @@ -1907,7 +2059,7 @@ stream_receive( return; } clear_err(parse, ERR_BADIO); - + memmove((caddr_t)&parsetime, (caddr_t)rbufp->recv_buffer, sizeof(parsetime_t)); @@ -1933,15 +2085,17 @@ stream_receive( * errors. */ - cvt_ts(parsetime.parse_stime, "parse_stime"); + parsetime.parse_stime.fp = tval_stamp_to_lfp(parsetime.parse_stime.tv); if (PARSE_TIMECODE(parsetime.parse_state)) { - cvt_ts(parsetime.parse_time, "parse_time"); + parsetime.parse_time.fp = tval_stamp_to_lfp(parsetime.parse_time.tv); } if (PARSE_PPS(parsetime.parse_state)) - cvt_ts(parsetime.parse_ptime, "parse_ptime"); + { + parsetime.parse_ptime.fp = tval_stamp_to_lfp(parsetime.parse_ptime.tv); + } parse_process(parse, &parsetime); } @@ -2038,11 +2192,13 @@ local_input( struct recvbuf *rbufp ) { - struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock); + struct parseunit * parse; + int count; unsigned char *s; timestamp_t ts; + parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr; if (!parse->peer) return 0; @@ -2069,11 +2225,11 @@ local_input( { struct timespec pps_timeout; pps_info_t pps_info; - + pps_timeout.tv_sec = 0; pps_timeout.tv_nsec = 0; - if (time_pps_fetch(parse->ppshandle, PPS_TSFMT_TSPEC, &pps_info, + if (time_pps_fetch(parse->atom.handle, PPS_TSFMT_TSPEC, &pps_info, &pps_timeout) == 0) { if (pps_info.assert_sequence + pps_info.clear_sequence != parse->ppsserial) @@ -2090,9 +2246,9 @@ local_input( else pts = pps_info.assert_timestamp; - parse->parseio.parse_dtime.parse_ptime.fp.l_ui = pts.tv_sec + JAN_1970; + parse->parseio.parse_dtime.parse_ptime.fp.l_ui = (uint32_t) (pts.tv_sec + JAN_1970); - dtemp = pts.tv_nsec / 1e9; + dtemp = (double) pts.tv_nsec / 1e9; if (dtemp < 0.) { dtemp += 1; parse->parseio.parse_dtime.parse_ptime.fp.l_ui--; @@ -2101,9 +2257,9 @@ local_input( dtemp -= 1; parse->parseio.parse_dtime.parse_ptime.fp.l_ui++; } - parse->parseio.parse_dtime.parse_ptime.fp.l_uf = dtemp * FRAC; + parse->parseio.parse_dtime.parse_ptime.fp.l_uf = (uint32_t)(dtemp * FRAC); - parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS; + parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS; #ifdef DEBUG if (debug > 3) { @@ -2145,11 +2301,11 @@ local_input( #else #ifdef TIOCDCDTIMESTAMP struct timeval dcd_time; - + if (ioctl(parse->ppsfd, TIOCDCDTIMESTAMP, &dcd_time) != -1) { l_fp tstmp; - + TVTOTS(&dcd_time, &tstmp); tstmp.l_ui += JAN_1970; L_SUB(&ts.fp, &tstmp); @@ -2217,12 +2373,19 @@ local_input( sizeof(parsetime_t)); buf->recv_length = sizeof(parsetime_t); buf->recv_time = rbufp->recv_time; +#ifndef HAVE_IO_COMPLETION_PORT buf->srcadr = rbufp->srcadr; +#endif buf->dstadr = rbufp->dstadr; buf->receiver = rbufp->receiver; buf->fd = rbufp->fd; buf->X_from_where = rbufp->X_from_where; + parse->generic->io.recvcount++; + packets_received++; add_full_recv_buffer(buf); +#ifdef HAVE_IO_COMPLETION_PORT + SetEvent(WaitableIoEventHandle); +#endif } parse_iodone(&parse->parseio); } @@ -2248,9 +2411,10 @@ local_receive( struct recvbuf *rbufp ) { - struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock); + struct parseunit * parse; parsetime_t parsetime; + parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr; if (!parse->peer) return; @@ -2263,7 +2427,7 @@ local_receive( return; } clear_err(parse, ERR_BADIO); - + memmove((caddr_t)&parsetime, (caddr_t)rbufp->recv_buffer, sizeof(parsetime_t)); @@ -2312,6 +2476,31 @@ init_iobinding( ** support routines **/ +static NTP_PRINTF(4, 5) char * +ap(char *buffer, size_t len, char *pos, const char *fmt, ...) +{ + va_list va; + int l; + size_t rem = len - (pos - buffer); + + if (rem == 0) + return pos; + + va_start(va, fmt); + l = vsnprintf(pos, rem, fmt, va); + va_end(va); + + if (l != -1) { + rem--; + if (rem >= (size_t)l) + pos += l; + else + pos += rem; + } + + return pos; +} + /*-------------------------------------------------- * convert a flag field to a string */ @@ -2336,11 +2525,11 @@ parsestate( { PARSEB_LEAPADD, "LEAP ADD WARNING" }, { PARSEB_LEAPDEL, "LEAP DELETE WARNING" }, { PARSEB_LEAPSECOND, "LEAP SECOND" }, - { PARSEB_ALTERNATE, "ALTERNATE ANTENNA" }, + { PARSEB_CALLBIT, "CALL BIT" }, { PARSEB_TIMECODE, "TIME CODE" }, { PARSEB_PPS, "PPS" }, { PARSEB_POSITION, "POSITION" }, - { 0 } + { 0, NULL } }; static struct sbits @@ -2351,14 +2540,13 @@ parsestate( { { PARSEB_S_LEAP, "LEAP INDICATION" }, { PARSEB_S_PPS, "PPS SIGNAL" }, - { PARSEB_S_ANTENNA, "ANTENNA" }, + { PARSEB_S_CALLBIT, "CALLBIT" }, { PARSEB_S_POSITION, "POSITION" }, - { 0 } + { 0, NULL } }; int i; char *s, *t; - *buffer = '\0'; s = t = buffer; @@ -2368,23 +2556,20 @@ parsestate( if (flagstrings[i].bit & lstate) { if (s != t) - strncpy(t, "; ", BUFFER_SIZES(buffer, t, size)); - strncat(t, flagstrings[i].name, BUFFER_SIZES(buffer, t, size)); - t += strlen(t); + t = ap(buffer, size, t, "; "); + t = ap(buffer, size, t, "%s", flagstrings[i].name); } i++; } - if (lstate & (PARSEB_S_LEAP|PARSEB_S_ANTENNA|PARSEB_S_PPS|PARSEB_S_POSITION)) + if (lstate & (PARSEB_S_LEAP|PARSEB_S_CALLBIT|PARSEB_S_PPS|PARSEB_S_POSITION)) { if (s != t) - strncpy(t, "; ", BUFFER_SIZES(buffer, t, size)); - - t += strlen(t); + t = ap(buffer, size, t, "; "); - strncpy(t, "(", BUFFER_SIZES(buffer, t, size)); + t = ap(buffer, size, t, "("); - s = t = t + strlen(t); + s = t; i = 0; while (sflagstrings[i].bit) @@ -2393,16 +2578,15 @@ parsestate( { if (t != s) { - strncpy(t, "; ", BUFFER_SIZES(buffer, t, size)); - t += 2; + t = ap(buffer, size, t, "; "); } - - strncpy(t, sflagstrings[i].name, BUFFER_SIZES(buffer, t, size)); - t += strlen(t); + + t = ap(buffer, size, t, "%s", + sflagstrings[i].name); } i++; } - strncpy(t, ")", BUFFER_SIZES(buffer, t, size)); + t = ap(buffer, size, t, ")"); } return buffer; } @@ -2430,10 +2614,12 @@ parsestatus( { CVT_BADDATE, "DATE ILLEGAL" }, { CVT_BADTIME, "TIME ILLEGAL" }, { CVT_ADDITIONAL, "ADDITIONAL DATA" }, - { 0 } + { 0, NULL } }; int i; + char *t; + t = buffer; *buffer = '\0'; i = 0; @@ -2441,9 +2627,9 @@ parsestatus( { if (flagstrings[i].bit & lstate) { - if (buffer[0]) - strncat(buffer, "; ", size); - strncat(buffer, flagstrings[i].name, size); + if (t != buffer) + t = ap(buffer, size, t, "; "); + t = ap(buffer, size, t, "%s", flagstrings[i].name); } i++; } @@ -2473,12 +2659,12 @@ clockstatus( { CEVNT_PROP, "PROPAGATION DELAY" }, { CEVNT_BADDATE, "ILLEGAL DATE" }, { CEVNT_BADTIME, "ILLEGAL TIME" }, - { (unsigned)~0L } + { (unsigned)~0L, NULL } }; int i; i = 0; - while (flagstrings[i].value != ~0) + while (flagstrings[i].value != (u_int)~0) { if (flagstrings[i].value == lstate) { @@ -2506,10 +2692,11 @@ l_mktime( char *t; buffer[0] = '\0'; + t = buffer; if ((tmp = delta / (60*60*24)) != 0) { - snprintf(buffer, BUFFER_SIZE(buffer, buffer), "%ldd+", (u_long)tmp); + t = ap(buffer, sizeof(buffer), t, "%ldd+", (u_long)tmp); delta -= tmp * 60*60*24; } @@ -2518,10 +2705,8 @@ l_mktime( m = delta % 60; delta /= 60; - t = buffer + strlen(buffer); - - snprintf(t, BUFFER_SIZE(buffer, t), "%02d:%02d:%02d", - (int)delta, (int)m, (int)s); + t = ap(buffer, sizeof(buffer), t, "%02d:%02d:%02d", + (int)delta, (int)m, (int)s); return buffer; } @@ -2601,10 +2786,10 @@ parse_shutdown( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)0; + struct parseunit *parse = NULL; if (peer && peer->procptr) - parse = (struct parseunit *)peer->procptr->unitptr; + parse = peer->procptr->unitptr; if (!parse) { @@ -2612,7 +2797,7 @@ parse_shutdown( return; } - if (!parse->peer) + if (!parse->peer) { msyslog(LOG_INFO, "PARSE receiver #%d: INTERNAL ERROR - unit already inactive - shutdown ignored", unit); return; @@ -2621,11 +2806,11 @@ parse_shutdown( #ifdef HAVE_PPSAPI if (parse->flags & PARSE_PPSCLOCK) { - (void)time_pps_destroy(parse->ppshandle); + (void)time_pps_destroy(parse->atom.handle); } #endif if (parse->generic->io.fd != parse->ppsfd && parse->ppsfd != -1) - (void)close(parse->ppsfd); /* close separate PPS source */ + (void)closeserial(parse->ppsfd); /* close separate PPS source */ /* * print statistics a last time and @@ -2637,7 +2822,7 @@ parse_shutdown( { parse->parse_type->cl_end(parse); } - + /* * cleanup before leaving this world */ @@ -2650,7 +2835,7 @@ parse_shutdown( io_closeclock(&parse->generic->io); free_varlist(parse->kv); - + NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" removed", CLK_UNIT(parse->peer), parse->parse_type->cl_description); @@ -2676,15 +2861,15 @@ parse_hardpps( if (CLK_PPS(parse->peer) && (parse->flags & PARSE_PPSKERNEL)) { int i = 0; - if (mode == PARSE_HARDPPS_ENABLE) + if (mode == PARSE_HARDPPS_ENABLE) { if (parse->flags & PARSE_CLEAR) i = PPS_CAPTURECLEAR; else i = PPS_CAPTUREASSERT; } - - if (time_pps_kcbind(parse->ppshandle, PPS_KC_HARDPPS, i, + + if (time_pps_kcbind(parse->atom.handle, PPS_KC_HARDPPS, i, PPS_TSFMT_TSPEC) < 0) { msyslog(LOG_ERR, "PARSE receiver #%d: time_pps_kcbind failed: %m", CLK_UNIT(parse->peer)); @@ -2696,7 +2881,7 @@ parse_hardpps( * tell the rest, that we have a kernel PPS source, iff we ever enable HARDPPS */ if (mode == PARSE_HARDPPS_ENABLE) - pps_enable = 1; + hardpps_enable = 1; } } @@ -2711,23 +2896,30 @@ parse_ppsapi( struct parseunit *parse ) { - int cap, mode, mode1; - char *cp; - - parse->flags &= ~PARSE_PPSCLOCK; + int cap, mode_ppsoffset; + const char *cp; + + parse->flags &= (u_char) (~PARSE_PPSCLOCK); - if (time_pps_getcap(parse->ppshandle, &cap) < 0) { + /* + * collect PPSAPI offset capability - should move into generic handling + */ + if (time_pps_getcap(parse->atom.handle, &cap) < 0) { msyslog(LOG_ERR, "PARSE receiver #%d: parse_ppsapi: time_pps_getcap failed: %m", CLK_UNIT(parse->peer)); - + return 0; } - if (time_pps_getparams(parse->ppshandle, &parse->ppsparams) < 0) { - msyslog(LOG_ERR, "PARSE receiver #%d: parse_ppsapi: time_pps_getparams failed: %m", - CLK_UNIT(parse->peer)); + /* + * initialize generic PPSAPI interface + * + * we leave out CLK_FLAG3 as time_pps_kcbind() + * is handled here for now. Ideally this should also + * be part of the generic PPSAPI interface + */ + if (!refclock_params(parse->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG4), &parse->atom)) return 0; - } /* nb. only turn things on, if someone else has turned something * on before we get here, leave it alone! @@ -2735,47 +2927,36 @@ parse_ppsapi( if (parse->flags & PARSE_CLEAR) { cp = "CLEAR"; - mode = PPS_CAPTURECLEAR; - mode1 = PPS_OFFSETCLEAR; + mode_ppsoffset = PPS_OFFSETCLEAR; } else { cp = "ASSERT"; - mode = PPS_CAPTUREASSERT; - mode1 = PPS_OFFSETASSERT; + mode_ppsoffset = PPS_OFFSETASSERT; } msyslog(LOG_INFO, "PARSE receiver #%d: initializing PPS to %s", CLK_UNIT(parse->peer), cp); - if (!(mode & cap)) { - msyslog(LOG_ERR, "PARSE receiver #%d: FAILED to initialize PPS to %s (PPS API capabilities=0x%x)", - CLK_UNIT(parse->peer), cp, cap); - - return 0; - } - - if (!(mode1 & cap)) { + if (!(mode_ppsoffset & cap)) { msyslog(LOG_WARNING, "PARSE receiver #%d: Cannot set PPS_%sCLEAR, this will increase jitter (PPS API capabilities=0x%x)", CLK_UNIT(parse->peer), cp, cap); - mode1 = 0; + mode_ppsoffset = 0; } else { - if (mode1 == PPS_OFFSETCLEAR) - { - parse->ppsparams.clear_offset.tv_sec = -parse->ppsphaseadjust; - parse->ppsparams.clear_offset.tv_nsec = -1e9*(parse->ppsphaseadjust - (long)parse->ppsphaseadjust); + if (mode_ppsoffset == PPS_OFFSETCLEAR) + { + parse->atom.pps_params.clear_offset.tv_sec = (time_t)(-parse->ppsphaseadjust); + parse->atom.pps_params.clear_offset.tv_nsec = (long)(-1e9*(parse->ppsphaseadjust - (double)(long)parse->ppsphaseadjust)); } - - if (mode1 == PPS_OFFSETASSERT) - { - parse->ppsparams.assert_offset.tv_sec = -parse->ppsphaseadjust; - parse->ppsparams.assert_offset.tv_nsec = -1e9*(parse->ppsphaseadjust - (long)parse->ppsphaseadjust); + + if (mode_ppsoffset == PPS_OFFSETASSERT) + { + parse->atom.pps_params.assert_offset.tv_sec = (time_t)(-parse->ppsphaseadjust); + parse->atom.pps_params.assert_offset.tv_nsec = (long)(-1e9*(parse->ppsphaseadjust - (double)(long)parse->ppsphaseadjust)); } } - - /* only set what is legal */ - parse->ppsparams.mode = (mode | mode1 | PPS_TSFMT_TSPEC) & cap; + parse->atom.pps_params.mode |= mode_ppsoffset; - if (time_pps_setparams(parse->ppshandle, &parse->ppsparams) < 0) { + if (time_pps_setparams(parse->atom.handle, &parse->atom.pps_params) < 0) { msyslog(LOG_ERR, "PARSE receiver #%d: FAILED set PPS parameters: %m", CLK_UNIT(parse->peer)); return 0; @@ -2817,14 +2998,14 @@ parse_start( if (!notice) { NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ - msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-2006, Frank Kardel"); + msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-2015, Frank Kardel"); notice = 1; } type = CLK_TYPE(peer); unit = CLK_UNIT(peer); - if ((type == ~0) || (parse_clockinfo[type].cl_description == (char *)0)) + if ((type == (u_int)~0) || (parse_clockinfo[type].cl_description == (char *)0)) { msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: unsupported clock type %d (max %d)", unit, CLK_REALTYPE(peer), ncltypes-1); @@ -2840,12 +3021,11 @@ parse_start( #ifndef O_NOCTTY #define O_NOCTTY 0 #endif - - fd232 = open(parsedev, O_RDWR | O_NOCTTY -#ifdef O_NONBLOCK - | O_NONBLOCK +#ifndef O_NONBLOCK +#define O_NONBLOCK 0 #endif - , 0777); + + fd232 = tty_open(parsedev, O_RDWR | O_NOCTTY | O_NONBLOCK, 0777); if (fd232 == -1) { @@ -2853,9 +3033,7 @@ parse_start( return 0; } - parse = (struct parseunit *)emalloc(sizeof(struct parseunit)); - - memset((char *)parse, 0, sizeof(struct parseunit)); + parse = emalloc_zero(sizeof(*parse)); parse->generic = peer->procptr; /* link up */ parse->generic->unitptr = (caddr_t)parse; /* link down */ @@ -2879,9 +3057,9 @@ parse_start( parse->kv = (struct ctl_var *)0; clear_err(parse, ERR_ALL); - + parse->parse_type = &parse_clockinfo[type]; - + parse->maxunsync = parse->parse_type->cl_maxunsync; parse->generic->fudgetime1 = parse->parse_type->cl_basedelay; @@ -2894,16 +3072,16 @@ parse_start( peer->rootdelay = parse->parse_type->cl_rootdelay; peer->sstclktype = parse->parse_type->cl_type; peer->precision = sys_precision; - + peer->stratum = STRATUM_REFCLOCK; if (peer->stratum <= 1) memmove((char *)&parse->generic->refid, parse->parse_type->cl_id, 4); else parse->generic->refid = htonl(PARSEHSREFID); - + parse->generic->io.fd = fd232; - + parse->peer = peer; /* marks it also as busy */ /* @@ -2946,15 +3124,15 @@ parse_start( } #endif - tio.c_cflag = parse_clockinfo[type].cl_cflag; - tio.c_iflag = parse_clockinfo[type].cl_iflag; - tio.c_oflag = parse_clockinfo[type].cl_oflag; - tio.c_lflag = parse_clockinfo[type].cl_lflag; - + tio.c_cflag = (tcflag_t) parse_clockinfo[type].cl_cflag; + tio.c_iflag = (tcflag_t) parse_clockinfo[type].cl_iflag; + tio.c_oflag = (tcflag_t) parse_clockinfo[type].cl_oflag; + tio.c_lflag = (tcflag_t) parse_clockinfo[type].cl_lflag; + #ifdef HAVE_TERMIOS - if ((cfsetospeed(&tio, parse_clockinfo[type].cl_speed) == -1) || - (cfsetispeed(&tio, parse_clockinfo[type].cl_speed) == -1)) + if ((cfsetospeed(&tio, (speed_t) parse_clockinfo[type].cl_speed) == -1) || + (cfsetispeed(&tio, (speed_t) parse_clockinfo[type].cl_speed) == -1)) { msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcset{i,o}speed(&tio, speed): %m", unit); parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */ @@ -2969,11 +3147,7 @@ parse_start( * if the PARSEPPSDEVICE can be opened that will be used * for PPS else PARSEDEVICE will be used */ - parse->ppsfd = open(parseppsdev, O_RDWR | O_NOCTTY -#ifdef O_NONBLOCK - | O_NONBLOCK -#endif - , 0777); + parse->ppsfd = tty_open(parseppsdev, O_RDWR | O_NOCTTY | O_NONBLOCK, 0777); if (parse->ppsfd == -1) { @@ -3018,7 +3192,7 @@ parse_start( if (CLK_PPS(parse->peer)) { int i = 1; - + if (ioctl(parse->ppsfd, TIOCSPPS, (caddr_t)&i) == 0) { parse->flags |= PARSE_PPSCLOCK; @@ -3033,7 +3207,7 @@ parse_start( parse->hardppsstate = PARSE_HARDPPS_DISABLE; if (CLK_PPS(parse->peer)) { - if (time_pps_create(parse->ppsfd, &parse->ppshandle) < 0) + if (!refclock_ppsapi(parse->ppsfd, &parse->atom)) { msyslog(LOG_NOTICE, "PARSE receiver #%d: parse_start: could not set up PPS: %m", CLK_UNIT(parse->peer)); } @@ -3055,9 +3229,9 @@ parse_start( /* * pick correct input machine */ - parse->generic->io.srcclock = (caddr_t)parse; + parse->generic->io.srcclock = peer; parse->generic->io.datalen = 0; - + parse->binding = init_iobinding(parse); if (parse->binding == (bind_t *)0) @@ -3065,7 +3239,7 @@ parse_start( msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: io sub system initialisation failed.", CLK_UNIT(parse->peer)); parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */ return 0; /* well, ok - special initialisation broke */ - } + } parse->generic->io.clock_recv = parse->binding->bd_receive; /* pick correct receive routine */ parse->generic->io.io_input = parse->binding->bd_io_input; /* pick correct input routine */ @@ -3103,9 +3277,9 @@ parse_start( parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */ return 0; /* well, ok - special initialisation broke */ } - - strncpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format, sizeof(tmp_ctl.parseformat.parse_buffer)); - tmp_ctl.parseformat.parse_count = strlen(tmp_ctl.parseformat.parse_buffer); + + strlcpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format, sizeof(tmp_ctl.parseformat.parse_buffer)); + tmp_ctl.parseformat.parse_count = (u_short) strlen(tmp_ctl.parseformat.parse_buffer); if (!PARSE_SETFMT(parse, &tmp_ctl)) { @@ -3113,7 +3287,7 @@ parse_start( parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */ return 0; /* well, ok - special initialisation broke */ } - + /* * get rid of all IO accumulated so far */ @@ -3140,7 +3314,7 @@ parse_start( return 0; /* well, ok - special initialisation broke */ } } - + /* * Insert in async io device list. */ @@ -3198,15 +3372,15 @@ parse_start( static void parse_ctl( struct parseunit *parse, - struct refclockstat *in + const struct refclockstat *in ) { if (in) { if (in->haveflags & (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4)) { - parse->flags = (parse->flags & ~(CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4)) | - (in->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4)); + u_char mask = CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4; + parse->flags = (parse->flags & (u_char)(~mask)) | (in->flags & mask); #if defined(HAVE_PPSAPI) if (CLK_PPS(parse->peer)) { @@ -3214,7 +3388,7 @@ parse_ctl( } #endif } - + if (in->haveflags & CLK_HAVETIME1) { parse->generic->fudgetime1 = in->fudgetime1; @@ -3222,11 +3396,11 @@ parse_ctl( CLK_UNIT(parse->peer), parse->generic->fudgetime1); } - + if (in->haveflags & CLK_HAVETIME2) { parse->generic->fudgetime2 = in->fudgetime2; - if (parse->flags & PARSE_TRUSTTIME) + if (parse->flags & PARSE_TRUSTTIME) { parse->maxunsync = (u_long)ABS(in->fudgetime2); msyslog(LOG_INFO, "PARSE receiver #%d: new trust time %s", @@ -3259,7 +3433,7 @@ parse_poll( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; if (peer != parse->peer) { @@ -3274,8 +3448,8 @@ parse_poll( */ parse->generic->polls++; - if (parse->pollneeddata && - ((current_time - parse->pollneeddata) > (1<<(max(min(parse->peer->hpoll, parse->peer->ppoll), parse->peer->minpoll))))) + if (parse->pollneeddata && + ((int)(current_time - parse->pollneeddata) > (1<<(max(min(parse->peer->hpoll, parse->peer->ppoll), parse->peer->minpoll))))) { /* * start worrying when exceeding a poll inteval @@ -3283,7 +3457,7 @@ parse_poll( */ parse->lastmissed = current_time; parse_event(parse, CEVNT_TIMEOUT); - + ERR(ERR_NODATA) msyslog(LOG_WARNING, "PARSE receiver #%d: no data from device within poll interval (check receiver / wiring)", CLK_UNIT(parse->peer)); } @@ -3311,12 +3485,12 @@ parse_poll( static void parse_control( int unit, - struct refclockstat *in, + const struct refclockstat *in, struct refclockstat *out, struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; parsectl_t tmpctl; static char outstatus[400]; /* status output buffer */ @@ -3341,7 +3515,7 @@ parse_control( * handle changes */ parse_ctl(parse, in); - + /* * supply data */ @@ -3388,16 +3562,16 @@ parse_control( } start = tt = add_var(&out->kv_list, 128, RO|DEF); - snprintf(tt, 128, "refclock_time=\""); - tt += strlen(tt); + tt = ap(start, 128, tt, "refclock_time=\""); if (parse->timedata.parse_time.fp.l_ui == 0) { - strncpy(tt, "<UNDEFINED>\"", BUFFER_SIZES(start, tt, 128)); + tt = ap(start, 128, tt, "<UNDEFINED>\""); } else { - snprintf(tt, 128, "%s\"", gmprettydate(&parse->timedata.parse_time.fp)); + tt = ap(start, 128, tt, "%s\"", + gmprettydate(&parse->timedata.parse_time.fp)); } if (!PARSE_GETTIMECODE(parse, &tmpctl)) @@ -3408,8 +3582,7 @@ parse_control( else { start = tt = add_var(&out->kv_list, 512, RO|DEF); - snprintf(tt, 512, "refclock_status=\""); - tt += strlen(tt); + tt = ap(start, 512, tt, "refclock_status=\""); /* * copy PPS flags from last read transaction (informational only) @@ -3417,18 +3590,20 @@ parse_control( tmpctl.parsegettc.parse_state |= parse->timedata.parse_state & (PARSEB_PPS|PARSEB_S_PPS); - (void) parsestate(tmpctl.parsegettc.parse_state, tt, BUFFER_SIZES(start, tt, 512)); + (void)parsestate(tmpctl.parsegettc.parse_state, tt, BUFFER_SIZES(start, tt, 512)); + + tt += strlen(tt); - strncat(tt, "\"", BUFFER_SIZES(start, tt, 512)); + tt = ap(start, 512, tt, "\""); if (tmpctl.parsegettc.parse_count) mkascii(outstatus+strlen(outstatus), (int)(sizeof(outstatus)- strlen(outstatus) - 1), tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count)); } - + tmpctl.parseformat.parse_format = tmpctl.parsegettc.parse_format; - + if (!PARSE_GETFMT(parse, &tmpctl)) { ERR(ERR_INTERNAL) @@ -3436,11 +3611,19 @@ parse_control( } else { - tt = add_var(&out->kv_list, 80, RO|DEF); - snprintf(tt, 80, "refclock_format=\""); + int count = tmpctl.parseformat.parse_count - 1; + + start = tt = add_var(&out->kv_list, 80, RO|DEF); + tt = ap(start, 80, tt, "refclock_format=\""); + + if (count > 0) { + tt = ap(start, 80, tt, "%*.*s", + count, + count, + tmpctl.parseformat.parse_buffer); + } - strncat(tt, tmpctl.parseformat.parse_buffer, tmpctl.parseformat.parse_count); - strncat(tt,"\"", 80); + tt = ap(start, 80, tt, "\""); } /* @@ -3448,8 +3631,7 @@ parse_control( */ start = tt = add_var(&out->kv_list, LEN_STATES, RO|DEF); - strncpy(tt, "refclock_states=\"", LEN_STATES); - tt += strlen(tt); + tt = ap(start, LEN_STATES, tt, "refclock_states=\""); for (i = 0; i <= CEVNT_MAX; i++) { @@ -3464,7 +3646,7 @@ parse_control( percent /= 10; d /= 10; } - + if (d) percent = (percent * 10000) / d; else @@ -3474,36 +3656,37 @@ parse_control( { char item[80]; int count; - + snprintf(item, 80, "%s%s%s: %s (%d.%02d%%)", sum ? "; " : "", (parse->generic->currentstatus == i) ? "*" : "", clockstatus((unsigned int)i), l_mktime(s_time), (int)(percent / 100), (int)(percent % 100)); - if ((count = strlen(item)) < (LEN_STATES - 40 - (tt - start))) + if ((count = (int) strlen(item)) < (LEN_STATES - 40 - (tt - start))) { - strncpy(tt, item, BUFFER_SIZES(start, tt, LEN_STATES)); - tt += count; + tt = ap(start, LEN_STATES, tt, + "%s", item); } sum += s_time; } } - - snprintf(tt, BUFFER_SIZES(start, tt, LEN_STATES), "; running time: %s\"", l_mktime(sum)); - + + tt = ap(start, LEN_STATES, tt, + "; running time: %s\"", l_mktime(sum)); + tt = add_var(&out->kv_list, 32, RO); snprintf(tt, 32, "refclock_id=\"%s\"", parse->parse_type->cl_id); - + tt = add_var(&out->kv_list, 80, RO); snprintf(tt, 80, "refclock_iomode=\"%s\"", parse->binding->bd_description); tt = add_var(&out->kv_list, 128, RO); snprintf(tt, 128, "refclock_driver_version=\"%s\"", rcsid); - + { struct ctl_var *k; - + k = parse->kv; while (k && !(k->flags & EOV)) { @@ -3511,8 +3694,8 @@ parse_control( k++; } } - - out->lencode = strlen(outstatus); + + out->lencode = (u_short) strlen(outstatus); out->p_lastcode = outstatus; } } @@ -3538,7 +3721,7 @@ parse_event( if (parse->parse_type->cl_event) parse->parse_type->cl_event(parse, event); - + if (event == CEVNT_NOMINAL) { NLOG(NLOG_CLOCKSTATUS) @@ -3561,7 +3744,10 @@ parse_process( { l_fp off, rectime, reftime; double fudge; - + + /* silence warning: 'off.Ul_i.Xl_i' may be used uninitialized in this function */ + ZERO(off); + /* * check for changes in conversion status * (only one for each new status !) @@ -3571,11 +3757,11 @@ parse_process( (parse->timedata.parse_status != parsetime->parse_status)) { char buffer[400]; - + NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ msyslog(LOG_WARNING, "PARSE receiver #%d: conversion status \"%s\"", CLK_UNIT(parse->peer), parsestatus(parsetime->parse_status, buffer, sizeof(buffer))); - + if ((parsetime->parse_status & CVT_MASK) == CVT_FAIL) { /* @@ -3584,7 +3770,7 @@ parse_process( * the time code might be overwritten by the next packet */ parsectl_t tmpctl; - + if (!PARSE_GETTIMECODE(parse, &tmpctl)) { ERR(ERR_INTERNAL) @@ -3596,6 +3782,8 @@ parse_process( msyslog(LOG_WARNING, "PARSE receiver #%d: FAILED TIMECODE: \"%s\" (check receiver configuration / wiring)", CLK_UNIT(parse->peer), mkascii(buffer, sizeof buffer, tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count - 1))); } + /* copy status to show only changes in case of failures */ + parse->timedata.parse_status = parsetime->parse_status; } } @@ -3622,7 +3810,7 @@ parse_process( parse->timedata.parse_ptime = parsetime->parse_ptime; } break; /* well, still waiting - timeout is handled at higher levels */ - + case CVT_FAIL: if (parsetime->parse_status & CVT_BADFMT) { @@ -3653,7 +3841,7 @@ parse_process( if (parse->lastformat != parsetime->parse_format) { parsectl_t tmpctl; - + tmpctl.parseformat.parse_format = parsetime->parse_format; if (!PARSE_GETFMT(parse, &tmpctl)) @@ -3681,10 +3869,10 @@ parse_process( /* * something happend - except for PPS events */ - + (void) parsestate(parsetime->parse_state, tmp1, sizeof(tmp1)); (void) parsestate(parse->timedata.parse_state, tmp2, sizeof(tmp2)); - + NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ msyslog(LOG_INFO,"PARSE receiver #%d: STATE CHANGE: %s -> %s", CLK_UNIT(parse->peer), tmp2, tmp1); @@ -3716,7 +3904,7 @@ parse_process( * for PARSE Meinberg DCF77 receivers the lost synchronisation * is true as it is the powerup state and the time is taken * from a crude real time clock chip - * for the PZF series this is only partly true, as + * for the PZF/GPS series this is only partly true, as * PARSE_POWERUP only means that the pseudo random * phase shift sequence cannot be found. this is only * bad, if we have never seen the clock in the SYNC @@ -3734,11 +3922,14 @@ parse_process( * interval. fortunately powerdowns last usually longer than 64 * seconds and the receiver is at least 2 minutes in the * POWERUP or NOSYNC state before switching to SYNC + * for GPS receivers this can mean antenna problems and other causes. + * the additional grace period can be enables by a clock + * mode having the PARSE_F_POWERUPTRUST flag in cl_flag set. */ parse_event(parse, CEVNT_FAULT); NLOG(NLOG_CLOCKSTATUS) ERR(ERR_BADSTATUS) - msyslog(LOG_ERR,"PARSE receiver #%d: NOT SYNCHRONIZED", + msyslog(LOG_ERR,"PARSE receiver #%d: NOT SYNCHRONIZED/RECEIVER PROBLEMS", CLK_UNIT(parse->peer)); } else @@ -3784,12 +3975,12 @@ parse_process( } fudge = parse->generic->fudgetime1; /* standard RS232 Fudgefactor */ - + if (PARSE_TIMECODE(parsetime->parse_state)) { rectime = parsetime->parse_stime.fp; off = reftime = parsetime->parse_time.fp; - + L_SUB(&off, &rectime); /* prepare for PPS adjustments logic */ #ifdef DEBUG @@ -3811,7 +4002,7 @@ parse_process( /* * set fudge = 0.0 if already included in PPS time stamps */ - if (parse->ppsparams.mode & (PPS_OFFSETCLEAR|PPS_OFFSETASSERT)) + if (parse->atom.pps_params.mode & (PPS_OFFSETCLEAR|PPS_OFFSETASSERT)) { ppsphaseadjust = 0.0; } @@ -3830,11 +4021,11 @@ parse_process( #endif if (PARSE_TIMECODE(parsetime->parse_state)) { - if (M_ISGEQ(off.l_i, off.l_f, -1, 0x80000000) && - M_ISGEQ(0, 0x7fffffff, off.l_i, off.l_f)) + if (M_ISGEQ(off.l_i, off.l_uf, -1, 0x80000000) && + M_ISGEQ(0, 0x7fffffff, off.l_i, off.l_uf)) { fudge = ppsphaseadjust; /* pick PPS fudge factor */ - + /* * RS232 offsets within [-0.5..0.5[ - take PPS offsets */ @@ -3842,16 +4033,16 @@ parse_process( if (parse->parse_type->cl_flags & PARSE_F_PPSONSECOND) { reftime = off = offset; - if (reftime.l_uf & (unsigned)0x80000000) + if (reftime.l_uf & 0x80000000) reftime.l_ui++; reftime.l_uf = 0; - + /* * implied on second offset */ off.l_uf = ~off.l_uf; /* map [0.5..1[ -> [-0.5..0[ */ - off.l_ui = (off.l_f < 0) ? ~0 : 0; /* sign extend */ + off.l_i = (off.l_uf & 0x80000000) ? -1 : 0; /* sign extend */ } else { @@ -3876,14 +4067,14 @@ parse_process( */ off = offset; reftime = offset; - if (reftime.l_uf & (unsigned)0x80000000) + if (reftime.l_uf & 0x80000000) reftime.l_ui++; reftime.l_uf = 0; /* * implied on second offset */ off.l_uf = ~off.l_uf; /* map [0.5..1[ -> [-0.5..0[ */ - off.l_ui = (off.l_f < 0) ? ~0 : 0; /* sign extend */ + off.l_i = (off.l_uf & 0x80000000) ? -1 : 0; /* sign extend */ } } else @@ -3912,7 +4103,7 @@ parse_process( rectime = reftime; L_SUB(&rectime, &off); /* just to keep the ntp interface happy */ - + #ifdef DEBUG if (debug > 3) printf("PARSE receiver #%d: calculated Reftime %s, Recvtime %s\n", @@ -3937,20 +4128,21 @@ parse_process( clear_err(parse, ERR_BADDATA); clear_err(parse, ERR_NODATA); clear_err(parse, ERR_INTERNAL); - + /* * and now stick it into the clock machine * samples are only valid iff lastsync is not too old and * we have seen the clock in sync at least once * after the last time we didn't see an expected data telegram * at startup being not in sync is also bad just like - * POWERUP state + * POWERUP state unless PARSE_F_POWERUPTRUST is set * see the clock states section above for more reasoning */ - if (((current_time - parse->lastsync) > parse->maxunsync) || - (parse->lastsync < parse->lastmissed) || + if (((current_time - parse->lastsync) > parse->maxunsync) || + (parse->lastsync < parse->lastmissed) || ((parse->lastsync == 0) && !PARSE_SYNC(parsetime->parse_state)) || - PARSE_POWERUP(parsetime->parse_state)) + (((parse->parse_type->cl_flags & PARSE_F_POWERUPTRUST) == 0) && + PARSE_POWERUP(parsetime->parse_state))) { parse->generic->leap = LEAP_NOTINSYNC; parse->lastsync = 0; /* wait for full sync again */ @@ -3983,9 +4175,9 @@ parse_process( * only good/trusted samples are interesting */ #ifdef DEBUG - if (debug > 2) - { - printf("PARSE receiver #%d: refclock_process_offset(reftime=%s, rectime=%s, Fudge=%f)\n", + if (debug > 2) + { + printf("PARSE receiver #%d: refclock_process_offset(reftime=%s, rectime=%s, Fudge=%f)\n", CLK_UNIT(parse->peer), prettydate(&reftime), prettydate(&rectime), @@ -3993,23 +4185,26 @@ parse_process( } #endif parse->generic->lastref = reftime; - + refclock_process_offset(parse->generic, reftime, rectime, fudge); +#ifdef HAVE_PPSAPI /* * pass PPS information on to PPS clock */ if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer)) - { - (void) pps_sample(&parse->timedata.parse_ptime.fp); + { + parse->peer->flags |= (FLAG_PPS | FLAG_TSTAMP_PPS); parse_hardpps(parse, PARSE_HARDPPS_ENABLE); } +#endif } else { - parse_hardpps(parse, PARSE_HARDPPS_DISABLE); + parse_hardpps(parse, PARSE_HARDPPS_DISABLE); + parse->peer->flags &= ~(FLAG_PPS | FLAG_TSTAMP_PPS); } /* - * ready, unless the machine wants a sample or + * ready, unless the machine wants a sample or * we are in fast startup mode (peer->dist > MAXDISTANCE) */ if (!parse->pollneeddata && parse->peer->disp <= MAXDISTANCE) @@ -4021,56 +4216,71 @@ parse_process( refclock_receive(parse->peer); } - + /**=========================================================================== ** special code for special clocks **/ static void mk_utcinfo( - char *t, + char *t, // pointer to the output string buffer int wnt, int wnlsf, int dn, int dtls, int dtlsf, - int size + int size // size of the output string buffer ) { - l_fp leapdate; - char *start = t; - - snprintf(t, size, "current correction %d sec", dtls); - t += strlen(t); - - if (wnlsf < 990) - wnlsf += 1024; - - if (wnt < 990) - wnt += 1024; - - gpstolfp((unsigned short)wnlsf, (unsigned short)dn, 0, &leapdate); - - if ((dtlsf != dtls) && - ((wnlsf - wnt) < 52)) - { - snprintf(t, BUFFER_SIZES(start, t, size), ", next correction %d sec on %s, new GPS-UTC offset %d", - dtlsf - dtls, gmprettydate(&leapdate), dtlsf); - } - else - { - snprintf(t, BUFFER_SIZES(start, t, size), ", last correction on %s", - gmprettydate(&leapdate)); - } + /* + * The week number transmitted by the GPS satellites for the leap date + * is truncated to 8 bits only. If the nearest leap second date is off + * the current date by more than +/- 128 weeks then conversion to a + * calendar date is ambiguous. On the other hand, if a leap second is + * currently being announced (i.e. dtlsf != dtls) then the week number + * wnlsf is close enough, and we can unambiguously determine the date + * for which the leap second is scheduled. + */ + if ( dtlsf != dtls ) + { + time_t t_ls; + struct tm *tm; + int n = 0; + + if (wnlsf < GPSWRAP) + wnlsf += GPSWEEKS; + + if (wnt < GPSWRAP) + wnt += GPSWEEKS; + + t_ls = (time_t) wnlsf * SECSPERWEEK + + (time_t) dn * SECSPERDAY + + GPS_SEC_BIAS - 1; + + tm = gmtime( &t_ls ); + if (tm == NULL) // gmtime() failed + { + snprintf( t, size, "** (gmtime() failed in mk_utcinfo())" ); + return; + } + + n += snprintf( t, size, "UTC offset transition from %is to %is due to leap second %s", + dtls, dtlsf, ( dtls < dtlsf ) ? "insertion" : "deletion" ); + n += snprintf( t + n, size - n, " at UTC midnight at the end of %s, %04i-%02i-%02i", + daynames[tm->tm_wday], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday ); + } + else + snprintf( t, size, "UTC offset parameter: %is, no leap second announced.\n", dtls ); + } #ifdef CLOCK_MEINBERG /**=========================================================================== - ** Meinberg GPS166/GPS167 support + ** Meinberg GPS receiver support **/ /*------------------------------------------------------------ - * gps16x_message - process GPS16x messages + * gps16x_message - process messages from Meinberg GPS receiver */ static void gps16x_message( @@ -4082,12 +4292,12 @@ gps16x_message( { GPS_MSG_HDR header; unsigned char *bufp = (unsigned char *)parsetime->parse_msg + 1; - + #ifdef DEBUG if (debug > 2) { char msgbuffer[600]; - + mkreadable(msgbuffer, sizeof(msgbuffer), (char *)parsetime->parse_msg, parsetime->parse_msglen, 1); printf("PARSE receiver #%d: received message (%d bytes) >%s<\n", CLK_UNIT(parse->peer), @@ -4096,21 +4306,21 @@ gps16x_message( } #endif get_mbg_header(&bufp, &header); - if (header.gps_hdr_csum == mbg_csum(parsetime->parse_msg + 1, 6) && - (header.gps_len == 0 || - (header.gps_len < sizeof(parsetime->parse_msg) && - header.gps_data_csum == mbg_csum(bufp, header.gps_len)))) + if (header.hdr_csum == mbg_csum(parsetime->parse_msg + 1, 6) && + (header.len == 0 || + (header.len < sizeof(parsetime->parse_msg) && + header.data_csum == mbg_csum(bufp, header.len)))) { /* * clean message */ - switch (header.gps_cmd) + switch (header.cmd) { case GPS_SW_REV: { char buffer[64]; SW_REV gps_sw_rev; - + get_mbg_sw_rev(&bufp, &gps_sw_rev); snprintf(buffer, sizeof(buffer), "meinberg_gps_version=\"%x.%02x%s%s\"", (gps_sw_rev.code >> 8) & 0xFF, @@ -4121,54 +4331,56 @@ gps16x_message( } break; - case GPS_STAT: + case GPS_BVAR_STAT: { static struct state { - unsigned short flag; /* status flag */ - unsigned const char *string; /* bit name */ + BVAR_STAT flag; /* status flag */ + const char *string; /* bit name */ } states[] = { - { TM_ANT_DISCONN, (const unsigned char *)"ANTENNA FAULTY" }, - { TM_SYN_FLAG, (const unsigned char *)"NO SYNC SIGNAL" }, - { TM_NO_SYNC, (const unsigned char *)"NO SYNC POWERUP" }, - { TM_NO_POS, (const unsigned char *)"NO POSITION" }, - { 0, (const unsigned char *)"" } + { BVAR_CFGH_INVALID, "Configuration/Health" }, + { BVAR_ALM_NOT_COMPLETE, "Almanachs" }, + { BVAR_UTC_INVALID, "UTC Correction" }, + { BVAR_IONO_INVALID, "Ionospheric Correction" }, + { BVAR_RCVR_POS_INVALID, "Receiver Position" }, + { 0, "" } }; - unsigned short status; + BVAR_STAT status; struct state *s = states; char buffer[512]; char *p, *b; - - status = get_lsb_short(&bufp); - snprintf(buffer, sizeof(buffer), "meinberg_gps_status=\"[0x%04x] ", status); - + + status = (BVAR_STAT) get_lsb_short(&bufp); + p = b = buffer; + p = ap(buffer, sizeof(buffer), p, + "meinberg_gps_status=\"[0x%04x] ", + status); + if (status) { - p = b = buffer + strlen(buffer); + p = ap(buffer, sizeof(buffer), p, "incomplete buffered data: "); + b = p; while (s->flag) { if (status & s->flag) { if (p != b) { - *p++ = ','; - *p++ = ' '; + p = ap(buffer, sizeof(buffer), p, ", "); } - - strncat(p, (const char *)s->string, sizeof(buffer)); + + p = ap(buffer, sizeof(buffer), p, "%s", (const char *)s->string); } s++; } - - *p++ = '"'; - *p = '\0'; + p = ap(buffer, sizeof(buffer), p, "\""); } else { - strncat(buffer, "<OK>\"", sizeof(buffer)); + p = ap(buffer, sizeof(buffer), p, "<all buffered data complete>\""); } - + set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF); } break; @@ -4177,282 +4389,259 @@ gps16x_message( { XYZ xyz; char buffer[256]; - + get_mbg_xyz(&bufp, xyz); snprintf(buffer, sizeof(buffer), "gps_position(XYZ)=\"%s m, %s m, %s m\"", mfptoa(xyz[XP].l_ui, xyz[XP].l_uf, 1), mfptoa(xyz[YP].l_ui, xyz[YP].l_uf, 1), mfptoa(xyz[ZP].l_ui, xyz[ZP].l_uf, 1)); - + set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF); } break; - + case GPS_POS_LLA: { LLA lla; char buffer[256]; - + get_mbg_lla(&bufp, lla); - + snprintf(buffer, sizeof(buffer), "gps_position(LLA)=\"%s deg, %s deg, %s m\"", mfptoa(lla[LAT].l_ui, lla[LAT].l_uf, 4), - mfptoa(lla[LON].l_ui, lla[LON].l_uf, 4), + mfptoa(lla[LON].l_ui, lla[LON].l_uf, 4), mfptoa(lla[ALT].l_ui, lla[ALT].l_uf, 1)); - + set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF); } break; - + case GPS_TZDL: break; - + case GPS_PORT_PARM: break; - + case GPS_SYNTH: break; - + case GPS_ANT_INFO: { ANT_INFO antinfo; char buffer[512]; - char *p; - + char *p, *q; + get_mbg_antinfo(&bufp, &antinfo); - snprintf(buffer, sizeof(buffer), "meinberg_antenna_status=\""); - p = buffer + strlen(buffer); - + p = buffer; + p = ap(buffer, sizeof(buffer), p, "meinberg_antenna_status=\""); switch (antinfo.status) { - case ANT_INVALID: - strncat(p, "<OK>", BUFFER_SIZE(buffer, p)); - p += strlen(p); + case ANT_INVALID: // No other fields valid since antenna has not yet been disconnected + p = ap(buffer, sizeof(buffer), + p, "<OK>"); break; - - case ANT_DISCONN: - strncat(p, "DISCONNECTED since ", BUFFER_SIZE(buffer, p)); + + case ANT_DISCONN: // Antenna is disconnected, tm_reconn and delta_t not yet set + q = ap(buffer, sizeof(buffer), + p, "DISCONNECTED since "); NLOG(NLOG_CLOCKSTATUS) ERR(ERR_BADSTATUS) msyslog(LOG_ERR,"PARSE receiver #%d: ANTENNA FAILURE: %s", CLK_UNIT(parse->peer), p); - - p += strlen(p); - mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p)); + + p = q; + mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p), 0); *p = '\0'; break; - - case ANT_RECONN: - strncat(p, "RECONNECTED on ", BUFFER_SIZE(buffer, p)); - p += strlen(p); - mbg_tm_str(&p, &antinfo.tm_reconn, BUFFER_SIZE(buffer, p)); - snprintf(p, BUFFER_SIZE(buffer, p), ", reconnect clockoffset %c%ld.%07ld s, disconnect time ", + + case ANT_RECONN: // Antenna had been disconnect, but receiver sync. after reconnect, so all fields valid + p = ap(buffer, sizeof(buffer), + p, "SYNC AFTER RECONNECT on "); + mbg_tm_str(&p, &antinfo.tm_reconn, BUFFER_SIZE(buffer, p), 0); + p = ap(buffer, sizeof(buffer), + p, ", clock offset at reconnect %c%ld.%07ld s, disconnect time ", (antinfo.delta_t < 0) ? '-' : '+', - ABS(antinfo.delta_t) / 10000, - ABS(antinfo.delta_t) % 10000); - p += strlen(p); - mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p)); + (long) ABS(antinfo.delta_t) / 10000, + (long) ABS(antinfo.delta_t) % 10000); + mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p), 0); *p = '\0'; break; - + default: - snprintf(p, BUFFER_SIZE(buffer, p), "bad status 0x%04x", antinfo.status); - p += strlen(p); + p = ap(buffer, sizeof(buffer), + p, "bad status 0x%04x", + antinfo.status); break; } - - strncat(p, "\"", BUFFER_SIZE(buffer, p)); - - set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF); + + p = ap(buffer, sizeof(buffer), p, "\""); + + set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF); } break; - + case GPS_UCAP: break; - + case GPS_CFGH: { CFGH cfgh; char buffer[512]; char *p; - + get_mbg_cfgh(&bufp, &cfgh); if (cfgh.valid) { + const char *cp; + uint16_t tmp_val; int i; - + p = buffer; - strncpy(buffer, "gps_tot_51=\"", BUFFER_SIZE(buffer, p)); - p += strlen(p); + p = ap(buffer, sizeof(buffer), + p, "gps_tot_51=\""); mbg_tgps_str(&p, &cfgh.tot_51, BUFFER_SIZE(buffer, p)); - strncpy(p, "\"", BUFFER_SIZE(buffer, p)); - set_var(&parse->kv, buffer, strlen(buffer)+1, RO); - + p = ap(buffer, sizeof(buffer), + p, "\""); + set_var(&parse->kv, buffer, sizeof(buffer), RO|COND_DEF); + p = buffer; - strncpy(buffer, "gps_tot_63=\"", BUFFER_SIZE(buffer, p)); - p += strlen(p); + p = ap(buffer, sizeof(buffer), + p, "gps_tot_63=\""); mbg_tgps_str(&p, &cfgh.tot_63, BUFFER_SIZE(buffer, p)); - strncpy(p, "\"", BUFFER_SIZE(buffer, p)); - set_var(&parse->kv, buffer, strlen(buffer)+1, RO); - + p = ap(buffer, sizeof(buffer), + p, "\""); + set_var(&parse->kv, buffer, sizeof(buffer), RO|COND_DEF); + p = buffer; - strncpy(buffer, "gps_t0a=\"", BUFFER_SIZE(buffer, p)); - p += strlen(p); + p = ap(buffer, sizeof(buffer), + p, "gps_t0a=\""); mbg_tgps_str(&p, &cfgh.t0a, BUFFER_SIZE(buffer, p)); - strncpy(p, "\"", BUFFER_SIZE(buffer, p)); - set_var(&parse->kv, buffer, strlen(buffer)+1, RO); - - for (i = MIN_SVNO; i < MAX_SVNO; i++) + p = ap(buffer, sizeof(buffer), + p, "\""); + set_var(&parse->kv, buffer, sizeof(buffer), RO|COND_DEF); + + for (i = 0; i < N_SVNO_GPS; i++) { p = buffer; - snprintf(p, BUFFER_SIZE(buffer, p), "gps_cfg[%d]=\"[0x%x] ", i, cfgh.cfg[i]); - p += strlen(p); - switch (cfgh.cfg[i] & 0x7) - { - case 0: - strncpy(p, "BLOCK I", BUFFER_SIZE(buffer, p)); - break; - case 1: - strncpy(p, "BLOCK II", BUFFER_SIZE(buffer, p)); - break; - default: - strncpy(p, "bad CFG", BUFFER_SIZE(buffer, p)); - break; - } - strncat(p, "\"", BUFFER_SIZE(buffer, p)); - set_var(&parse->kv, buffer, strlen(buffer)+1, RO); - - p = buffer; - snprintf(p, BUFFER_SIZE(buffer, p), "gps_health[%d]=\"[0x%x] ", i, cfgh.health[i]); - p += strlen(p); - switch ((cfgh.health[i] >> 5) & 0x7 ) - { - case 0: - strncpy(p, "OK;", BUFFER_SIZE(buffer, p)); - break; - case 1: - strncpy(p, "PARITY;", BUFFER_SIZE(buffer, p)); - break; - case 2: - strncpy(p, "TLM/HOW;", BUFFER_SIZE(buffer, p)); - break; - case 3: - strncpy(p, "Z-COUNT;", BUFFER_SIZE(buffer, p)); - break; - case 4: - strncpy(p, "SUBFRAME 1,2,3;", BUFFER_SIZE(buffer, p)); - break; - case 5: - strncpy(p, "SUBFRAME 4,5;", BUFFER_SIZE(buffer, p)); - break; - case 6: - strncpy(p, "UPLOAD BAD;", BUFFER_SIZE(buffer, p)); - break; - case 7: - strncpy(p, "DATA BAD;", BUFFER_SIZE(buffer, p)); - break; + p = ap(buffer, sizeof(buffer), p, "sv_info[%d]=\"PRN%d", i, i + N_SVNO_GPS); + + tmp_val = cfgh.health[i]; /* a 6 bit SV health code */ + p = ap(buffer, sizeof(buffer), p, "; health=0x%02x (", tmp_val); + /* "All Ones" has a special meaning" */ + if (tmp_val == 0x3F) /* satellite is unusable or doesn't even exist */ + cp = "SV UNAVAILABLE"; + else { + /* The MSB contains a summary of the 3 MSBs of the 8 bit health code, + * indicating if the data sent by the satellite is OK or not. */ + p = ap(buffer, sizeof(buffer), p, "DATA %s, ", (tmp_val & 0x20) ? "BAD" : "OK" ); + + /* The 5 LSBs contain the status of the different signals sent by the satellite. */ + switch (tmp_val & 0x1F) + { + case 0x00: cp = "SIGNAL OK"; break; + /* codes 0x01 through 0x1B indicate that one or more + * specific signal components are weak or dead. + * We don't decode this here in detail. */ + case 0x1C: cp = "SV IS TEMP OUT"; break; + case 0x1D: cp = "SV WILL BE TEMP OUT"; break; + default: cp = "TRANSMISSION PROBLEMS"; break; + } } - - p += strlen(p); - - switch (cfgh.health[i] & 0x1F) + p = ap(buffer, sizeof(buffer), p, "%s)", cp ); + + tmp_val = cfgh.cfg[i]; /* a 4 bit SV configuration/type code */ + p = ap(buffer, sizeof(buffer), p, "; cfg=0x%02x (", tmp_val); + switch (tmp_val & 0x7) { - case 0: - strncpy(p, "SIGNAL OK", BUFFER_SIZE(buffer, p)); - break; - case 0x1C: - strncpy(p, "SV TEMP OUT", BUFFER_SIZE(buffer, p)); - break; - case 0x1D: - strncpy(p, "SV WILL BE TEMP OUT", BUFFER_SIZE(buffer, p)); - break; - case 0x1E: - break; - case 0x1F: - strncpy(p, "MULTIPLE ERRS", BUFFER_SIZE(buffer, p)); - break; - default: - strncpy(p, "TRANSMISSION PROBLEMS", BUFFER_SIZE(buffer, p)); - break; + case 0x00: cp = "(reserved)"; break; + case 0x01: cp = "BLOCK II/IIA/IIR"; break; + case 0x02: cp = "BLOCK IIR-M"; break; + case 0x03: cp = "BLOCK IIF"; break; + case 0x04: cp = "BLOCK III"; break; + default: cp = "unknown SV type"; break; } - - strncat(p, "\"", sizeof(buffer)); - set_var(&parse->kv, buffer, strlen(buffer)+1, RO); + p = ap(buffer, sizeof(buffer), p, "%s", cp ); + if (tmp_val & 0x08) /* A-S is on, P-code is encrypted */ + p = ap( buffer, sizeof(buffer), p, ", A-S on" ); + + p = ap(buffer, sizeof(buffer), p, ")\""); + set_var(&parse->kv, buffer, sizeof(buffer), RO|COND_DEF); } } } break; - + case GPS_ALM: break; - + case GPS_EPH: break; - + case GPS_UTC: { UTC utc; char buffer[512]; char *p; - + p = buffer; - + get_mbg_utc(&bufp, &utc); - + if (utc.valid) { - strncpy(p, "gps_utc_correction=\"", sizeof(buffer)); - p += strlen(p); + p = ap(buffer, sizeof(buffer), p, "gps_utc_correction=\""); mk_utcinfo(p, utc.t0t.wn, utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf, BUFFER_SIZE(buffer, p)); - strncat(p, "\"", BUFFER_SIZE(buffer, p)); + p += strlen(p); + p = ap(buffer, sizeof(buffer), p, "\""); } else { - strncpy(p, "gps_utc_correction=\"<NO UTC DATA>\"", BUFFER_SIZE(buffer, p)); + p = ap(buffer, sizeof(buffer), p, "gps_utc_correction=\"<NO UTC DATA>\""); } - set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF); + set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF); } break; - + case GPS_IONO: break; - + case GPS_ASCII_MSG: { ASCII_MSG gps_ascii_msg; char buffer[128]; - + get_mbg_ascii_msg(&bufp, &gps_ascii_msg); - + if (gps_ascii_msg.valid) { char buffer1[128]; mkreadable(buffer1, sizeof(buffer1), gps_ascii_msg.s, strlen(gps_ascii_msg.s), (int)0); - + snprintf(buffer, sizeof(buffer), "gps_message=\"%s\"", buffer1); } else - strncpy(buffer, "gps_message=<NONE>", sizeof(buffer)); - - set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF); + snprintf(buffer, sizeof(buffer), "gps_message=<NONE>"); + + set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF); } - + break; - + default: break; } } else { - msyslog(LOG_DEBUG, "PARSE receiver #%d: gps16x_message: message checksum error: hdr_csum = 0x%x (expected 0x%lx), data_len = %d, data_csum = 0x%x (expected 0x%lx)", + msyslog(LOG_DEBUG, "PARSE receiver #%d: gps16x_message: message checksum error: hdr_csum = 0x%x (expected 0x%x), " + "data_len = %d, data_csum = 0x%x (expected 0x%x)", CLK_UNIT(parse->peer), - header.gps_hdr_csum, mbg_csum(parsetime->parse_msg + 1, 6), - header.gps_len, - header.gps_data_csum, mbg_csum(bufp, (unsigned)((header.gps_len < sizeof(parsetime->parse_msg)) ? header.gps_len : 0))); + header.hdr_csum, mbg_csum(parsetime->parse_msg + 1, 6), + header.len, + header.data_csum, mbg_csum(bufp, (unsigned)((header.len < sizeof(parsetime->parse_msg)) ? header.len : 0))); } } - + return; } @@ -4464,12 +4653,12 @@ gps16x_poll( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; - - static GPS_MSG_HDR sequence[] = + struct parseunit *parse = peer->procptr->unitptr; + + static GPS_MSG_HDR sequence[] = { { GPS_SW_REV, 0, 0, 0 }, - { GPS_STAT, 0, 0, 0 }, + { GPS_BVAR_STAT, 0, 0, 0 }, { GPS_UTC, 0, 0, 0 }, { GPS_ASCII_MSG, 0, 0, 0 }, { GPS_ANT_INFO, 0, 0, 0 }, @@ -4478,46 +4667,46 @@ gps16x_poll( { GPS_POS_LLA, 0, 0, 0 }, { (unsigned short)~0, 0, 0, 0 } }; - + int rtc; unsigned char cmd_buffer[64]; unsigned char *outp = cmd_buffer; GPS_MSG_HDR *header; - + if (((poll_info_t *)parse->parse_type->cl_data)->rate) { - parse->peer->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate; + parse->peer->procptr->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate; } - if (sequence[parse->localstate].gps_cmd == (unsigned short)~0) + if (sequence[parse->localstate].cmd == (unsigned short)~0) parse->localstate = 0; - + header = sequence + parse->localstate++; - + *outp++ = SOH; /* start command */ - + put_mbg_header(&outp, header); outp = cmd_buffer + 1; - - header->gps_hdr_csum = (short)mbg_csum(outp, 6); + + header->hdr_csum = (short)mbg_csum(outp, 6); put_mbg_header(&outp, header); - + #ifdef DEBUG if (debug > 2) { char buffer[128]; - + mkreadable(buffer, sizeof(buffer), (char *)cmd_buffer, (unsigned)(outp - cmd_buffer), 1); printf("PARSE receiver #%d: transmitted message #%ld (%d bytes) >%s<\n", CLK_UNIT(parse->peer), parse->localstate - 1, (int)(outp - cmd_buffer), - buffer); + buffer); } #endif - - rtc = write(parse->generic->io.fd, cmd_buffer, (unsigned long)(outp - cmd_buffer)); - + + rtc = (int) write(parse->generic->io.fd, cmd_buffer, (unsigned long)(outp - cmd_buffer)); + if (rtc < 0) { ERR(ERR_BADIO) @@ -4544,7 +4733,7 @@ gps16x_poll_init( { if (((poll_info_t *)parse->parse_type->cl_data)->rate) { - parse->peer->action = gps16x_poll; + parse->peer->procptr->action = gps16x_poll; gps16x_poll(parse->peer); } @@ -4566,7 +4755,7 @@ gps16x_poll_init( return 1; } #endif /* CLOCK_MEINBERG */ - + /**=========================================================================== ** clock polling support **/ @@ -4579,11 +4768,11 @@ poll_dpoll( struct parseunit *parse ) { - int rtc; + long rtc; const char *ps = ((poll_info_t *)parse->parse_type->cl_data)->string; - int ct = ((poll_info_t *)parse->parse_type->cl_data)->count; + long ct = ((poll_info_t *)parse->parse_type->cl_data)->count; - rtc = write(parse->generic->io.fd, ps, (unsigned long)ct); + rtc = write(parse->generic->io.fd, ps, ct); if (rtc < 0) { ERR(ERR_BADIO) @@ -4593,7 +4782,7 @@ poll_dpoll( if (rtc != ct) { ERR(ERR_BADIO) - msyslog(LOG_ERR, "PARSE receiver #%d: poll_dpoll: failed to send cmd incomplete (%d of %d bytes sent)", CLK_UNIT(parse->peer), rtc, ct); + msyslog(LOG_ERR, "PARSE receiver #%d: poll_dpoll: failed to send cmd incomplete (%ld of %ld bytes sent)", CLK_UNIT(parse->peer), rtc, ct); } clear_err(parse, ERR_BADIO); } @@ -4606,14 +4795,14 @@ poll_poll( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; - + struct parseunit *parse = peer->procptr->unitptr; + if (parse->parse_type->cl_poll) parse->parse_type->cl_poll(parse); if (((poll_info_t *)parse->parse_type->cl_data)->rate) { - parse->peer->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate; + parse->peer->procptr->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate; } } @@ -4627,13 +4816,13 @@ poll_init( { if (((poll_info_t *)parse->parse_type->cl_data)->rate) { - parse->peer->action = poll_poll; + parse->peer->procptr->action = poll_poll; poll_poll(parse->peer); } return 0; } - + /**=========================================================================== ** Trimble support **/ @@ -4663,7 +4852,7 @@ trimbletaip_init( else { tio.c_cc[VEOL] = TRIMBLETAIP_EOL; - + if (TTY_SETATTR(parse->generic->io.fd, &tio) == -1) { msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_init: tcsetattr(fd, &tio): %m", CLK_UNIT(parse->peer)); @@ -4682,7 +4871,7 @@ static const char *taipinit[] = { ">FTM00020001<", (char *)0 }; - + static void trimbletaip_event( struct parseunit *parse, @@ -4699,7 +4888,7 @@ trimbletaip_event( iv = taipinit; while (*iv) { - int rtc = write(parse->generic->io.fd, *iv, strlen(*iv)); + int rtc = (int) write(parse->generic->io.fd, *iv, strlen(*iv)); if (rtc < 0) { msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: failed to send cmd to clock: %m", CLK_UNIT(parse->peer)); @@ -4707,7 +4896,7 @@ trimbletaip_event( } else { - if (rtc != strlen(*iv)) + if (rtc != (int)strlen(*iv)) { msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: failed to send cmd incomplete (%d of %d bytes sent)", CLK_UNIT(parse->peer), rtc, (int)strlen(*iv)); @@ -4827,19 +5016,19 @@ union uval { float fv; double dv; }; - + struct txbuf { short idx; /* index to first unused byte */ u_char *txt; /* pointer to actual data buffer */ }; -void sendcmd P((struct txbuf *buf, int c)); -void sendbyte P((struct txbuf *buf, int b)); -void sendetx P((struct txbuf *buf, struct parseunit *parse)); -void sendint P((struct txbuf *buf, int a)); -void sendflt P((struct txbuf *buf, double a)); - +void sendcmd (struct txbuf *buf, int c); +void sendbyte (struct txbuf *buf, int b); +void sendetx (struct txbuf *buf, struct parseunit *parse); +void sendint (struct txbuf *buf, int a); +void sendflt (struct txbuf *buf, double a); + void sendcmd( struct txbuf *buf, @@ -4851,12 +5040,12 @@ sendcmd( buf->idx = 2; } -void sendcmd P((struct txbuf *buf, int c)); -void sendbyte P((struct txbuf *buf, int b)); -void sendetx P((struct txbuf *buf, struct parseunit *parse)); -void sendint P((struct txbuf *buf, int a)); -void sendflt P((struct txbuf *buf, double a)); - +void sendcmd (struct txbuf *buf, int c); +void sendbyte (struct txbuf *buf, int b); +void sendetx (struct txbuf *buf, struct parseunit *parse); +void sendint (struct txbuf *buf, int a); +void sendflt (struct txbuf *buf, double a); + void sendbyte( struct txbuf *buf, @@ -4888,18 +5077,18 @@ sendetx( if (debug > 2) { char buffer[256]; - + mkreadable(buffer, sizeof(buffer), (char *)buf->txt, (unsigned)buf->idx, 1); printf("PARSE receiver #%d: transmitted message (%d bytes) >%s<\n", CLK_UNIT(parse->peer), - buf->idx, buffer); + buf->idx, buffer); } #endif clear_err(parse, ERR_BADIO); } } -void +void sendint( struct txbuf *buf, int a @@ -4919,7 +5108,7 @@ sendflt( int i; union uval uval; - uval.fv = a; + uval.fv = (float) a; #ifdef WORDS_BIGENDIAN for (i=0; i<=3; i++) #else @@ -4951,12 +5140,12 @@ trimbletsip_setup( if (t) t->last_reset = current_time; - + buf.txt = buffer; - + sendcmd(&buf, CMD_CVERSION); /* request software versions */ sendetx(&buf, parse); - + sendcmd(&buf, CMD_COPERPARAM); /* set operating parameters */ sendbyte(&buf, 4); /* static */ sendflt(&buf, 5.0*D2R); /* elevation angle mask = 10 deg XXX */ @@ -4964,25 +5153,25 @@ trimbletsip_setup( sendflt(&buf, 12.0); /* PDOP mask = 12 */ sendflt(&buf, 8.0); /* PDOP switch level = 8 */ sendetx(&buf, parse); - + sendcmd(&buf, CMD_CMODESEL); /* fix mode select */ sendbyte(&buf, 1); /* time transfer mode */ sendetx(&buf, parse); - + sendcmd(&buf, CMD_CMESSAGE); /* request system message */ sendetx(&buf, parse); - + sendcmd(&buf, CMD_CSUPER); /* superpacket fix */ sendbyte(&buf, 0x2); /* binary mode */ sendetx(&buf, parse); - + sendcmd(&buf, CMD_CIOOPTIONS); /* set I/O options */ sendbyte(&buf, TRIM_POS_OPT); /* position output */ sendbyte(&buf, 0x00); /* no velocity output */ sendbyte(&buf, TRIM_TIME_OPT); /* UTC, compute on seconds */ sendbyte(&buf, 0x00); /* no raw measurements */ sendetx(&buf, parse); - + sendcmd(&buf, CMD_CUTCPARAM); /* request UTC correction data */ sendetx(&buf, parse); @@ -5001,12 +5190,12 @@ trimble_check( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; trimble_t *t = parse->localdata; u_char buffer[256]; struct txbuf buf; buf.txt = buffer; - + if (t) { if (current_time > t->last_msg + TRIMBLETSIP_IDLE_TIME) @@ -5014,18 +5203,18 @@ trimble_check( } poll_poll(parse->peer); /* emit query string and re-arm timer */ - + if (t && t->qtracking) { u_long oldsats = t->ltrack & ~t->ctrack; - + t->qtracking = 0; t->ltrack = t->ctrack; - + if (oldsats) { int i; - + for (i = 0; oldsats; i++) { if (oldsats & (1 << i)) { @@ -5036,7 +5225,7 @@ trimble_check( oldsats &= ~(1 << i); } } - + sendcmd(&buf, CMD_CSTATTRACK); sendbyte(&buf, 0x00); /* current tracking set */ sendetx(&buf, parse); @@ -5051,14 +5240,14 @@ trimbletsip_end( struct parseunit *parse ) { trimble_t *t = parse->localdata; - + if (t) { free(t); - parse->localdata = (void *)0; + parse->localdata = NULL; } - parse->peer->nextaction = 0; - parse->peer->action = (void (*) P((struct peer *)))0; + parse->peer->procptr->nextaction = 0; + parse->peer->procptr->action = NULL; } /*-------------------------------------------------- @@ -5082,9 +5271,9 @@ trimbletsip_init( if (!parse->localdata) { trimble_t *t; - + t = (trimble_t *)(parse->localdata = emalloc(sizeof(trimble_t))); - + if (t) { memset((char *)t, 0, sizeof(trimble_t)); @@ -5092,8 +5281,8 @@ trimbletsip_init( } } - parse->peer->action = trimble_check; - parse->peer->nextaction = current_time; + parse->peer->procptr->action = trimble_check; + parse->peer->procptr->nextaction = current_time; /* * configure terminal line for ICANON mode with VEOL characters @@ -5164,7 +5353,7 @@ getflt( ) { union uval uval; - + #ifdef WORDS_BIGENDIAN uval.bd[0] = *bp++; uval.bd[1] = *bp++; @@ -5185,7 +5374,7 @@ getdbl( ) { union uval uval; - + #ifdef WORDS_BIGENDIAN uval.bd[0] = *bp++; uval.bd[1] = *bp++; @@ -5213,7 +5402,7 @@ getshort( unsigned char *p ) { - return get_msb_short(&p); + return (int) get_msb_short(&p); } /*-------------------------------------------------- @@ -5230,7 +5419,7 @@ trimbletsip_message( { unsigned char *buffer = parsetime->parse_msg; unsigned int size = parsetime->parse_msglen; - + if ((size < 4) || (buffer[0] != DLE) || (buffer[size-1] != ETX) || @@ -5238,7 +5427,7 @@ trimbletsip_message( { #ifdef DEBUG if (debug > 2) { - int i; + size_t i; printf("TRIMBLE BAD packet, size %d:\n ", size); for (i = 0; i < size; i++) { @@ -5252,16 +5441,16 @@ trimbletsip_message( } else { - int var_flag; + u_short var_flag; trimble_t *tr = parse->localdata; unsigned int cmd = buffer[1]; char pbuffer[200]; char *t = pbuffer; cmd_info_t *s; - + #ifdef DEBUG if (debug > 3) { - int i; + size_t i; printf("TRIMBLE packet 0x%02x, size %d:\n ", cmd, size); for (i = 0; i < size; i++) { @@ -5274,12 +5463,12 @@ trimbletsip_message( if (tr) tr->last_msg = current_time; - + s = trimble_convert(cmd, trimble_rcmds); - + if (s) { - snprintf(t, BUFFER_SIZE(pbuffer, t), "%s=\"", s->varname); + t = ap(pbuffer, sizeof(pbuffer), t, "%s=\"", s->varname); } else { @@ -5287,47 +5476,43 @@ trimbletsip_message( return; } - var_flag = s->varmode; + var_flag = (u_short) s->varmode; - t += strlen(t); - switch(cmd) { case CMD_RCURTIME: - snprintf(t, BUFFER_SIZE(pbuffer, t), "%f, %d, %f", + t = ap(pbuffer, sizeof(pbuffer), t, "%f, %d, %f", getflt((unsigned char *)&mb(0)), getshort((unsigned char *)&mb(4)), getflt((unsigned char *)&mb(6))); break; - + case CMD_RBEST4: - strncpy(t, "mode: ", BUFFER_SIZE(pbuffer, t)); - t += strlen(t); + t = ap(pbuffer, sizeof(pbuffer), t, "mode: "); switch (mb(0) & 0xF) { default: - snprintf(t, BUFFER_SIZE(pbuffer, t), "0x%x", mb(0) & 0x7); + t = ap(pbuffer, sizeof(pbuffer), t, + "0x%x", mb(0) & 0x7); break; case 1: - strncpy(t, "0D", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "0D"); break; - + case 3: - strncpy(t, "2D", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "2D"); break; - + case 4: - strncpy(t, "3D", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "3D"); break; } - t += strlen(t); if (mb(0) & 0x10) - strncpy(t, "-MANUAL, ", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "-MANUAL, "); else - strncpy(t, "-AUTO, ", BUFFER_SIZE(pbuffer, t)); - t += strlen(t); - - snprintf(t, BUFFER_SIZE(pbuffer, t), "satellites %02d %02d %02d %02d, PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f", + t = ap(pbuffer, sizeof(pbuffer), t, "-AUTO, "); + + t = ap(pbuffer, sizeof(pbuffer), t, "satellites %02d %02d %02d %02d, PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f", mb(1), mb(2), mb(3), mb(4), getflt((unsigned char *)&mb(5)), getflt((unsigned char *)&mb(9)), @@ -5335,12 +5520,12 @@ trimbletsip_message( getflt((unsigned char *)&mb(17))); break; - + case CMD_RVERSION: - snprintf(t, BUFFER_SIZE(pbuffer, t), "%d.%d (%d/%d/%d)", + t = ap(pbuffer, sizeof(pbuffer), t, "%d.%d (%d/%d/%d)", mb(0)&0xff, mb(1)&0xff, 1900+(mb(4)&0xff), mb(2)&0xff, mb(3)&0xff); break; - + case CMD_RRECVHEALTH: { static const char *msgs[] = @@ -5354,57 +5539,54 @@ trimbletsip_message( "<BIT 6>", "<BIT 7>" }; - + int i, bits; - + switch (mb(0) & 0xFF) { default: - snprintf(t, BUFFER_SIZE(pbuffer, t), "illegal value 0x%02x", mb(0) & 0xFF); + t = ap(pbuffer, sizeof(pbuffer), t, "illegal value 0x%02x", mb(0) & 0xFF); break; case 0x00: - strncpy(t, "doing position fixes", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "doing position fixes"); break; case 0x01: - strncpy(t, "no GPS time yet", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "no GPS time yet"); break; case 0x03: - strncpy(t, "PDOP too high", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "PDOP too high"); break; case 0x08: - strncpy(t, "no usable satellites", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "no usable satellites"); break; case 0x09: - strncpy(t, "only ONE usable satellite", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "only ONE usable satellite"); break; case 0x0A: - strncpy(t, "only TWO usable satellites", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "only TWO usable satellites"); break; case 0x0B: - strncpy(t, "only THREE usable satellites", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "only THREE usable satellites"); break; case 0x0C: - strncpy(t, "the chosen satellite is unusable", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "the chosen satellite is unusable"); break; } - t += strlen(t); - bits = mb(1) & 0xFF; - + for (i = 0; i < 8; i++) if (bits & (0x1<<i)) { - snprintf(t, BUFFER_SIZE(pbuffer, t), ", %s", msgs[i]); - t += strlen(t); + t = ap(pbuffer, sizeof(pbuffer), t, ", %s", msgs[i]); } } break; - + case CMD_RMESSAGE: mkreadable(t, (int)BUFFER_SIZE(pbuffer, t), (char *)&mb(0), (unsigned)(size - 2 - (&mb(0) - buffer)), 0); break; - + case CMD_RMACHSTAT: { static const char *msgs[] = @@ -5418,59 +5600,56 @@ trimbletsip_message( "<BIT 6>", "<BIT 7>" }; - + int i, bits; - snprintf(t, BUFFER_SIZE(pbuffer, t), "machine id 0x%02x", mb(0) & 0xFF); - t += strlen(t); - + t = ap(pbuffer, sizeof(pbuffer), t, "machine id 0x%02x", mb(0) & 0xFF); bits = mb(1) & 0xFF; - + for (i = 0; i < 8; i++) if (bits & (0x1<<i)) { - snprintf(t, BUFFER_SIZE(pbuffer, t), ", %s", msgs[i]); - t += strlen(t); + t = ap(pbuffer, sizeof(pbuffer), t, ", %s", msgs[i]); } - snprintf(t, BUFFER_SIZE(pbuffer, t), ", Superpackets %ssupported", (mb(2) & 0xFF) ? "" :"un" ); + t = ap(pbuffer, sizeof(pbuffer), t, ", Superpackets %ssupported", (mb(2) & 0xFF) ? "" :"un" ); } break; - + case CMD_ROPERPARAM: - snprintf(t, BUFFER_SIZE(pbuffer, t), "%2x %.1f %.1f %.1f %.1f", + t = ap(pbuffer, sizeof(pbuffer), t, "%2x %.1f %.1f %.1f %.1f", mb(0), getflt((unsigned char *)&mb(1)), getflt((unsigned char *)&mb(5)), getflt((unsigned char *)&mb(9)), getflt((unsigned char *)&mb(13))); break; - + case CMD_RUTCPARAM: { float t0t = getflt((unsigned char *)&mb(14)); - short wnt = getshort((unsigned char *)&mb(18)); - short dtls = getshort((unsigned char *)&mb(12)); - short wnlsf = getshort((unsigned char *)&mb(20)); - short dn = getshort((unsigned char *)&mb(22)); - short dtlsf = getshort((unsigned char *)&mb(24)); + short wnt = (short) getshort((unsigned char *)&mb(18)); + short dtls = (short) getshort((unsigned char *)&mb(12)); + short wnlsf = (short) getshort((unsigned char *)&mb(20)); + short dn = (short) getshort((unsigned char *)&mb(22)); + short dtlsf = (short) getshort((unsigned char *)&mb(24)); if ((int)t0t != 0) - { - mk_utcinfo(t, wnt, wnlsf, dn, dtls, dtlsf, BUFFER_SIZE(pbuffer, t)); - } + { + mk_utcinfo(t, wnt, wnlsf, dn, dtls, dtlsf, BUFFER_SIZE(pbuffer, t)); + } else - { - strncpy(t, "<NO UTC DATA>", BUFFER_SIZE(pbuffer, t)); - } + { + t = ap(pbuffer, sizeof(pbuffer), t, "<NO UTC DATA>"); + } } break; case CMD_RSAT1BIAS: - snprintf(t, BUFFER_SIZE(pbuffer, t), "%.1fm %.2fm/s at %.1fs", + t = ap(pbuffer, sizeof(pbuffer), t, "%.1fm %.2fm/s at %.1fs", getflt(&mb(0)), getflt(&mb(4)), getflt(&mb(8))); break; case CMD_RIOOPTIONS: { - snprintf(t, BUFFER_SIZE(pbuffer, t), "%02x %02x %02x %02x", + t = ap(pbuffer, sizeof(pbuffer), t, "%02x %02x %02x %02x", mb(0), mb(1), mb(2), mb(3)); if (mb(0) != TRIM_POS_OPT || mb(2) != TRIM_TIME_OPT) @@ -5479,20 +5658,20 @@ trimbletsip_message( } } break; - + case CMD_RSPOSXYZ: { double x = getflt((unsigned char *)&mb(0)); double y = getflt((unsigned char *)&mb(4)); double z = getflt((unsigned char *)&mb(8)); double f = getflt((unsigned char *)&mb(12)); - + if (f > 0.0) - snprintf(t, BUFFER_SIZE(pbuffer, t), "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec", + t = ap(pbuffer, sizeof(pbuffer), t, "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec", x, y, z, f); else - return; + return; } break; @@ -5501,14 +5680,14 @@ trimbletsip_message( double lat = getflt((unsigned char *)&mb(0)); double lng = getflt((unsigned char *)&mb(4)); double f = getflt((unsigned char *)&mb(12)); - + if (f > 0.0) - snprintf(t, BUFFER_SIZE(pbuffer, t), "lat %f %c, long %f %c, alt %.2fm", + t = ap(pbuffer, sizeof(pbuffer), t, "lat %f %c, long %f %c, alt %.2fm", ((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'), ((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'), getflt((unsigned char *)&mb(8))); else - return; + return; } break; @@ -5517,16 +5696,16 @@ trimbletsip_message( double x = getdbl((unsigned char *)&mb(0)); double y = getdbl((unsigned char *)&mb(8)); double z = getdbl((unsigned char *)&mb(16)); - snprintf(t, BUFFER_SIZE(pbuffer, t), "x= %.1fm, y= %.1fm, z= %.1fm", + t = ap(pbuffer, sizeof(pbuffer), t, "x= %.1fm, y= %.1fm, z= %.1fm", x, y, z); } break; - + case CMD_RDOUBLELLA: { double lat = getdbl((unsigned char *)&mb(0)); double lng = getdbl((unsigned char *)&mb(8)); - snprintf(t, BUFFER_SIZE(pbuffer, t), "lat %f %c, lon %f %c, alt %.2fm", + t = ap(pbuffer, sizeof(pbuffer), t, "lat %f %c, lon %f %c, alt %.2fm", ((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'), ((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'), getdbl((unsigned char *)&mb(16))); @@ -5536,108 +5715,97 @@ trimbletsip_message( case CMD_RALLINVIEW: { int i, sats; - - strncpy(t, "mode: ", BUFFER_SIZE(pbuffer, t)); - t += strlen(t); + + t = ap(pbuffer, sizeof(pbuffer), t, "mode: "); switch (mb(0) & 0x7) { default: - snprintf(t, BUFFER_SIZE(pbuffer, t), "0x%x", mb(0) & 0x7); + t = ap(pbuffer, sizeof(pbuffer), t, "0x%x", mb(0) & 0x7); break; case 3: - strncpy(t, "2D", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "2D"); break; - + case 4: - strncpy(t, "3D", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "3D"); break; } - t += strlen(t); if (mb(0) & 0x8) - strncpy(t, "-MANUAL, ", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "-MANUAL, "); else - strncpy(t, "-AUTO, ", BUFFER_SIZE(pbuffer, t)); - t += strlen(t); - + t = ap(pbuffer, sizeof(pbuffer), t, "-AUTO, "); + sats = (mb(0)>>4) & 0xF; - - snprintf(t, BUFFER_SIZE(pbuffer, t), "PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f, %d satellite%s in view: ", + + t = ap(pbuffer, sizeof(pbuffer), t, "PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f, %d satellite%s in view: ", getflt((unsigned char *)&mb(1)), getflt((unsigned char *)&mb(5)), getflt((unsigned char *)&mb(9)), getflt((unsigned char *)&mb(13)), sats, (sats == 1) ? "" : "s"); - t += strlen(t); for (i=0; i < sats; i++) { - snprintf(t, BUFFER_SIZE(pbuffer, t), "%s%02d", i ? ", " : "", mb(17+i)); - t += strlen(t); + t = ap(pbuffer, sizeof(pbuffer), t, "%s%02d", i ? ", " : "", mb(17+i)); if (tr) tr->ctrack |= (1 << (mb(17+i)-1)); } if (tr) - { /* mark for tracking status query */ + { /* mark for tracking status query */ tr->qtracking = 1; } } break; - + case CMD_RSTATTRACK: { - snprintf(t-2, BUFFER_SIZE(pbuffer, t-2), "[%02d]=\"", mb(0)); /* add index to var name */ - t += strlen(t); - + t = ap(pbuffer, sizeof(pbuffer), t-2, "[%02d]=\"", mb(0)); /* add index to var name */ if (getflt((unsigned char *)&mb(4)) < 0.0) { - strncpy(t, "<NO MEASUREMENTS>", BUFFER_SIZE(pbuffer, t)); - var_flag &= ~DEF; + t = ap(pbuffer, sizeof(pbuffer), t, "<NO MEASUREMENTS>"); + var_flag &= (u_short)(~DEF); } else - { - snprintf(t, BUFFER_SIZE(pbuffer, t), "ch=%d, acq=%s, eph=%d, signal_level= %5.2f, elevation= %5.2f, azimuth= %6.2f", + { + t = ap(pbuffer, sizeof(pbuffer), t, "ch=%d, acq=%s, eph=%d, signal_level= %5.2f, elevation= %5.2f, azimuth= %6.2f", (mb(1) & 0xFF)>>3, mb(2) ? ((mb(2) == 1) ? "ACQ" : "SRCH") : "NEVER", mb(3), getflt((unsigned char *)&mb(4)), getflt((unsigned char *)&mb(12)) * RTOD, getflt((unsigned char *)&mb(16)) * RTOD); - t += strlen(t); if (mb(20)) { - var_flag &= ~DEF; - strncpy(t, ", OLD", BUFFER_SIZE(pbuffer, t)); + var_flag &= (u_short)(~DEF); + t = ap(pbuffer, sizeof(pbuffer), t, ", OLD"); } - t += strlen(t); if (mb(22)) { if (mb(22) == 1) - strncpy(t, ", BAD PARITY", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, ", BAD PARITY"); else if (mb(22) == 2) - strncpy(t, ", BAD EPH HEALTH", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, ", BAD EPH HEALTH"); } - t += strlen(t); if (mb(23)) - strncpy(t, ", collecting data", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, ", collecting data"); } } break; - + default: - strncpy(t, "<UNDECODED>", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "<UNDECODED>"); break; } - t += strlen(t); - strncpy(t,"\"", BUFFER_SIZE(pbuffer, t)); + t = ap(pbuffer, sizeof(pbuffer), t, "\""); set_var(&parse->kv, pbuffer, sizeof(pbuffer), var_flag); } } - + /**============================================================ ** RAWDCF support **/ @@ -5737,13 +5905,16 @@ rawdcf_init_2( #endif /* DTR initialisation type */ #else /* defined(REFCLOCK) && defined(PARSE) */ -int refclock_parse_bs; +NONEMPTY_TRANSLATION_UNIT #endif /* defined(REFCLOCK) && defined(PARSE) */ /* * History: * * refclock_parse.c,v + * Revision 4.81 2009/05/01 10:15:29 kardel + * use new refclock_ppsapi interface + * * Revision 4.80 2007/08/11 12:06:29 kardel * update comments wrt/ to PPS * @@ -5858,7 +6029,7 @@ int refclock_parse_bs; * implement fast refclock startup * * Revision 4.50 2005/04/16 20:51:35 kardel - * set pps_enable = 1 when binding a kernel PPS source + * set hardpps_enable = 1 when binding a kernel PPS source * * Revision 4.49 2005/04/16 17:29:26 kardel * add non polling clock type 18 for just listenning to Meinberg clocks |