static void stop_adjust(void) { struct timeval T1; struct timeval zeroadj, remadj; double adjustment_remaining, adjustment_achieved; double elapsed, elapsed_plus_adjust; zeroadj.tv_sec = 0; zeroadj.tv_usec = 0; if (adjtime(&zeroadj, &remadj) < 0) { LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed"); } if (gettimeofday(&T1, NULL) < 0) { LOG_FATAL(LOGF_SysNetBSD, "gettimeofday() failed"); } UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); UTI_TimevalToDouble(&remadj, &adjustment_remaining); adjustment_achieved = adjustment_requested - adjustment_remaining; elapsed_plus_adjust = elapsed - adjustment_achieved; offset_register += current_freq * elapsed_plus_adjust - adjustment_remaining; adjustment_requested = 0.0; T0 = T1; }
static Boolean setFrequency (ClockDriver *self, double adj, double tau) { if (self->config.readOnly){ DBGV("adjFreq2: noAdjust on, returning\n"); return FALSE; } self->_tau = tau; /* * adjFreq simulation for QNX: correct clock by x ns per tick over clock adjust interval, * to make it equal adj ns per second. Makes sense only if intervals are regular. */ #ifdef __QNXNTO__ struct _clockadjust clockadj; struct _clockperiod period; if (ClockPeriod (CLOCK_REALTIME, 0, &period, 0) < 0) return FALSE; adj = clampDouble(adj, self->maxFrequency); /* adjust clock for the duration of 0.9 clock update period in ticks (so we're done before the next) */ clockadj.tick_count = 0.9 * tau * 1E9 / (period.nsec + 0.0); /* scale adjustment per second to adjustment per single tick */ clockadj.tick_nsec_inc = (adj * tau / clockadj.tick_count) / 0.9; DBGV("QNX: adj: %.09f, dt: %.09f, ticks per dt: %d, inc per tick %d\n", adj, tau, clockadj.tick_count, clockadj.tick_nsec_inc); if (ClockAdjust(CLOCK_REALTIME, &clockadj, NULL) < 0) { DBGV("QNX: failed to call ClockAdjust: %s\n", strERROR(THIS_COMPONENTerrno)); } /* regular adjFreq */ #elif defined(HAVE_SYS_TIMEX_H) DBG2(" adjFreq2: call adjfreq to %.09f us \n", adj / DBG_UNIT); adjFreq_unix(self, adj); /* otherwise use adjtime */ #else struct timeval tv; adj = clampDouble(adj, self->maxFrequency); tv.tv_sec = 0; tv.tv_usec = (adj / 1000); if((tau > 0) && (tau < 1.0)) { tv.tv_usec *= tau; } adjtime(&tv, NULL); #endif self->lastFrequency = adj; return TRUE; }
void GnssDevice::slotSetSystemTime(const qint32& tow) { // The Host uses UTC time, but currentTow() applies the leap-second offset (currently 16s). const qint32 currentHostTow = GnssTime::currentTow(); // First, what time is it now? struct timeval system; gettimeofday(&system, NULL); // SecondsPerWeek - CurrentSecondInWeek is number of seconds till rollover const quint32 secondsToRollOver = (7 * 86400) - (tow / 1000); const qint32 offsetHostToGnss = tow - currentHostTow + 7; // Oscilloscope indicates 7ms offset is a good value. qDebug() << "GnssDevice::slotSetSystemTime(): time rollover in" << ((float)secondsToRollOver)/86400.0f << "d, offset host time" << currentHostTow << "to gnss time" << tow << "is" << offsetHostToGnss/1000 << "s and" << (offsetHostToGnss%1000) << "ms"; // For small clock drifts, adjust clock. Else, set clock if(abs(offsetHostToGnss) < 10) { qDebug() << __PRETTY_FUNCTION__ << "unix-time now is" << QDateTime::currentMSecsSinceEpoch() / 1000 << "- offset smaller than 10ms, using adjtime to correct clock drift..."; system.tv_sec = 0; system.tv_usec = offsetHostToGnss * 1000; if(adjtime(&system, NULL) < 0) { qDebug() << __PRETTY_FUNCTION__ << "adjtime failed, tried to set to" << system.tv_sec << "s and" << system.tv_usec << "usecs"; if(errno == EINVAL) qFatal("couldn't adjust system time, values invalid."); else if(errno == EPERM) qFatal("couldn't adjust system time, insufficient permissions."); else qFatal("couldn't adjust system time, no idea why, error %d.", errno); } } else { qDebug() << "GnssDevice::slotSetSystemTime(): unix-time now is" << QDateTime::currentMSecsSinceEpoch() / 1000 << "- offset larger than 10ms, using settimeofday to set clock..."; system.tv_sec += offsetHostToGnss/1000; system.tv_usec += (offsetHostToGnss%1000)*1000; // usec can under/overflow; fix it if(system.tv_usec > 1000000) { qDebug() << __PRETTY_FUNCTION__ << "system.tv" << system.tv_sec << "system.tv_usec > 1000000:" << system.tv_usec << "subtracting 1000000"; system.tv_usec -= 1000000; system.tv_sec += 1; qDebug() << __PRETTY_FUNCTION__ << "system.tv" << system.tv_sec << "system.tv_usec" << system.tv_usec; } if(settimeofday(&system, NULL) < 0) { qDebug() << __PRETTY_FUNCTION__ << "settimeofday failed, tried to set to" << system.tv_sec << "s and" << system.tv_usec << "usecs"; if(errno == EFAULT) qFatal("couldn't set system time, values outside of range."); else if(errno == EINVAL) qFatal("couldn't set system time, values invalid."); else if(errno == EPERM) qFatal("couldn't set system time, insufficient permissions."); else qFatal("couldn't set system time, no idea why, error %d.", errno); } } qDebug() << __PRETTY_FUNCTION__ << "time synchronized, offset host to gnss was" << offsetHostToGnss << "ms, unix-time now is" << QDateTime::currentMSecsSinceEpoch() / 1000; emit systemTimeSynchronized(); }
bool performGradualAdjustment(const uavcan::UtcDuration adjustment) { gradual_adj_cnt_++; const std::int64_t usec = adjustment.toUSec(); timeval tv; tv.tv_sec = usec / Int1e6; tv.tv_usec = usec % Int1e6; return adjtime(&tv, nullptr) == 0; }
void reset_adjtime(void) { struct timeval tv; timerclear(&tv); if (adjtime(&tv, NULL) == -1) log_warn("reset adjtime failed"); }
static void start_adjust(void) { struct timeval newadj, oldadj; struct timeval T1; double elapsed, accrued_error; double adjust_required; struct timeval exact_newadj; long delta, tickdelta; double rounding_error; double old_adjust_remaining; /* Determine the amount of error built up since the last adjustment */ if (gettimeofday(&T1, NULL) < 0) { LOG_FATAL(LOGF_SysNetBSD, "gettimeofday() failed"); } UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); accrued_error = elapsed * current_freq; adjust_required = - (accrued_error + offset_register); UTI_DoubleToTimeval(adjust_required, &exact_newadj); /* At this point, we need to round the required adjustment the same way the kernel does. */ delta = exact_newadj.tv_sec * 1000000 + exact_newadj.tv_usec; if (delta > kern_bigadj || delta < -kern_bigadj) tickdelta = 10 * kern_tickadj; else tickdelta = kern_tickadj; if (delta % tickdelta) delta = delta / tickdelta * tickdelta; newadj.tv_sec = 0; newadj.tv_usec = delta; UTI_NormaliseTimeval(&newadj); /* Add rounding error back onto offset register. */ UTI_DiffTimevalsToDouble(&rounding_error, &newadj, &exact_newadj); if (adjtime(&newadj, &oldadj) < 0) { LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed"); } UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); offset_register = rounding_error - old_adjust_remaining; T0 = T1; UTI_TimevalToDouble(&newadj, &adjustment_requested); }
int priv_adjtime_setup(int asroot, int injail, struct test *test) { if (initialized) return (0); if (adjtime(NULL, &query_tv) < 0) { warn("priv_adjtime_setup: adjtime(NULL)"); return (-1); } initialized = 1; return (0); }
/* * step_systime - step the system clock. */ int step_systime(double now) { struct timeval timetv, adjtv, oldtimetv; int isneg = 0; double dtemp; dtemp = now; if (dtemp < 0) { isneg = 1; dtemp = - dtemp; adjtv.tv_sec = (int32_t)dtemp; adjtv.tv_usec = (uint32_t)((dtemp - (double)adjtv.tv_sec) * 1e6 + .5); } else { adjtv.tv_sec = (int32_t)dtemp; adjtv.tv_usec = (uint32_t)((dtemp - (double)adjtv.tv_sec) * 1e6 + .5); } gettimeofday(&timetv, NULL); oldtimetv = timetv; if (isneg) { timetv.tv_sec -= adjtv.tv_sec; timetv.tv_usec -= adjtv.tv_usec; if (timetv.tv_usec < 0) { timetv.tv_sec--; timetv.tv_usec += 1000000; } } else { timetv.tv_sec += adjtv.tv_sec; timetv.tv_usec += adjtv.tv_usec; if (timetv.tv_usec >= 1000000) { timetv.tv_sec++; timetv.tv_usec -= 1000000; } } /* * Some broken systems don't reset adjtime() when the * clock is stepped. */ adjtv.tv_sec = adjtv.tv_usec = 0; adjtime(&adjtv, NULL); if (settimeofday(&timetv, NULL) < 0) { //msyslog(LOG_ERR, "step-systime: failed to set system time"); return (0); } return (1); }
void priv_adjtime_set(int asroot, int injail, struct test *test) { int error; error = adjtime(&query_tv, NULL); if (asroot && injail) expect("priv_adjtime(asroot, injail)", error, -1, EPERM); if (asroot && !injail) expect("priv_adjtime(asroot, !injail)", error, 0, 0); if (!asroot && injail) expect("priv_adjtime(!asroot, injail)", error, -1, EPERM); if (!asroot && !injail) expect("priv_adjtime(!asroot, !injail)", error, -1, EPERM); }
int timeout( int sig, int code, struct sigcontext *scp ) { signal (SIGALRM, timeout); if (adjtime(&adjustment, &result)) printf("adjtime call failed\n"); if (result.tv_sec != 0 || result.tv_usec != 0) { printf("result.u = %d.%06.6d ", (int) result.tv_sec, (int) result.tv_usec); } }
int /* 0 okay, 1 error */ adj_systime( double now /* adjustment (s) */ ) { struct timeval adjtv; /* new adjustment */ struct timeval oadjtv; /* residual adjustment */ double dtemp; long ticks; int isneg = 0; os_trace("Adjust: %f", now); /* * Most Unix adjtime() implementations adjust the system clock * in microsecond quanta, but some adjust in 10-ms quanta. We * carefully round the adjustment to the nearest quantum, then * adjust in quanta and keep the residue for later. */ dtemp = now + sys_residual; if (dtemp < 0) { isneg = 1; dtemp = -dtemp; } adjtv.tv_sec = (long)dtemp; dtemp -= adjtv.tv_sec; ticks = (long)(dtemp / sys_tick + .5); adjtv.tv_usec = (long)(ticks * sys_tick * 1e6); dtemp -= adjtv.tv_usec / 1e6; sys_residual = dtemp; /* * Convert to signed seconds and microseconds for the Unix * adjtime() system call. Note we purposely lose the adjtime() * leftover. */ if (isneg) { adjtv.tv_sec = -adjtv.tv_sec; adjtv.tv_usec = -adjtv.tv_usec; sys_residual = -sys_residual; } if (adjtv.tv_sec != 0 || adjtv.tv_usec != 0) { if (adjtime(&adjtv, &oadjtv) < 0) { msyslog(LOG_ERR, "adj_systime: %m"); return (0); } } return (1); }
int UpdateSystemClock(struct timeval *Time) { uint64_t usec_diff=0, sec_diff=0; struct timeval adjust_tm; int result=FALSE; /* if (stime(&NewTime)!=0) return(FALSE); */ sec_diff=TimeNow.tv_sec - Time->tv_sec; if (Time->tv_usec > 0) usec_diff=abs(TimeNow.tv_usec - Time->tv_usec); if ((sec_diff==0) && (usec_diff==0)) { printf("Clock already synchroized\n"); return(TRUE); } if ( (sec_diff ==0) && (usec_diff < 40000) ) { adjust_tm.tv_sec=0; adjust_tm.tv_usec=TimeNow.tv_usec - Time->tv_usec; if (adjtime(&adjust_tm, NULL) ==0) result=TRUE; } else if (settimeofday(Time, NULL) ==0) result=TRUE; if (! result) { LastError=CopyStr(LastError, strerror(errno)); if (Args->Flags & FLAG_SYSLOG) syslog(LOG_ERR, "Failed to update system clock by %ld millisecs. Error was: %s", (long) diff_millisecs(&TimeNow, Time), LastError); printf("Failed to update system clock by %ld millisecs. Error was: %s\n", (long) diff_millisecs(&TimeNow, Time), LastError); } else { if (Args->Flags & FLAG_SYSLOG) syslog(LOG_INFO, "updated system clock by %ld millisecs", (long) diff_millisecs(&TimeNow, Time)); printf("updated system clock by %ld millisecs\n", (long) diff_millisecs(&TimeNow, Time)); } return(TRUE); }
int ntpd_adjtime(double d) { struct timeval tv, olddelta; int synced = 0; static int firstadj = 1; if (d >= (double)LOG_NEGLIGEE / 1000 || d <= -1 * (double)LOG_NEGLIGEE / 1000) log_info("adjusting local clock by %fs", d); else log_debug("adjusting local clock by %fs", d); d_to_tv(d, &tv); if (adjtime(&tv, &olddelta) == -1) log_warn("adjtime failed"); else if (!firstadj && olddelta.tv_sec == 0 && olddelta.tv_usec == 0) synced = 1; firstadj = 0; return (synced); }
static void clock_initialise(void) { struct timeval newadj, oldadj; offset_register = 0.0; adjustment_requested = 0.0; current_freq = 0.0; if (gettimeofday(&T0, NULL) < 0) { LOG_FATAL(LOGF_SysNetBSD, "gettimeofday() failed"); } newadj.tv_sec = 0; newadj.tv_usec = 0; if (adjtime(&newadj, &oldadj) < 0) { LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed"); } }
int main (int ac, char **av) { struct timeval tv; time_t dt; int err; if (ac < 2) { fprintf(stderr, "*** can't set time : options for rfatime missing ***\n"); exit(-1); } if ((dt = atol(av[1])) == 0L) { fprintf(stderr,"*** can't set time : invalid time delta %s ***\n", av[1]); exit(-2); } if (dt > 0) { /*--- clock "jumps" forwards ---*/ gettimeofday(&tv, NULL); tv.tv_sec += dt; if (settimeofday(&tv, NULL) == -1) { err = errno; fprintf(stderr,"*** can't set time : %s ***\n", sys_errname(errno)); exit(err); } } else { tv.tv_sec = dt; tv.tv_usec = 0L; if (adjtime(&tv, NULL) == -1) { err = errno; fprintf(stderr,"*** can't set time : %s ***\n", sys_errname(errno)); exit(err); } } exit(0); }
static void setthetime(const char *p) { struct timeval tv; time_t new_time; struct tm *lt; const char *dot, *t; size_t len; int yearset; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* Divine correct DST */ if (dot != NULL) { /* .ss */ len = strlen(dot); if (len != 3) badformat(); ++dot; lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badvalue("seconds"); } else { len = 0; lt->tm_sec = 0; } yearset = 0; switch (strlen(p) - len) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; if (lt->tm_year < 0) badtime(); yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { yearset = ATOI2(p); if (yearset < 69) lt->tm_year = yearset + 2000 - TM_YEAR_BASE; else lt->tm_year = yearset + 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12 || lt->tm_mon == 0) badvalue("month"); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); switch (lt->tm_mon) { case 0: case 2: case 4: case 6: case 7: case 9: case 11: if (lt->tm_mday > 31 || lt->tm_mday == 0) badvalue("day of month"); break; case 3: case 5: case 8: case 10: if (lt->tm_mday > 30 || lt->tm_mday == 0) badvalue("day of month"); break; case 1: if (lt->tm_mday > 29 || lt->tm_mday == 0 || (lt->tm_mday == 29 && !isleap(lt->tm_year + TM_YEAR_BASE))) badvalue("day of month"); break; default: badvalue("month"); break; } /* FALLTHROUGH */ case 4: /* hh */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badvalue("hour"); /* FALLTHROUGH */ case 2: /* mm */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badvalue("minute"); break; case 0: /* was just .sss */ if (len != 0) break; /* FALLTHROUGH */ default: badformat(); } /* convert broken-down time to UTC clock time */ if ((new_time = mktime(lt)) == -1) badtime(); /* if jflag is set, don't actually change the time, just return */ if (jflag) { tval = new_time; return; } /* set the time */ if (nflag || netsettime(new_time)) { logwtmp("|", "date", ""); if (aflag) { tv.tv_sec = new_time - tval; tv.tv_usec = 0; if (adjtime(&tv, NULL)) err(EXIT_FAILURE, "adjtime"); } else { tval = new_time; tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(EXIT_FAILURE, "settimeofday"); } logwtmp("{", "date", ""); } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); }
int ntp_set_tod( struct timeval *tvp, void *tzp ) { static int tod; int rc = -1; int saved_errno = 0; #ifdef DEBUG if (debug) printf("In ntp_set_tod\n"); #endif #ifdef HAVE_CLOCK_SETTIME if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) { struct timespec ts; /* Convert timeval to timespec */ ts.tv_sec = tvp->tv_sec; ts.tv_nsec = 1000 * tvp->tv_usec; errno = 0; rc = clock_settime(CLOCK_REALTIME, &ts); saved_errno = errno; #ifdef DEBUG if (debug) { printf("ntp_set_tod: clock_settime: %d: %s\n", rc, strerror(saved_errno)); } #endif if (!tod && !rc) tod = SET_TOD_CLOCK_SETTIME; } #endif /* HAVE_CLOCK_SETTIME */ #ifdef HAVE_SETTIMEOFDAY if (rc && (SET_TOD_SETTIMEOFDAY == tod || !tod)) { struct timeval adjtv; /* * Some broken systems don't reset adjtime() when the * clock is stepped. */ adjtv.tv_sec = adjtv.tv_usec = 0; adjtime(&adjtv, NULL); errno = 0; rc = SETTIMEOFDAY(tvp, tzp); saved_errno = errno; #ifdef DEBUG if (debug) { printf("ntp_set_tod: settimeofday: %d: %s\n", rc, strerror(saved_errno)); } #endif if (!tod && !rc) tod = SET_TOD_SETTIMEOFDAY; } #endif /* HAVE_SETTIMEOFDAY */ #ifdef HAVE_STIME if (rc && (SET_TOD_STIME == tod || !tod)) { long tp = tvp->tv_sec; errno = 0; rc = stime(&tp); /* lie as bad as SysVR4 */ saved_errno = errno; #ifdef DEBUG if (debug) { printf("ntp_set_tod: stime: %d: %s\n", rc, strerror(saved_errno)); } #endif if (!tod && !rc) tod = SET_TOD_STIME; } #endif /* HAVE_STIME */ #ifdef DEBUG if (debug) { printf("ntp_set_tod: Final result: %s: %d: %s\n", set_tod_used[tod], rc, strerror(saved_errno)); } #endif /* * Say how we're setting the time of day */ if (!rc && NULL != set_tod_using) { (*set_tod_using)(set_tod_used[tod]); set_tod_using = NULL; } if (rc) errno = saved_errno; return rc; }
static void decode_msg(void *base, size_t len, struct timeval *tv, struct timespec *mrx_time) { struct ntp_msg *msg = base; double m_delta, org, rec, xmt, dst; double delay, offset; static guint transmit_delay; if (len < sizeof(*msg)) { connman_error("Invalid response from time server"); return; } if (!tv) { connman_error("Invalid packet timestamp from time server"); return; } DBG("flags : 0x%02x", msg->flags); DBG("stratum : %u", msg->stratum); DBG("poll : %f seconds (%d)", LOGTOD(msg->poll), msg->poll); DBG("precision : %f seconds (%d)", LOGTOD(msg->precision), msg->precision); DBG("root delay : %u seconds (fraction %u)", msg->rootdelay.seconds, msg->rootdelay.fraction); DBG("root disp. : %u seconds (fraction %u)", msg->rootdisp.seconds, msg->rootdisp.fraction); DBG("reference : 0x%04x", msg->refid); transmit_delay = LOGTOD(msg->poll); if (NTP_FLAGS_LI_DECODE(msg->flags) == NTP_FLAG_LI_NOTINSYNC) { DBG("ignoring unsynchronized peer"); return; } if (NTP_FLAGS_VN_DECODE(msg->flags) != NTP_FLAG_VN_VER4) { if (NTP_FLAGS_VN_DECODE(msg->flags) == NTP_FLAG_VN_VER3) { DBG("requested version %d, accepting version %d", NTP_FLAG_VN_VER4, NTP_FLAGS_VN_DECODE(msg->flags)); } else { DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags)); return; } } if (NTP_FLAGS_MD_DECODE(msg->flags) != NTP_FLAG_MD_SERVER) { DBG("unsupported mode %d", NTP_FLAGS_MD_DECODE(msg->flags)); return; } m_delta = mrx_time->tv_sec - mtx_time.tv_sec + 1.0e-9 * (mrx_time->tv_nsec - mtx_time.tv_nsec); org = tv->tv_sec + (1.0e-6 * tv->tv_usec) - m_delta + OFFSET_1900_1970; rec = ntohl(msg->rectime.seconds) + ((double) ntohl(msg->rectime.fraction) / UINT_MAX); xmt = ntohl(msg->xmttime.seconds) + ((double) ntohl(msg->xmttime.fraction) / UINT_MAX); dst = tv->tv_sec + (1.0e-6 * tv->tv_usec) + OFFSET_1900_1970; DBG("org=%f rec=%f xmt=%f dst=%f", org, rec, xmt, dst); offset = ((rec - org) + (xmt - dst)) / 2; delay = (dst - org) - (xmt - rec); DBG("offset=%f delay=%f", offset, delay); /* Remove the timeout, as timeserver has responded */ reset_timeout(); /* * Now poll the server every transmit_delay seconds * for time correction. */ if (poll_id > 0) g_source_remove(poll_id); DBG("Timeserver %s, next sync in %d seconds", timeserver, transmit_delay); poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL); connman_info("ntp: time slew %+.6f s", offset); if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) { struct timeval adj; adj.tv_sec = (long) offset; adj.tv_usec = (offset - adj.tv_sec) * 1000000; DBG("adjusting time"); if (adjtime(&adj, &adj) < 0) { connman_error("Failed to adjust time"); return; } DBG("%lu seconds, %lu msecs", adj.tv_sec, adj.tv_usec); } else { struct timeval cur; double dtime; gettimeofday(&cur, NULL); dtime = offset + cur.tv_sec + 1.0e-6 * cur.tv_usec; cur.tv_sec = (long) dtime; cur.tv_usec = (dtime - cur.tv_sec) * 1000000; DBG("setting time"); if (settimeofday(&cur, NULL) < 0) { connman_error("Failed to set time"); return; } DBG("%lu seconds, %lu msecs", cur.tv_sec, cur.tv_usec); } }
void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint64_t Timeout, bool bAllowRepeatLR) { static uint64_t last_keypress = 0ULL; //uint64_t getKeyBegin; //static __u16 rc_last_key = KEY_MAX; static __u16 rc_last_repeat_key = KEY_MAX; struct timeval tv; struct timeval tvselect; uint64_t InitialTimeout = Timeout; int64_t targetTimeout; int timer_id; fd_set rfds; t_input_event ev; *data = 0; // wiederholung reinmachen - dass wirklich die ganze zeit bis timeout gewartet wird! #ifdef USE_GETTIMEOFDAY gettimeofday( &tv, NULL ); uint64_t getKeyBegin = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); #else uint64_t getKeyBegin = time_monotonic_us(); #endif while(1) { timer_id = 0; if ( !timers.empty() ) { #ifdef USE_GETTIMEOFDAY gettimeofday( &tv, NULL ); uint64_t t_n= (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); #else uint64_t t_n = time_monotonic_us(); #endif if ( timers[0].times_out< t_n ) { timer_id = checkTimers(); *msg = NeutrinoMessages::EVT_TIMER; *data = timer_id; return; } else { targetTimeout = timers[0].times_out - t_n; if ( (uint64_t) targetTimeout> Timeout) targetTimeout= Timeout; else timer_id = timers[0].id; } } else targetTimeout= Timeout; tvselect.tv_sec = targetTimeout/1000000; tvselect.tv_usec = targetTimeout%1000000; FD_ZERO(&rfds); for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if (fd_rc[i] != -1) FD_SET(fd_rc[i], &rfds); } #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL if (true) #else if (fd_keyb> 0) #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ FD_SET(fd_keyb, &rfds); FD_SET(fd_event, &rfds); FD_SET(fd_pipe_high_priority[0], &rfds); FD_SET(fd_pipe_low_priority[0], &rfds); int status = select(fd_max+1, &rfds, NULL, NULL, &tvselect); if ( status == -1 ) { perror("[neutrino - getMsg_us]: select returned "); // in case of an error return timeout...?! *msg = RC_timeout; *data = 0; return; } else if ( status == 0 ) // Timeout! { if ( timer_id != 0 ) { timer_id = checkTimers(); if ( timer_id != 0 ) { *msg = NeutrinoMessages::EVT_TIMER; *data = timer_id; return; } else continue; } else { *msg = RC_timeout; *data = 0; return; } } if(FD_ISSET(fd_pipe_high_priority[0], &rfds)) { struct event buf; read(fd_pipe_high_priority[0], &buf, sizeof(buf)); *msg = buf.msg; *data = buf.data; // printf("got event from high-pri pipe %x %x\n", *msg, *data ); return; } #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL if (FD_ISSET(fd_keyb, &rfds)) { int trkey; char key = 0; read(fd_keyb, &key, sizeof(key)); switch(key) { case 27: // <- Esc trkey = KEY_HOME; break; case 10: // <- Return case 'o': trkey = KEY_OK; break; case 'p': trkey = KEY_POWER; break; case 's': trkey = KEY_SETUP; break; case 'h': trkey = KEY_HELP; break; case 'i': trkey = KEY_UP; break; case 'm': trkey = KEY_DOWN; break; case 'j': trkey = KEY_LEFT; break; case 'k': trkey = KEY_RIGHT; break; case 'r': trkey = KEY_RED; break; case 'g': trkey = KEY_GREEN; break; case 'y': trkey = KEY_YELLOW; break; case 'b': trkey = KEY_BLUE; break; case '0': trkey = RC_0; break; case '1': trkey = RC_1; break; case '2': trkey = RC_2; break; case '3': trkey = RC_3; break; case '4': trkey = RC_4; break; case '5': trkey = RC_5; break; case '6': trkey = RC_6; break; case '7': trkey = RC_7; break; case '8': trkey = RC_8; break; case '9': trkey = RC_9; break; case '+': trkey = RC_plus; break; case '-': trkey = RC_minus; break; case 'a': trkey = KEY_A; break; case 'u': trkey = KEY_U; break; case '/': trkey = KEY_SLASH; break; case '\\': trkey = KEY_BACKSLASH; break; default: trkey = RC_nokey; } if (trkey != RC_nokey) { *msg = trkey; *data = 0; /* <- button pressed */ return; } } #else /* if(FD_ISSET(fd_keyb, &rfds)) { char key = 0; read(fd_keyb, &key, sizeof(key)); printf("keyboard: %d\n", rc_key); } */ #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ if(FD_ISSET(fd_event, &rfds)) { //printf("[neutrino] event - accept!\n"); socklen_t clilen; struct sockaddr_in cliaddr; clilen = sizeof(cliaddr); int fd_eventclient = accept(fd_event, (struct sockaddr *) &cliaddr, &clilen); *msg = RC_nokey; //printf("[neutrino] network event - read!\n"); CEventServer::eventHead emsg; int read_bytes= recv(fd_eventclient, &emsg, sizeof(emsg), MSG_WAITALL); //printf("[neutrino] event read %d bytes - following %d bytes\n", read_bytes, emsg.dataSize ); if ( read_bytes == sizeof(emsg) ) { bool dont_delete_p = false; unsigned char* p; p= new unsigned char[ emsg.dataSize + 1 ]; if ( p!=NULL ) { read_bytes= recv(fd_eventclient, p, emsg.dataSize, MSG_WAITALL); //printf("[neutrino] eventbody read %d bytes - initiator %x\n", read_bytes, emsg.initiatorID ); #if 0 if ( emsg.initiatorID == CEventServer::INITID_CONTROLD ) { switch(emsg.eventID) { case CControldClient::EVT_VOLUMECHANGED : *msg = NeutrinoMessages::EVT_VOLCHANGED; *data = 0; break; case CControldClient::EVT_MUTECHANGED : *msg = NeutrinoMessages::EVT_MUTECHANGED; *data = (unsigned) p; dont_delete_p = true; break; case CControldClient::EVT_VCRCHANGED : *msg = NeutrinoMessages::EVT_VCRCHANGED; *data = *(int*) p; break; case CControldClient::EVT_MODECHANGED : *msg = NeutrinoMessages::EVT_MODECHANGED; *data = *(int*) p; break; default: printf("[neutrino] event INITID_CONTROLD - unknown eventID 0x%x\n", emsg.eventID ); } } else #endif if ( emsg.initiatorID == CEventServer::INITID_HTTPD ) { switch(emsg.eventID) { case NeutrinoMessages::SHUTDOWN : *msg = NeutrinoMessages::SHUTDOWN; *data = 0; break; case NeutrinoMessages::REBOOT : *msg = NeutrinoMessages::REBOOT; *data = 0; break; case NeutrinoMessages::EVT_POPUP : *msg = NeutrinoMessages::EVT_POPUP; *data = (unsigned) p; dont_delete_p = true; break; case NeutrinoMessages::EVT_EXTMSG : *msg = NeutrinoMessages::EVT_EXTMSG; *data = (unsigned) p; dont_delete_p = true; break; case NeutrinoMessages::CHANGEMODE : // Change *msg = NeutrinoMessages::CHANGEMODE; *data = *(unsigned*) p; break; case NeutrinoMessages::STANDBY_TOGGLE : *msg = NeutrinoMessages::STANDBY_TOGGLE; *data = 0; break; case NeutrinoMessages::STANDBY_ON : *msg = NeutrinoMessages::STANDBY_ON; *data = 0; break; case NeutrinoMessages::STANDBY_OFF : *msg = NeutrinoMessages::STANDBY_OFF; *data = 0; break; case NeutrinoMessages::EVT_START_PLUGIN : *msg = NeutrinoMessages::EVT_START_PLUGIN; *data = (unsigned) p; dont_delete_p = true; break; case NeutrinoMessages::LOCK_RC : *msg = NeutrinoMessages::LOCK_RC; *data = 0; break; case NeutrinoMessages::UNLOCK_RC : *msg = NeutrinoMessages::UNLOCK_RC; *data = 0; break; case NeutrinoMessages::RELOAD_SETUP : *msg = NeutrinoMessages::RELOAD_SETUP; *data = 0; break; case NeutrinoMessages::EVT_HDMI_CEC_VIEW_ON: *msg = NeutrinoMessages::EVT_HDMI_CEC_VIEW_ON; *data = 0; break; case NeutrinoMessages::EVT_HDMI_CEC_STANDBY: *msg = NeutrinoMessages::EVT_HDMI_CEC_STANDBY; *data = 0; break; case NeutrinoMessages::EVT_SET_MUTE : *msg = NeutrinoMessages::EVT_SET_MUTE; *data = *(char*) p; break; case NeutrinoMessages::EVT_SET_VOLUME : *msg = NeutrinoMessages::EVT_SET_VOLUME; *data = *(char*) p; break; default: printf("[neutrino] event INITID_HTTPD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_SECTIONSD ) { //printf("[neutrino] event - from SECTIONSD %x %x\n", emsg.eventID, *(unsigned*) p); switch(emsg.eventID) { case CSectionsdClient::EVT_TIMESET: { #if 0 struct timeval ltv; gettimeofday(<v, NULL); int64_t timeOld = ltv.tv_usec + ltv.tv_sec * (int64_t)1000000; time_t dvbtime = *((time_t*)p); if (dvbtime) { printf("[neutrino] timeset event. "); time_t difftime = dvbtime - ltv.tv_sec; if (abs(difftime) > 120) { printf("difference is %ld s, stepping...\n", difftime); if (stime(&dvbtime)) perror("stime"); } else if (difftime != 0) { struct timeval oldd; ltv.tv_sec = difftime; ltv.tv_usec = 0; if (adjtime(<v, &oldd)) perror("adjtime"); int64_t t = oldd.tv_sec * 1000000LL + oldd.tv_usec; printf("difference is %ld s, using adjtime(). oldd: %lld us\n", difftime, t); } else printf("difference is 0 s, nothing to do...\n"); } gettimeofday( <v, NULL ); int64_t timeNew = ltv.tv_usec + ltv.tv_sec * (int64_t)1000000; delete[] p;//new [] delete [] p = new unsigned char[sizeof(int64_t)]; *(int64_t*) p = timeNew - timeOld; #endif printf("[neutrino] CSectionsdClient::EVT_TIMESET: timediff %" PRId64 "\n", *(int64_t*) p); /* FIXME what this code really do ? */ if ((int64_t)last_keypress > *(int64_t*)p) last_keypress += *(int64_t *)p; #ifdef USE_GETTIMEOFDAY // Timer anpassen for(std::vector<timer>::iterator e = timers.begin(); e != timers.end(); ++e) if (e->correct_time) e->times_out+= *(int64_t*) p; #endif *msg = NeutrinoMessages::EVT_TIMESET; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; } case CSectionsdClient::EVT_GOT_CN_EPG: printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); *msg = NeutrinoMessages::EVT_CURRENTNEXT_EPG; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; case CSectionsdClient::EVT_WRITE_SI_FINISHED: *msg = NeutrinoMessages::EVT_SI_FINISHED; *data = 0; break; case CSectionsdClient::EVT_EIT_COMPLETE: printf("[neutrino] CSectionsdClient::EVT_EIT_COMPLETE\n"); *msg = NeutrinoMessages::EVT_EIT_COMPLETE; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; #if 0 case CSectionsdClient::EVT_SERVICES_UPDATE: *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; case CSectionsdClient::EVT_BOUQUETS_UPDATE: break; #endif default: printf("[neutrino] event INITID_SECTIONSD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_ZAPIT ) { //printf("[neutrino] event - from ZAPIT %x %x\n", emsg.eventID, *(unsigned*) p); switch(emsg.eventID) { case CZapitClient::EVT_RECORDMODE_ACTIVATED: *msg = NeutrinoMessages::EVT_RECORDMODE; *data = true; break; case CZapitClient::EVT_RECORDMODE_DEACTIVATED: *msg = NeutrinoMessages::EVT_RECORDMODE; *data = false; break; case CZapitClient::EVT_ZAP_COMPLETE: *msg = NeutrinoMessages::EVT_ZAP_COMPLETE; break; case CZapitClient::EVT_ZAP_FAILED: *msg = NeutrinoMessages::EVT_ZAP_FAILED; break; case CZapitClient::EVT_ZAP_SUB_FAILED: *msg = NeutrinoMessages::EVT_ZAP_SUB_FAILED; break; case CZapitClient::EVT_ZAP_COMPLETE_IS_NVOD: *msg = NeutrinoMessages::EVT_ZAP_ISNVOD; break; case CZapitClient::EVT_ZAP_SUB_COMPLETE: *msg = NeutrinoMessages::EVT_ZAP_SUB_COMPLETE; break; case CZapitClient::EVT_SCAN_COMPLETE: *msg = NeutrinoMessages::EVT_SCAN_COMPLETE; *data = 0; break; case CZapitClient::EVT_SCAN_NUM_TRANSPONDERS: *msg = NeutrinoMessages::EVT_SCAN_NUM_TRANSPONDERS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_NUM_SCANNED_TRANSPONDERS: *msg = NeutrinoMessages::EVT_SCAN_REPORT_NUM_SCANNED_TRANSPONDERS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_FREQUENCY: *msg = NeutrinoMessages::EVT_SCAN_REPORT_FREQUENCY; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_A_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_A_CHAN; break; case CZapitClient::EVT_SCAN_SERVICENAME: *msg = NeutrinoMessages::EVT_SCAN_SERVICENAME; break; case CZapitClient::EVT_SCAN_FOUND_TV_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_TV_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_RADIO_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_RADIO_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_DATA_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_DATA_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_FREQUENCYP: *msg = NeutrinoMessages::EVT_SCAN_REPORT_FREQUENCYP; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_NUM_CHANNELS: *msg = NeutrinoMessages::EVT_SCAN_NUM_CHANNELS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_PROVIDER: *msg = NeutrinoMessages::EVT_SCAN_PROVIDER; break; case CZapitClient::EVT_SCAN_SATELLITE: *msg = NeutrinoMessages::EVT_SCAN_SATELLITE; break; case CZapitClient::EVT_BOUQUETS_CHANGED: *msg = NeutrinoMessages::EVT_BOUQUETSCHANGED; *data = 0; break; case CZapitClient::EVT_SERVICES_CHANGED: *msg = NeutrinoMessages::EVT_SERVICESCHANGED; *data = 0; break; case CZapitClient::EVT_ZAP_CA_CLEAR: *msg = NeutrinoMessages::EVT_ZAP_CA_CLEAR; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_LOCK: *msg = NeutrinoMessages::EVT_ZAP_CA_LOCK; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_FTA: *msg = NeutrinoMessages::EVT_ZAP_CA_FTA; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_ID : *msg = NeutrinoMessages::EVT_ZAP_CA_ID; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FAILED: *msg = NeutrinoMessages::EVT_SCAN_FAILED; *data = 0; break; case CZapitClient::EVT_ZAP_MOTOR: *msg = NeutrinoMessages::EVT_ZAP_MOTOR; *data = *(unsigned*) p; break; case CZapitClient::EVT_SDT_CHANGED: *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; case CZapitClient::EVT_PMT_CHANGED: *msg = NeutrinoMessages::EVT_PMT_CHANGED; *data = (neutrino_msg_data_t) p; break; case CZapitClient::EVT_TUNE_COMPLETE: *msg = NeutrinoMessages::EVT_TUNE_COMPLETE; *data = (neutrino_msg_data_t) p; break; case CZapitClient::EVT_BACK_ZAP_COMPLETE: *msg = NeutrinoMessages::EVT_BACK_ZAP_COMPLETE; *data = (neutrino_msg_data_t) p; break; default: printf("[neutrino] event INITID_ZAPIT - unknown eventID 0x%x\n", emsg.eventID ); } if (((*msg) >= CRCInput::RC_WithData) && ((*msg) < CRCInput::RC_WithData + 0x10000000)) { *data = (neutrino_msg_data_t) p; dont_delete_p = true; } } else if ( emsg.initiatorID == CEventServer::INITID_TIMERD ) { /* if (emsg.eventID==CTimerdClient::EVT_ANNOUNCE_NEXTPROGRAM) { } if (emsg.eventID==CTimerdClient::EVT_NEXTPROGRAM) { *msg = NeutrinoMessages::EVT_NEXTPROGRAM; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } */ switch(emsg.eventID) { case CTimerdClient::EVT_ANNOUNCE_RECORD : *msg = NeutrinoMessages::ANNOUNCE_RECORD; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_ANNOUNCE_ZAPTO : *msg = NeutrinoMessages::ANNOUNCE_ZAPTO; *data = (neutrino_msg_data_t)p; dont_delete_p = true; break; case CTimerdClient::EVT_ANNOUNCE_SHUTDOWN : *msg = NeutrinoMessages::ANNOUNCE_SHUTDOWN; *data = 0; break; case CTimerdClient::EVT_ANNOUNCE_SLEEPTIMER : *msg = NeutrinoMessages::ANNOUNCE_SLEEPTIMER; *data = 0; break; case CTimerdClient::EVT_SLEEPTIMER : *msg = NeutrinoMessages::SLEEPTIMER; *data = 0; break; case CTimerdClient::EVT_RECORD_START : *msg = NeutrinoMessages::RECORD_START; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_RECORD_STOP : *msg = NeutrinoMessages::RECORD_STOP; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_ZAPTO : *msg = NeutrinoMessages::ZAPTO; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_SHUTDOWN : *msg = NeutrinoMessages::SHUTDOWN; *data = 0; break; case CTimerdClient::EVT_STANDBY_ON : *msg = NeutrinoMessages::STANDBY_ON; *data = 0; break; case CTimerdClient::EVT_STANDBY_OFF : *msg = NeutrinoMessages::STANDBY_OFF; *data = 0; break; case CTimerdClient::EVT_REMIND : *msg = NeutrinoMessages::REMIND; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_EXEC_PLUGIN : *msg = NeutrinoMessages::EVT_START_PLUGIN; *data = (unsigned) p; dont_delete_p = true; break; default : printf("[neutrino] event INITID_TIMERD - unknown eventID 0x%x\n", emsg.eventID ); } } else if (emsg.initiatorID == CEventServer::INITID_NEUTRINO) { #if 0 if ((emsg.eventID == NeutrinoMessages::EVT_RECORDING_ENDED) && (read_bytes == sizeof(stream2file_status2_t))) { *msg = NeutrinoMessages::EVT_RECORDING_ENDED; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } #endif } else if (emsg.initiatorID == CEventServer::INITID_GENERIC_INPUT_EVENT_PROVIDER) { if (read_bytes == sizeof(int)) { *msg = *(int *)p; *data = emsg.eventID; } } else printf("[neutrino] event - unknown initiatorID 0x%x\n", emsg.initiatorID); if ( !dont_delete_p ) { delete[] p;//new [] delete [] p= NULL; } } } else { printf("[neutrino] event - read failed!\n"); } ::close(fd_eventclient); if ( *msg != RC_nokey ) { // raus hier :) //printf("[neutrino] event 0x%x\n", *msg); return; } } for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if ((fd_rc[i] != -1) && (FD_ISSET(fd_rc[i], &rfds))) { int ret; ret = read(fd_rc[i], &ev, sizeof(t_input_event)); if(ret != sizeof(t_input_event)) continue; SHTDCNT::getInstance()->resetSleepTimer(); if (firstKey) { firstKey = false; CTimerManager::getInstance()->cancelShutdownOnWakeup(); } uint32_t trkey = translate(ev.code, i); #ifdef DEBUG printf("key: %04x value %d, translate: %04x -%s-\n", ev.code, ev.value, trkey, getKeyName(trkey).c_str()); #endif if (trkey == RC_nokey) continue; if (ev.value) { #ifdef RCDEBUG printf("got keydown native key: %04x %04x, translate: %04x -%s-\n", ev.code, ev.code&0x1f, translate(ev.code, 0), getKeyName(translate(ev.code, 0)).c_str()); printf("rc_last_key %04x rc_last_repeat_key %04x\n\n", rc_last_key, rc_last_repeat_key); #endif uint64_t now_pressed; bool keyok = true; tv = ev.time; now_pressed = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); if (ev.code == rc_last_key) { /* only allow selected keys to be repeated */ /* (why?) */ if( (trkey == RC_up) || (trkey == RC_down ) || (trkey == RC_plus ) || (trkey == RC_minus ) || (trkey == RC_page_down ) || (trkey == RC_page_up ) || ((bAllowRepeatLR) && ((trkey == RC_left ) || (trkey == RC_right))) || (g_settings.shutdown_real_rcdelay && ((trkey == RC_standby) && (cs_get_revision() > 7))) ) { #ifdef ENABLE_REPEAT_CHECK if (rc_last_repeat_key != ev.code) { if ((now_pressed > last_keypress + repeat_block) || /* accept all keys after time discontinuity: */ (now_pressed < last_keypress)) rc_last_repeat_key = ev.code; else keyok = false; } #endif } else keyok = false; } else rc_last_repeat_key = KEY_MAX; rc_last_key = ev.code; if (keyok) { #ifdef ENABLE_REPEAT_CHECK if ((now_pressed > last_keypress + repeat_block_generic) || /* accept all keys after time discontinuity: */ (now_pressed < last_keypress)) #endif { last_keypress = now_pressed; *msg = trkey; *data = 0; /* <- button pressed */ if(g_settings.key_click) play_click(); return; } } /*if keyok */ } /* if (ev.value) */ else { // clear rc_last_key on keyup event #ifdef RCDEBUG printf("got keyup native key: %04x %04x, translate: %04x -%s-\n", ev.code, ev.code&0x1f, translate(ev.code, 0), getKeyName(translate(ev.code, 0)).c_str() ); #endif rc_last_key = KEY_MAX; if (trkey == RC_standby) { *msg = RC_standby; *data = 1; /* <- button released */ return; } } }/* if FDSET */ } /* for NUMBER_OF_EVENT_DEVICES */ if(FD_ISSET(fd_pipe_low_priority[0], &rfds)) { struct event buf; read(fd_pipe_low_priority[0], &buf, sizeof(buf)); *msg = buf.msg; *data = buf.data; // printf("got event from low-pri pipe %x %x\n", *msg, *data ); return; } if ( InitialTimeout == 0 ) { //nicht warten wenn kein key da ist *msg = RC_timeout; *data = 0; return; } else { //timeout neu kalkulieren #ifdef USE_GETTIMEOFDAY gettimeofday( &tv, NULL ); int64_t getKeyNow = (int64_t) tv.tv_usec + (int64_t)((int64_t) tv.tv_sec * (int64_t) 1000000); #else int64_t getKeyNow = time_monotonic_us(); #endif int64_t diff = (getKeyNow - getKeyBegin); if( Timeout <= (uint64_t) diff ) { *msg = RC_timeout; *data = 0; return; } else Timeout -= diff; } } }
void setthetime(char *p) { struct tm *lt; struct timeval tv; char *dot, *t; int yearset = 0; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* correct for DST */ if (dot != NULL) { /* .SS */ *dot++ = '\0'; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; switch (strlen(p)) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (!yearset) { /* mask out current year, leaving only century */ lt->tm_year = ((lt->tm_year / 100) * 100); } lt->tm_year += ATOI2(p); /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* convert broken-down time to UTC clock time */ if ((tval = mktime(lt)) < 0) errx(1, "specified date is outside allowed range"); if (jflag) return; /* set the time */ if (slidetime) { struct timeval tv_current; if (gettimeofday(&tv_current, NULL) == -1) err(1, "Could not get local time of day"); tv.tv_sec = tval - tv_current.tv_sec; tv.tv_usec = 0; if (adjtime(&tv, NULL) == -1) errx(1, "adjtime"); } else { #ifndef SMALL logwtmp("|", "date", ""); #endif tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday"); #ifndef SMALL logwtmp("{", "date", ""); #endif } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); }
void setthetime(char *p) { struct tm *lt; struct timeval tv; char *dot, *t; const char *pc; int bigyear; int yearset = 0; for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* correct for DST */ if (dot != NULL) { /* .SS */ *dot++ = '\0'; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; switch (strlen(p)) { case 12: /* cc */ bigyear = ATOI2(p); lt->tm_year = bigyear * 100 - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { lt->tm_year = ATOI2(p); if (lt->tm_year < 69) /* hack for 2000 ;-} */ lt->tm_year += (2000 - TM_YEAR_BASE); else lt->tm_year += (1900 - TM_YEAR_BASE); } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* convert broken-down time to UTC clock time */ if ((tval = mktime(lt)) < 0) errx(1, "specified date is outside allowed range"); /* set the time */ if (slidetime) { struct timeval tv_current; if (gettimeofday(&tv_current, NULL) == -1) err(1, "Could not get local time of day"); tv.tv_sec = tval - tv_current.tv_sec; tv.tv_usec = 0; if (adjtime(&tv, NULL) == -1) errx(1, "adjtime"); } else { tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday"); } if ((pc = getlogin()) == NULL) pc = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", pc); }
int set_adj_time(const struct timeval *delta, struct timeval *olddelta) { return adjtime(delta, olddelta); }
void test_adjtime(void) { int sc; rtems_status_code status; struct timeval delta; struct timeval olddelta; rtems_time_of_day *the_tod; rtems_time_of_day tod; rtems_interval ticks; the_tod = &Dates[0]; print_time( "rtems_clock_set ", the_tod, "\n" ); status = rtems_clock_set( the_tod ); rtems_test_assert( !status ); delta.tv_sec = 0; delta.tv_usec = 0; olddelta.tv_sec = 0; olddelta.tv_usec = 0; puts( "adjtime - NULL delta - EINVAL" ); sc = adjtime( NULL, &olddelta ); rtems_test_assert( sc == -1 ); rtems_test_assert( errno == EINVAL ); puts( "adjtime - delta out of range - EINVAL" ); delta.tv_usec = 1000000000; /* 100 seconds worth */ sc = adjtime( &delta, &olddelta ); rtems_test_assert( sc == -1 ); rtems_test_assert( errno == EINVAL ); puts( "adjtime - delta too small - do nothing" ); delta.tv_sec = 0; delta.tv_usec = 1; sc = adjtime( &delta, &olddelta ); rtems_test_assert( sc == 0 ); puts( "adjtime - delta too small - do nothing, olddelta=NULL" ); sc = adjtime( &delta, NULL ); rtems_test_assert( sc == 0 ); puts( "adjtime - delta of one second forward, olddelta=NULL" ); delta.tv_sec = 1; delta.tv_usec = 0; sc = adjtime( &delta, NULL ); rtems_test_assert( sc == 0 ); puts( "adjtime - delta of one second forward" ); delta.tv_sec = 1; delta.tv_usec = 0; sc = adjtime( &delta, &olddelta ); rtems_test_assert( sc == 0 ); puts( "adjtime - delta of almost two seconds forward" ); delta.tv_sec = 1; delta.tv_usec = 1000000 - 1; sc = adjtime( &delta, &olddelta ); rtems_test_assert( sc == 0 ); /* * spin until over 1/2 of the way to the */ ticks = rtems_clock_get_ticks_per_second(); rtems_test_assert( ticks ); ticks /= 2; do { status = rtems_clock_get_tod( &tod ); rtems_test_assert( !status ); } while ( tod.ticks <= ticks ); puts( "adjtime - delta of almost one second forward which bumps second" ); delta.tv_sec = 0; delta.tv_usec = 1000000 - 1; sc = adjtime( &delta, &olddelta ); rtems_test_assert( sc == 0 ); status = rtems_clock_get_tod( &tod ); rtems_test_assert( !status ); print_time( "rtems_clock_get_tod ", &tod, "\n" ); }
int main(int argc, char **argv) { struct tm *tp, tm; struct timeval tv; char *fmt; char *fmtbuf; int c, aflag = 0, illflag = 0; struct timespec ts; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, "a:uR")) != EOF) switch (c) { case 'a': aflag++; if (get_adj(optarg, &tv) < 0) { (void) fprintf(stderr, gettext("date: invalid argument -- %s\n"), optarg); illflag++; } break; case 'u': uflag++; break; case 'R': Rflag++; break; default: illflag++; } argc -= optind; argv = &argv[optind]; /* -a is mutually exclusive with -u and -R */ if (uflag && aflag) illflag++; if (Rflag && aflag) illflag++; if (illflag) { (void) fprintf(stderr, gettext(usage)); exit(1); } if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { perror(gettext("data: Failed to obtain system time")); exit(1); } clock_val = ts.tv_sec; if (aflag) { if (adjtime(&tv, 0) < 0) { perror(gettext("date: Failed to adjust date")); exit(1); } exit(0); } if (argc > 0) { if (*argv[0] == '+') fmt = &argv[0][1]; else { if (setdate(localtime(&clock_val), argv[0])) { (void) fprintf(stderr, gettext(usage)); exit(1); } fmt = nl_langinfo(_DATE_FMT); } } else if (Rflag) { fmt = "%a, %d %h %Y %H:%M:%S %z"; } else fmt = nl_langinfo(_DATE_FMT); fmtbuf = fmt_extensions(fmt, &ts); if (uflag) { (void) putenv("TZ=GMT0"); tzset(); tp = gmtime(&clock_val); } else tp = localtime(&clock_val); (void) memcpy(&tm, tp, sizeof (struct tm)); (void) strftime(buf, BUFSIZ, fmtbuf, &tm); (void) puts(buf); return (0); }
/** * Try adjust the time using adjtime or similar. * * @returns true on success, false on failure. * * @param pDrift The time adjustment. */ static bool vgsvcTimeSyncAdjust(PCRTTIMESPEC pDrift) { #ifdef RT_OS_WINDOWS /** @todo r=bird: g_hTokenProcess cannot be NULL here. * vgsvcTimeSyncInit will fail and the service will not be started with * it being NULL. vgsvcTimeSyncInit OTOH will *NOT* be called until the * service thread has terminated. If anything * else is the case, there is buggy code somewhere.*/ if (g_hTokenProcess == NULL) /* Is the token already closed when shutting down? */ return false; DWORD dwWinTimeAdjustment, dwWinNewTimeAdjustment, dwWinTimeIncrement; BOOL fWinTimeAdjustmentDisabled; if (GetSystemTimeAdjustment(&dwWinTimeAdjustment, &dwWinTimeIncrement, &fWinTimeAdjustmentDisabled)) { DWORD dwDiffMax = g_dwWinTimeAdjustment * 0.50; DWORD dwDiffNew = dwWinTimeAdjustment * 0.10; if (RTTimeSpecGetMilli(pDrift) > 0) { dwWinNewTimeAdjustment = dwWinTimeAdjustment + dwDiffNew; if (dwWinNewTimeAdjustment > (g_dwWinTimeAdjustment + dwDiffMax)) { dwWinNewTimeAdjustment = g_dwWinTimeAdjustment + dwDiffMax; dwDiffNew = dwDiffMax; } } else { dwWinNewTimeAdjustment = dwWinTimeAdjustment - dwDiffNew; if (dwWinNewTimeAdjustment < (g_dwWinTimeAdjustment - dwDiffMax)) { dwWinNewTimeAdjustment = g_dwWinTimeAdjustment - dwDiffMax; dwDiffNew = dwDiffMax; } } VGSvcVerbose(3, "vgsvcTimeSyncAdjust: Drift=%lldms\n", RTTimeSpecGetMilli(pDrift)); VGSvcVerbose(3, "vgsvcTimeSyncAdjust: OrgTA=%ld, CurTA=%ld, NewTA=%ld, DiffNew=%ld, DiffMax=%ld\n", g_dwWinTimeAdjustment, dwWinTimeAdjustment, dwWinNewTimeAdjustment, dwDiffNew, dwDiffMax); if (SetSystemTimeAdjustment(dwWinNewTimeAdjustment, FALSE /* Periodic adjustments enabled. */)) { g_cTimeSyncErrors = 0; return true; } if (g_cTimeSyncErrors++ < 10) VGSvcError("vgsvcTimeSyncAdjust: SetSystemTimeAdjustment failed, error=%u\n", GetLastError()); } else if (g_cTimeSyncErrors++ < 10) VGSvcError("vgsvcTimeSyncAdjust: GetSystemTimeAdjustment failed, error=%ld\n", GetLastError()); #elif defined(RT_OS_OS2) || defined(RT_OS_HAIKU) /* No API for doing gradual time adjustments. */ #else /* PORTME */ /* * Try use adjtime(), most unix-like systems have this. */ struct timeval tv; RTTimeSpecGetTimeval(pDrift, &tv); if (adjtime(&tv, NULL) == 0) { if (g_cVerbosity >= 1) VGSvcVerbose(1, "vgsvcTimeSyncAdjust: adjtime by %RDtimespec\n", pDrift); g_cTimeSyncErrors = 0; return true; } #endif /* failed */ return false; }
int main(const int argc, char *argv[]) { register const char * format; register const char * value; register const char * cp; register int ch; register int dousg; register int aflag = 0; register int dflag = 0; register int nflag = 0; register int tflag = 0; register int minuteswest; register int dsttime; register double adjust; time_t now; time_t t; INITIALIZE(dousg); INITIALIZE(minuteswest); INITIALIZE(dsttime); INITIALIZE(adjust); INITIALIZE(t); #ifdef LC_ALL (void) setlocale(LC_ALL, ""); #endif /* defined(LC_ALL) */ #if HAVE_GETTEXT #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined(TEXTDOMAINDIR) */ (void) textdomain(TZ_DOMAIN); #endif /* HAVE_GETTEXT */ (void) time(&now); format = value = NULL; while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF && ch != -1) { switch (ch) { default: usage(); case 'u': /* do it in UTC */ case 'c': dogmt(); break; case 'n': /* don't set network */ nflag = 1; break; case 'd': /* daylight saving time */ if (dflag) { (void) fprintf(stderr, _("date: error: multiple -d's used")); usage(); } dflag = 1; cp = optarg; dsttime = atoi(cp); if (*cp == '\0' || *nondigit(cp) != '\0') wildinput(_("-t value"), optarg, _("must be a non-negative number")); break; case 't': /* minutes west of UTC */ if (tflag) { (void) fprintf(stderr, _("date: error: multiple -t's used")); usage(); } tflag = 1; cp = optarg; minuteswest = atoi(cp); if (*cp == '+' || *cp == '-') ++cp; if (*cp == '\0' || *nondigit(cp) != '\0') wildinput(_("-d value"), optarg, _("must be a number")); break; case 'a': /* adjustment */ if (aflag) { (void) fprintf(stderr, _("date: error: multiple -a's used")); usage(); } aflag = 1; cp = optarg; adjust = atof(cp); if (*cp == '+' || *cp == '-') ++cp; if (*cp == '\0' || strcmp(cp, ".") == 0) wildinput(_("-a value"), optarg, _("must be a number")); cp = nondigit(cp); if (*cp == '.') ++cp; if (*nondigit(cp) != '\0') wildinput(_("-a value"), optarg, _("must be a number")); break; } } while (optind < argc) { cp = argv[optind++]; if (*cp == '+') if (format == NULL) format = cp + 1; else { (void) fprintf(stderr, _("date: error: multiple formats in command line\n")); usage(); } else if (value == NULL) value = cp; else { (void) fprintf(stderr, _("date: error: multiple values in command line\n")); usage(); } } if (value != NULL) { /* ** This order ensures that "reasonable" twelve-digit inputs ** (such as 120203042006) won't be misinterpreted ** even if time_t's range all the way back to the thirteenth ** century. Do not change the order. */ t = convert(value, (dousg = TRUE), now); if (t == -1) t = convert(value, (dousg = FALSE), now); if (t == -1) { /* ** Out of range values, ** or time that falls in a DST transition hole? */ if ((cp = strchr(value, '.')) != NULL) { /* ** Ensure that the failure of ** TZ=America/New_York date 8712312359.60 ** doesn't get misdiagnosed. (It was ** TZ=America/New_York date 8712311859.60 ** when the leap second was inserted.) ** The normal check won't work since ** the given time is valid in UTC. */ if (atoi(cp + 1) >= SECSPERMIN) wildinput(_("time"), value, _("out of range seconds given")); } dogmt(); t = convert(value, FALSE, now); if (t == -1) t = convert(value, TRUE, now); wildinput(_("time"), value, (t == -1) ? _("out of range value given") : _("time skipped when clock springs forward")); } } /* ** Entire command line has now been checked. */ if (aflag) { #if HAVE_ADJTIME struct timeval tv; tv.tv_sec = (int) adjust; tv.tv_usec = (int) ((adjust - tv.tv_sec) * 1000000L); if (adjtime(&tv, NULL) != 0) oops("adjtime"); #endif /* HAVE_ADJTIME */ #if !HAVE_ADJTIME reset(now + adjust, nflag); #endif /* !HAVE_ADJTIME */ /* ** Sun silently ignores everything else; we follow suit. */ exit(retval); } if (dflag || tflag) { #if HAVE_SETTIMEOFDAY == 2 struct timezone tz; if (!dflag || !tflag) if (gettimeofday(NULL, &tz) != 0) oops("gettimeofday"); if (dflag) tz.tz_dsttime = dsttime; if (tflag) tz.tz_minuteswest = minuteswest; if (settimeofday(NULL, &tz) != 0) oops("settimeofday"); #endif /* HAVE_SETTIMEOFDAY == 2 */ #if HAVE_SETTIMEOFDAY != 2 (void) fprintf(stderr, _("date: warning: kernel doesn't keep -d/-t information, option ignored\n")); #endif /* HAVE_SETTIMEOFDAY != 2 */ } if (value == NULL) display(format); reset(t, nflag); checkfinal(value, dousg, t, now); #ifdef EBUG { struct tm tm; tm = *localtime(&t); timeout(stdout, "%c\n", &tm); exit(retval); } #endif /* defined EBUG */ display(format); /* gcc -Wall pacifier */ for ( ; ; ) continue; }
void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int update_count ) { int time_difference; bool restart_tdt = false; if (!tp_time) restart_tdt = true; else if (tp_time == -1) { restart_tdt = true; eDebug("[eDVBLocalTimerHandler] no transponder tuned... or no TDT/TOT avail .. try to use RTC :)"); time_t rtc_time = getRTC(); if (rtc_time) // RTC Ready? { tm now; localtime_r(&rtc_time, &now); eDebug("[eDVBLocalTimerHandler] RTC time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_t linuxTime=time(0); localtime_r(&linuxTime, &now); eDebug("[eDVBLocalTimerHandler] Receiver time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_difference = rtc_time - linuxTime; eDebug("[eDVBLocalTimerHandler] RTC to Receiver time difference is %ld seconds", linuxTime - rtc_time ); if (time_difference) { if ((time_difference >= -15) && (time_difference <= 15)) { timeval tdelta, tolddelta; // Slew small diffs ... // Even good transponders can differ by 0-5 sec, if we would step these // the system clock would permanentely jump around when zapping. tdelta.tv_sec = time_difference; if(adjtime(&tdelta, &tolddelta) == 0) eDebug("[eDVBLocalTimerHandler] slewing Linux Time by %03d seconds", time_difference); else eDebug("[eDVBLocalTimerHandler] slewing Linux Time by %03d seconds FAILED", time_difference); } else { timeval tnow; // ... only step larger diffs gettimeofday(&tnow, 0); tnow.tv_sec = rtc_time; settimeofday(&tnow, 0); linuxTime = time(0); localtime_r(&linuxTime, &now); eDebug("[eDVBLocalTimerHandler] stepped Linux Time to %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); } } else if ( !time_difference ) eDebug("[eDVBLocalTimerHandler] no change needed"); else eDebug("[eDVBLocalTimerHandler] set to RTC time"); /*emit*/ m_timeUpdated(); } else eDebug("[eDVBLocalTimerHandler] getRTC returned time=0. RTC problem?"); } else { std::map< eDVBChannelID, int >::iterator it( m_timeOffsetMap.find( chan->getChannelID() ) ); // current linux time time_t linuxTime = time(0); // difference between current enigma time and transponder time int enigma_diff = tp_time-linuxTime; int new_diff=0; bool updated = m_time_ready; if ( m_time_ready ) // ref time ready? { // difference between reference time (current enigma time) // and the transponder time eDebug("[eDVBLocalTimerHandler] diff is %d", enigma_diff); if ( abs(enigma_diff) < 120 ) { eDebug("[eDVBLocalTimerHandler] diff < 120 .. use Transponder Time"); m_timeOffsetMap[chan->getChannelID()] = 0; new_diff = enigma_diff; } else if ( it != m_timeOffsetMap.end() ) // correction saved? { eDebug("[eDVBLocalTimerHandler] we have correction %d", it->second); time_t CorrectedTpTime = tp_time+it->second; int ddiff = CorrectedTpTime-linuxTime; eDebug("[eDVBLocalTimerHandler] diff after add correction is %d", ddiff); if ( abs(it->second) < 300 ) // stored correction < 5 min { eDebug("[eDVBLocalTimerHandler] use stored correction(<5 min)"); new_diff = ddiff; } else if ( getRTC() ) { time_t rtc=getRTC(); m_timeOffsetMap[chan->getChannelID()] = rtc-tp_time; new_diff = rtc-linuxTime; // set enigma time to rtc eDebug("[eDVBLocalTimerHandler] update stored correction to %ld (calced against RTC time)", rtc-tp_time ); } else if ( abs(ddiff) <= 120 ) { // with stored correction calced time difference is lower 2 min // this don't help when a transponder have a clock running to slow or to fast // then its better to have a DM7020 with always running RTC eDebug("[eDVBLocalTimerHandler] use stored correction(corr < 2 min)"); new_diff = ddiff; } else // big change in calced correction.. hold current time and update correction { eDebug("[eDVBLocalTimerHandler] update stored correction to %d", -enigma_diff); m_timeOffsetMap[chan->getChannelID()] = -enigma_diff; } } else { eDebug("[eDVBLocalTimerHandler] no correction found... store calced correction(%d)",-enigma_diff); m_timeOffsetMap[chan->getChannelID()] = -enigma_diff; } } else // no time setted yet { if ( it != m_timeOffsetMap.end() ) { enigma_diff += it->second; eDebug("[eDVBLocalTimerHandler] we have correction (%d)... use", it->second ); } else eDebug("[eDVBLocalTimerHandler] dont have correction.. set Transponder Diff"); new_diff=enigma_diff; m_time_ready=true; } time_t t = linuxTime+new_diff; m_last_tp_time_difference=tp_time-t; if (!new_diff && updated) // overrride this check on first received TDT { eDebug("[eDVBLocalTimerHandler] not changed"); return; } if ( !update_count ) { // set rtc to calced transponder time when the first tdt is received on this // transponder setRTC(t); eDebug("[eDVBLocalTimerHandler] update RTC"); } else if (getRTC()) { if (abs(getRTC() - t) > 60) { eDebug("[eDVBLocalTimerHandler] difference between new linux time and RTC time is > 60 sec... transponder time looks not ok... use rtc time"); t = getRTC(); } else eDebug("[eDVBLocalTimerHandler] difference between linux time and RTC time is < 60 sec... so the transponder time looks ok"); } else eDebug("[eDVBLocalTimerHandler] no RTC available :("); tm now; localtime_r(&t, &now); eDebug("[eDVBLocalTimerHandler] time update to %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_difference = t - linuxTime; // calc our new linux_time -> enigma_time correction eDebug("[eDVBLocalTimerHandler] m_time_difference is %d", time_difference ); if ( time_difference ) { eDebug("[eDVBLocalTimerHandler] set Linux Time"); timeval tnow; gettimeofday(&tnow,0); tnow.tv_sec=t; settimeofday(&tnow,0); } /*emit*/ m_timeUpdated(); } if ( restart_tdt ) { std::map<iDVBChannel*, channel_data>::iterator it = m_knownChannels.find(chan); if ( it != m_knownChannels.end() ) { int system = iDVBFrontend::feSatellite; ePtr<iDVBFrontendParameters> parms; chan->getCurrentFrontendParameters(parms); if (parms) { parms->getSystem(system); } int updateCount = it->second.timetable->getUpdateCount(); it->second.timetable = NULL; if (system == iDVBFrontend::feATSC) { it->second.timetable = new STT(chan, updateCount); } else { it->second.timetable = new TDT(chan, updateCount); } it->second.timetable->startTimer(TIME_UPDATE_INTERVAL); // restart TDT for this transponder in 30min } } }
int /* 0 okay, 1 error */ adj_systime( double now /* adjustment (s) */ ) { struct timeval adjtv; /* new adjustment */ struct timeval oadjtv; /* residual adjustment */ double quant; /* quantize to multiples of */ double dtemp; long ticks; int isneg = 0; /* * The Windows port adj_systime() depends on being called each * second even when there's no additional correction, to allow * emulation of adjtime() behavior on top of an API that simply * sets the current rate. This POSIX implementation needs to * ignore invocations with zero correction, otherwise ongoing * EVNT_NSET adjtime() can be aborted by a tiny adjtime() * triggered by sys_residual. */ if (0. == now) return TRUE; /* * Most Unix adjtime() implementations adjust the system clock * in microsecond quanta, but some adjust in 10-ms quanta. We * carefully round the adjustment to the nearest quantum, then * adjust in quanta and keep the residue for later. */ dtemp = now + sys_residual; if (dtemp < 0) { isneg = 1; dtemp = -dtemp; } adjtv.tv_sec = (long)dtemp; dtemp -= adjtv.tv_sec; if (sys_tick > sys_fuzz) quant = sys_tick; else quant = 1e-6; ticks = (long)(dtemp / quant + .5); adjtv.tv_usec = (long)(ticks * quant * 1e6); dtemp -= adjtv.tv_usec / 1e6; sys_residual = dtemp; /* * Convert to signed seconds and microseconds for the Unix * adjtime() system call. Note we purposely lose the adjtime() * leftover. */ if (isneg) { adjtv.tv_sec = -adjtv.tv_sec; adjtv.tv_usec = -adjtv.tv_usec; sys_residual = -sys_residual; } if (adjtv.tv_sec != 0 || adjtv.tv_usec != 0) { if (adjtime(&adjtv, &oadjtv) < 0) { msyslog(LOG_ERR, "adj_systime: %m"); return FALSE; } } return TRUE; }
/* * The timedaemons synchronize the clocks of hosts in a local area network. * One daemon runs as master, all the others as slaves. The master * performs the task of computing clock differences and sends correction * values to the slaves. * Slaves start an election to choose a new master when the latter disappears * because of a machine crash, network partition, or when killed. * A resolution protocol is used to kill all but one of the masters * that happen to exist in segments of a partitioned network when the * network partition is fixed. * * Authors: Riccardo Gusella & Stefano Zatti * * overhauled at Silicon Graphics */ int main(int argc, char *argv[]) { int on; int ret; int nflag, iflag; struct timeval ntime; struct servent *srvp; char buf[BUFSIZ], *cp, *cplim; struct ifconf ifc; struct ifreq ifreq, ifreqf, *ifr; register struct netinfo *ntp; struct netinfo *ntip; struct netinfo *savefromnet; struct netent *nentp; struct nets *nt; struct sockaddr_in server; u_short port; int c; #ifdef lint ntip = NULL; #endif on = 1; nflag = OFF; iflag = OFF; opterr = 0; while ((c = getopt(argc, argv, "Mtdn:i:F:G:P:")) != -1) { switch (c) { case 'M': Mflag = 1; break; case 't': trace = 1; break; case 'n': if (iflag) { errx(1, "-i and -n make no sense together"); } else { nflag = ON; addnetname(optarg); } break; case 'i': if (nflag) { errx(1, "-i and -n make no sense together"); } else { iflag = ON; addnetname(optarg); } break; case 'F': add_good_host(optarg,1); while (optind < argc && argv[optind][0] != '-') add_good_host(argv[optind++], 1); break; case 'd': debug = 1; break; case 'G': if (goodgroup != NULL) errx(1, "only one net group"); goodgroup = optarg; break; default: usage(); break; } } if (optind < argc) usage(); /* If we care about which machine is the master, then we must * be willing to be a master */ if (goodgroup != NULL || goodhosts != NULL) Mflag = 1; if (gethostname(hostname, sizeof(hostname) - 1) < 0) err(1, "gethostname"); self.l_bak = &self; self.l_fwd = &self; self.h_bak = &self; self.h_fwd = &self; self.head = 1; self.good = 1; if (goodhosts != NULL) /* trust ourself */ add_good_host(hostname,1); srvp = getservbyname("timed", "udp"); if (srvp == NULL) errx(1, "timed/udp: unknown service"); port = srvp->s_port; bzero(&server, sizeof(struct sockaddr_in)); server.sin_port = srvp->s_port; server.sin_family = AF_INET; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) err(1, "socket"); if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt"); if (bind(sock, (struct sockaddr*)&server, sizeof(server))) { if (errno == EADDRINUSE) warnx("time daemon already running"); else warn("bind"); exit(1); } sequence = arc4random(); /* initial seq number */ (void)gettimeofday(&ntime, NULL); /* rounds kernel variable time to multiple of 5 ms. */ ntime.tv_sec = 0; ntime.tv_usec = -((ntime.tv_usec/1000) % 5) * 1000; (void)adjtime(&ntime, (struct timeval *)0); for (nt = nets; nt; nt = nt->next) { nentp = getnetbyname(nt->name); if (nentp == NULL) { nt->net = inet_network(nt->name); if (nt->net != INADDR_NONE) nentp = getnetbyaddr(nt->net, AF_INET); } if (nentp != NULL) { nt->net = nentp->n_net; } else if (nt->net == INADDR_NONE) { errx(1, "unknown net %s", nt->name); } else if (nt->net == INADDR_ANY) { errx(1, "bad net %s", nt->name); } else { warnx("warning: %s unknown in /etc/networks", nt->name); } if (0 == (nt->net & 0xff000000)) nt->net <<= 8; if (0 == (nt->net & 0xff000000)) nt->net <<= 8; if (0 == (nt->net & 0xff000000)) nt->net <<= 8; } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) err(1, "get interface configuration"); ntp = NULL; #define size(p) max((p).sa_len, sizeof(p)) cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ for (cp = buf; cp < cplim; cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { ifr = (struct ifreq *)cp; if (ifr->ifr_addr.sa_family != AF_INET) continue; if (!ntp) ntp = (struct netinfo*)malloc(sizeof(struct netinfo)); bzero(ntp,sizeof(*ntp)); ntp->my_addr=((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; ntp->status = NOMASTER; ifreq = *ifr; ifreqf = *ifr; if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreqf) < 0) { warn("get interface flags"); continue; } if ((ifreqf.ifr_flags & IFF_UP) == 0) continue; if ((ifreqf.ifr_flags & IFF_BROADCAST) == 0 && (ifreqf.ifr_flags & IFF_POINTOPOINT) == 0) { continue; } if (ioctl(sock, SIOCGIFNETMASK, (char *)&ifreq) < 0) { warn("get netmask"); continue; } ntp->mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; if (ifreqf.ifr_flags & IFF_BROADCAST) { if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { warn("get broadaddr"); continue; } ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_broadaddr; /* What if the broadcast address is all ones? * So we cannot just mask ntp->dest_addr. */ ntp->net = ntp->my_addr; ntp->net.s_addr &= ntp->mask; } else { if (ioctl(sock, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { warn("get destaddr"); continue; } ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_dstaddr; ntp->net = ntp->dest_addr.sin_addr; } ntp->dest_addr.sin_port = port; for (nt = nets; nt; nt = nt->next) { if (ntp->net.s_addr == htonl(nt->net)) break; } if ((nflag && !nt) || (iflag && nt)) continue; ntp->next = NULL; if (nettab == NULL) { nettab = ntp; } else { ntip->next = ntp; } ntip = ntp; ntp = NULL; } if (ntp) (void) free((char *)ntp); if (nettab == NULL) errx(1, "no network usable"); /* microseconds to delay before responding to a broadcast */ delay1 = casual(1, 100*1000); /* election timer delay in secs. */ delay2 = casual(MINTOUT, MAXTOUT); if (!debug) daemon(debug, 0); if (trace) traceon(); openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON); /* * keep returning here */ ret = setjmp(jmpenv); savefromnet = fromnet; setstatus(); if (Mflag) { switch (ret) { case 0: checkignorednets(); pickslavenet(0); break; case 1: /* Just lost our master */ if (slavenet != NULL) slavenet->status = election(slavenet); if (!slavenet || slavenet->status == MASTER) { checkignorednets(); pickslavenet(0); } else { makeslave(slavenet); /* prune extras */ } break; case 2: /* Just been told to quit */ justquit = 1; pickslavenet(savefromnet); break; } setstatus(); if (!(status & MASTER) && sock_raw != -1) { /* sock_raw is not being used now */ (void)close(sock_raw); sock_raw = -1; } if (status == MASTER) master(); else slave(); } else { if (sock_raw != -1) { (void)close(sock_raw); sock_raw = -1; } if (ret) { /* we just lost our master or were told to quit */ justquit = 1; } for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER) { rmnetmachs(ntp); ntp->status = NOMASTER; } } checkignorednets(); pickslavenet(0); setstatus(); slave(); } /* NOTREACHED */ return(0); }
void *POSIX_Init( void *argument ) { unsigned int remaining; int sc; struct sigaction act; sigset_t mask; struct timeval delta; TEST_BEGIN(); /* install a signal handler for SIGALRM and unblock it */ sc = sigemptyset( &act.sa_mask ); rtems_test_assert( !sc ); act.sa_handler = Signal_handler; act.sa_flags = 0; sigaction( SIGALRM, &act, NULL ); sc = sigemptyset( &mask ); rtems_test_assert( !sc ); sc = sigaddset( &mask, SIGALRM ); rtems_test_assert( !sc ); puts( "Init: Unblock SIGALRM" ); sc = sigprocmask( SIG_UNBLOCK, &mask, NULL ); rtems_test_assert( !sc ); /* schedule the alarm */ puts( "Init: Firing alarm in 1 second" ); remaining = alarm( 1 ); printf( "Init: %d seconds left on previous alarm\n", sc ); rtems_test_assert( !sc ); puts( "Init: Wait for alarm" ); sleep( 2 ); rtems_test_assert( Signal_count == 1 ); puts( "Init: Cancel alarm" ); remaining = alarm( 0 ); printf( "Init: %d seconds left on previous alarm\n", remaining ); rtems_test_assert( remaining == 0 ); remaining = alarm( 1 ); rtems_test_assert( remaining == 0 ); delta.tv_sec = 2; delta.tv_usec = 0; sc = adjtime( &delta, NULL ); rtems_test_assert( sc == 0 ); rtems_test_assert( Signal_count == 1 ); remaining = alarm( 0 ); rtems_test_assert( remaining == 1 ); TEST_END(); rtems_test_exit( 0 ); return NULL; /* just so the compiler thinks we returned something */ }