PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/ntp-4.2.6p5/ntpd/refclock_parse.c

#
C | 6158 lines | 5120 code | 326 blank | 712 comment | 147 complexity | 7da9ac33c84e1bc9693c191d86bdcc5b MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * /src/NTP/REPOSITORY/ntp4-dev/ntpd/refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A
  3. *
  4. * refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A
  5. *
  6. * generic reference clock driver for several DCF/GPS/MSF/... receivers
  7. *
  8. * PPS notes:
  9. * On systems that support PPSAPI (RFC2783) PPSAPI is the
  10. * preferred interface.
  11. *
  12. * Optionally make use of a STREAMS module for input processing where
  13. * available and configured. This STREAMS module reduces the time
  14. * stamp latency for serial and PPS events.
  15. * Currently the STREAMS module is only available for Suns running
  16. * SunOS 4.x and SunOS5.x.
  17. *
  18. * Copyright (c) 1995-2009 by Frank Kardel <kardel <AT> ntp.org>
  19. * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
  20. *
  21. * Redistribution and use in source and binary forms, with or without
  22. * modification, are permitted provided that the following conditions
  23. * are met:
  24. * 1. Redistributions of source code must retain the above copyright
  25. * notice, this list of conditions and the following disclaimer.
  26. * 2. Redistributions in binary form must reproduce the above copyright
  27. * notice, this list of conditions and the following disclaimer in the
  28. * documentation and/or other materials provided with the distribution.
  29. * 3. Neither the name of the author nor the names of its contributors
  30. * may be used to endorse or promote products derived from this software
  31. * without specific prior written permission.
  32. *
  33. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  34. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  36. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  37. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  38. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  39. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  40. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  41. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  42. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  43. * SUCH DAMAGE.
  44. *
  45. */
  46. #ifdef HAVE_CONFIG_H
  47. # include "config.h"
  48. #endif
  49. #if defined(REFCLOCK) && defined(CLOCK_PARSE)
  50. /*
  51. * This driver currently provides the support for
  52. * - Meinberg receiver DCF77 PZF 535 (TCXO version) (DCF)
  53. * - Meinberg receiver DCF77 PZF 535 (OCXO version) (DCF)
  54. * - Meinberg receiver DCF77 PZF 509 (DCF)
  55. * - Meinberg receiver DCF77 AM receivers (e.g. C51) (DCF)
  56. * - IGEL CLOCK (DCF)
  57. * - ELV DCF7000 (DCF)
  58. * - Schmid clock (DCF)
  59. * - Conrad DCF77 receiver module (DCF)
  60. * - FAU DCF77 NTP receiver (TimeBrick) (DCF)
  61. * - WHARTON 400A Series clock (DCF)
  62. *
  63. * - Meinberg GPS166/GPS167 (GPS)
  64. * - Trimble (TSIP and TAIP protocol) (GPS)
  65. *
  66. * - RCC8000 MSF Receiver (MSF)
  67. * - VARITEXT clock (MSF)
  68. */
  69. /*
  70. * Meinberg receivers are usually connected via a
  71. * 9600 baud serial line
  72. *
  73. * The Meinberg GPS receivers also have a special NTP time stamp
  74. * format. The firmware release is Uni-Erlangen.
  75. *
  76. * Meinberg generic receiver setup:
  77. * output time code every second
  78. * Baud rate 9600 7E2S
  79. *
  80. * Meinberg GPS16x setup:
  81. * output time code every second
  82. * Baudrate 19200 8N1
  83. *
  84. * This software supports the standard data formats used
  85. * in Meinberg receivers.
  86. *
  87. * Special software versions are only sensible for the
  88. * GPS 16x family of receivers.
  89. *
  90. * Meinberg can be reached via: http://www.meinberg.de/
  91. */
  92. #include "ntpd.h"
  93. #include "ntp_refclock.h"
  94. #include "ntp_unixtime.h" /* includes <sys/time.h> */
  95. #include "ntp_control.h"
  96. #include "ntp_string.h"
  97. #include <stdio.h>
  98. #include <ctype.h>
  99. #ifndef TM_IN_SYS_TIME
  100. # include <time.h>
  101. #endif
  102. #ifdef HAVE_UNISTD_H
  103. # include <unistd.h>
  104. #endif
  105. #if !defined(STREAM) && !defined(HAVE_SYSV_TTYS) && !defined(HAVE_BSD_TTYS) && !defined(HAVE_TERMIOS)
  106. # include "Bletch: Define one of {STREAM,HAVE_SYSV_TTYS,HAVE_TERMIOS}"
  107. #endif
  108. #ifdef STREAM
  109. # include <sys/stream.h>
  110. # include <sys/stropts.h>
  111. #endif
  112. #ifdef HAVE_TERMIOS
  113. # define TTY_GETATTR(_FD_, _ARG_) tcgetattr((_FD_), (_ARG_))
  114. # define TTY_SETATTR(_FD_, _ARG_) tcsetattr((_FD_), TCSANOW, (_ARG_))
  115. # undef HAVE_SYSV_TTYS
  116. #endif
  117. #ifdef HAVE_SYSV_TTYS
  118. # define TTY_GETATTR(_FD_, _ARG_) ioctl((_FD_), TCGETA, (_ARG_))
  119. # define TTY_SETATTR(_FD_, _ARG_) ioctl((_FD_), TCSETAW, (_ARG_))
  120. #endif
  121. #ifdef HAVE_BSD_TTYS
  122. /* #error CURRENTLY NO BSD TTY SUPPORT */
  123. # include "Bletch: BSD TTY not currently supported"
  124. #endif
  125. #ifdef HAVE_SYS_IOCTL_H
  126. # include <sys/ioctl.h>
  127. #endif
  128. #ifdef HAVE_PPSAPI
  129. # include "ppsapi_timepps.h"
  130. # include "refclock_atom.h"
  131. #endif
  132. #ifdef PPS
  133. # ifdef HAVE_SYS_PPSCLOCK_H
  134. # include <sys/ppsclock.h>
  135. # endif
  136. # ifdef HAVE_TIO_SERIAL_STUFF
  137. # include <linux/serial.h>
  138. # endif
  139. #endif
  140. #define BUFFER_SIZE(_BUF, _PTR) ((_BUF) + sizeof(_BUF) - (_PTR))
  141. #define BUFFER_SIZES(_BUF, _PTR, _SZ) ((_BUF) + (_SZ) - (_PTR))
  142. /*
  143. * document type of PPS interfacing - copy of ifdef mechanism in local_input()
  144. */
  145. #undef PPS_METHOD
  146. #ifdef HAVE_PPSAPI
  147. #define PPS_METHOD "PPS API"
  148. #else
  149. #ifdef TIOCDCDTIMESTAMP
  150. #define PPS_METHOD "TIOCDCDTIMESTAMP"
  151. #else /* TIOCDCDTIMESTAMP */
  152. #if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
  153. #ifdef HAVE_CIOGETEV
  154. #define PPS_METHOD "CIOGETEV"
  155. #endif
  156. #ifdef HAVE_TIOCGPPSEV
  157. #define PPS_METHOD "TIOCGPPSEV"
  158. #endif
  159. #endif
  160. #endif /* TIOCDCDTIMESTAMP */
  161. #endif /* HAVE_PPSAPI */
  162. #include "ntp_io.h"
  163. #include "ntp_stdlib.h"
  164. #include "parse.h"
  165. #include "mbg_gps166.h"
  166. #include "trimble.h"
  167. #include "binio.h"
  168. #include "ascii.h"
  169. #include "ieee754io.h"
  170. #include "recvbuff.h"
  171. static char rcsid[] = "refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A+POWERUPTRUST";
  172. /**===========================================================================
  173. ** external interface to ntp mechanism
  174. **/
  175. static int parse_start (int, struct peer *);
  176. static void parse_shutdown (int, struct peer *);
  177. static void parse_poll (int, struct peer *);
  178. static void parse_control (int, struct refclockstat *, struct refclockstat *, struct peer *);
  179. struct refclock refclock_parse = {
  180. parse_start,
  181. parse_shutdown,
  182. parse_poll,
  183. parse_control,
  184. noentry,
  185. noentry,
  186. NOFLAGS
  187. };
  188. /*
  189. * Definitions
  190. */
  191. #define MAXUNITS 4 /* maximum number of "PARSE" units permitted */
  192. #define PARSEDEVICE "/dev/refclock-%d" /* device to open %d is unit number */
  193. #define PARSEPPSDEVICE "/dev/refclockpps-%d" /* optional pps device to open %d is unit number */
  194. #undef ABS
  195. #define ABS(_X_) (((_X_) < 0) ? -(_X_) : (_X_))
  196. #define PARSE_HARDPPS_DISABLE 0
  197. #define PARSE_HARDPPS_ENABLE 1
  198. /**===========================================================================
  199. ** function vector for dynamically binding io handling mechanism
  200. **/
  201. struct parseunit; /* to keep inquiring minds happy */
  202. typedef struct bind
  203. {
  204. const char *bd_description; /* name of type of binding */
  205. int (*bd_init) (struct parseunit *); /* initialize */
  206. void (*bd_end) (struct parseunit *); /* end */
  207. int (*bd_setcs) (struct parseunit *, parsectl_t *); /* set character size */
  208. int (*bd_disable) (struct parseunit *); /* disable */
  209. int (*bd_enable) (struct parseunit *); /* enable */
  210. int (*bd_getfmt) (struct parseunit *, parsectl_t *); /* get format */
  211. int (*bd_setfmt) (struct parseunit *, parsectl_t *); /* setfmt */
  212. int (*bd_timecode) (struct parseunit *, parsectl_t *); /* get time code */
  213. void (*bd_receive) (struct recvbuf *); /* receive operation */
  214. int (*bd_io_input) (struct recvbuf *); /* input operation */
  215. } bind_t;
  216. #define PARSE_END(_X_) (*(_X_)->binding->bd_end)(_X_)
  217. #define PARSE_SETCS(_X_, _CS_) (*(_X_)->binding->bd_setcs)(_X_, _CS_)
  218. #define PARSE_ENABLE(_X_) (*(_X_)->binding->bd_enable)(_X_)
  219. #define PARSE_DISABLE(_X_) (*(_X_)->binding->bd_disable)(_X_)
  220. #define PARSE_GETFMT(_X_, _DCT_) (*(_X_)->binding->bd_getfmt)(_X_, _DCT_)
  221. #define PARSE_SETFMT(_X_, _DCT_) (*(_X_)->binding->bd_setfmt)(_X_, _DCT_)
  222. #define PARSE_GETTIMECODE(_X_, _DCT_) (*(_X_)->binding->bd_timecode)(_X_, _DCT_)
  223. /*
  224. * special handling flags
  225. */
  226. #define PARSE_F_PPSONSECOND 0x00000001 /* PPS pulses are on second */
  227. #define PARSE_F_POWERUPTRUST 0x00000100 /* POWERUP state ist trusted for */
  228. /* trusttime after SYNC was seen */
  229. /**===========================================================================
  230. ** error message regression handling
  231. **
  232. ** there are quite a few errors that can occur in rapid succession such as
  233. ** noisy input data or no data at all. in order to reduce the amount of
  234. ** syslog messages in such case, we are using a backoff algorithm. We limit
  235. ** the number of error messages of a certain class to 1 per time unit. if a
  236. ** configurable number of messages is displayed that way, we move on to the
  237. ** next time unit / count for that class. a count of messages that have been
  238. ** suppressed is held and displayed whenever a corresponding message is
  239. ** displayed. the time units for a message class will also be displayed.
  240. ** whenever an error condition clears we reset the error message state,
  241. ** thus we would still generate much output on pathological conditions
  242. ** where the system oscillates between OK and NOT OK states. coping
  243. ** with that condition is currently considered too complicated.
  244. **/
  245. #define ERR_ALL (unsigned)~0 /* "all" errors */
  246. #define ERR_BADDATA (unsigned)0 /* unusable input data/conversion errors */
  247. #define ERR_NODATA (unsigned)1 /* no input data */
  248. #define ERR_BADIO (unsigned)2 /* read/write/select errors */
  249. #define ERR_BADSTATUS (unsigned)3 /* unsync states */
  250. #define ERR_BADEVENT (unsigned)4 /* non nominal events */
  251. #define ERR_INTERNAL (unsigned)5 /* internal error */
  252. #define ERR_CNT (unsigned)(ERR_INTERNAL+1)
  253. #define ERR(_X_) if (list_err(parse, (_X_)))
  254. struct errorregression
  255. {
  256. u_long err_count; /* number of repititions per class */
  257. u_long err_delay; /* minimum delay between messages */
  258. };
  259. static struct errorregression
  260. err_baddata[] = /* error messages for bad input data */
  261. {
  262. { 1, 0 }, /* output first message immediately */
  263. { 5, 60 }, /* output next five messages in 60 second intervals */
  264. { 3, 3600 }, /* output next 3 messages in hour intervals */
  265. { 0, 12*3600 } /* repeat messages only every 12 hours */
  266. };
  267. static struct errorregression
  268. err_nodata[] = /* error messages for missing input data */
  269. {
  270. { 1, 0 }, /* output first message immediately */
  271. { 5, 60 }, /* output next five messages in 60 second intervals */
  272. { 3, 3600 }, /* output next 3 messages in hour intervals */
  273. { 0, 12*3600 } /* repeat messages only every 12 hours */
  274. };
  275. static struct errorregression
  276. err_badstatus[] = /* unsynchronized state messages */
  277. {
  278. { 1, 0 }, /* output first message immediately */
  279. { 5, 60 }, /* output next five messages in 60 second intervals */
  280. { 3, 3600 }, /* output next 3 messages in hour intervals */
  281. { 0, 12*3600 } /* repeat messages only every 12 hours */
  282. };
  283. static struct errorregression
  284. err_badio[] = /* io failures (bad reads, selects, ...) */
  285. {
  286. { 1, 0 }, /* output first message immediately */
  287. { 5, 60 }, /* output next five messages in 60 second intervals */
  288. { 5, 3600 }, /* output next 3 messages in hour intervals */
  289. { 0, 12*3600 } /* repeat messages only every 12 hours */
  290. };
  291. static struct errorregression
  292. err_badevent[] = /* non nominal events */
  293. {
  294. { 20, 0 }, /* output first message immediately */
  295. { 6, 60 }, /* output next five messages in 60 second intervals */
  296. { 5, 3600 }, /* output next 3 messages in hour intervals */
  297. { 0, 12*3600 } /* repeat messages only every 12 hours */
  298. };
  299. static struct errorregression
  300. err_internal[] = /* really bad things - basically coding/OS errors */
  301. {
  302. { 0, 0 }, /* output all messages immediately */
  303. };
  304. static struct errorregression *
  305. err_tbl[] =
  306. {
  307. err_baddata,
  308. err_nodata,
  309. err_badio,
  310. err_badstatus,
  311. err_badevent,
  312. err_internal
  313. };
  314. struct errorinfo
  315. {
  316. u_long err_started; /* begin time (ntp) of error condition */
  317. u_long err_last; /* last time (ntp) error occurred */
  318. u_long err_cnt; /* number of error repititions */
  319. u_long err_suppressed; /* number of suppressed messages */
  320. struct errorregression *err_stage; /* current error stage */
  321. };
  322. /**===========================================================================
  323. ** refclock instance data
  324. **/
  325. struct parseunit
  326. {
  327. /*
  328. * NTP management
  329. */
  330. struct peer *peer; /* backlink to peer structure - refclock inactive if 0 */
  331. struct refclockproc *generic; /* backlink to refclockproc structure */
  332. /*
  333. * PARSE io
  334. */
  335. bind_t *binding; /* io handling binding */
  336. /*
  337. * parse state
  338. */
  339. parse_t parseio; /* io handling structure (user level parsing) */
  340. /*
  341. * type specific parameters
  342. */
  343. struct parse_clockinfo *parse_type; /* link to clock description */
  344. /*
  345. * clock state handling/reporting
  346. */
  347. u_char flags; /* flags (leap_control) */
  348. u_long lastchange; /* time (ntp) when last state change accured */
  349. u_long statetime[CEVNT_MAX+1]; /* accumulated time of clock states */
  350. u_long pollneeddata; /* current_time(!=0) for receive sample expected in PPS mode */
  351. u_short lastformat; /* last format used */
  352. u_long lastsync; /* time (ntp) when clock was last seen fully synchronized */
  353. u_long maxunsync; /* max time in seconds a receiver is trusted after loosing synchronisation */
  354. double ppsphaseadjust; /* phase adjustment of PPS time stamp */
  355. u_long lastmissed; /* time (ntp) when poll didn't get data (powerup heuristic) */
  356. u_long ppsserial; /* magic cookie for ppsclock serials (avoids stale ppsclock data) */
  357. int ppsfd; /* fd to ise for PPS io */
  358. #ifdef HAVE_PPSAPI
  359. int hardppsstate; /* current hard pps state */
  360. struct refclock_atom atom; /* PPSAPI structure */
  361. #endif
  362. parsetime_t timedata; /* last (parse module) data */
  363. void *localdata; /* optional local, receiver-specific data */
  364. unsigned long localstate; /* private local state */
  365. struct errorinfo errors[ERR_CNT]; /* error state table for suppressing excessive error messages */
  366. struct ctl_var *kv; /* additional pseudo variables */
  367. u_long laststatistic; /* time when staticstics where output */
  368. };
  369. /**===========================================================================
  370. ** Clockinfo section all parameter for specific clock types
  371. ** includes NTP parameters, TTY parameters and IO handling parameters
  372. **/
  373. static void poll_dpoll (struct parseunit *);
  374. static void poll_poll (struct peer *);
  375. static int poll_init (struct parseunit *);
  376. typedef struct poll_info
  377. {
  378. u_long rate; /* poll rate - once every "rate" seconds - 0 off */
  379. const char *string; /* string to send for polling */
  380. u_long count; /* number of characters in string */
  381. } poll_info_t;
  382. #define NO_CL_FLAGS 0
  383. #define NO_POLL 0
  384. #define NO_INIT 0
  385. #define NO_END 0
  386. #define NO_EVENT 0
  387. #define NO_LCLDATA 0
  388. #define NO_MESSAGE 0
  389. #define NO_PPSDELAY 0
  390. #define DCF_ID "DCF" /* generic DCF */
  391. #define DCF_A_ID "DCFa" /* AM demodulation */
  392. #define DCF_P_ID "DCFp" /* psuedo random phase shift */
  393. #define GPS_ID "GPS" /* GPS receiver */
  394. #define NOCLOCK_ROOTDELAY 0.0
  395. #define NOCLOCK_BASEDELAY 0.0
  396. #define NOCLOCK_DESCRIPTION 0
  397. #define NOCLOCK_MAXUNSYNC 0
  398. #define NOCLOCK_CFLAG 0
  399. #define NOCLOCK_IFLAG 0
  400. #define NOCLOCK_OFLAG 0
  401. #define NOCLOCK_LFLAG 0
  402. #define NOCLOCK_ID "TILT"
  403. #define NOCLOCK_POLL NO_POLL
  404. #define NOCLOCK_INIT NO_INIT
  405. #define NOCLOCK_END NO_END
  406. #define NOCLOCK_DATA NO_LCLDATA
  407. #define NOCLOCK_FORMAT ""
  408. #define NOCLOCK_TYPE CTL_SST_TS_UNSPEC
  409. #define NOCLOCK_SAMPLES 0
  410. #define NOCLOCK_KEEP 0
  411. #define DCF_TYPE CTL_SST_TS_LF
  412. #define GPS_TYPE CTL_SST_TS_UHF
  413. /*
  414. * receiver specific constants
  415. */
  416. #define MBG_SPEED (B9600)
  417. #define MBG_CFLAG (CS7|PARENB|CREAD|CLOCAL|HUPCL|CSTOPB)
  418. #define MBG_IFLAG (IGNBRK|IGNPAR|ISTRIP)
  419. #define MBG_OFLAG 0
  420. #define MBG_LFLAG 0
  421. #define MBG_FLAGS PARSE_F_PPSONSECOND
  422. /*
  423. * Meinberg DCF77 receivers
  424. */
  425. #define DCFUA31_ROOTDELAY 0.0 /* 0 */
  426. #define DCFUA31_BASEDELAY 0.010 /* 10.7421875ms: 10 ms (+/- 3 ms) */
  427. #define DCFUA31_DESCRIPTION "Meinberg DCF77 C51 or compatible"
  428. #define DCFUA31_MAXUNSYNC 60*30 /* only trust clock for 1/2 hour */
  429. #define DCFUA31_SPEED MBG_SPEED
  430. #define DCFUA31_CFLAG MBG_CFLAG
  431. #define DCFUA31_IFLAG MBG_IFLAG
  432. #define DCFUA31_OFLAG MBG_OFLAG
  433. #define DCFUA31_LFLAG MBG_LFLAG
  434. #define DCFUA31_SAMPLES 5
  435. #define DCFUA31_KEEP 3
  436. #define DCFUA31_FORMAT "Meinberg Standard"
  437. /*
  438. * Meinberg DCF PZF535/TCXO (FM/PZF) receiver
  439. */
  440. #define DCFPZF535_ROOTDELAY 0.0
  441. #define DCFPZF535_BASEDELAY 0.001968 /* 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
  442. #define DCFPZF535_DESCRIPTION "Meinberg DCF PZF 535/509 / TCXO"
  443. #define DCFPZF535_MAXUNSYNC 60*60*12 /* only trust clock for 12 hours
  444. * @ 5e-8df/f we have accumulated
  445. * at most 2.16 ms (thus we move to
  446. * NTP synchronisation */
  447. #define DCFPZF535_SPEED MBG_SPEED
  448. #define DCFPZF535_CFLAG MBG_CFLAG
  449. #define DCFPZF535_IFLAG MBG_IFLAG
  450. #define DCFPZF535_OFLAG MBG_OFLAG
  451. #define DCFPZF535_LFLAG MBG_LFLAG
  452. #define DCFPZF535_SAMPLES 5
  453. #define DCFPZF535_KEEP 3
  454. #define DCFPZF535_FORMAT "Meinberg Standard"
  455. /*
  456. * Meinberg DCF PZF535/OCXO receiver
  457. */
  458. #define DCFPZF535OCXO_ROOTDELAY 0.0
  459. #define DCFPZF535OCXO_BASEDELAY 0.001968 /* 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
  460. #define DCFPZF535OCXO_DESCRIPTION "Meinberg DCF PZF 535/509 / OCXO"
  461. #define DCFPZF535OCXO_MAXUNSYNC 60*60*96 /* only trust clock for 4 days
  462. * @ 5e-9df/f we have accumulated
  463. * at most an error of 1.73 ms
  464. * (thus we move to NTP synchronisation) */
  465. #define DCFPZF535OCXO_SPEED MBG_SPEED
  466. #define DCFPZF535OCXO_CFLAG MBG_CFLAG
  467. #define DCFPZF535OCXO_IFLAG MBG_IFLAG
  468. #define DCFPZF535OCXO_OFLAG MBG_OFLAG
  469. #define DCFPZF535OCXO_LFLAG MBG_LFLAG
  470. #define DCFPZF535OCXO_SAMPLES 5
  471. #define DCFPZF535OCXO_KEEP 3
  472. #define DCFPZF535OCXO_FORMAT "Meinberg Standard"
  473. /*
  474. * Meinberg GPS16X receiver
  475. */
  476. static void gps16x_message (struct parseunit *, parsetime_t *);
  477. static int gps16x_poll_init (struct parseunit *);
  478. #define GPS16X_ROOTDELAY 0.0 /* nothing here */
  479. #define GPS16X_BASEDELAY 0.001968 /* XXX to be fixed ! 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
  480. #define GPS16X_DESCRIPTION "Meinberg GPS16x receiver"
  481. #define GPS16X_MAXUNSYNC 60*60*96 /* only trust clock for 4 days
  482. * @ 5e-9df/f we have accumulated
  483. * at most an error of 1.73 ms
  484. * (thus we move to NTP synchronisation) */
  485. #define GPS16X_SPEED B19200
  486. #define GPS16X_CFLAG (CS8|CREAD|CLOCAL|HUPCL)
  487. #define GPS16X_IFLAG (IGNBRK|IGNPAR)
  488. #define GPS16X_OFLAG MBG_OFLAG
  489. #define GPS16X_LFLAG MBG_LFLAG
  490. #define GPS16X_POLLRATE 6
  491. #define GPS16X_POLLCMD ""
  492. #define GPS16X_CMDSIZE 0
  493. static poll_info_t gps16x_pollinfo = { GPS16X_POLLRATE, GPS16X_POLLCMD, GPS16X_CMDSIZE };
  494. #define GPS16X_INIT gps16x_poll_init
  495. #define GPS16X_POLL 0
  496. #define GPS16X_END 0
  497. #define GPS16X_DATA ((void *)(&gps16x_pollinfo))
  498. #define GPS16X_MESSAGE gps16x_message
  499. #define GPS16X_ID GPS_ID
  500. #define GPS16X_FORMAT "Meinberg GPS Extended"
  501. #define GPS16X_SAMPLES 5
  502. #define GPS16X_KEEP 3
  503. /*
  504. * ELV DCF7000 Wallclock-Receiver/Switching Clock (Kit)
  505. *
  506. * This is really not the hottest clock - but before you have nothing ...
  507. */
  508. #define DCF7000_ROOTDELAY 0.0 /* 0 */
  509. #define DCF7000_BASEDELAY 0.405 /* slow blow */
  510. #define DCF7000_DESCRIPTION "ELV DCF7000"
  511. #define DCF7000_MAXUNSYNC (60*5) /* sorry - but it just was not build as a clock */
  512. #define DCF7000_SPEED (B9600)
  513. #define DCF7000_CFLAG (CS8|CREAD|PARENB|PARODD|CLOCAL|HUPCL)
  514. #define DCF7000_IFLAG (IGNBRK)
  515. #define DCF7000_OFLAG 0
  516. #define DCF7000_LFLAG 0
  517. #define DCF7000_SAMPLES 5
  518. #define DCF7000_KEEP 3
  519. #define DCF7000_FORMAT "ELV DCF7000"
  520. /*
  521. * Schmid DCF Receiver Kit
  522. *
  523. * When the WSDCF clock is operating optimally we want the primary clock
  524. * distance to come out at 300 ms. Thus, peer.distance in the WSDCF peer
  525. * structure is set to 290 ms and we compute delays which are at least
  526. * 10 ms long. The following are 290 ms and 10 ms expressed in u_fp format
  527. */
  528. #define WS_POLLRATE 1 /* every second - watch interdependency with poll routine */
  529. #define WS_POLLCMD "\163"
  530. #define WS_CMDSIZE 1
  531. static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE };
  532. #define WSDCF_INIT poll_init
  533. #define WSDCF_POLL poll_dpoll
  534. #define WSDCF_END 0
  535. #define WSDCF_DATA ((void *)(&wsdcf_pollinfo))
  536. #define WSDCF_ROOTDELAY 0.0 /* 0 */
  537. #define WSDCF_BASEDELAY 0.010 /* ~ 10ms */
  538. #define WSDCF_DESCRIPTION "WS/DCF Receiver"
  539. #define WSDCF_FORMAT "Schmid"
  540. #define WSDCF_MAXUNSYNC (60*60) /* assume this beast hold at 1 h better than 2 ms XXX-must verify */
  541. #define WSDCF_SPEED (B1200)
  542. #define WSDCF_CFLAG (CS8|CREAD|CLOCAL)
  543. #define WSDCF_IFLAG 0
  544. #define WSDCF_OFLAG 0
  545. #define WSDCF_LFLAG 0
  546. #define WSDCF_SAMPLES 5
  547. #define WSDCF_KEEP 3
  548. /*
  549. * RAW DCF77 - input of DCF marks via RS232 - many variants
  550. */
  551. #define RAWDCF_FLAGS 0
  552. #define RAWDCF_ROOTDELAY 0.0 /* 0 */
  553. #define RAWDCF_BASEDELAY 0.258
  554. #define RAWDCF_FORMAT "RAW DCF77 Timecode"
  555. #define RAWDCF_MAXUNSYNC (0) /* sorry - its a true receiver - no signal - no time */
  556. #define RAWDCF_SPEED (B50)
  557. #ifdef NO_PARENB_IGNPAR /* Was: defined(SYS_IRIX4) || defined(SYS_IRIX5) */
  558. /* somehow doesn't grok PARENB & IGNPAR (mj) */
  559. # define RAWDCF_CFLAG (CS8|CREAD|CLOCAL)
  560. #else
  561. # define RAWDCF_CFLAG (CS8|CREAD|CLOCAL|PARENB)
  562. #endif
  563. #ifdef RAWDCF_NO_IGNPAR /* Was: defined(SYS_LINUX) && defined(CLOCK_RAWDCF) */
  564. # define RAWDCF_IFLAG 0
  565. #else
  566. # define RAWDCF_IFLAG (IGNPAR)
  567. #endif
  568. #define RAWDCF_OFLAG 0
  569. #define RAWDCF_LFLAG 0
  570. #define RAWDCF_SAMPLES 20
  571. #define RAWDCF_KEEP 12
  572. #define RAWDCF_INIT 0
  573. /*
  574. * RAW DCF variants
  575. */
  576. /*
  577. * Conrad receiver
  578. *
  579. * simplest (cheapest) DCF clock - e. g. DCF77 receiver by Conrad
  580. * (~40DM - roughly $30 ) followed by a level converter for RS232
  581. */
  582. #define CONRAD_BASEDELAY 0.292 /* Conrad receiver @ 50 Baud on a Sun */
  583. #define CONRAD_DESCRIPTION "RAW DCF77 CODE (Conrad DCF77 receiver module)"
  584. /* Gude Analog- und Digitalsystem GmbH 'Expert mouseCLOCK USB v2.0' */
  585. #define GUDE_EMC_USB_V20_SPEED (B4800)
  586. #define GUDE_EMC_USB_V20_BASEDELAY 0.425 /* USB serial<->USB converter FTDI232R */
  587. #define GUDE_EMC_USB_V20_DESCRIPTION "RAW DCF77 CODE (Expert mouseCLOCK USB v2.0)"
  588. /*
  589. * TimeBrick receiver
  590. */
  591. #define TIMEBRICK_BASEDELAY 0.210 /* TimeBrick @ 50 Baud on a Sun */
  592. #define TIMEBRICK_DESCRIPTION "RAW DCF77 CODE (TimeBrick)"
  593. /*
  594. * IGEL:clock receiver
  595. */
  596. #define IGELCLOCK_BASEDELAY 0.258 /* IGEL:clock receiver */
  597. #define IGELCLOCK_DESCRIPTION "RAW DCF77 CODE (IGEL:clock)"
  598. #define IGELCLOCK_SPEED (B1200)
  599. #define IGELCLOCK_CFLAG (CS8|CREAD|HUPCL|CLOCAL)
  600. /*
  601. * RAWDCF receivers that need to be powered from DTR
  602. * (like Expert mouse clock)
  603. */
  604. static int rawdcf_init_1 (struct parseunit *);
  605. #define RAWDCFDTRSET_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR)"
  606. #define RAWDCFDTRSET75_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR @ 75 baud)"
  607. #define RAWDCFDTRSET_INIT rawdcf_init_1
  608. /*
  609. * RAWDCF receivers that need to be powered from
  610. * DTR CLR and RTS SET
  611. */
  612. static int rawdcf_init_2 (struct parseunit *);
  613. #define RAWDCFDTRCLRRTSSET_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET)"
  614. #define RAWDCFDTRCLRRTSSET75_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET @ 75 baud)"
  615. #define RAWDCFDTRCLRRTSSET_INIT rawdcf_init_2
  616. /*
  617. * Trimble GPS receivers (TAIP and TSIP protocols)
  618. */
  619. #ifndef TRIM_POLLRATE
  620. #define TRIM_POLLRATE 0 /* only true direct polling */
  621. #endif
  622. #define TRIM_TAIPPOLLCMD ">SRM;FR_FLAG=F;EC_FLAG=F<>QTM<"
  623. #define TRIM_TAIPCMDSIZE (sizeof(TRIM_TAIPPOLLCMD)-1)
  624. static poll_info_t trimbletaip_pollinfo = { TRIM_POLLRATE, TRIM_TAIPPOLLCMD, TRIM_TAIPCMDSIZE };
  625. static int trimbletaip_init (struct parseunit *);
  626. static void trimbletaip_event (struct parseunit *, int);
  627. /* query time & UTC correction data */
  628. static char tsipquery[] = { DLE, 0x21, DLE, ETX, DLE, 0x2F, DLE, ETX };
  629. static poll_info_t trimbletsip_pollinfo = { TRIM_POLLRATE, tsipquery, sizeof(tsipquery) };
  630. static int trimbletsip_init (struct parseunit *);
  631. static void trimbletsip_end (struct parseunit *);
  632. static void trimbletsip_message (struct parseunit *, parsetime_t *);
  633. static void trimbletsip_event (struct parseunit *, int);
  634. #define TRIMBLETSIP_IDLE_TIME (300) /* 5 minutes silence at most */
  635. #define TRIMBLE_RESET_HOLDOFF TRIMBLETSIP_IDLE_TIME
  636. #define TRIMBLETAIP_SPEED (B4800)
  637. #define TRIMBLETAIP_CFLAG (CS8|CREAD|CLOCAL)
  638. #define TRIMBLETAIP_IFLAG (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON)
  639. #define TRIMBLETAIP_OFLAG (OPOST|ONLCR)
  640. #define TRIMBLETAIP_LFLAG (0)
  641. #define TRIMBLETSIP_SPEED (B9600)
  642. #define TRIMBLETSIP_CFLAG (CS8|CLOCAL|CREAD|PARENB|PARODD)
  643. #define TRIMBLETSIP_IFLAG (IGNBRK)
  644. #define TRIMBLETSIP_OFLAG (0)
  645. #define TRIMBLETSIP_LFLAG (ICANON)
  646. #define TRIMBLETSIP_SAMPLES 5
  647. #define TRIMBLETSIP_KEEP 3
  648. #define TRIMBLETAIP_SAMPLES 5
  649. #define TRIMBLETAIP_KEEP 3
  650. #define TRIMBLETAIP_FLAGS (PARSE_F_PPSONSECOND)
  651. #define TRIMBLETSIP_FLAGS (TRIMBLETAIP_FLAGS)
  652. #define TRIMBLETAIP_POLL poll_dpoll
  653. #define TRIMBLETSIP_POLL poll_dpoll
  654. #define TRIMBLETAIP_INIT trimbletaip_init
  655. #define TRIMBLETSIP_INIT trimbletsip_init
  656. #define TRIMBLETAIP_EVENT trimbletaip_event
  657. #define TRIMBLETSIP_EVENT trimbletsip_event
  658. #define TRIMBLETSIP_MESSAGE trimbletsip_message
  659. #define TRIMBLETAIP_END 0
  660. #define TRIMBLETSIP_END trimbletsip_end
  661. #define TRIMBLETAIP_DATA ((void *)(&trimbletaip_pollinfo))
  662. #define TRIMBLETSIP_DATA ((void *)(&trimbletsip_pollinfo))
  663. #define TRIMBLETAIP_ID GPS_ID
  664. #define TRIMBLETSIP_ID GPS_ID
  665. #define TRIMBLETAIP_FORMAT "Trimble TAIP"
  666. #define TRIMBLETSIP_FORMAT "Trimble TSIP"
  667. #define TRIMBLETAIP_ROOTDELAY 0x0
  668. #define TRIMBLETSIP_ROOTDELAY 0x0
  669. #define TRIMBLETAIP_BASEDELAY 0.0
  670. #define TRIMBLETSIP_BASEDELAY 0.020 /* GPS time message latency */
  671. #define TRIMBLETAIP_DESCRIPTION "Trimble GPS (TAIP) receiver"
  672. #define TRIMBLETSIP_DESCRIPTION "Trimble GPS (TSIP) receiver"
  673. #define TRIMBLETAIP_MAXUNSYNC 0
  674. #define TRIMBLETSIP_MAXUNSYNC 0
  675. #define TRIMBLETAIP_EOL '<'
  676. /*
  677. * RadioCode Clocks RCC 800 receiver
  678. */
  679. #define RCC_POLLRATE 0 /* only true direct polling */
  680. #define RCC_POLLCMD "\r"
  681. #define RCC_CMDSIZE 1
  682. static poll_info_t rcc8000_pollinfo = { RCC_POLLRATE, RCC_POLLCMD, RCC_CMDSIZE };
  683. #define RCC8000_FLAGS 0
  684. #define RCC8000_POLL poll_dpoll
  685. #define RCC8000_INIT poll_init
  686. #define RCC8000_END 0
  687. #define RCC8000_DATA ((void *)(&rcc8000_pollinfo))
  688. #define RCC8000_ROOTDELAY 0.0
  689. #define RCC8000_BASEDELAY 0.0
  690. #define RCC8000_ID "MSF"
  691. #define RCC8000_DESCRIPTION "RCC 8000 MSF Receiver"
  692. #define RCC8000_FORMAT "Radiocode RCC8000"
  693. #define RCC8000_MAXUNSYNC (60*60) /* should be ok for an hour */
  694. #define RCC8000_SPEED (B2400)
  695. #define RCC8000_CFLAG (CS8|CREAD|CLOCAL)
  696. #define RCC8000_IFLAG (IGNBRK|IGNPAR)
  697. #define RCC8000_OFLAG 0
  698. #define RCC8000_LFLAG 0
  699. #define RCC8000_SAMPLES 5
  700. #define RCC8000_KEEP 3
  701. /*
  702. * Hopf Radio clock 6021 Format
  703. *
  704. */
  705. #define HOPF6021_ROOTDELAY 0.0
  706. #define HOPF6021_BASEDELAY 0.0
  707. #define HOPF6021_DESCRIPTION "HOPF 6021"
  708. #define HOPF6021_FORMAT "hopf Funkuhr 6021"
  709. #define HOPF6021_MAXUNSYNC (60*60) /* should be ok for an hour */
  710. #define HOPF6021_SPEED (B9600)
  711. #define HOPF6021_CFLAG (CS8|CREAD|CLOCAL)
  712. #define HOPF6021_IFLAG (IGNBRK|ISTRIP)
  713. #define HOPF6021_OFLAG 0
  714. #define HOPF6021_LFLAG 0
  715. #define HOPF6021_FLAGS 0
  716. #define HOPF6021_SAMPLES 5
  717. #define HOPF6021_KEEP 3
  718. /*
  719. * Diem's Computime Radio Clock Receiver
  720. */
  721. #define COMPUTIME_FLAGS 0
  722. #define COMPUTIME_ROOTDELAY 0.0
  723. #define COMPUTIME_BASEDELAY 0.0
  724. #define COMPUTIME_ID DCF_ID
  725. #define COMPUTIME_DESCRIPTION "Diem's Computime receiver"
  726. #define COMPUTIME_FORMAT "Diem's Computime Radio Clock"
  727. #define COMPUTIME_TYPE DCF_TYPE
  728. #define COMPUTIME_MAXUNSYNC (60*60) /* only trust clock for 1 hour */
  729. #define COMPUTIME_SPEED (B9600)
  730. #define COMPUTIME_CFLAG (CSTOPB|CS7|CREAD|CLOCAL)
  731. #define COMPUTIME_IFLAG (IGNBRK|IGNPAR|ISTRIP)
  732. #define COMPUTIME_OFLAG 0
  733. #define COMPUTIME_LFLAG 0
  734. #define COMPUTIME_SAMPLES 5
  735. #define COMPUTIME_KEEP 3
  736. /*
  737. * Varitext Radio Clock Receiver
  738. */
  739. #define VARITEXT_FLAGS 0
  740. #define VARITEXT_ROOTDELAY 0.0
  741. #define VARITEXT_BASEDELAY 0.0
  742. #define VARITEXT_ID "MSF"
  743. #define VARITEXT_DESCRIPTION "Varitext receiver"
  744. #define VARITEXT_FORMAT "Varitext Radio Clock"
  745. #define VARITEXT_TYPE DCF_TYPE
  746. #define VARITEXT_MAXUNSYNC (60*60) /* only trust clock for 1 hour */
  747. #define VARITEXT_SPEED (B9600)
  748. #define VARITEXT_CFLAG (CS7|CREAD|CLOCAL|PARENB|PARODD)
  749. #define VARITEXT_IFLAG (IGNPAR|IGNBRK|INPCK) /*|ISTRIP)*/
  750. #define VARITEXT_OFLAG 0
  751. #define VARITEXT_LFLAG 0
  752. #define VARITEXT_SAMPLES 32
  753. #define VARITEXT_KEEP 20
  754. static struct parse_clockinfo
  755. {
  756. u_long cl_flags; /* operation flags (PPS interpretation, trust handling) */
  757. void (*cl_poll) (struct parseunit *); /* active poll routine */
  758. int (*cl_init) (struct parseunit *); /* active poll init routine */
  759. void (*cl_event) (struct parseunit *, int); /* special event handling (e.g. reset clock) */
  760. void (*cl_end) (struct parseunit *); /* active poll end routine */
  761. void (*cl_message) (struct parseunit *, parsetime_t *); /* process a lower layer message */
  762. void *cl_data; /* local data area for "poll" mechanism */
  763. double cl_rootdelay; /* rootdelay */
  764. double cl_basedelay; /* current offset by which the RS232
  765. time code is delayed from the actual time */
  766. const char *cl_id; /* ID code */
  767. const char *cl_description; /* device name */
  768. const char *cl_format; /* fixed format */
  769. u_char cl_type; /* clock type (ntp control) */
  770. u_long cl_maxunsync; /* time to trust oscillator after losing synch */
  771. u_long cl_speed; /* terminal input & output baudrate */
  772. u_long cl_cflag; /* terminal control flags */
  773. u_long cl_iflag; /* terminal input flags */
  774. u_long cl_oflag; /* terminal output flags */
  775. u_long cl_lflag; /* terminal local flags */
  776. u_long cl_samples; /* samples for median filter */
  777. u_long cl_keep; /* samples for median filter to keep */
  778. } parse_clockinfo[] =
  779. {
  780. { /* mode 0 */
  781. MBG_FLAGS,
  782. NO_POLL,
  783. NO_INIT,
  784. NO_EVENT,
  785. NO_END,
  786. NO_MESSAGE,
  787. NO_LCLDATA,
  788. DCFPZF535_ROOTDELAY,
  789. DCFPZF535_BASEDELAY,
  790. DCF_P_ID,
  791. DCFPZF535_DESCRIPTION,
  792. DCFPZF535_FORMAT,
  793. DCF_TYPE,
  794. DCFPZF535_MAXUNSYNC,
  795. DCFPZF535_SPEED,
  796. DCFPZF535_CFLAG,
  797. DCFPZF535_IFLAG,
  798. DCFPZF535_OFLAG,
  799. DCFPZF535_LFLAG,
  800. DCFPZF535_SAMPLES,
  801. DCFPZF535_KEEP
  802. },
  803. { /* mode 1 */
  804. MBG_FLAGS,
  805. NO_POLL,
  806. NO_INIT,
  807. NO_EVENT,
  808. NO_END,
  809. NO_MESSAGE,
  810. NO_LCLDATA,
  811. DCFPZF535OCXO_ROOTDELAY,
  812. DCFPZF535OCXO_BASEDELAY,
  813. DCF_P_ID,
  814. DCFPZF535OCXO_DESCRIPTION,
  815. DCFPZF535OCXO_FORMAT,
  816. DCF_TYPE,
  817. DCFPZF535OCXO_MAXUNSYNC,
  818. DCFPZF535OCXO_SPEED,
  819. DCFPZF535OCXO_CFLAG,
  820. DCFPZF535OCXO_IFLAG,
  821. DCFPZF535OCXO_OFLAG,
  822. DCFPZF535OCXO_LFLAG,
  823. DCFPZF535OCXO_SAMPLES,
  824. DCFPZF535OCXO_KEEP
  825. },
  826. { /* mode 2 */
  827. MBG_FLAGS,
  828. NO_POLL,
  829. NO_INIT,
  830. NO_EVENT,
  831. NO_END,
  832. NO_MESSAGE,
  833. NO_LCLDATA,
  834. DCFUA31_ROOTDELAY,
  835. DCFUA31_BASEDELAY,
  836. DCF_A_ID,
  837. DCFUA31_DESCRIPTION,
  838. DCFUA31_FORMAT,
  839. DCF_TYPE,
  840. DCFUA31_MAXUNSYNC,
  841. DCFUA31_SPEED,
  842. DCFUA31_CFLAG,
  843. DCFUA31_IFLAG,
  844. DCFUA31_OFLAG,
  845. DCFUA31_LFLAG,
  846. DCFUA31_SAMPLES,
  847. DCFUA31_KEEP
  848. },
  849. { /* mode 3 */
  850. MBG_FLAGS,
  851. NO_POLL,
  852. NO_INIT,
  853. NO_EVENT,
  854. NO_END,
  855. NO_MESSAGE,
  856. NO_LCLDATA,
  857. DCF7000_ROOTDELAY,
  858. DCF7000_BASEDELAY,
  859. DCF_A_ID,
  860. DCF7000_DESCRIPTION,
  861. DCF7000_FORMAT,
  862. DCF_TYPE,
  863. DCF7000_MAXUNSYNC,
  864. DCF7000_SPEED,
  865. DCF7000_CFLAG,
  866. DCF7000_IFLAG,
  867. DCF7000_OFLAG,
  868. DCF7000_LFLAG,
  869. DCF7000_SAMPLES,
  870. DCF7000_KEEP
  871. },
  872. { /* mode 4 */
  873. NO_CL_FLAGS,
  874. WSDCF_POLL,
  875. WSDCF_INIT,
  876. NO_EVENT,
  877. WSDCF_END,
  878. NO_MESSAGE,
  879. WSDCF_DATA,
  880. WSDCF_ROOTDELAY,
  881. WSDCF_BASEDELAY,
  882. DCF_A_ID,
  883. WSDCF_DESCRIPTION,
  884. WSDCF_FORMAT,
  885. DCF_TYPE,
  886. WSDCF_MAXUNSYNC,
  887. WSDCF_SPEED,
  888. WSDCF_CFLAG,
  889. WSDCF_IFLAG,
  890. WSDCF_OFLAG,
  891. WSDCF_LFLAG,
  892. WSDCF_SAMPLES,
  893. WSDCF_KEEP
  894. },
  895. { /* mode 5 */
  896. RAWDCF_FLAGS,
  897. NO_POLL,
  898. RAWDCF_INIT,
  899. NO_EVENT,
  900. NO_END,
  901. NO_MESSAGE,
  902. NO_LCLDATA,
  903. RAWDCF_ROOTDELAY,
  904. CONRAD_BASEDELAY,
  905. DCF_A_ID,
  906. CONRAD_DESCRIPTION,
  907. RAWDCF_FORMAT,
  908. DCF_TYPE,
  909. RAWDCF_MAXUNSYNC,
  910. RAWDCF_SPEED,
  911. RAWDCF_CFLAG,
  912. RAWDCF_IFLAG,
  913. RAWDCF_OFLAG,
  914. RAWDCF_LFLAG,
  915. RAWDCF_SAMPLES,
  916. RAWDCF_KEEP
  917. },
  918. { /* mode 6 */
  919. RAWDCF_FLAGS,
  920. NO_POLL,
  921. RAWDCF_INIT,
  922. NO_EVENT,
  923. NO_END,
  924. NO_MESSAGE,
  925. NO_LCLDATA,
  926. RAWDCF_ROOTDELAY,
  927. TIMEBRICK_BASEDELAY,
  928. DCF_A_ID,
  929. TIMEBRICK_DESCRIPTION,
  930. RAWDCF_FORMAT,
  931. DCF_TYPE,
  932. RAWDCF_MAXUNSYNC,
  933. RAWDCF_SPEED,
  934. RAWDCF_CFLAG,
  935. RAWDCF_IFLAG,
  936. RAWDCF_OFLAG,
  937. RAWDCF_LFLAG,
  938. RAWDCF_SAMPLES,
  939. RAWDCF_KEEP
  940. },
  941. { /* mode 7 */
  942. MBG_FLAGS,
  943. GPS16X_POLL,
  944. GPS16X_INIT,
  945. NO_EVENT,
  946. GPS16X_END,
  947. GPS16X_MESSAGE,
  948. GPS16X_DATA,
  949. GPS16X_ROOTDELAY,
  950. GPS16X_BASEDELAY,
  951. GPS16X_ID,
  952. GPS16X_DESCRIPTION,
  953. GPS16X_FORMAT,
  954. GPS_TYPE,
  955. GPS16X_MAXUNSYNC,
  956. GPS16X_SPEED,
  957. GPS16X_CFLAG,
  958. GPS16X_IFLAG,
  959. GPS16X_OFLAG,
  960. GPS16X_LFLAG,
  961. GPS16X_SAMPLES,
  962. GPS16X_KEEP
  963. },
  964. { /* mode 8 */
  965. RAWDCF_FLAGS,
  966. NO_POLL,
  967. NO_INIT,
  968. NO_EVENT,
  969. NO_END,
  970. NO_MESSAGE,
  971. NO_LCLDATA,
  972. RAWDCF_ROOTDELAY,
  973. IGELCLOCK_BASEDELAY,
  974. DCF_A_ID,
  975. IGELCLOCK_DESCRIPTION,
  976. RAWDCF_FORMAT,
  977. DCF_TYPE,
  978. RAWDCF_MAXUNSYNC,
  979. IGELCLOCK_SPEED,
  980. IGELCLOCK_CFLAG,
  981. RAWDCF_IFLAG,
  982. RAWDCF_OFLAG,
  983. RAWDCF_LFLAG,
  984. RAWDCF_SAMPLES,
  985. RAWDCF_KEEP
  986. },
  987. { /* mode 9 */
  988. TRIMBLETAIP_FLAGS,
  989. #if TRIM_POLLRATE /* DHD940515: Allow user config */
  990. NO_POLL,
  991. #else
  992. TRIMBLETAIP_POLL,
  993. #endif
  994. TRIMBLETAIP_INIT,
  995. TRIMBLETAIP_EVENT,
  996. TRIMBLETAIP_END,
  997. NO_MESSAGE,
  998. TRIMBLETAIP_DATA,
  999. TRIMBLETAIP_ROOTDELAY,
  1000. TRIMBLETAIP_BASEDELAY,
  1001. TRIMBLETAIP_ID,
  1002. TRIMBLETAIP_DESCRIPTION,
  1003. TRIMBLETAIP_FORMAT,
  1004. GPS_TYPE,
  1005. TRIMBLETAIP_MAXUNSYNC,
  1006. TRIMBLETAIP_SPEED,
  1007. TRIMBLETAIP_CFLAG,
  1008. TRIMBLETAIP_IFLAG,
  1009. TRIMBLETAIP_OFLAG,
  1010. TRIMBLETAIP_LFLAG,
  1011. TRIMBLETAIP_SAMPLES,
  1012. TRIMBLETAIP_KEEP
  1013. },
  1014. { /* mode 10 */
  1015. TRIMBLETSIP_FLAGS,
  1016. #if TRIM_POLLRATE /* DHD940515: Allow user config */
  1017. NO_POLL,
  1018. #else
  1019. TRIMBLETSIP_POLL,
  1020. #endif
  1021. TRIMBLETSIP_INIT,
  1022. TRIMBLETSIP_EVENT,
  1023. TRIMBLETSIP_END,
  1024. TRIMBLETSIP_MESSAGE,
  1025. TRIMBLETSIP_DATA,
  1026. TRIMBLETSIP_ROOTDELAY,
  1027. TRIMBLETSIP_BASEDELAY,
  1028. TRIMBLETSIP_ID,
  1029. TRIMBLETSIP_DESCRIPTION,
  1030. TRIMBLETSIP_FORMAT,
  1031. GPS_TYPE,
  1032. TRIMBLETSIP_MAXUNSYNC,
  1033. TRIMBLETSIP_SPEED,
  1034. TRIMBLETSIP_CFLAG,
  1035. TRIMBLETSIP_IFLAG,
  1036. TRIMBLETSIP_OFLAG,
  1037. TRIMBLETSIP_LFLAG,
  1038. TRIMBLETSIP_SAMPLES,
  1039. TRIMBLETSIP_KEEP
  1040. },
  1041. { /* mode 11 */
  1042. NO_CL_FLAGS,
  1043. RCC8000_POLL,
  1044. RCC8000_INIT,
  1045. NO_EVENT,
  1046. RCC8000_END,
  1047. NO_MESSAGE,
  1048. RCC8000_DATA,
  1049. RCC8000_ROOTDELAY,
  1050. RCC8000_BASEDELAY,
  1051. RCC8000_ID,
  1052. RCC8000_DESCRIPTION,
  1053. RCC8000_FORMAT,
  1054. DCF_TYPE,
  1055. RCC8000_MAXUNSYNC,
  1056. RCC8000_SPEED,
  1057. RCC8000_CFLAG,
  1058. RCC8000_IFLAG,
  1059. RCC8000_OFLAG,
  1060. RCC8000_LFLAG,
  1061. RCC8000_SAMPLES,
  1062. RCC8000_KEEP
  1063. },
  1064. { /* mode 12 */
  1065. HOPF6021_FLAGS,
  1066. NO_POLL,
  1067. NO_INIT,
  1068. NO_EVENT,
  1069. NO_END,
  1070. NO_MESSAGE,
  1071. NO_LCLDATA,
  1072. HOPF6021_ROOTDELAY,
  1073. HOPF6021_BASEDELAY,
  1074. DCF_ID,
  1075. HOPF6021_DESCRIPTION,
  1076. HOPF6021_FORMAT,
  1077. DCF_TYPE,
  1078. HOPF6021_MAXUNSYNC,
  1079. HOPF6021_SPEED,
  1080. HOPF6021_CFLAG,
  1081. HOPF6021_IFLAG,
  1082. HOPF6021_OFLAG,
  1083. HOPF6021_LFLAG,
  1084. HOPF6021_SAMPLES,
  1085. HOPF6021_KEEP
  1086. },
  1087. { /* mode 13 */
  1088. COMPUTIME_FLAGS,
  1089. NO_POLL,
  1090. NO_INIT,
  1091. NO_EVENT,
  1092. NO_END,
  1093. NO_MESSAGE,
  1094. NO_LCLDATA,
  1095. COMPUTIME_ROOTDELAY,
  1096. COMPUTIME_BASEDELAY,
  1097. COMPUTIME_ID,
  1098. COMPUTIME_DESCRIPTION,
  1099. COMPUTIME_FORMAT,
  1100. COMPUTIME_TYPE,
  1101. COMPUTIME_MAXUNSYNC,
  1102. COMPUTIME_SPEED,
  1103. COMPUTIME_CFLAG,
  1104. COMPUTIME_IFLAG,
  1105. COMPUTIME_OFLAG,
  1106. COMPUTIME_LFLAG,
  1107. COMPUTIME_SAMPLES,
  1108. COMPUTIME_KEEP
  1109. },
  1110. { /* mode 14 */
  1111. RAWDCF_FLAGS,
  1112. NO_POLL,
  1113. RAWDCFDTRSET_INIT,
  1114. NO_EVENT,
  1115. NO_END,
  1116. NO_MESSAGE,
  1117. NO_LCLDATA,
  1118. RAWDCF_ROOTDELAY,
  1119. RAWDCF_BASEDELAY,
  1120. DCF_A_ID,
  1121. RAWDCFDTRSET_DESCRIPTION,
  1122. RAWDCF_FORMAT,
  1123. DCF_TYPE,
  1124. RAWDCF_MAXUNSYNC,
  1125. RAWDCF_SPEED,
  1126. RAWDCF_CFLAG,
  1127. RAWDCF_IFLAG,
  1128. RAWDCF_OFLAG,
  1129. RAWDCF_LFLAG,
  1130. RAWDCF_SAMPLES,
  1131. RAWDCF_KEEP
  1132. },
  1133. { /* mode 15 */
  1134. 0, /* operation flags (io modes) */
  1135. NO_POLL, /* active poll routine */
  1136. NO_INIT, /* active poll init routine */
  1137. NO_EVENT, /* special event handling (e.g. reset clock) */
  1138. NO_END, /* active poll end routine */
  1139. NO_MESSAGE, /* process a lower layer message */
  1140. NO_LCLDATA, /* local data area for "poll" mechanism */
  1141. 0, /* rootdelay */
  1142. 11.0 /* bits */ / 9600, /* current offset by which the RS232
  1143. time code is delayed from the actual time */
  1144. DCF_ID, /* ID code */
  1145. "WHARTON 400A Series clock", /* device name */
  1146. "WHARTON 400A Series clock Output Format 1", /* fixed format */
  1147. /* Must match a format-name in a libparse/clk_xxx.c file */
  1148. DCF_TYPE, /* clock type (ntp control) */
  1149. (1*60*60), /* time to trust oscillator after losing synch */
  1150. B9600, /* terminal input & output baudrate */
  1151. (CS8|CREAD|PARENB|CLOCAL|HUPCL),/* terminal control flags */
  1152. 0, /* terminal input flags */
  1153. 0, /* terminal output flags */
  1154. 0, /* terminal local flags */
  1155. 5, /* samples for median filter */
  1156. 3, /* samples for median filter to keep */
  1157. },
  1158. { /* mode 16 - RAWDCF RTS set, DTR clr */
  1159. RAWDCF_FLAGS,
  1160. NO_POLL,
  1161. RAWDCFDTRCLRRTSSET_INIT,
  1162. NO_EVENT,
  1163. NO_END,
  1164. NO_MESSAGE,
  1165. NO_LCLDATA,
  1166. RAWDCF_ROOTDELAY,
  1167. RAWDCF_BASEDELAY,
  1168. DCF_A_ID,
  1169. RAWDCFDTRCLRRTSSET_DESCRIPTION,
  1170. RAWDCF_FORMAT,
  1171. DCF_TYPE,
  1172. RAWDCF_MAXUNSYNC,
  1173. RAWDCF_SPEED,
  1174. RAWDCF_CFLAG,
  1175. RAWDCF_IFLAG,
  1176. RAWDCF_OFLAG,
  1177. RAWDCF_LFLAG,
  1178. RAWDCF_SAMPLES,
  1179. RAWDCF_KEEP
  1180. },
  1181. { /* mode 17 */
  1182. VARITEXT_FLAGS,
  1183. NO_POLL,
  1184. NO_INIT,
  1185. NO_EVENT,
  1186. NO_END,
  1187. NO_MESSAGE,
  1188. NO_LCLDATA,
  1189. VARITEXT_ROOTDELAY,
  1190. VARITEXT_BASEDELAY,
  1191. VARITEXT_ID,
  1192. VARITEXT_DESCRIPTION,
  1193. VARITEXT_FORMAT,
  1194. VARITEXT_TYPE,
  1195. VARITEXT_MAXUNSYNC,
  1196. VARITEXT_SPEED,
  1197. VARITEXT_CFLAG,
  1198. VARITEXT_IFLAG,
  1199. VARITEXT_OFLAG,
  1200. VARITEXT_LFLAG,
  1201. VARITEXT_SAMPLES,
  1202. VARITEXT_KEEP
  1203. },
  1204. { /* mode 18 */
  1205. MBG_FLAGS,
  1206. NO_POLL,
  1207. NO_INIT,
  1208. NO_EVENT,
  1209. GPS16X_END,
  1210. GPS16X_MESSAGE,
  1211. GPS16X_DATA,
  1212. GPS16X_ROOTDELAY,
  1213. GPS16X_BASEDELAY,
  1214. GPS16X_ID,
  1215. GPS16X_DESCRIPTION,
  1216. GPS16X_FORMAT,
  1217. GPS_TYPE,
  1218. GPS16X_MAXUNSYNC,
  1219. GPS16X_SPEED,
  1220. GPS16X_CFLAG,
  1221. GPS16X_IFLAG,
  1222. GPS16X_OFLAG,
  1223. GPS16X_LFLAG,
  1224. GPS16X_SAMPLES,
  1225. GPS16X_KEEP
  1226. },
  1227. { /* mode 19 */
  1228. RAWDCF_FLAGS,
  1229. NO_POLL,
  1230. RAWDCF_INIT,
  1231. NO_EVENT,
  1232. NO_END,
  1233. NO_MESSAGE,
  1234. NO_LCLDATA,
  1235. RAWDCF_ROOTDELAY,
  1236. GUDE_EMC_USB_V20_BASEDELAY,
  1237. DCF_A_ID,
  1238. GUDE_EMC_USB_V20_DESCRIPTION,
  1239. RAWDCF_FORMAT,
  1240. DCF_TYPE,
  1241. RAWDCF_MAXUNSYNC,
  1242. GUDE_EMC_USB_V20_SPEED,
  1243. RAWDCF_CFLAG,
  1244. RAWDCF_IFLAG,
  1245. RAWDCF_OFLAG,
  1246. RAWDCF_LFLAG,
  1247. RAWDCF_SAMPLES,
  1248. RAWDCF_KEEP
  1249. },
  1250. { /* mode 20, like mode 14 but driven by 75 baud */
  1251. RAWDCF_FLAGS,
  1252. NO_POLL,
  1253. RAWDCFDTRSET_INIT,
  1254. NO_EVENT,
  1255. NO_END,
  1256. NO_MESSAGE,
  1257. NO_LCLDATA,
  1258. RAWDCF_ROOTDELAY,
  1259. RAWDCF_BASEDELAY,
  1260. DCF_A_ID,
  1261. RAWDCFDTRSET75_DESCRIPTION,
  1262. RAWDCF_FORMAT,
  1263. DCF_TYPE,
  1264. RAWDCF_MAXUNSYNC,
  1265. B75,
  1266. RAWDCF_CFLAG,
  1267. RAWDCF_IFLAG,
  1268. RAWDCF_OFLAG,
  1269. RAWDCF_LFLAG,
  1270. RAWDCF_SAMPLES,
  1271. RAWDCF_KEEP
  1272. },
  1273. { /* mode 21, like mode 16 but driven by 75 baud
  1274. - RAWDCF RTS set, DTR clr */
  1275. RAWDCF_FLAGS,
  1276. NO_POLL,
  1277. RAWDCFDTRCLRRTSSET_INIT,
  1278. NO_EVENT,
  1279. NO_END,
  1280. NO_MESSAGE,
  1281. NO_LCLDATA,
  1282. RAWDCF_ROOTDELAY,
  1283. RAWDCF_BASEDELAY,
  1284. DCF_A_ID,
  1285. RAWDCFDTRCLRRTSSET75_DESCRIPTION,
  1286. RAWDCF_FORMAT,
  1287. DCF_TYPE,
  1288. RAWDCF_MAXUNSYNC,
  1289. B75,
  1290. RAWDCF_CFLAG,
  1291. RAWDCF_IFLAG,
  1292. RAWDCF_OFLAG,
  1293. RAWDCF_LFLAG,
  1294. RAWDCF_SAMPLES,
  1295. RAWDCF_KEEP
  1296. },
  1297. { /* mode 22 - like 2 with POWERUP trust */
  1298. MBG_FLAGS | PARSE_F_POWERUPTRUST,
  1299. NO_POLL,
  1300. NO_INIT,
  1301. NO_EVENT,
  1302. NO_END,
  1303. NO_MESSAGE,
  1304. NO_LCLDATA,
  1305. DCFUA31_ROOTDELAY,
  1306. DCFUA31_BASEDELAY,
  1307. DCF_A_ID,
  1308. DCFUA31_DESCRIPTION,
  1309. DCFUA31_FORMAT,
  1310. DCF_TYPE,
  1311. DCFUA31_MAXUNSYNC,
  1312. DCFUA31_SPEED,
  1313. DCFUA31_CFLAG,
  1314. DCFUA31_IFLAG,
  1315. DCFUA31_OFLAG,
  1316. DCFUA31_LFLAG,
  1317. DCFUA31_SAMPLES,
  1318. DCFUA31_KEEP
  1319. },
  1320. { /* mode 23 - like 7 with POWERUP trust */
  1321. MBG_FLAGS | PARSE_F_POWERUPTRUST,
  1322. GPS16X_POLL,
  1323. GPS16X_INIT,
  1324. NO_EVENT,
  1325. GPS16X_END,
  1326. GPS16X_MESSAGE,
  1327. GPS16X_DATA,
  1328. GPS16X_ROOTDELAY,
  1329. GPS16X_BASEDELAY,
  1330. GPS16X_ID,
  1331. GPS16X_DESCRIPTION,
  1332. GPS16X_FORMAT,
  1333. GPS_TYPE,
  1334. GPS16X_MAXUNSYNC,
  1335. GPS16X_SPEED,
  1336. GPS16X_CFLAG,
  1337. GPS16X_IFLAG,
  1338. GPS16X_OFLAG,
  1339. GPS16X_LFLAG,
  1340. GPS16X_SAMPLES,
  1341. GPS16X_KEEP
  1342. },
  1343. };
  1344. static int ncltypes = sizeof(parse_clockinfo) / sizeof(struct parse_clockinfo);
  1345. #define CLK_REALTYPE(x) ((int)(((x)->ttl) & 0x7F))
  1346. #define CLK_TYPE(x) ((CLK_REALTYPE(x) >= ncltypes) ? ~0 : CLK_REALTYPE(x))
  1347. #define CLK_UNIT(x) ((int)REFCLOCKUNIT(&(x)->srcadr))
  1348. #define CLK_PPS(x) (((x)->ttl) & 0x80)
  1349. /*
  1350. * Other constant stuff
  1351. */
  1352. #define PARSEHSREFID 0x7f7f08ff /* 127.127.8.255 refid for hi strata */
  1353. #define PARSESTATISTICS (60*60) /* output state statistics every hour */
  1354. static int notice = 0;
  1355. #define PARSE_STATETIME(parse, i) ((parse->generic->currentstatus == i) ? parse->statetime[i] + current_time - parse->lastchange : parse->statetime[i])
  1356. static void parse_event (struct parseunit *, int);
  1357. static void parse_process (struct parseunit *, parsetime_t *);
  1358. static void clear_err (struct parseunit *, u_long);
  1359. static int list_err (struct parseunit *, u_long);
  1360. static char * l_mktime (u_long);
  1361. /**===========================================================================
  1362. ** implementation error message regression module
  1363. **/
  1364. static void
  1365. clear_err(
  1366. struct parseunit *parse,
  1367. u_long lstate
  1368. )
  1369. {
  1370. if (lstate == ERR_ALL)
  1371. {
  1372. int i;
  1373. for (i = 0; i < ERR_CNT; i++)
  1374. {
  1375. parse->errors[i].err_stage = err_tbl[i];
  1376. parse->errors[i].err_cnt = 0;
  1377. parse->errors[i].err_last = 0;
  1378. parse->errors[i].err_started = 0;
  1379. parse->errors[i].err_suppressed = 0;
  1380. }
  1381. }
  1382. else
  1383. {
  1384. parse->errors[lstate].err_stage = err_tbl[lstate];
  1385. parse->errors[lstate].err_cnt = 0;
  1386. parse->errors[lstate].err_last = 0;
  1387. parse->errors[lstate].err_started = 0;
  1388. parse->errors[lstate].err_suppressed = 0;
  1389. }
  1390. }
  1391. static int
  1392. list_err(
  1393. struct parseunit *parse,
  1394. u_long lstate
  1395. )
  1396. {
  1397. int do_it;
  1398. struct errorinfo *err = &parse->errors[lstate];
  1399. if (err->err_started == 0)
  1400. {
  1401. err->err_started = current_time;
  1402. }
  1403. do_it = (current_time - err->err_last) >= err->err_stage->err_delay;
  1404. if (do_it)
  1405. err->err_cnt++;
  1406. if (err->err_stage->err_count &&
  1407. (err->err_cnt >= err->err_stage->err_count))
  1408. {
  1409. err->err_stage++;
  1410. err->err_cnt = 0;
  1411. }
  1412. if (!err->err_cnt && do_it)
  1413. msyslog(LOG_INFO, "PARSE receiver #%d: interval for following error message class is at least %s",
  1414. CLK_UNIT(parse->peer), l_mktime(err->err_stage->err_delay));
  1415. if (!do_it)
  1416. err->err_suppressed++;
  1417. else
  1418. err->err_last = current_time;
  1419. if (do_it && err->err_suppressed)
  1420. {
  1421. msyslog(LOG_INFO, "PARSE receiver #%d: %ld message%s suppressed, error condition class persists for %s",
  1422. CLK_UNIT(parse->peer), err->err_suppressed, (err->err_suppressed == 1) ? " was" : "s where",
  1423. l_mktime(current_time - err->err_started));
  1424. err->err_suppressed = 0;
  1425. }
  1426. return do_it;
  1427. }
  1428. /*--------------------------------------------------
  1429. * mkreadable - make a printable ascii string (without
  1430. * embedded quotes so that the ntpq protocol isn't
  1431. * fooled
  1432. */
  1433. #ifndef isprint
  1434. #define isprint(_X_) (((_X_) > 0x1F) && ((_X_) < 0x7F))
  1435. #endif
  1436. static char *
  1437. mkreadable(
  1438. char *buffer,
  1439. long blen,
  1440. const char *src,
  1441. u_long srclen,
  1442. int hex
  1443. )
  1444. {
  1445. char *b = buffer;
  1446. char *endb = NULL;
  1447. if (blen < 4)
  1448. return NULL; /* don't bother with mini buffers */
  1449. endb = buffer + blen - 4;
  1450. blen--; /* account for '\0' */
  1451. while (blen && srclen--)
  1452. {
  1453. if (!hex && /* no binary only */
  1454. (*src != '\\') && /* no plain \ */
  1455. (*src != '"') && /* no " */
  1456. isprint((int)*src)) /* only printables */
  1457. { /* they are easy... */
  1458. *buffer++ = *src++;
  1459. blen--;
  1460. }
  1461. else
  1462. {
  1463. if (blen < 4)
  1464. {
  1465. while (blen--)
  1466. {
  1467. *buffer++ = '.';
  1468. }
  1469. *buffer = '\0';
  1470. return b;
  1471. }
  1472. else
  1473. {
  1474. if (*src == '\\')
  1475. {
  1476. strcpy(buffer,"\\\\");
  1477. buffer += 2;
  1478. blen -= 2;
  1479. src++;
  1480. }
  1481. else
  1482. {
  1483. snprintf(buffer, blen, "\\x%02x", *src++);
  1484. blen -= 4;
  1485. buffer += 4;
  1486. }
  1487. }
  1488. }
  1489. if (srclen && !blen && endb) /* overflow - set last chars to ... */
  1490. strcpy(endb, "...");
  1491. }
  1492. *buffer = '\0';
  1493. return b;
  1494. }
  1495. /*--------------------------------------------------
  1496. * mkascii - make a printable ascii string
  1497. * assumes (unless defined better) 7-bit ASCII
  1498. */
  1499. static char *
  1500. mkascii(
  1501. char *buffer,
  1502. long blen,
  1503. const char *src,
  1504. u_long srclen
  1505. )
  1506. {
  1507. return mkreadable(buffer, blen, src, srclen, 0);
  1508. }
  1509. /**===========================================================================
  1510. ** implementation of i/o handling methods
  1511. ** (all STREAM, partial STREAM, user level)
  1512. **/
  1513. /*
  1514. * define possible io handling methods
  1515. */
  1516. #ifdef STREAM
  1517. static int ppsclock_init (struct parseunit *);
  1518. static int stream_init (struct parseunit *);
  1519. static void stream_end (struct parseunit *);
  1520. static int stream_enable (struct parseunit *);
  1521. static int stream_disable (struct parseunit *);
  1522. static int stream_setcs (struct parseunit *, parsectl_t *);
  1523. static int stream_getfmt (struct parseunit *, parsectl_t *);
  1524. static int stream_setfmt (struct parseunit *, parsectl_t *);
  1525. static int stream_timecode (struct parseunit *, parsectl_t *);
  1526. static void stream_receive (struct recvbuf *);
  1527. #endif
  1528. static int local_init (struct parseunit *);
  1529. static void local_end (struct parseunit *);
  1530. static int local_nop (struct parseunit *);
  1531. static int local_setcs (struct parseunit *, parsectl_t *);
  1532. static int local_getfmt (struct parseunit *, parsectl_t *);
  1533. static int local_setfmt (struct parseunit *, parsectl_t *);
  1534. static int local_timecode (struct parseunit *, parsectl_t *);
  1535. static void local_receive (struct recvbuf *);
  1536. static int local_input (struct recvbuf *);
  1537. static bind_t io_bindings[] =
  1538. {
  1539. #ifdef STREAM
  1540. {
  1541. "parse STREAM",
  1542. stream_init,
  1543. stream_end,
  1544. stream_setcs,
  1545. stream_disable,
  1546. stream_enable,
  1547. stream_getfmt,
  1548. stream_setfmt,
  1549. stream_timecode,
  1550. stream_receive,
  1551. 0,
  1552. },
  1553. {
  1554. "ppsclock STREAM",
  1555. ppsclock_init,
  1556. local_end,
  1557. local_setcs,
  1558. local_nop,
  1559. local_nop,
  1560. local_getfmt,
  1561. local_setfmt,
  1562. local_timecode,
  1563. local_receive,
  1564. local_input,
  1565. },
  1566. #endif
  1567. {
  1568. "normal",
  1569. local_init,
  1570. local_end,
  1571. local_setcs,
  1572. local_nop,
  1573. local_nop,
  1574. local_getfmt,
  1575. local_setfmt,
  1576. local_timecode,
  1577. local_receive,
  1578. local_input,
  1579. },
  1580. {
  1581. (char *)0,
  1582. }
  1583. };
  1584. #ifdef STREAM
  1585. #define fix_ts(_X_) \
  1586. if ((&(_X_))->tv.tv_usec >= 1000000) \
  1587. { \
  1588. (&(_X_))->tv.tv_usec -= 1000000; \
  1589. (&(_X_))->tv.tv_sec += 1; \
  1590. }
  1591. #define cvt_ts(_X_, _Y_) \
  1592. { \
  1593. l_fp ts; \
  1594. fix_ts((_X_)); \
  1595. if (!buftvtots((const char *)&(&(_X_))->tv, &ts)) \
  1596. { \
  1597. ERR(ERR_BADDATA) \
  1598. msyslog(LOG_ERR,"parse: stream_receive: timestamp conversion error (buftvtots) (%s) (%ld.%06ld) ", (_Y_), (long)(&(_X_))->tv.tv_sec, (long)(&(_X_))->tv.tv_usec);\
  1599. return; \
  1600. } \
  1601. else \
  1602. { \
  1603. (&(_X_))->fp = ts; \
  1604. } \
  1605. }
  1606. /*--------------------------------------------------
  1607. * ppsclock STREAM init
  1608. */
  1609. static int
  1610. ppsclock_init(
  1611. struct pa

Large files files are truncated, but you can click here to view the full file