/contrib/ntp/libparse/clk_rcc8000.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 198 lines · 101 code · 24 blank · 73 comment · 15 complexity · 0f5e2f9c65dd16021bf6ec19a5443e74 MD5 · raw file

  1. /*
  2. * /src/NTP/ntp4-dev/libparse/clk_rcc8000.c,v 4.9 2004/11/14 15:29:41 kardel RELEASE_20050508_A
  3. *
  4. * clk_rcc8000.c,v 4.9 2004/11/14 15:29:41 kardel RELEASE_20050508_A
  5. *
  6. * Radiocode Clocks Ltd RCC 8000 Intelligent Off-Air Master Clock support
  7. *
  8. * Created by R.E.Broughton from clk_trimtaip.c
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. */
  15. #if HAVE_CONFIG_H
  16. # include <config.h>
  17. #endif
  18. #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_RCC8000)
  19. #include "ntp_fp.h"
  20. #include "ntp_unixtime.h"
  21. #include "ntp_calendar.h"
  22. #include "parse.h"
  23. #ifndef PARSESTREAM
  24. #include "ntp_stdlib.h"
  25. #include <stdio.h>
  26. #else
  27. #include "sys/parsestreams.h"
  28. extern void printf P((const char *, ...));
  29. #endif
  30. /* Type II Serial Output format
  31. *
  32. * 0000000000111111111122222222223 / char
  33. * 0123456789012345678901234567890 \ posn
  34. * HH:MM:SS.XYZ DD/MM/YY DDD W Prn Actual
  35. * 33 44 55 666 00 11 22 7 Parse
  36. * : : . / / rn Check
  37. * "15:50:36.534 30/09/94 273 5 A\x0d\x0a"
  38. *
  39. * DDD - Day of year number
  40. * W - Day of week number (Sunday is 0)
  41. * P is the Status. See comment below for details.
  42. */
  43. #define O_USEC O_WDAY
  44. static struct format rcc8000_fmt =
  45. { { { 13, 2 }, {16, 2}, { 19, 2}, /* Day, Month, Year */
  46. { 0, 2 }, { 3, 2}, { 6, 2}, /* Hour, Minute, Second */
  47. { 9, 3 }, {28, 1}, { 0, 0}, /* uSec, Status (Valid,Reject,BST,Leapyear) */ },
  48. (const unsigned char *)" : : . / / \r\n",
  49. /*"15:50:36.534 30/09/94 273 5 A\x0d\x0a" */
  50. 0
  51. };
  52. static unsigned long cvt_rcc8000 P((unsigned char *, int, struct format *, clocktime_t *, void *));
  53. static unsigned long inp_rcc8000 P((parse_t *, unsigned int, timestamp_t *));
  54. clockformat_t clock_rcc8000 =
  55. {
  56. inp_rcc8000, /* no input handling */
  57. cvt_rcc8000, /* Radiocode clock conversion */
  58. 0, /* no direct PPS monitoring */
  59. (void *)&rcc8000_fmt, /* conversion configuration */
  60. "Radiocode RCC8000",
  61. 31, /* string buffer */
  62. 0 /* no private data */
  63. };
  64. static unsigned long
  65. cvt_rcc8000(
  66. unsigned char *buffer,
  67. int size,
  68. struct format *format,
  69. clocktime_t *clock_time,
  70. void *local
  71. )
  72. {
  73. if (!Strok(buffer, format->fixed_string)) return CVT_NONE;
  74. #define OFFS(x) format->field_offsets[(x)].offset
  75. #define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length)
  76. if ( STOI(O_DAY, &clock_time->day) ||
  77. STOI(O_MONTH, &clock_time->month) ||
  78. STOI(O_YEAR, &clock_time->year) ||
  79. STOI(O_HOUR, &clock_time->hour) ||
  80. STOI(O_MIN, &clock_time->minute) ||
  81. STOI(O_SEC, &clock_time->second) ||
  82. STOI(O_USEC, &clock_time->usecond)
  83. ) return CVT_FAIL|CVT_BADFMT;
  84. clock_time->usecond *= 1000;
  85. clock_time->utcoffset = 0;
  86. #define RCCP buffer[28]
  87. /*
  88. * buffer[28] is the ASCII representation of a hex character ( 0 through F )
  89. * The four bits correspond to:
  90. * 8 - Valid Time
  91. * 4 - Reject Code
  92. * 2 - British Summer Time (receiver set to emit GMT all year.)
  93. * 1 - Leap year
  94. */
  95. #define RCC8000_VALID 0x8
  96. #define RCC8000_REJECT 0x4
  97. #define RCC8000_BST 0x2
  98. #define RCC8000_LEAPY 0x1
  99. clock_time->flags = 0;
  100. if ( (RCCP >= '0' && RCCP <= '9') || (RCCP >= 'A' && RCCP <= 'F') )
  101. {
  102. register int flag;
  103. flag = (RCCP >= '0' && RCCP <= '9' ) ? RCCP - '0' : RCCP - 'A' + 10;
  104. if (!(flag & RCC8000_VALID))
  105. clock_time->flags |= PARSEB_POWERUP;
  106. clock_time->flags |= PARSEB_UTC; /* British special - guess why 8-) */
  107. /* other flags not used */
  108. }
  109. return CVT_OK;
  110. }
  111. /*
  112. * inp_rcc8000
  113. *
  114. * grep data from input stream
  115. */
  116. static u_long
  117. inp_rcc8000(
  118. parse_t *parseio,
  119. unsigned int ch,
  120. timestamp_t *tstamp
  121. )
  122. {
  123. unsigned int rtc;
  124. parseprintf(DD_PARSE, ("inp_rcc8000(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
  125. switch (ch)
  126. {
  127. case '\n':
  128. parseprintf(DD_PARSE, ("inp_rcc8000: EOL seen\n"));
  129. if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
  130. return parse_end(parseio);
  131. else
  132. return rtc;
  133. default:
  134. if (parseio->parse_index == 0) /* take sample at start of message */
  135. {
  136. parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
  137. }
  138. return parse_addchar(parseio, ch);
  139. }
  140. }
  141. #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RCC8000) */
  142. int clk_rcc8000_bs;
  143. #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RCC8000) */
  144. /*
  145. * History:
  146. *
  147. * clk_rcc8000.c,v
  148. * Revision 4.9 2004/11/14 15:29:41 kardel
  149. * support PPSAPI, upgrade Copyright to Berkeley style
  150. *
  151. * Revision 4.6 1999/11/28 09:13:51 kardel
  152. * RECON_4_0_98F
  153. *
  154. * Revision 4.5 1998/06/14 21:09:38 kardel
  155. * Sun acc cleanup
  156. *
  157. * Revision 4.4 1998/06/13 12:05:02 kardel
  158. * fix SYSV clock name clash
  159. *
  160. * Revision 4.3 1998/06/12 15:22:29 kardel
  161. * fix prototypes
  162. *
  163. * Revision 4.2 1998/06/12 09:13:25 kardel
  164. * conditional compile macros fixed
  165. * printf prototype
  166. *
  167. * Revision 4.1 1998/05/24 09:39:53 kardel
  168. * implementation of the new IO handling model
  169. *
  170. * Revision 4.0 1998/04/10 19:45:30 kardel
  171. * Start 4.0 release version numbering
  172. *
  173. * from V3 3.5 log info deleted 1998/04/11 kardel
  174. */