blob: 06232bb848ee6ea98ce51c078c8db7b819b45978 [file] [log] [blame]
Lei YU2f9c0cc2017-01-20 14:02:03 +08001#include "epoch_base.hpp"
2
3#include <phosphor-logging/log.hpp>
4
5#include <iomanip>
6#include <sstream>
7
8namespace // anonymous
9{
10constexpr auto SETTINGS_SERVICE = "org.openbmc.settings.Host";
11constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
12constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";
13constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
14constexpr auto METHOD_GET = "Get";
15}
16
17namespace phosphor
18{
19namespace time
20{
21
22using namespace phosphor::logging;
23
24const std::map<std::string, EpochBase::Owner>
25EpochBase::ownerMap = {
26 { "BMC", EpochBase::Owner::BMC },
27 { "HOST", EpochBase::Owner::HOST },
28 { "SPLIT", EpochBase::Owner::SPLIT },
29 { "BOTH", EpochBase::Owner::BOTH },
30};
31
32EpochBase::EpochBase(sdbusplus::bus::bus& bus,
33 const char* objPath)
34 : sdbusplus::server::object::object<EpochTime>(bus, objPath, true),
35 bus(bus)
36{
37 initialize();
38 // Deferred this until we could get our property correct
39 emit_object_added();
40}
41
42void EpochBase::setCurrentTimeMode(const std::string& mode)
43{
44 log<level::INFO>("Time mode is changed",
45 entry("MODE=%s", mode.c_str()));
46 timeMode = convertToMode(mode);
47}
48
49void EpochBase::setCurrentTimeOwner(const std::string& owner)
50{
51 log<level::INFO>("Time owner is changed",
52 entry("OWNER=%s", owner.c_str()));
53 timeOwner = convertToOwner(owner);
54}
55
56void EpochBase::initialize()
57{
58 setCurrentTimeMode(getSettings("time_mode"));
59 setCurrentTimeOwner(getSettings("time_owner"));
60 // TODO: subscribe settingsd's property changes callback
61}
62
63std::string EpochBase::getSettings(const char* value) const
64{
65 sdbusplus::message::variant<std::string> mode;
66 auto method = bus.new_method_call(SETTINGS_SERVICE,
67 SETTINGS_PATH,
68 PROPERTY_INTERFACE,
69 METHOD_GET);
70 method.append(SETTINGS_INTERFACE, value);
71 auto reply = bus.call(method);
72 if (reply)
73 {
74 reply.read(mode);
75 }
76
77 return mode.get<std::string>();
78}
79
80EpochBase::Mode EpochBase::convertToMode(const std::string& mode)
81{
82 if (mode == "NTP")
83 {
84 return Mode::NTP;
85 }
86 else if (mode == "MANUAL")
87 {
88 return Mode::MANUAL;
89 }
90 else
91 {
92 log<level::ERR>("Unrecognized mode",
93 entry("%s", mode.c_str()));
94 return Mode::NTP;
95 }
96}
97
98EpochBase::Owner EpochBase::convertToOwner(const std::string& owner)
99{
100 auto it = ownerMap.find(owner);
101 if (it == ownerMap.end())
102 {
103 log<level::ERR>("Unrecognized owner",
104 entry("%s", owner.c_str()));
105 return Owner::BMC;
106 }
107 return it->second;
108}
109
110using namespace std::chrono;
111void EpochBase::setTime(const microseconds& usec)
112{
113 auto method = bus.new_method_call("org.freedesktop.timedate1",
114 "/org/freedesktop/timedate1",
115 "org.freedesktop.timedate1",
116 "SetTime");
117 method.append(static_cast<int64_t>(usec.count()),
118 false, // relative
119 false); // user_interaction
120 bus.call_noreply(method);
121}
122
123microseconds EpochBase::getTime() const
124{
125 auto now = system_clock::now();
126 return duration_cast<microseconds>
127 (now.time_since_epoch());
128}
129
130} // namespace time
131} // namespace phosphor