📄 clk_meinberg.c
字号:
*/ if (f[3] == 'A') clock_time->flags |= PARSEB_LEAPADD; if (f[3] == 'a') clock_time->flags |= PARSEB_LEAPDEL; if (format->flags & MBG_EXTENDED) { clock_time->flags |= PARSEB_S_ANTENNA; /* * DCF77 does not encode the direction - * so we take the current default - * earth slowing down */ clock_time->flags &= ~PARSEB_LEAPDEL; if (f[4] == 'A') clock_time->flags |= PARSEB_LEAPADD; if (f[5] == 'R') clock_time->flags |= PARSEB_ALTERNATE; } return CVT_OK; }}/* * mbg_input * * grep data from input stream */static u_longmbg_input( parse_t *parseio, unsigned int ch, timestamp_t *tstamp ){ unsigned int rtc; parseprintf(DD_PARSE, ("mbg_input(0x%lx, 0x%x, ...)\n", (long)parseio, ch)); switch (ch) { case STX: parseprintf(DD_PARSE, ("mbg_input: STX seen\n")); parseio->parse_index = 1; parseio->parse_data[0] = ch; parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */ return PARSE_INP_SKIP; case ETX: parseprintf(DD_PARSE, ("mbg_input: ETX seen\n")); if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) return parse_end(parseio); else return rtc; default: return parse_addchar(parseio, ch); }}/* * cvt_mgps * * convert Meinberg GPS format */static u_longcvt_mgps( unsigned char *buffer, int size, struct format *format, clocktime_t *clock_time, void *local ){ if (!Strok(buffer, format->fixed_string)) { return cvt_meinberg(buffer, size, format, clock_time, local); } else { if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day, format->field_offsets[O_DAY].length) || Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month, format->field_offsets[O_MONTH].length) || Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year, format->field_offsets[O_YEAR].length) || Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour, format->field_offsets[O_HOUR].length) || Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute, format->field_offsets[O_MIN].length) || Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second, format->field_offsets[O_SEC].length)) { return CVT_FAIL|CVT_BADFMT; } else { long h; unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset]; clock_time->flags = PARSEB_S_LEAP|PARSEB_S_POSITION; clock_time->usecond = 0; /* * calculate UTC offset */ if (Stoi(&buffer[format->field_offsets[O_UTCHOFFSET].offset], &h, format->field_offsets[O_UTCHOFFSET].length)) { return CVT_FAIL|CVT_BADFMT; } else { if (Stoi(&buffer[format->field_offsets[O_UTCMOFFSET].offset], &clock_time->utcoffset, format->field_offsets[O_UTCMOFFSET].length)) { return CVT_FAIL|CVT_BADFMT; } clock_time->utcoffset += TIMES60(h); clock_time->utcoffset = TIMES60(clock_time->utcoffset); if (buffer[format->field_offsets[O_UTCSOFFSET].offset] != '-') { clock_time->utcoffset = -clock_time->utcoffset; } } /* * gather status flags */ if (buffer[format->field_offsets[O_ZONE].offset] == 'S') clock_time->flags |= PARSEB_DST; if (clock_time->utcoffset == 0) clock_time->flags |= PARSEB_UTC; /* * no sv's seen - no time & position */ if (f[0] == '#') clock_time->flags |= PARSEB_POWERUP; /* * at least one sv seen - time (for last position) */ if (f[1] == '*') clock_time->flags |= PARSEB_NOSYNC; else if (!(clock_time->flags & PARSEB_POWERUP)) clock_time->flags |= PARSEB_POSITION; /* * oncoming zone switch */ if (f[3] == '!') clock_time->flags |= PARSEB_ANNOUNCE; /* * oncoming leap second * 'a' code not confirmed - earth is not * expected to speed up */ if (f[4] == 'A') clock_time->flags |= PARSEB_LEAPADD; if (f[4] == 'a') clock_time->flags |= PARSEB_LEAPDEL; /* * f[5] == ' ' */ /* * this is the leap second */ if ((f[6] == 'L') || (clock_time->second == 60)) clock_time->flags |= PARSEB_LEAPSECOND; return CVT_OK; } }}/* * gps_input * * grep binary data from input stream */static u_longgps_input( parse_t *parseio, unsigned int ch, timestamp_t *tstamp ){ CSUM calc_csum; /* used to compare the incoming csums */ GPS_MSG_HDR header; struct msg_buf *msg_buf; msg_buf = (struct msg_buf *)parseio->parse_pdata; parseprintf(DD_PARSE, ("gps_input(0x%lx, 0x%x, ...)\n", (long)parseio, ch)); if (!msg_buf) return PARSE_INP_SKIP; if ( msg_buf->phase == MBG_NONE ) { /* not receiving yet */ switch (ch) { case SOH: parseprintf(DD_PARSE, ("gps_input: SOH seen\n")); msg_buf->len = sizeof( header ); /* prepare to receive msg header */ msg_buf->phase = MBG_HEADER; /* receiving header */ break; case STX: parseprintf(DD_PARSE, ("gps_input: STX seen\n")); msg_buf->len = 0; msg_buf->phase = MBG_STRING; /* prepare to receive ASCII ETX delimited message */ parseio->parse_index = 1; parseio->parse_data[0] = ch; break; default: return PARSE_INP_SKIP; /* keep searching */ } parseio->parse_dtime.parse_msglen = 1; /* reset buffer pointer */ parseio->parse_dtime.parse_msg[0] = ch; /* fill in first character */ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */ return PARSE_INP_SKIP; } /* SOH/STX has already been received */ /* save incoming character in both buffers if needbe */ if ((msg_buf->phase == MBG_STRING) && (parseio->parse_index < parseio->parse_dsize)) parseio->parse_data[parseio->parse_index++] = ch; parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch; if (parseio->parse_dtime.parse_msglen > sizeof(parseio->parse_dtime.parse_msg)) { msg_buf->phase = MBG_NONE; /* buffer overflow - discard */ parseio->parse_data[parseio->parse_index] = '\0'; memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1)); parseio->parse_ldsize = parseio->parse_index+1; return PARSE_INP_DATA; } switch (msg_buf->phase) { case MBG_HEADER: case MBG_DATA: msg_buf->len--; if ( msg_buf->len ) /* transfer not complete */ return PARSE_INP_SKIP; parseprintf(DD_PARSE, ("gps_input: %s complete\n", (msg_buf->phase == MBG_DATA) ? "data" : "header")); break; case MBG_STRING: if ((ch == ETX) || (parseio->parse_index >= parseio->parse_dsize)) { msg_buf->phase = MBG_NONE; parseprintf(DD_PARSE, ("gps_input: string complete\n")); parseio->parse_data[parseio->parse_index] = '\0'; memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1)); parseio->parse_ldsize = parseio->parse_index+1; parseio->parse_index = 0; return PARSE_INP_TIME; } else { return PARSE_INP_SKIP; } } /* cnt == 0, so the header or the whole message is complete */ if ( msg_buf->phase == MBG_HEADER ) { /* header complete now */ unsigned char *datap = parseio->parse_dtime.parse_msg + 1; get_mbg_header(&datap, &header); parseprintf(DD_PARSE, ("gps_input: header: cmd 0x%x, len %d, dcsum 0x%x, hcsum 0x%x\n", (int)header.gps_cmd, (int)header.gps_len, (int)header.gps_data_csum, (int)header.gps_hdr_csum)); calc_csum = mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg + 1, (unsigned short)6 ); if ( calc_csum != header.gps_hdr_csum ) { parseprintf(DD_PARSE, ("gps_input: header checksum mismatch expected 0x%x, got 0x%x\n", (int)calc_csum, (int)mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg, (unsigned short)6 ))); msg_buf->phase = MBG_NONE; /* back to hunting mode */ return PARSE_INP_DATA; /* invalid header checksum received - pass up for detection */ } if ((header.gps_len == 0) || /* no data to wait for */ (header.gps_len >= (sizeof (parseio->parse_dtime.parse_msg) - sizeof(header) - 1))) /* blows anything we have space for */ { msg_buf->phase = MBG_NONE; /* back to hunting mode */ return (header.gps_len == 0) ? PARSE_INP_DATA : PARSE_INP_SKIP; /* message complete/throwaway */ } parseprintf(DD_PARSE, ("gps_input: expecting %d bytes of data message\n", (int)header.gps_len)); msg_buf->len = header.gps_len;/* save number of bytes to wait for */ msg_buf->phase = MBG_DATA; /* flag header already complete */ return PARSE_INP_SKIP; } parseprintf(DD_PARSE, ("gps_input: message data complete\n")); /* Header and data have been received. The header checksum has been */ /* checked */ msg_buf->phase = MBG_NONE; /* back to hunting mode */ return PARSE_INP_DATA; /* message complete, must be evaluated */}#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_MEINBERG) */int clk_meinberg_bs;#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_MEINBERG) *//* * History: * * clk_meinberg.c,v * Revision 4.12 2005/04/16 17:32:10 kardel * update copyright * * Revision 4.11 2004/11/14 15:29:41 kardel * support PPSAPI, upgrade Copyright to Berkeley style * * Revision 4.8 1999/11/28 09:13:50 kardel * RECON_4_0_98F * * Revision 4.7 1999/02/21 11:09:14 kardel * cleanup * * Revision 4.6 1998/06/14 21:09:36 kardel * Sun acc cleanup * * Revision 4.5 1998/06/13 15:18:54 kardel * fix mem*() to b*() function macro emulation * * Revision 4.4 1998/06/13 12:03:23 kardel * fix SYSV clock name clash * * Revision 4.3 1998/06/12 15:22:28 kardel * fix prototypes * * Revision 4.2 1998/05/24 16:14:42 kardel * support current Meinberg standard data formats * * Revision 4.1 1998/05/24 09:39:52 kardel * implementation of the new IO handling model * * Revision 4.0 1998/04/10 19:45:29 kardel * Start 4.0 release version numbering * * from V3 3.23 - log info deleted 1998/04/11 kardel * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -