Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ntp / libparse / clk_meinberg.c
blobbdbe633603587357ed187bfb5e536189149f6ffd
1 /* $NetBSD: clk_meinberg.c,v 1.4 2006/06/11 19:34:10 kardel Exp $ */
3 /*
4 * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_meinberg.c,v 4.12.2.1 2005/09/25 10:22:35 kardel RELEASE_20050925_A
5 *
6 * clk_meinberg.c,v 4.12.2.1 2005/09/25 10:22:35 kardel RELEASE_20050925_A
8 * Meinberg clock support
10 * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
11 * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the author nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
39 #ifdef HAVE_CONFIG_H
40 # include <config.h>
41 #endif
43 #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_MEINBERG)
45 #include "ntp_fp.h"
46 #include "ntp_unixtime.h"
47 #include "ntp_calendar.h"
49 #include "ntp_machine.h"
51 #include "parse.h"
53 #ifndef PARSESTREAM
54 #include <stdio.h>
55 #else
56 #include "sys/parsestreams.h"
57 #endif
59 #include "ntp_stdlib.h"
61 #include "ntp_stdlib.h"
63 #include "mbg_gps166.h"
64 #include "binio.h"
65 #include "ascii.h"
68 * The Meinberg receiver every second sends a datagram of the following form
69 * (Standard Format)
71 * <STX>D:<dd>.<mm>.<yy>;T:<w>;U:<hh>:<mm>:<ss>;<S><F><D><A><ETX>
72 * pos: 0 00 00 0 00 0 11 111 1 111 12 2 22 2 22 2 2 2 3 3 3
73 * 1 23 45 6 78 9 01 234 5 678 90 1 23 4 56 7 8 9 0 1 2
74 * <STX> = '\002' ASCII start of text
75 * <ETX> = '\003' ASCII end of text
76 * <dd>,<mm>,<yy> = day, month, year(2 digits!!)
77 * <w> = day of week (sunday= 0)
78 * <hh>,<mm>,<ss> = hour, minute, second
79 * <S> = '#' if never synced since powerup for DCF C51
80 * = '#' if not PZF sychronisation available for PZF 535/509
81 * = ' ' if ok
82 * <F> = '*' if time comes from internal quartz
83 * = ' ' if completely synched
84 * <D> = 'S' if daylight saving time is active
85 * = 'U' if time is represented in UTC
86 * = ' ' if no special condition exists
87 * <A> = '!' during the hour preceeding an daylight saving time
88 * start/end change
89 * = 'A' leap second insert warning
90 * = ' ' if no special condition exists
92 * Extended data format (PZFUERL for PZF type clocks)
94 * <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <U><S><F><D><A><L><R><ETX>
95 * pos: 0 00 0 00 0 00 11 1 11 11 1 11 2 22 22 2 2 2 2 2 3 3 3
96 * 1 23 4 56 7 89 01 2 34 56 7 89 0 12 34 5 6 7 8 9 0 1 2
97 * <STX> = '\002' ASCII start of text
98 * <ETX> = '\003' ASCII end of text
99 * <dd>,<mm>,<yy> = day, month, year(2 digits!!)
100 * <w> = day of week (sunday= 0)
101 * <hh>,<mm>,<ss> = hour, minute, second
102 * <U> = 'U' UTC time display
103 * <S> = '#' if never synced since powerup else ' ' for DCF C51
104 * '#' if not PZF sychronisation available else ' ' for PZF 535/509
105 * <F> = '*' if time comes from internal quartz else ' '
106 * <D> = 'S' if daylight saving time is active else ' '
107 * <A> = '!' during the hour preceeding an daylight saving time
108 * start/end change
109 * <L> = 'A' LEAP second announcement
110 * <R> = 'R' alternate antenna
112 * Meinberg GPS166 receiver
114 * You must get the Uni-Erlangen firmware for the GPS receiver support
115 * to work to full satisfaction !
117 * <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <+/-><00:00>; <U><S><F><D><A><L><R><L>; <position...><ETX>
119 * 000000000111111111122222222223333333333444444444455555555556666666
120 * 123456789012345678901234567890123456789012345678901234567890123456
121 * \x0209.07.93; 5; 08:48:26; +00:00; #*S!A L; 49.5736N 11.0280E 373m\x03
124 * <STX> = '\002' ASCII start of text
125 * <ETX> = '\003' ASCII end of text
126 * <dd>,<mm>,<yy> = day, month, year(2 digits!!)
127 * <w> = day of week (sunday= 0)
128 * <hh>,<mm>,<ss> = hour, minute, second
129 * <+/->,<00:00> = offset to UTC
130 * <S> = '#' if never synced since powerup else ' '
131 * <F> = '*' if position is not confirmed else ' '
132 * <D> = 'S' if daylight saving time is active else ' '
133 * <A> = '!' during the hour preceeding an daylight saving time
134 * start/end change
135 * <L> = 'A' LEAP second announcement
136 * <R> = 'R' alternate antenna (reminiscent of PZF535) usually ' '
137 * <L> = 'L' on 23:59:60
139 * Binary messages have a lead in for a fixed header of SOH
142 /*--------------------------------------------------------------*/
143 /* Name: csum() */
144 /* */
145 /* Purpose: Compute a checksum about a number of bytes */
146 /* */
147 /* Input: uchar *p address of the first byte */
148 /* short n the number of bytes */
149 /* */
150 /* Output: -- */
151 /* */
152 /* Ret val: the checksum */
153 /*+-------------------------------------------------------------*/
155 unsigned long
156 mbg_csum(
157 unsigned char *p,
158 unsigned int n
161 unsigned long sum = 0;
162 short i;
164 for ( i = 0; i < n; i++ )
165 sum += *p++;
167 return( sum );
168 } /* csum */
170 void
171 get_mbg_header(
172 unsigned char **bufpp,
173 GPS_MSG_HDR *headerp
176 headerp->gps_cmd = get_lsb_short(bufpp);
177 headerp->gps_len = get_lsb_short(bufpp);
178 headerp->gps_data_csum = get_lsb_short(bufpp);
179 headerp->gps_hdr_csum = get_lsb_short(bufpp);
182 static struct format meinberg_fmt[] =
186 { 3, 2}, { 6, 2}, { 9, 2},
187 { 18, 2}, { 21, 2}, { 24, 2},
188 { 14, 1}, { 27, 4}, { 29, 1},
190 (const unsigned char *)"\2D: . . ;T: ;U: . . ; \3",
193 { /* special extended FAU Erlangen extended format */
195 { 1, 2}, { 4, 2}, { 7, 2},
196 { 14, 2}, { 17, 2}, { 20, 2},
197 { 11, 1}, { 25, 4}, { 27, 1},
199 (const unsigned char *)"\2 . . ; ; : : ; \3",
200 MBG_EXTENDED
202 { /* special extended FAU Erlangen GPS format */
204 { 1, 2}, { 4, 2}, { 7, 2},
205 { 14, 2}, { 17, 2}, { 20, 2},
206 { 11, 1}, { 32, 7}, { 35, 1},
207 { 25, 2}, { 28, 2}, { 24, 1}
209 (const unsigned char *)"\2 . . ; ; : : ; : ; ; . . ",
214 static u_long cvt_meinberg P((unsigned char *, int, struct format *, clocktime_t *, void *));
215 static u_long cvt_mgps P((unsigned char *, int, struct format *, clocktime_t *, void *));
216 static u_long mbg_input P((parse_t *, unsigned int, timestamp_t *));
217 static u_long gps_input P((parse_t *, unsigned int, timestamp_t *));
219 struct msg_buf
221 unsigned short len; /* len to fill */
222 unsigned short phase; /* current input phase */
225 #define MBG_NONE 0 /* no data input */
226 #define MBG_HEADER 1 /* receiving header */
227 #define MBG_DATA 2 /* receiving data */
228 #define MBG_STRING 3 /* receiving standard data message */
230 clockformat_t clock_meinberg[] =
233 mbg_input, /* normal input handling */
234 cvt_meinberg, /* Meinberg conversion */
235 pps_one, /* easy PPS monitoring */
236 0, /* conversion configuration */
237 "Meinberg Standard", /* Meinberg simple format - beware */
238 32, /* string buffer */
239 0 /* no private data (complete pakets) */
242 mbg_input, /* normal input handling */
243 cvt_meinberg, /* Meinberg conversion */
244 pps_one, /* easy PPS monitoring */
245 0, /* conversion configuration */
246 "Meinberg Extended", /* Meinberg enhanced format */
247 32, /* string buffer */
248 0 /* no private data (complete pakets) */
251 gps_input, /* no input handling */
252 cvt_mgps, /* Meinberg GPS166 conversion */
253 pps_one, /* easy PPS monitoring */
254 (void *)&meinberg_fmt[2], /* conversion configuration */
255 "Meinberg GPS Extended", /* Meinberg FAU GPS format */
256 512, /* string buffer */
257 sizeof(struct msg_buf) /* no private data (complete pakets) */
262 * cvt_meinberg
264 * convert simple type format
266 static u_long
267 cvt_meinberg(
268 unsigned char *buffer,
269 int size,
270 struct format *unused,
271 clocktime_t *clock_time,
272 void *local
275 struct format *format;
278 * select automagically correct data format
280 if (Strok(buffer, meinberg_fmt[0].fixed_string))
282 format = &meinberg_fmt[0];
284 else
286 if (Strok(buffer, meinberg_fmt[1].fixed_string))
288 format = &meinberg_fmt[1];
290 else
292 return CVT_FAIL|CVT_BADFMT;
297 * collect data
299 if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
300 format->field_offsets[O_DAY].length) ||
301 Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
302 format->field_offsets[O_MONTH].length) ||
303 Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
304 format->field_offsets[O_YEAR].length) ||
305 Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
306 format->field_offsets[O_HOUR].length) ||
307 Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
308 format->field_offsets[O_MIN].length) ||
309 Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
310 format->field_offsets[O_SEC].length))
312 return CVT_FAIL|CVT_BADFMT;
314 else
316 unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
318 clock_time->usecond = 0;
319 clock_time->flags = PARSEB_S_LEAP;
321 if (clock_time->second == 60)
322 clock_time->flags |= PARSEB_LEAPSECOND;
325 * in the extended timecode format we have also the
326 * indication that the timecode is in UTC
327 * for compatibilty reasons we start at the USUAL
328 * offset (POWERUP flag) and know that the UTC indication
329 * is the character before the powerup flag
331 if ((format->flags & MBG_EXTENDED) && (f[-1] == 'U'))
334 * timecode is in UTC
336 clock_time->utcoffset = 0; /* UTC */
337 clock_time->flags |= PARSEB_UTC;
339 else
342 * only calculate UTC offset if MET/MED is in time code
343 * or we have the old time code format, where we do not
344 * know whether it is UTC time or MET/MED
345 * pray that nobody switches to UTC in the *old* standard time code
346 * ROMS !!!! The new ROMS have 'U' at the ZONE field - good.
348 switch (buffer[format->field_offsets[O_ZONE].offset])
350 case ' ':
351 clock_time->utcoffset = -1*60*60; /* MET */
352 break;
354 case 'S':
355 clock_time->utcoffset = -2*60*60; /* MED */
356 break;
358 case 'U':
360 * timecode is in UTC
362 clock_time->utcoffset = 0; /* UTC */
363 clock_time->flags |= PARSEB_UTC;
364 break;
366 default:
367 return CVT_FAIL|CVT_BADFMT;
372 * gather status flags
374 if (buffer[format->field_offsets[O_ZONE].offset] == 'S')
375 clock_time->flags |= PARSEB_DST;
377 if (f[0] == '#')
378 clock_time->flags |= PARSEB_POWERUP;
380 if (f[1] == '*')
381 clock_time->flags |= PARSEB_NOSYNC;
383 if (f[3] == '!')
384 clock_time->flags |= PARSEB_ANNOUNCE;
387 * oncoming leap second
388 * 'a' code not confirmed - earth is not
389 * expected to speed up
391 if (f[3] == 'A')
392 clock_time->flags |= PARSEB_LEAPADD;
394 if (f[3] == 'a')
395 clock_time->flags |= PARSEB_LEAPDEL;
398 if (format->flags & MBG_EXTENDED)
400 clock_time->flags |= PARSEB_S_ANTENNA;
403 * DCF77 does not encode the direction -
404 * so we take the current default -
405 * earth slowing down
407 clock_time->flags &= ~PARSEB_LEAPDEL;
409 if (f[4] == 'A')
410 clock_time->flags |= PARSEB_LEAPADD;
412 if (f[5] == 'R')
413 clock_time->flags |= PARSEB_ALTERNATE;
415 return CVT_OK;
421 * mbg_input
423 * grep data from input stream
425 static u_long
426 mbg_input(
427 parse_t *parseio,
428 unsigned int ch,
429 timestamp_t *tstamp
432 unsigned int rtc;
434 parseprintf(DD_PARSE, ("mbg_input(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
436 switch (ch)
438 case STX:
439 parseprintf(DD_PARSE, ("mbg_input: STX seen\n"));
441 parseio->parse_index = 1;
442 parseio->parse_data[0] = ch;
443 parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
444 return PARSE_INP_SKIP;
446 case ETX:
447 parseprintf(DD_PARSE, ("mbg_input: ETX seen\n"));
448 if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
449 return parse_end(parseio);
450 else
451 return rtc;
453 default:
454 return parse_addchar(parseio, ch);
460 * cvt_mgps
462 * convert Meinberg GPS format
464 static u_long
465 cvt_mgps(
466 unsigned char *buffer,
467 int size,
468 struct format *format,
469 clocktime_t *clock_time,
470 void *local
473 if (!Strok(buffer, format->fixed_string))
475 return cvt_meinberg(buffer, size, format, clock_time, local);
477 else
479 if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
480 format->field_offsets[O_DAY].length) ||
481 Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
482 format->field_offsets[O_MONTH].length) ||
483 Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
484 format->field_offsets[O_YEAR].length) ||
485 Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
486 format->field_offsets[O_HOUR].length) ||
487 Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
488 format->field_offsets[O_MIN].length) ||
489 Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
490 format->field_offsets[O_SEC].length))
492 return CVT_FAIL|CVT_BADFMT;
494 else
496 long h;
497 unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
499 clock_time->flags = PARSEB_S_LEAP|PARSEB_S_POSITION;
501 clock_time->usecond = 0;
504 * calculate UTC offset
506 if (Stoi(&buffer[format->field_offsets[O_UTCHOFFSET].offset], &h,
507 format->field_offsets[O_UTCHOFFSET].length))
509 return CVT_FAIL|CVT_BADFMT;
511 else
513 if (Stoi(&buffer[format->field_offsets[O_UTCMOFFSET].offset], &clock_time->utcoffset,
514 format->field_offsets[O_UTCMOFFSET].length))
516 return CVT_FAIL|CVT_BADFMT;
519 clock_time->utcoffset += TIMES60(h);
520 clock_time->utcoffset = TIMES60(clock_time->utcoffset);
522 if (buffer[format->field_offsets[O_UTCSOFFSET].offset] != '-')
524 clock_time->utcoffset = -clock_time->utcoffset;
529 * gather status flags
531 if (buffer[format->field_offsets[O_ZONE].offset] == 'S')
532 clock_time->flags |= PARSEB_DST;
534 if (clock_time->utcoffset == 0)
535 clock_time->flags |= PARSEB_UTC;
538 * no sv's seen - no time & position
540 if (f[0] == '#')
541 clock_time->flags |= PARSEB_POWERUP;
544 * at least one sv seen - time (for last position)
546 if (f[1] == '*')
547 clock_time->flags |= PARSEB_NOSYNC;
548 else
549 if (!(clock_time->flags & PARSEB_POWERUP))
550 clock_time->flags |= PARSEB_POSITION;
553 * oncoming zone switch
555 if (f[3] == '!')
556 clock_time->flags |= PARSEB_ANNOUNCE;
559 * oncoming leap second
560 * 'a' code not confirmed - earth is not
561 * expected to speed up
563 if (f[4] == 'A')
564 clock_time->flags |= PARSEB_LEAPADD;
566 if (f[4] == 'a')
567 clock_time->flags |= PARSEB_LEAPDEL;
570 * f[5] == ' '
574 * this is the leap second
576 if ((f[6] == 'L') || (clock_time->second == 60))
577 clock_time->flags |= PARSEB_LEAPSECOND;
579 return CVT_OK;
585 * gps_input
587 * grep binary data from input stream
589 static u_long
590 gps_input(
591 parse_t *parseio,
592 unsigned int ch,
593 timestamp_t *tstamp
596 CSUM calc_csum; /* used to compare the incoming csums */
597 GPS_MSG_HDR header;
598 struct msg_buf *msg_buf;
600 msg_buf = (struct msg_buf *)parseio->parse_pdata;
602 parseprintf(DD_PARSE, ("gps_input(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
604 if (!msg_buf)
605 return PARSE_INP_SKIP;
607 if ( msg_buf->phase == MBG_NONE )
608 { /* not receiving yet */
609 switch (ch)
611 case SOH:
612 parseprintf(DD_PARSE, ("gps_input: SOH seen\n"));
614 msg_buf->len = sizeof( header ); /* prepare to receive msg header */
615 msg_buf->phase = MBG_HEADER; /* receiving header */
616 break;
618 case STX:
619 parseprintf(DD_PARSE, ("gps_input: STX seen\n"));
621 msg_buf->len = 0;
622 msg_buf->phase = MBG_STRING; /* prepare to receive ASCII ETX delimited message */
623 parseio->parse_index = 1;
624 parseio->parse_data[0] = ch;
625 break;
627 default:
628 return PARSE_INP_SKIP; /* keep searching */
631 parseio->parse_dtime.parse_msglen = 1; /* reset buffer pointer */
632 parseio->parse_dtime.parse_msg[0] = ch; /* fill in first character */
633 parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
634 return PARSE_INP_SKIP;
637 /* SOH/STX has already been received */
639 /* save incoming character in both buffers if needbe */
640 if ((msg_buf->phase == MBG_STRING) &&
641 (parseio->parse_index < parseio->parse_dsize))
642 parseio->parse_data[parseio->parse_index++] = ch;
644 parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
646 if (parseio->parse_dtime.parse_msglen > sizeof(parseio->parse_dtime.parse_msg))
648 msg_buf->phase = MBG_NONE; /* buffer overflow - discard */
649 parseio->parse_data[parseio->parse_index] = '\0';
650 memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
651 parseio->parse_ldsize = parseio->parse_index;
652 return PARSE_INP_DATA;
655 switch (msg_buf->phase)
657 case MBG_HEADER:
658 case MBG_DATA:
659 msg_buf->len--;
661 if ( msg_buf->len ) /* transfer not complete */
662 return PARSE_INP_SKIP;
664 parseprintf(DD_PARSE, ("gps_input: %s complete\n", (msg_buf->phase == MBG_DATA) ? "data" : "header"));
666 break;
668 case MBG_STRING:
669 if ((ch == ETX) || (parseio->parse_index >= parseio->parse_dsize))
671 msg_buf->phase = MBG_NONE;
672 parseprintf(DD_PARSE, ("gps_input: string complete\n"));
673 parseio->parse_data[parseio->parse_index] = '\0';
674 memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
675 parseio->parse_ldsize = parseio->parse_index;
676 parseio->parse_index = 0;
677 return PARSE_INP_TIME;
679 else
681 return PARSE_INP_SKIP;
685 /* cnt == 0, so the header or the whole message is complete */
687 if ( msg_buf->phase == MBG_HEADER )
688 { /* header complete now */
689 unsigned char *datap = parseio->parse_dtime.parse_msg + 1;
691 get_mbg_header(&datap, &header);
693 parseprintf(DD_PARSE, ("gps_input: header: cmd 0x%x, len %d, dcsum 0x%x, hcsum 0x%x\n",
694 (int)header.gps_cmd, (int)header.gps_len, (int)header.gps_data_csum,
695 (int)header.gps_hdr_csum));
698 calc_csum = mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg + 1, (unsigned short)6 );
700 if ( calc_csum != header.gps_hdr_csum )
702 parseprintf(DD_PARSE, ("gps_input: header checksum mismatch expected 0x%x, got 0x%x\n",
703 (int)calc_csum, (int)mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg, (unsigned short)6 )));
705 msg_buf->phase = MBG_NONE; /* back to hunting mode */
706 return PARSE_INP_DATA; /* invalid header checksum received - pass up for detection */
709 if ((header.gps_len == 0) || /* no data to wait for */
710 (header.gps_len >= (sizeof (parseio->parse_dtime.parse_msg) - sizeof(header) - 1))) /* blows anything we have space for */
712 msg_buf->phase = MBG_NONE; /* back to hunting mode */
713 return (header.gps_len == 0) ? PARSE_INP_DATA : PARSE_INP_SKIP; /* message complete/throwaway */
716 parseprintf(DD_PARSE, ("gps_input: expecting %d bytes of data message\n", (int)header.gps_len));
718 msg_buf->len = header.gps_len;/* save number of bytes to wait for */
719 msg_buf->phase = MBG_DATA; /* flag header already complete */
720 return PARSE_INP_SKIP;
723 parseprintf(DD_PARSE, ("gps_input: message data complete\n"));
725 /* Header and data have been received. The header checksum has been */
726 /* checked */
728 msg_buf->phase = MBG_NONE; /* back to hunting mode */
729 return PARSE_INP_DATA; /* message complete, must be evaluated */
732 #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_MEINBERG) */
733 int clk_meinberg_bs;
734 #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_MEINBERG) */
737 * History:
739 * clk_meinberg.c,v
740 * Revision 4.12.2.1 2005/09/25 10:22:35 kardel
741 * cleanup buffer bounds
743 * Revision 4.12 2005/04/16 17:32:10 kardel
744 * update copyright
746 * Revision 4.11 2004/11/14 15:29:41 kardel
747 * support PPSAPI, upgrade Copyright to Berkeley style
749 * Revision 4.8 1999/11/28 09:13:50 kardel
750 * RECON_4_0_98F
752 * Revision 4.7 1999/02/21 11:09:14 kardel
753 * cleanup
755 * Revision 4.6 1998/06/14 21:09:36 kardel
756 * Sun acc cleanup
758 * Revision 4.5 1998/06/13 15:18:54 kardel
759 * fix mem*() to b*() function macro emulation
761 * Revision 4.4 1998/06/13 12:03:23 kardel
762 * fix SYSV clock name clash
764 * Revision 4.3 1998/06/12 15:22:28 kardel
765 * fix prototypes
767 * Revision 4.2 1998/05/24 16:14:42 kardel
768 * support current Meinberg standard data formats
770 * Revision 4.1 1998/05/24 09:39:52 kardel
771 * implementation of the new IO handling model
773 * Revision 4.0 1998/04/10 19:45:29 kardel
774 * Start 4.0 release version numbering
776 * from V3 3.23 - log info deleted 1998/04/11 kardel