~ubuntu-branches/debian/sid/ntp/sid

« back to all changes in this revision

Viewing changes to ntpd/refclock_wwvb.c

  • Committer: Package Import Robot
  • Author(s): Peter Eisentraut
  • Date: 2012-02-27 13:55:56 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20120227135556-dkx4mkod5trl5bgt
Tags: 1:4.2.6.p5+dfsg-1
* New upstream release (closes: #644673)
* Updated instructions on generating autotools.patch
* Updated standards version

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
 *      hh:mm:ss = hours, minutes, seconds
55
55
 *      i = synchronization flag (' ' = in synch, '?' = out of synch)
56
56
 *
57
 
 * The alarm condition is indicated by other than ' ' at a, which occurs
 
57
 * The alarm condition is indicated by other than ' ' at i, which occurs
58
58
 * during initial synchronization and when received signal is lost for
59
59
 * about ten hours.
60
60
 *
69
69
 *      ddd = day of year
70
70
 *      hh:mm:ss.fff = hours, minutes, seconds, milliseconds
71
71
 *
72
 
 * The alarm condition is indicated by other than ' ' at a, which occurs
 
72
 * The alarm condition is indicated by other than ' ' at i, which occurs
73
73
 * during initial synchronization and when received signal is lost for
74
74
 * about ten hours. The unlock condition is indicated by other than ' '
75
75
 * at q.
120
120
#define DESCRIPTION     "Spectracom WWVB/GPS Receiver" /* WRU */
121
121
 
122
122
#define LENWWVB0        22      /* format 0 timecode length */
123
 
#define LENWWVB1        22      /* format 1 timecode length */
124
123
#define LENWWVB2        24      /* format 2 timecode length */
125
 
#define LENWWVB3        29      /* format 3 timecode length */
 
124
#define LENWWVB3        29      /* format 3 timecode length */
126
125
#define MONLIN          15      /* number of monitoring lines */
127
126
 
128
127
/*
136
135
        int     tcount;         /* timecode sample counter */
137
136
        int     pcount;         /* PPS sample counter */
138
137
#endif /* HAVE_PPSAPI */
139
 
        l_fp    laststamp;      /* last receive timestamp */
 
138
        l_fp    laststamp;      /* last <CR> timestamp */
 
139
        int     prev_eol_cr;    /* was last EOL <CR> (not <LF>)? */
140
140
        u_char  lasthour;       /* last hour (for monitor) */
141
141
        u_char  linect;         /* count ignored lines (for monitor */
142
142
};
150
150
static  void    wwvb_poll       (int, struct peer *);
151
151
static  void    wwvb_timer      (int, struct peer *);
152
152
#ifdef HAVE_PPSAPI
153
 
static  void    wwvb_control    (int, struct refclockstat *,
 
153
static  void    wwvb_control    (int, const struct refclockstat *,
154
154
                                 struct refclockstat *, struct peer *);
155
155
#define         WWVB_CONTROL    wwvb_control
156
156
#else
189
189
         * Open serial port. Use CLK line discipline, if available.
190
190
         */
191
191
        snprintf(device, sizeof(device), DEVICE, unit);
192
 
        if (0 == (fd = refclock_open(device, SPEED232, LDISC_CLK)))
 
192
        fd = refclock_open(device, SPEED232, LDISC_CLK);
 
193
        if (fd <= 0)
193
194
                return (0);
194
195
 
195
196
        /*
196
197
         * Allocate and initialize unit structure
197
198
         */
198
 
        up = emalloc(sizeof(*up));
199
 
        memset(up, 0, sizeof(*up));
 
199
        up = emalloc_zero(sizeof(*up));
200
200
        pp = peer->procptr;
201
 
        pp->unitptr = (caddr_t)up;
202
201
        pp->io.clock_recv = wwvb_receive;
203
 
        pp->io.srcclock = (caddr_t)peer;
 
202
        pp->io.srcclock = (void *)peer;
204
203
        pp->io.datalen = 0;
205
204
        pp->io.fd = fd;
206
205
        if (!io_addclock(&pp->io)) {
207
206
                close(fd);
208
207
                pp->io.fd = -1;
209
208
                free(up);
210
 
                pp->unitptr = NULL;
211
209
                return (0);
212
210
        }
 
211
        pp->unitptr = up;
213
212
 
214
213
        /*
215
214
         * Initialize miscellaneous variables
234
233
        struct refclockproc *pp;
235
234
 
236
235
        pp = peer->procptr;
237
 
        up = (struct wwvbunit *)pp->unitptr;
 
236
        up = pp->unitptr;
238
237
        if (-1 != pp->io.fd)
239
238
                io_closeclock(&pp->io);
240
239
        if (NULL != up)
267
266
        /*
268
267
         * Initialize pointers and read the timecode and timestamp
269
268
         */
270
 
        peer = (struct peer *)rbufp->recv_srcclock;
 
269
        peer = rbufp->recv_peer;
271
270
        pp = peer->procptr;
272
 
        up = (struct wwvbunit *)pp->unitptr;
 
271
        up = pp->unitptr;
273
272
        temp = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp);
274
273
 
275
274
        /*
281
280
         * reading precision is only to the millisecond. Thus, unless
282
281
         * you have a PPS gadget and don't have to have the year, format
283
282
         * 0 provides the lowest jitter.
 
283
         * Save the timestamp of each <CR> in up->laststamp.  Lines with
 
284
         * no characters occur for every <LF>, and for some <CR>s when
 
285
         * format 0 is used. Format 0 starts and ends each cycle with a
 
286
         * <CR><LF> pair, format 2 starts each cycle with its only pair.
 
287
         * The preceding <CR> is the on-time character for both formats.
 
288
         * The timestamp provided with non-empty lines corresponds to
 
289
         * the <CR> following the timecode, which is ultimately not used
 
290
         * with format 0 and is used for the following timecode for
 
291
         * format 2.
284
292
         */
285
293
        if (temp == 0) {
286
 
                up->laststamp = trtmp;
 
294
                if (up->prev_eol_cr) {
 
295
                        DPRINTF(2, ("wwvb: <LF> @ %s\n",
 
296
                                    prettydate(&trtmp)));
 
297
                } else {
 
298
                        up->laststamp = trtmp;
 
299
                        DPRINTF(2, ("wwvb: <CR> @ %s\n", 
 
300
                                    prettydate(&trtmp)));
 
301
                }
 
302
                up->prev_eol_cr = !up->prev_eol_cr;
287
303
                return;
288
304
        }
289
305
        pp->lencode = temp;
290
306
        pp->lastrec = up->laststamp;
 
307
        up->laststamp = trtmp;
 
308
        up->prev_eol_cr = TRUE;
 
309
        DPRINTF(2, ("wwvb: code @ %s\n"
 
310
                    "       using %s minus one char\n",
 
311
                    prettydate(&trtmp), prettydate(&pp->lastrec)));
 
312
        if (L_ISZERO(&pp->lastrec))
 
313
                return;
291
314
 
292
315
        /*
293
316
         * We get down to business, check the timecode format and decode
307
330
                if (sscanf(pp->a_lastcode,
308
331
                    "%c %3d %2d:%2d:%2d%c%cTZ=%2d",
309
332
                    &syncchar, &pp->day, &pp->hour, &pp->minute,
310
 
                    &pp->second, &tmpchar, &dstchar, &tz) == 8)
 
333
                    &pp->second, &tmpchar, &dstchar, &tz) == 8) {
311
334
                        pp->nsec = 0;
312
335
                        break;
 
336
                }
 
337
                goto bad_format;
313
338
 
314
339
        case LENWWVB2:
315
340
 
319
344
                    "%c%c %2d %3d %2d:%2d:%2d.%3ld %c",
320
345
                    &syncchar, &qualchar, &pp->year, &pp->day,
321
346
                    &pp->hour, &pp->minute, &pp->second, &pp->nsec,
322
 
                    &leapchar) == 9)
 
347
                    &leapchar) == 9) {
323
348
                        pp->nsec *= 1000000;
324
349
                        break;
 
350
                }
 
351
                goto bad_format;
325
352
 
326
353
        case LENWWVB3:
327
354
 
328
 
                /*
 
355
                /*
329
356
                 * Timecode format 3: "0003I yyyymmdd hhmmss+0000SL#"
 
357
                 * WARNING: Undocumented, and the on-time character # is
 
358
                 * not yet handled correctly by this driver.  It may be
 
359
                 * as simple as compensating for an additional 1/960 s.
330
360
                 */
331
361
                if (sscanf(pp->a_lastcode,
332
362
                    "0003%c %4d%2d%2d %2d%2d%2d+0000%c%c",
337
367
                        pp->nsec = 0;
338
368
                        break;
339
369
                }
 
370
                goto bad_format;
340
371
 
341
372
        default:
 
373
        bad_format:
342
374
 
343
375
                /*
344
376
                 * Unknown format: If dumping internal table, record
423
455
        register struct wwvbunit *up;
424
456
        struct refclockproc *pp;
425
457
        char    pollchar;       /* character sent to clock */
 
458
        l_fp    now;
426
459
 
427
460
        /*
428
461
         * Time to poll the clock. The Spectracom clock responds to a
432
465
         * the clock; all others just listen in.
433
466
         */
434
467
        pp = peer->procptr;
435
 
        up = (struct wwvbunit *)pp->unitptr;
 
468
        up = pp->unitptr;
436
469
        if (up->linect > 0)
437
470
                pollchar = 'R';
438
471
        else
439
472
                pollchar = 'T';
440
473
        if (write(pp->io.fd, &pollchar, 1) != 1)
441
474
                refclock_report(peer, CEVNT_FAULT);
 
475
#ifdef DEBUG
 
476
        get_systime(&now);
 
477
        if (debug)
 
478
                printf("%c poll at %s\n", pollchar, prettydate(&now));
 
479
#endif
442
480
#ifdef HAVE_PPSAPI
443
481
        if (up->ppsapi_lit &&
444
482
            refclock_pps(peer, &up->atom, pp->sloppyclockflag) > 0) {
467
505
         * are received, declare a timeout and keep going.
468
506
         */
469
507
        pp = peer->procptr;
470
 
        up = (struct wwvbunit *)pp->unitptr;
 
508
        up = pp->unitptr;
471
509
        pp->polls++;
472
510
 
473
511
        /*
517
555
static void
518
556
wwvb_control(
519
557
        int unit,
520
 
        struct refclockstat *in_st,
 
558
        const struct refclockstat *in_st,
521
559
        struct refclockstat *out_st,
522
560
        struct peer *peer
523
561
        )
526
564
        struct refclockproc *pp;
527
565
        
528
566
        pp = peer->procptr;
529
 
        up = (struct wwvbunit *)pp->unitptr;
 
567
        up = pp->unitptr;
530
568
 
531
569
        if (!(pp->sloppyclockflag & CLK_FLAG1)) {
532
570
                if (!up->ppsapi_tried)