Logo Search packages:      
Sourcecode: hf version File versions

timedec.c

/*****************************************************************************/

/*
 *      timedec.c  --  Linux soundcard DCF77 receiver, time decoder.
 *
 *      Copyright (C) 1997  Thomas Sailer (sailer@ife.ee.ethz.ch)
 *        Swiss Federal Institute of Technology (ETH), Electronics Lab
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 */

/*****************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <time.h>
#include "dcf77.h"

/* --------------------------------------------------------------------- */

#define ZONE_MEZ  2
#define ZONE_MESZ 1

/* --------------------------------------------------------------------- */

void time_decode(unsigned long long bits, unsigned int samples)
{
      static const char *tz_name[4] = { "invalid 0", "MESZ", "MEZ", "invalid 3" };
      static const char *daynames = "MonTueWedThuFriSatSun";
      char system_set_date[128], system_set_time[128];
      unsigned int u;
      unsigned int pgrp1, pgrp2, pgrp3;
      struct tm tm, *tmp;
      time_t t;
      unsigned int dw;
      unsigned int tz;
      unsigned int tzchg;
      unsigned int leapsec;
      unsigned int backup_ant;

      pgrp1 = (bits >> 21) & 0xff;
      pgrp2 = (bits >> 29) & 0x7f;
      pgrp3 = (bits >> 36) & 0x7fffff;
      
//    if (!hbg_mode) { /* don't know the exact parity bits/format! */
            if (hweight8(pgrp1) & 1) {
                  vlprintf(3, "DCF77 time: parity 1 invalid\n");
                  goto error;
            }
            if (hweight8(pgrp2) & 1) {
                  vlprintf(3, "DCF77 time: parity 2 invalid\n");
                  goto error;
            }
            if (hweight32(pgrp3) & 1) {
                  vlprintf(3, "DCF77 time: parity 3 invalid\n");
                  goto error;
            }
            if (!(bits & 0x100000)) {
                  vlprintf(3, "DCF77 time: startbit wrong!\n");
                  goto error;
            }
//    }

      backup_ant = (bits & 0x8000) != 0;
      tzchg = (bits & 0x10000) != 0;
      tz = (bits >> 17) & 3;
      leapsec = (bits & 0x80000) != 0;

      u = pgrp1 & 0x7f;
      if ((u & 0x0f) >= 0x0a || u >= 0x60) {
            vlprintf(3, "DCF77 time: invalid minute field 0x%02x\n", u);
            goto error;
      }
      tm.tm_sec = tm.tm_isdst = 0;
      tm.tm_min = (u & 0x0f) + 10 * ((u >> 4) & 0x0f);
      u = pgrp2 & 0x3f;
      if ((u & 0x0f) >= 0x0a || u >= 0x24) {
            vlprintf(3, "DCF77 time: invalid hour field 0x%02x\n", u);
            goto error;
      }
      tm.tm_hour = (u & 0x0f) + 10 * ((u >> 4) & 0x0f);
      u = pgrp3 & 0x3f;
      if ((u & 0x0f) >= 0x0a || u >= 0x31) {
            vlprintf(3, "DCF77 time: invalid day field 0x%02x\n", u);
            goto error;
      }
      tm.tm_mday = (u & 0x0f) + 10 * ((u >> 4) & 0x0f);
      u = (pgrp3 >> 9) & 0x1f;
      if ((u & 0x0f) >= 0x0a || u >= 0x12) {
            vlprintf(3, "DCF77 time: invalid month field 0x%02x\n", u);
            goto error;
      }
      tm.tm_mon = (u & 0x0f) + 10 * ((u >> 4) & 0x0f);
      u = (pgrp3 >> 14) & 0xff;
      if ((u & 0x0f) >= 0x0a || u >= 0xa0) {
            vlprintf(3, "DCF77 time: invalid year field 0x%02x\n", u);
            goto error;
      }
      tm.tm_year = (u & 0x0f) + 10 * ((u >> 4) & 0x0f);
      if (tm.tm_year < 80)
            tm.tm_year += 100;
      dw = (pgrp3 >> 6) & 0x7;
      if (dw == 0) {
            vlprintf(3, "DCF77 time: invalid day of week field 0x%02x\n", u);
            goto error;
      }
      vlprintf(1, "\nDCF77 time: \n"
            "%s antenna, %s time zone change, time zone %s, "
            "leap second: %s\n", backup_ant ? "backup" : "normal", 
            tzchg ? "approaching" : "no", tz_name[tz], 
            leapsec ? "within 1 hour" : "none");
      vlprintf(1, "DCF77 time: TIME: %02d:%02d DATE: %.3s, " 
            // removed "-3" before .3s after date: %, typo? GŁnther
            "%02d.%02d.%02d\n",
              tm.tm_hour, tm.tm_min, daynames+3*(dw-1), 
              tm.tm_mday, tm.tm_mon, tm.tm_year + 1900);
      t = mktime(&tm);
      if (t == INVALID_TIME) {
            vlprintf(1, "mktime failed\n");
            goto error;
      }
      t -= timezone;
      t -= tz == ZONE_MESZ ? 7200 : 3600;
      tmp = localtime(&t);
      printf  ("DCF77 time: "
            "%02d:%02d:%02d  %02d.%02d.%02d\n",
             tmp->tm_hour, tmp->tm_min, tmp->tm_sec, 
             tmp->tm_mday, tmp->tm_mon, tmp->tm_year + 1900);
      tc_minute(t, samples);
      if (set_time) {
          sprintf(system_set_date, "date -s %02d/%02d/%02d > /dev/null", 
            tmp->tm_mon, tmp->tm_mday, tmp->tm_year + 1900);
          sprintf(system_set_time, "date -s %02d:%02d:%02d > /dev/null", 
            tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 
          system(system_set_date);
          system(system_set_time);
          //system("date");
          if (tz == ZONE_MESZ) 
              printf("I have set the system time to MESZ = CEST: ");
          else
              printf("I have set the system time to MEZ = CET: ");
          printf("%02d:%02d:%02d  %02d.%02d.%02d\n",
              tmp->tm_hour, tmp->tm_min, tmp->tm_sec, 
              tmp->tm_mday, tmp->tm_mon, tmp->tm_year + 1900);
      }
      return;
  error:
      tc_minute(INVALID_TIME, samples);
      return;
}

/* --------------------------------------------------------------------- */

Generated by  Doxygen 1.6.0   Back to index