blob: 7ec5945f5b16e9019c2baf4b8406bf370f502518 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/bin/network_time/timezone.h"
#include <fcntl.h>
#include <inttypes.h>
#include <sys/time.h>
#include <unistd.h>
#include <zircon/device/rtc.h>
#include <string>
#include "garnet/bin/network_time/roughtime_server.h"
#include "garnet/bin/network_time/time_server_config.h"
#include "lib/syslog/cpp/logger.h"
namespace time_zone {
bool Timezone::Run() {
FX_LOGS(INFO) << "started";
UpdateSystemTime(3);
return true;
}
bool Timezone::UpdateSystemTime(uint8_t tries) {
TimeServerConfig config;
if (!config.Parse(server_config_file_)) {
return false;
}
const RoughTimeServer* server = nullptr;
std::vector<RoughTimeServer> servers = config.ServerList();
for (const auto& s : servers) {
if (!s.IsValid()) {
continue;
}
server = &s;
break;
}
if (server == nullptr) {
FX_LOGS(ERROR) << "No valid server";
return false;
}
for (uint8_t i = 0; i < tries; i++) {
FX_VLOGS(1) << "Updating system time, attempt: " << i + 1;
roughtime::rough_time_t timestamp;
Status ret = server->GetTimeFromServer(&timestamp);
if (ret == NETWORK_ERROR) {
if (i != tries - 1) {
FX_VLOGS(1) << "Can't get time, sleeping for 10 sec";
sleep(10);
}
continue;
} else if (ret != OK) {
FX_LOGS(ERROR) << "Error with roughtime server, abort";
return false;
}
struct tm ptm;
time_t t = timestamp / 1000000;
gmtime_r(&t, &ptm);
rtc_t rtc;
rtc.seconds = ptm.tm_sec;
rtc.minutes = ptm.tm_min;
rtc.hours = ptm.tm_hour;
rtc.day = ptm.tm_mday;
rtc.month = ptm.tm_mon + 1;
rtc.year = ptm.tm_year + 1900;
int rtc_fd = open("/dev/sys/acpi/rtc/rtc", O_WRONLY);
if (rtc_fd < 0) {
FX_LOGS(ERROR) << "open rtc: " << strerror(errno);
return false;
}
ssize_t written = ioctl_rtc_set(rtc_fd, &rtc);
if (written != sizeof(rtc)) {
printf("%04d-%02d-%02dT%02d:%02d:%02d\n", rtc.year, rtc.month, rtc.day,
rtc.hours, rtc.minutes, rtc.seconds);
FX_LOGS(ERROR) << "ioctl_rtc_set: " << strerror(errno) << " " << t;
return false;
}
char time[20];
snprintf(time, 20, "%04d-%02d-%02dT%02d:%02d:%02d", rtc.year, rtc.month,
rtc.day, rtc.hours, rtc.minutes, rtc.seconds);
FX_LOGS(INFO) << "time set to: " << time;
break;
}
return true;
}
} // namespace time_zone