blob: c4732f459e35b6857c5263c1a233b19de6fbf8e9 [file] [log] [blame]
Lei YU415b9642017-02-09 11:37:26 +08001#include "manager.hpp"
2
3#include <phosphor-logging/log.hpp>
4
5namespace rules = sdbusplus::bus::match::rules;
6
7namespace // anonymous
8{
9constexpr auto SETTINGS_SERVICE = "org.openbmc.settings.Host";
10constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
11constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";
12constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
13constexpr auto METHOD_GET = "Get";
14
15constexpr auto PROPERTY_TIME_MODE = "time_mode";
16constexpr auto PROPERTY_TIME_OWNER = "time_owner";
17
18// TODO: Use new settings in xyz.openbmc_project
19const auto MATCH_PROPERTY_CHANGE =
20 rules::type::signal() +
21 rules::member("PropertiesChanged") +
22 rules::path("/org/openbmc/settings/host0") +
23 rules::interface("org.freedesktop.DBus.Properties");
24
25}
26
27namespace phosphor
28{
29namespace time
30{
31
32using namespace phosphor::logging;
33
34const std::set<std::string>
35Manager::managedProperties = {PROPERTY_TIME_MODE, PROPERTY_TIME_OWNER};
36
37const std::map<std::string, Owner> Manager::ownerMap =
38{
39 { "BMC", Owner::BMC },
40 { "HOST", Owner::HOST },
41 { "SPLIT", Owner::SPLIT },
42 { "BOTH", Owner::BOTH },
43};
44
45Manager::Manager(sdbusplus::bus::bus& bus)
46 : bus(bus),
47 propertyChangeMatch(bus, MATCH_PROPERTY_CHANGE, onPropertyChanged, this)
48{
49 setCurrentTimeMode(getSettings(PROPERTY_TIME_MODE));
50 setCurrentTimeOwner(getSettings(PROPERTY_TIME_OWNER));
51}
52
53void Manager::addListener(PropertyChangeListner* listener)
54{
55 // Notify listener about the initial value
56 listener->onModeChanged(timeMode);
57 listener->onOwnerChanged(timeOwner);
58
59 listeners.insert(listener);
60}
61
62void Manager::onPropertyChanged(const std::string& key,
63 const std::string& value)
64{
65 // TODO: Check pgood
66 // If it's off, notify listners;
67 // If it's on, hold the values and store in persistent storage.
68 // And when pgood turns back to off, notify the listners.
69
70 // TODO: Check dhcp_ntp
71
72 if (key == PROPERTY_TIME_MODE)
73 {
74 setCurrentTimeMode(value);
75 for (const auto& listener : listeners)
76 {
77 listener->onModeChanged(timeMode);
78 }
79 }
80 else if (key == PROPERTY_TIME_OWNER)
81 {
82 setCurrentTimeOwner(value);
83 for (const auto& listener : listeners)
84 {
85 listener->onOwnerChanged(timeOwner);
86 }
87 }
88}
89
90int Manager::onPropertyChanged(sd_bus_message* msg,
91 void* userData,
92 sd_bus_error* retError)
93{
94 using properties = std::map < std::string,
95 sdbusplus::message::variant<int, std::string >>;
96 auto m = sdbusplus::message::message(msg);
97 // message type: sa{sv}as
98 std::string ignore;
99 properties props;
100 m.read(ignore, props);
101 for (const auto& item : props)
102 {
103 if (managedProperties.find(item.first) != managedProperties.end())
104 {
105 static_cast<Manager*>(userData)
106 ->onPropertyChanged(item.first, item.second.get<std::string>());
107 }
108 }
109 return 0;
110}
111
112
113void Manager::setCurrentTimeMode(const std::string& mode)
114{
115 log<level::INFO>("Time mode is changed",
116 entry("MODE=%s", mode.c_str()));
117 timeMode = convertToMode(mode);
118}
119
120void Manager::setCurrentTimeOwner(const std::string& owner)
121{
122 log<level::INFO>("Time owner is changed",
123 entry("OWNER=%s", owner.c_str()));
124 timeOwner = convertToOwner(owner);
125}
126
127std::string Manager::getSettings(const char* value) const
128{
129 sdbusplus::message::variant<std::string> mode;
130 auto method = bus.new_method_call(SETTINGS_SERVICE,
131 SETTINGS_PATH,
132 PROPERTY_INTERFACE,
133 METHOD_GET);
134 method.append(SETTINGS_INTERFACE, value);
135 auto reply = bus.call(method);
136 if (reply)
137 {
138 reply.read(mode);
139 }
140 else
141 {
142 log<level::ERR>("Failed to get settings");
143 }
144
145 return mode.get<std::string>();
146}
147
148Mode Manager::convertToMode(const std::string& mode)
149{
150 if (mode == "NTP")
151 {
152 return Mode::NTP;
153 }
154 else if (mode == "MANUAL")
155 {
156 return Mode::MANUAL;
157 }
158 else
159 {
160 log<level::ERR>("Unrecognized mode",
161 entry("%s", mode.c_str()));
162 return Mode::NTP;
163 }
164}
165
166Owner Manager::convertToOwner(const std::string& owner)
167{
168 auto it = ownerMap.find(owner);
169 if (it == ownerMap.end())
170 {
171 log<level::ERR>("Unrecognized owner",
172 entry("%s", owner.c_str()));
173 return Owner::BMC;
174 }
175 return it->second;
176}
177
178}
179}