Annotation of embedaddon/ntp/libparse/clk_rawdcf.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_rawdcf.c,v 4.18 2006/06/22 18:40:01 kardel RELEASE_20060622_A
        !             3:  *  
        !             4:  * clk_rawdcf.c,v 4.18 2006/06/22 18:40:01 kardel RELEASE_20060622_A
        !             5:  *
        !             6:  * Raw DCF77 pulse clock support
        !             7:  *
        !             8:  * Copyright (c) 1995-2006 by Frank Kardel <kardel <AT> ntp.org>
        !             9:  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. Neither the name of the author nor the names of its contributors
        !            20:  *    may be used to endorse or promote products derived from this software
        !            21:  *    without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            33:  * SUCH DAMAGE.
        !            34:  *
        !            35:  */
        !            36: 
        !            37: #ifdef HAVE_CONFIG_H
        !            38: # include <config.h>
        !            39: #endif
        !            40: 
        !            41: #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_RAWDCF)
        !            42: 
        !            43: #include "ntp_fp.h"
        !            44: #include "ntp_unixtime.h"
        !            45: #include "ntp_calendar.h"
        !            46: 
        !            47: #include "parse.h"
        !            48: #ifdef PARSESTREAM
        !            49: # include <sys/parsestreams.h>
        !            50: #endif
        !            51: 
        !            52: #ifndef PARSEKERNEL
        !            53: # include "ntp_stdlib.h"
        !            54: #endif
        !            55: 
        !            56: /*
        !            57:  * DCF77 raw time code
        !            58:  *
        !            59:  * From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
        !            60:  * und Berlin, Maerz 1989
        !            61:  *
        !            62:  * Timecode transmission:
        !            63:  * AM:
        !            64:  *     time marks are send every second except for the second before the
        !            65:  *     next minute mark
        !            66:  *     time marks consist of a reduction of transmitter power to 25%
        !            67:  *     of the nominal level
        !            68:  *     the falling edge is the time indication (on time)
        !            69:  *     time marks of a 100ms duration constitute a logical 0
        !            70:  *     time marks of a 200ms duration constitute a logical 1
        !            71:  * FM:
        !            72:  *     see the spec. (basically a (non-)inverted psuedo random phase shift)
        !            73:  *
        !            74:  * Encoding:
        !            75:  * Second      Contents
        !            76:  * 0  - 10     AM: free, FM: 0
        !            77:  * 11 - 14     free
        !            78:  * 15          R     - alternate antenna
        !            79:  * 16          A1    - expect zone change (1 hour before)
        !            80:  * 17 - 18     Z1,Z2 - time zone
        !            81:  *              0  0 illegal
        !            82:  *              0  1 MEZ  (MET)
        !            83:  *              1  0 MESZ (MED, MET DST)
        !            84:  *              1  1 illegal
        !            85:  * 19          A2    - expect leap insertion/deletion (1 hour before)
        !            86:  * 20          S     - start of time code (1)
        !            87:  * 21 - 24     M1    - BCD (lsb first) Minutes
        !            88:  * 25 - 27     M10   - BCD (lsb first) 10 Minutes
        !            89:  * 28          P1    - Minute Parity (even)
        !            90:  * 29 - 32     H1    - BCD (lsb first) Hours
        !            91:  * 33 - 34      H10   - BCD (lsb first) 10 Hours
        !            92:  * 35          P2    - Hour Parity (even)
        !            93:  * 36 - 39     D1    - BCD (lsb first) Days
        !            94:  * 40 - 41     D10   - BCD (lsb first) 10 Days
        !            95:  * 42 - 44     DW    - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
        !            96:  * 45 - 49     MO    - BCD (lsb first) Month
        !            97:  * 50           MO0   - 10 Months
        !            98:  * 51 - 53     Y1    - BCD (lsb first) Years
        !            99:  * 54 - 57     Y10   - BCD (lsb first) 10 Years
        !           100:  * 58          P3    - Date Parity (even)
        !           101:  * 59                - usually missing (minute indication), except for leap insertion
        !           102:  */
        !           103: 
        !           104: static u_long pps_rawdcf (parse_t *, int, timestamp_t *);
        !           105: static u_long cvt_rawdcf (unsigned char *, int, struct format *, clocktime_t *, void *);
        !           106: static u_long inp_rawdcf (parse_t *, unsigned int, timestamp_t  *);
        !           107: 
        !           108: typedef struct last_tcode {
        !           109:        time_t tcode;   /* last converted time code */
        !           110: } last_tcode_t;
        !           111: 
        !           112: #define BUFFER_MAX     61
        !           113: 
        !           114: clockformat_t clock_rawdcf =
        !           115: {
        !           116:   inp_rawdcf,                  /* DCF77 input handling */
        !           117:   cvt_rawdcf,                  /* raw dcf input conversion */
        !           118:   pps_rawdcf,                  /* examining PPS information */
        !           119:   0,                           /* no private configuration data */
        !           120:   "RAW DCF77 Timecode",                /* direct decoding / time synthesis */
        !           121: 
        !           122:   BUFFER_MAX,                  /* bit buffer */
        !           123:   sizeof(last_tcode_t)
        !           124: };
        !           125: 
        !           126: static struct dcfparam
        !           127: {
        !           128:        unsigned char *onebits;
        !           129:        unsigned char *zerobits;
        !           130: } dcfparameter = 
        !           131: {
        !           132:        (unsigned char *)"###############RADMLS1248124P124812P1248121241248112481248P??", /* 'ONE' representation */
        !           133:        (unsigned char *)"--------------------s-------p------p----------------------p__"  /* 'ZERO' representation */
        !           134: };
        !           135: 
        !           136: static struct rawdcfcode 
        !           137: {
        !           138:        char offset;                    /* start bit */
        !           139: } rawdcfcode[] =
        !           140: {
        !           141:        {  0 }, { 15 }, { 16 }, { 17 }, { 19 }, { 20 }, { 21 }, { 25 }, { 28 }, { 29 },
        !           142:        { 33 }, { 35 }, { 36 }, { 40 }, { 42 }, { 45 }, { 49 }, { 50 }, { 54 }, { 58 }, { 59 }
        !           143: };
        !           144: 
        !           145: #define DCF_M  0
        !           146: #define DCF_R  1
        !           147: #define DCF_A1 2
        !           148: #define DCF_Z  3
        !           149: #define DCF_A2 4
        !           150: #define DCF_S  5
        !           151: #define DCF_M1 6
        !           152: #define DCF_M10        7
        !           153: #define DCF_P1 8
        !           154: #define DCF_H1 9
        !           155: #define DCF_H10        10
        !           156: #define DCF_P2 11
        !           157: #define DCF_D1 12
        !           158: #define DCF_D10        13
        !           159: #define DCF_DW 14
        !           160: #define DCF_MO 15
        !           161: #define DCF_MO0        16
        !           162: #define DCF_Y1 17
        !           163: #define DCF_Y10        18
        !           164: #define DCF_P3 19
        !           165: 
        !           166: static struct partab
        !           167: {
        !           168:        char offset;                    /* start bit of parity field */
        !           169: } partab[] =
        !           170: {
        !           171:        { 21 }, { 29 }, { 36 }, { 59 }
        !           172: };
        !           173: 
        !           174: #define DCF_P_P1       0
        !           175: #define DCF_P_P2       1
        !           176: #define DCF_P_P3       2
        !           177: 
        !           178: #define DCF_Z_MET 0x2
        !           179: #define DCF_Z_MED 0x1
        !           180: 
        !           181: static u_long
        !           182: ext_bf(
        !           183:        unsigned char *buf,
        !           184:        int   idx,
        !           185:        unsigned char *zero
        !           186:        )
        !           187: {
        !           188:        u_long sum = 0;
        !           189:        int i, first;
        !           190: 
        !           191:        first = rawdcfcode[idx].offset;
        !           192:   
        !           193:        for (i = rawdcfcode[idx+1].offset - 1; i >= first; i--)
        !           194:        {
        !           195:                sum <<= 1;
        !           196:                sum |= (buf[i] != zero[i]);
        !           197:        }
        !           198:        return sum;
        !           199: }
        !           200: 
        !           201: static unsigned
        !           202: pcheck(
        !           203:        unsigned char *buf,
        !           204:        int   idx,
        !           205:        unsigned char *zero
        !           206:        )
        !           207: {
        !           208:        int i,last;
        !           209:        unsigned psum = 1;
        !           210: 
        !           211:        last = partab[idx+1].offset;
        !           212: 
        !           213:        for (i = partab[idx].offset; i < last; i++)
        !           214:            psum ^= (buf[i] != zero[i]);
        !           215: 
        !           216:        return psum;
        !           217: }
        !           218: 
        !           219: static u_long
        !           220: convert_rawdcf(
        !           221:               unsigned char   *buffer,
        !           222:               int              size,
        !           223:               struct dcfparam *dcfprm,
        !           224:               clocktime_t     *clock_time
        !           225:               )
        !           226: {
        !           227:        unsigned char *s = buffer;
        !           228:        unsigned char *b = dcfprm->onebits;
        !           229:        unsigned char *c = dcfprm->zerobits;
        !           230:        int i;
        !           231: 
        !           232:        parseprintf(DD_RAWDCF,("parse: convert_rawdcf: \"%s\"\n", buffer));
        !           233: 
        !           234:        if (size < 57)
        !           235:        {
        !           236: #ifndef PARSEKERNEL
        !           237:                msyslog(LOG_ERR, "parse: convert_rawdcf: INCOMPLETE DATA - time code only has %d bits\n", size);
        !           238: #endif
        !           239:                return CVT_NONE;
        !           240:        }
        !           241:   
        !           242:        for (i = 0; i < size; i++)
        !           243:        {
        !           244:                if ((*s != *b) && (*s != *c))
        !           245:                {
        !           246:                        /*
        !           247:                         * we only have two types of bytes (ones and zeros)
        !           248:                         */
        !           249: #ifndef PARSEKERNEL
        !           250:                        msyslog(LOG_ERR, "parse: convert_rawdcf: BAD DATA - no conversion");
        !           251: #endif
        !           252:                        return CVT_NONE;
        !           253:                }
        !           254:                if (*b) b++;
        !           255:                if (*c) c++;
        !           256:                s++;
        !           257:        }
        !           258: 
        !           259:        /*
        !           260:         * check Start and Parity bits
        !           261:         */
        !           262:        if ((ext_bf(buffer, DCF_S, dcfprm->zerobits) == 1) &&
        !           263:            pcheck(buffer, DCF_P_P1, dcfprm->zerobits) &&
        !           264:            pcheck(buffer, DCF_P_P2, dcfprm->zerobits) &&
        !           265:            pcheck(buffer, DCF_P_P3, dcfprm->zerobits))
        !           266:        {
        !           267:                /*
        !           268:                 * buffer OK
        !           269:                 */
        !           270:                parseprintf(DD_RAWDCF,("parse: convert_rawdcf: parity check passed\n"));
        !           271: 
        !           272:                clock_time->flags  = PARSEB_S_ANTENNA|PARSEB_S_LEAP;
        !           273:                clock_time->utctime= 0;
        !           274:                clock_time->usecond= 0;
        !           275:                clock_time->second = 0;
        !           276:                clock_time->minute = ext_bf(buffer, DCF_M10, dcfprm->zerobits);
        !           277:                clock_time->minute = TIMES10(clock_time->minute) + ext_bf(buffer, DCF_M1, dcfprm->zerobits);
        !           278:                clock_time->hour   = ext_bf(buffer, DCF_H10, dcfprm->zerobits);
        !           279:                clock_time->hour   = TIMES10(clock_time->hour) + ext_bf(buffer, DCF_H1, dcfprm->zerobits);
        !           280:                clock_time->day    = ext_bf(buffer, DCF_D10, dcfprm->zerobits);
        !           281:                clock_time->day    = TIMES10(clock_time->day) + ext_bf(buffer, DCF_D1, dcfprm->zerobits);
        !           282:                clock_time->month  = ext_bf(buffer, DCF_MO0, dcfprm->zerobits);
        !           283:                clock_time->month  = TIMES10(clock_time->month) + ext_bf(buffer, DCF_MO, dcfprm->zerobits);
        !           284:                clock_time->year   = ext_bf(buffer, DCF_Y10, dcfprm->zerobits);
        !           285:                clock_time->year   = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1, dcfprm->zerobits);
        !           286: 
        !           287:                switch (ext_bf(buffer, DCF_Z, dcfprm->zerobits))
        !           288:                {
        !           289:                    case DCF_Z_MET:
        !           290:                        clock_time->utcoffset = -1*60*60;
        !           291:                        break;
        !           292: 
        !           293:                    case DCF_Z_MED:
        !           294:                        clock_time->flags     |= PARSEB_DST;
        !           295:                        clock_time->utcoffset  = -2*60*60;
        !           296:                        break;
        !           297: 
        !           298:                    default:
        !           299:                        parseprintf(DD_RAWDCF,("parse: convert_rawdcf: BAD TIME ZONE\n"));
        !           300:                        return CVT_FAIL|CVT_BADFMT;
        !           301:                }
        !           302: 
        !           303:                if (ext_bf(buffer, DCF_A1, dcfprm->zerobits))
        !           304:                    clock_time->flags |= PARSEB_ANNOUNCE;
        !           305: 
        !           306:                if (ext_bf(buffer, DCF_A2, dcfprm->zerobits))
        !           307:                    clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */
        !           308: 
        !           309:                if (ext_bf(buffer, DCF_R, dcfprm->zerobits))
        !           310:                    clock_time->flags |= PARSEB_ALTERNATE;
        !           311: 
        !           312:                parseprintf(DD_RAWDCF,("parse: convert_rawdcf: TIME CODE OK: %d:%d, %d.%d.%d, flags 0x%lx\n",
        !           313:                                       (int)clock_time->hour, (int)clock_time->minute, (int)clock_time->day, (int)clock_time->month,(int) clock_time->year,
        !           314:                                       (u_long)clock_time->flags));
        !           315:                return CVT_OK;
        !           316:        }
        !           317:        else
        !           318:        {
        !           319:                /*
        !           320:                 * bad format - not for us
        !           321:                 */
        !           322: #ifndef PARSEKERNEL
        !           323:                msyslog(LOG_ERR, "parse: convert_rawdcf: parity check FAILED for \"%s\"\n", buffer);
        !           324: #endif
        !           325:                return CVT_FAIL|CVT_BADFMT;
        !           326:        }
        !           327: }
        !           328: 
        !           329: /*
        !           330:  * raw dcf input routine - needs to fix up 50 baud
        !           331:  * characters for 1/0 decision
        !           332:  */
        !           333: static u_long
        !           334: cvt_rawdcf(
        !           335:           unsigned char   *buffer,
        !           336:           int              size,
        !           337:           struct format   *param,
        !           338:           clocktime_t     *clock_time,
        !           339:           void            *local
        !           340:           )
        !           341: {
        !           342:        last_tcode_t  *t = (last_tcode_t *)local;
        !           343:        unsigned char *s = (unsigned char *)buffer;
        !           344:        unsigned char *e = s + size;
        !           345:        unsigned char *b = dcfparameter.onebits;
        !           346:        unsigned char *c = dcfparameter.zerobits;
        !           347:        u_long       rtc = CVT_NONE;
        !           348:        unsigned int i, lowmax, highmax, cutoff, span;
        !           349: #define BITS 9
        !           350:        unsigned char     histbuf[BITS];
        !           351:        /*
        !           352:         * the input buffer contains characters with runs of consecutive
        !           353:         * bits set. These set bits are an indication of the DCF77 pulse
        !           354:         * length. We assume that we receive the pulse at 50 Baud. Thus
        !           355:         * a 100ms pulse would generate a 4 bit train (20ms per bit and
        !           356:         * start bit)
        !           357:         * a 200ms pulse would create all zeroes (and probably a frame error)
        !           358:         */
        !           359: 
        !           360:        for (i = 0; i < BITS; i++)
        !           361:        {
        !           362:                histbuf[i] = 0;
        !           363:        }
        !           364: 
        !           365:        cutoff = 0;
        !           366:        lowmax = 0;
        !           367: 
        !           368:        while (s < e)
        !           369:        {
        !           370:                unsigned int ch = *s ^ 0xFF;
        !           371:                /*
        !           372:                 * these lines are left as an excercise to the reader 8-)
        !           373:                 */
        !           374:                if (!((ch+1) & ch) || !*s)
        !           375:                {
        !           376: 
        !           377:                        for (i = 0; ch; i++)
        !           378:                        {
        !           379:                                ch >>= 1;
        !           380:                        }
        !           381: 
        !           382:                        *s = i;
        !           383:                        histbuf[i]++;
        !           384:                        cutoff += i;
        !           385:                        lowmax++;
        !           386:                }
        !           387:                else
        !           388:                {
        !           389:                        parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: character check for 0x%x@%d FAILED\n", *s, (int)(s - (unsigned char *)buffer)));
        !           390:                        *s = (unsigned char)~0;
        !           391:                        rtc = CVT_FAIL|CVT_BADFMT;
        !           392:                }
        !           393:                s++;
        !           394:        }
        !           395: 
        !           396:        if (lowmax)
        !           397:        {
        !           398:                cutoff /= lowmax;
        !           399:        }
        !           400:        else
        !           401:        {
        !           402:                cutoff = 4;     /* doesn't really matter - it'll fail anyway, but gives error output */
        !           403:        }
        !           404: 
        !           405:        parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: average bit count: %d\n", cutoff));
        !           406: 
        !           407:        lowmax = 0;
        !           408:        highmax = 0;
        !           409: 
        !           410:        parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: histogram:"));
        !           411:        for (i = 0; i <= cutoff; i++)
        !           412:        {
        !           413:                lowmax+=histbuf[i] * i;
        !           414:                highmax += histbuf[i];
        !           415:                parseprintf(DD_RAWDCF,(" %d", histbuf[i]));
        !           416:        }
        !           417:        parseprintf(DD_RAWDCF, (" <M>"));
        !           418: 
        !           419:        lowmax += highmax / 2;
        !           420: 
        !           421:        if (highmax)
        !           422:        {
        !           423:                lowmax /= highmax;
        !           424:        }
        !           425:        else
        !           426:        {
        !           427:                lowmax = 0;
        !           428:        }
        !           429: 
        !           430:        highmax = 0;
        !           431:        cutoff = 0;
        !           432: 
        !           433:        for (; i < BITS; i++)
        !           434:        {
        !           435:                highmax+=histbuf[i] * i;
        !           436:                cutoff +=histbuf[i];
        !           437:                parseprintf(DD_RAWDCF,(" %d", histbuf[i]));
        !           438:        }
        !           439:        parseprintf(DD_RAWDCF,("\n"));
        !           440: 
        !           441:        if (cutoff)
        !           442:        {
        !           443:                highmax /= cutoff;
        !           444:        }
        !           445:        else
        !           446:        {
        !           447:                highmax = BITS-1;
        !           448:        }
        !           449: 
        !           450:        span = cutoff = lowmax;
        !           451:        for (i = lowmax; i <= highmax; i++)
        !           452:        {
        !           453:                if (histbuf[cutoff] > histbuf[i])
        !           454:                {
        !           455:                        cutoff = i;
        !           456:                        span = i;
        !           457:                }
        !           458:                else
        !           459:                    if (histbuf[cutoff] == histbuf[i])
        !           460:                    {
        !           461:                            span = i;
        !           462:                    }
        !           463:        }
        !           464: 
        !           465:        cutoff = (cutoff + span) / 2;
        !           466: 
        !           467:        parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: lower maximum %d, higher maximum %d, cutoff %d\n", lowmax, highmax, cutoff));
        !           468: 
        !           469:        s = (unsigned char *)buffer;
        !           470:        while (s < e)
        !           471:        {
        !           472:                if (*s == (unsigned char)~0)
        !           473:                {
        !           474:                        *s = '?';
        !           475:                }
        !           476:                else
        !           477:                {
        !           478:                        *s = (*s >= cutoff) ? *b : *c;
        !           479:                }
        !           480:                s++;
        !           481:                if (*b) b++;
        !           482:                if (*c) c++;
        !           483:        }
        !           484: 
        !           485:         if (rtc == CVT_NONE)
        !           486:         {
        !           487:               rtc = convert_rawdcf(buffer, size, &dcfparameter, clock_time);
        !           488:               if (rtc == CVT_OK)
        !           489:               {
        !           490:                        time_t newtime;
        !           491: 
        !           492:                        newtime = parse_to_unixtime(clock_time, &rtc);
        !           493:                        if ((rtc == CVT_OK) && t)
        !           494:                        {
        !           495:                                if ((newtime - t->tcode) == 60) /* guard against multi bit errors */
        !           496:                                {
        !           497:                                        clock_time->utctime = newtime;
        !           498:                                }
        !           499:                                else
        !           500:                                {
        !           501:                                        rtc = CVT_FAIL|CVT_BADTIME;
        !           502:                                }
        !           503:                                t->tcode            = newtime;
        !           504:                        }
        !           505:               }
        !           506:         }
        !           507:         
        !           508:        return rtc;
        !           509: }
        !           510: 
        !           511: /*
        !           512:  * pps_rawdcf
        !           513:  *
        !           514:  * currently a very stupid version - should be extended to decode
        !           515:  * also ones and zeros (which is easy)
        !           516:  */
        !           517: /*ARGSUSED*/
        !           518: static u_long
        !           519: pps_rawdcf(
        !           520:        parse_t *parseio,
        !           521:        int status,
        !           522:        timestamp_t *ptime
        !           523:        )
        !           524: {
        !           525:        if (!status)            /* negative edge for simpler wiring (Rx->DCD) */
        !           526:        {
        !           527:                parseio->parse_dtime.parse_ptime  = *ptime;
        !           528:                parseio->parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
        !           529:        }
        !           530: 
        !           531:        return CVT_NONE;
        !           532: }
        !           533: 
        !           534: static u_long
        !           535: snt_rawdcf(
        !           536:        parse_t *parseio,
        !           537:        timestamp_t *ptime
        !           538:        )
        !           539: {
        !           540:        if ((parseio->parse_dtime.parse_status & CVT_MASK) == CVT_OK)
        !           541:        {
        !           542:                parseio->parse_dtime.parse_stime = *ptime;
        !           543: 
        !           544: #ifdef PARSEKERNEL
        !           545:                parseio->parse_dtime.parse_time.tv.tv_sec++;
        !           546: #else
        !           547:                parseio->parse_dtime.parse_time.fp.l_ui++;
        !           548: #endif
        !           549:                
        !           550:                parseprintf(DD_RAWDCF,("parse: snt_rawdcf: time stamp synthesized offset %d seconds\n", parseio->parse_index - 1));
        !           551:                
        !           552:                return updatetimeinfo(parseio, parseio->parse_lstate);
        !           553:        }
        !           554:        return CVT_NONE;
        !           555: }
        !           556: 
        !           557: /*
        !           558:  * inp_rawdcf
        !           559:  *
        !           560:  * grab DCF77 data from input stream
        !           561:  */
        !           562: static u_long
        !           563: inp_rawdcf(
        !           564:          parse_t      *parseio,
        !           565:          unsigned int  ch,
        !           566:          timestamp_t  *tstamp
        !           567:          )
        !           568: {
        !           569:        static struct timeval timeout = { 1, 500000 }; /* 1.5 secongs denote second #60 */
        !           570:        
        !           571:        parseprintf(DD_PARSE, ("inp_rawdcf(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
        !           572:        
        !           573:        parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
        !           574: 
        !           575:        if (parse_timedout(parseio, tstamp, &timeout))
        !           576:        {
        !           577:                parseprintf(DD_PARSE, ("inp_rawdcf: time out seen\n"));
        !           578: 
        !           579:                (void) parse_end(parseio);
        !           580:                (void) parse_addchar(parseio, ch);
        !           581:                return PARSE_INP_TIME;
        !           582:        }
        !           583:        else
        !           584:        {
        !           585:                unsigned int rtc;
        !           586:                
        !           587:                rtc = parse_addchar(parseio, ch);
        !           588:                if (rtc == PARSE_INP_SKIP)
        !           589:                {
        !           590:                        if (snt_rawdcf(parseio, tstamp) == CVT_OK)
        !           591:                                return PARSE_INP_SYNTH;
        !           592:                }
        !           593:                return rtc;
        !           594:        }
        !           595: }
        !           596: 
        !           597: #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RAWDCF) */
        !           598: int clk_rawdcf_bs;
        !           599: #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RAWDCF) */
        !           600: 
        !           601: /*
        !           602:  * History:
        !           603:  *
        !           604:  * clk_rawdcf.c,v
        !           605:  * Revision 4.18  2006/06/22 18:40:01  kardel
        !           606:  * clean up signedness (gcc 4)
        !           607:  *
        !           608:  * Revision 4.17  2006/01/22 16:01:55  kardel
        !           609:  * update version information
        !           610:  *
        !           611:  * Revision 4.16  2006/01/22 15:51:22  kardel
        !           612:  * generate reasonable timecode output on invalid input
        !           613:  *
        !           614:  * Revision 4.15  2005/08/06 19:17:06  kardel
        !           615:  * clean log output
        !           616:  *
        !           617:  * Revision 4.14  2005/08/06 17:39:40  kardel
        !           618:  * cleanup size handling wrt/ to buffer boundaries
        !           619:  *
        !           620:  * Revision 4.13  2005/04/16 17:32:10  kardel
        !           621:  * update copyright
        !           622:  *
        !           623:  * Revision 4.12  2004/11/14 15:29:41  kardel
        !           624:  * support PPSAPI, upgrade Copyright to Berkeley style
        !           625:  *
        !           626:  * Revision 4.9  1999/12/06 13:42:23  kardel
        !           627:  * transfer correctly converted time codes always into tcode
        !           628:  *
        !           629:  * Revision 4.8  1999/11/28 09:13:50  kardel
        !           630:  * RECON_4_0_98F
        !           631:  *
        !           632:  * Revision 4.7  1999/04/01 20:07:20  kardel
        !           633:  * added checking for minutie increment of timestamps in clk_rawdcf.c
        !           634:  *
        !           635:  * Revision 4.6  1998/06/14 21:09:37  kardel
        !           636:  * Sun acc cleanup
        !           637:  *
        !           638:  * Revision 4.5  1998/06/13 12:04:16  kardel
        !           639:  * fix SYSV clock name clash
        !           640:  *
        !           641:  * Revision 4.4  1998/06/12 15:22:28  kardel
        !           642:  * fix prototypes
        !           643:  *
        !           644:  * Revision 4.3  1998/06/06 18:33:36  kardel
        !           645:  * simplified condidional compile expression
        !           646:  *
        !           647:  * Revision 4.2  1998/05/24 11:04:18  kardel
        !           648:  * triggering PPS on negative edge for simpler wiring (Rx->DCD)
        !           649:  *
        !           650:  * Revision 4.1  1998/05/24 09:39:53  kardel
        !           651:  * implementation of the new IO handling model
        !           652:  *
        !           653:  * Revision 4.0  1998/04/10 19:45:30  kardel
        !           654:  * Start 4.0 release version numbering
        !           655:  *
        !           656:  * from V3 3.24 log info deleted 1998/04/11 kardel
        !           657:  *
        !           658:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>