blob: 8b63726cfe578a63b3a649e8341426079f0440c5 [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matt Spinlercad9c2b2019-12-02 15:42:01 -060016#include "config.h"
17
Matt Spinlerc8705e22019-09-11 12:36:07 -050018#include "data_interface.hpp"
19
Matt Spinlercad9c2b2019-12-02 15:42:01 -060020#include <fstream>
Matt Spinlera7d9d962019-11-06 15:01:25 -060021#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
22
Matt Spinlerc8705e22019-09-11 12:36:07 -050023namespace openpower
24{
25namespace pels
26{
27
28namespace service_name
29{
30constexpr auto objectMapper = "xyz.openbmc_project.ObjectMapper";
31} // namespace service_name
32
33namespace object_path
34{
35constexpr auto objectMapper = "/xyz/openbmc_project/object_mapper";
36constexpr auto systemInv = "/xyz/openbmc_project/inventory/system";
Matt Spinlera7d9d962019-11-06 15:01:25 -060037constexpr auto hostState = "/xyz/openbmc_project/state/host0";
Matt Spinlerb3f51862019-12-09 13:55:10 -060038constexpr auto pldm = "/xyz/openbmc_project/pldm";
Matt Spinler9cf3cfd2020-02-03 14:41:55 -060039constexpr auto enableHostPELs =
40 "/xyz/openbmc_project/logging/send_event_logs_to_host";
Matt Spinlerc8705e22019-09-11 12:36:07 -050041} // namespace object_path
42
43namespace interface
44{
45constexpr auto dbusProperty = "org.freedesktop.DBus.Properties";
46constexpr auto objectMapper = "xyz.openbmc_project.ObjectMapper";
47constexpr auto invAsset = "xyz.openbmc_project.Inventory.Decorator.Asset";
Matt Spinlera7d9d962019-11-06 15:01:25 -060048constexpr auto osStatus = "xyz.openbmc_project.State.OperatingSystem.Status";
Matt Spinlerb3f51862019-12-09 13:55:10 -060049constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester";
Matt Spinler9cf3cfd2020-02-03 14:41:55 -060050constexpr auto enable = "xyz.openbmc_project.Object.Enable";
Matt Spinlerc8705e22019-09-11 12:36:07 -050051} // namespace interface
52
Matt Spinlera7d9d962019-11-06 15:01:25 -060053using namespace sdbusplus::xyz::openbmc_project::State::OperatingSystem::server;
54
Matt Spinlerc8705e22019-09-11 12:36:07 -050055DataInterface::DataInterface(sdbusplus::bus::bus& bus) : _bus(bus)
56{
Matt Spinlercad9c2b2019-12-02 15:42:01 -060057 readBMCFWVersion();
58 readServerFWVersion();
Matt Spinler677381b2020-01-23 10:04:29 -060059 readBMCFWVersionID();
Matt Spinler2a28c932020-02-03 14:23:40 -060060
61 // Watch both the Model and SN properties on the system's Asset iface
62 _properties.emplace_back(std::make_unique<InterfaceWatcher<DataInterface>>(
63 bus, object_path::systemInv, interface::invAsset, *this,
64 [this](const auto& properties) {
65 auto model = properties.find("Model");
66 if (model != properties.end())
67 {
68 this->_machineTypeModel = std::get<std::string>(model->second);
69 }
70
71 auto sn = properties.find("SerialNumber");
72 if (sn != properties.end())
73 {
74 this->_machineSerialNumber = std::get<std::string>(sn->second);
75 }
76 }));
77
78 // Watch the OperatingSystemState property
79 _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
80 bus, object_path::hostState, interface::osStatus,
81 "OperatingSystemState", *this, [this](const auto& value) {
82 auto status =
83 Status::convertOSStatusFromString(std::get<std::string>(value));
84
85 if ((status == Status::OSStatus::BootComplete) ||
86 (status == Status::OSStatus::Standby))
87 {
88 setHostState(true);
89 }
90 else
91 {
92 setHostState(false);
93 }
94 }));
Matt Spinler9cf3cfd2020-02-03 14:41:55 -060095
96 // Watch the host PEL enable property
97 _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
98 bus, object_path::enableHostPELs, interface::enable, "Enabled", *this,
99 [this](const auto& value) {
100 this->_sendPELsToHost = std::get<bool>(value);
101 }));
Matt Spinlerc8705e22019-09-11 12:36:07 -0500102}
103
Matt Spinler2a28c932020-02-03 14:23:40 -0600104DBusPropertyMap
105 DataInterface::getAllProperties(const std::string& service,
106 const std::string& objectPath,
107 const std::string& interface) const
Matt Spinlerc8705e22019-09-11 12:36:07 -0500108{
109 DBusPropertyMap properties;
110
111 auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
112 interface::dbusProperty, "GetAll");
113 method.append(interface);
114 auto reply = _bus.call(method);
115
116 reply.read(properties);
117
118 return properties;
119}
120
Matt Spinlera7d9d962019-11-06 15:01:25 -0600121void DataInterface::getProperty(const std::string& service,
122 const std::string& objectPath,
123 const std::string& interface,
Matt Spinler2a28c932020-02-03 14:23:40 -0600124 const std::string& property,
125 DBusValue& value) const
Matt Spinlera7d9d962019-11-06 15:01:25 -0600126{
127
128 auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
129 interface::dbusProperty, "Get");
130 method.append(interface, property);
131 auto reply = _bus.call(method);
132
133 reply.read(value);
134}
135
Matt Spinlerc8705e22019-09-11 12:36:07 -0500136DBusService DataInterface::getService(const std::string& objectPath,
Matt Spinlerb3f51862019-12-09 13:55:10 -0600137 const std::string& interface) const
Matt Spinlerc8705e22019-09-11 12:36:07 -0500138{
139 auto method = _bus.new_method_call(service_name::objectMapper,
140 object_path::objectMapper,
141 interface::objectMapper, "GetObject");
142
143 method.append(objectPath, std::vector<std::string>({interface}));
144
145 auto reply = _bus.call(method);
146
147 std::map<DBusService, DBusInterfaceList> response;
148 reply.read(response);
149
150 if (!response.empty())
151 {
152 return response.begin()->first;
153 }
154
155 return std::string{};
156}
Matt Spinlera7d9d962019-11-06 15:01:25 -0600157
Matt Spinlerb3f51862019-12-09 13:55:10 -0600158uint8_t DataInterface::getPLDMInstanceID(uint8_t eid) const
159{
160 return 0;
161// Don't use until PLDM switches to async D-Bus.
162#if 0
163 auto service = getService(object_path::pldm, interface::pldmRequester);
164
165 auto method =
166 _bus.new_method_call(service.c_str(), object_path::pldm,
167 interface::pldmRequester, "GetInstanceId");
168 method.append(eid);
169 auto reply = _bus.call(method);
170
171 uint8_t instanceID = 0;
172 reply.read(instanceID);
173
174 return instanceID;
175#endif
176}
177
Matt Spinler677381b2020-01-23 10:04:29 -0600178/**
179 * @brief Return a value found in the /etc/os-release file
180 *
181 * @param[in] key - The key name, like "VERSION"
182 *
183 * @return std::optional<std::string> - The value
184 */
185std::optional<std::string> getOSReleaseValue(const std::string& key)
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600186{
187 std::ifstream versionFile{BMC_VERSION_FILE};
188 std::string line;
Matt Spinler677381b2020-01-23 10:04:29 -0600189 std::string keyPattern{key + '='};
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600190
191 while (std::getline(versionFile, line))
192 {
Matt Spinler677381b2020-01-23 10:04:29 -0600193 if (line.find(keyPattern) != std::string::npos)
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600194 {
195 auto pos = line.find_first_of('"') + 1;
Matt Spinler677381b2020-01-23 10:04:29 -0600196 auto value = line.substr(pos, line.find_last_of('"') - pos);
197 return value;
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600198 }
199 }
Matt Spinler677381b2020-01-23 10:04:29 -0600200
201 return std::nullopt;
202}
203
204void DataInterface::readBMCFWVersion()
205{
206 _bmcFWVersion = getOSReleaseValue("VERSION").value_or("");
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600207}
208
209void DataInterface::readServerFWVersion()
210{
211 // Not available yet
212}
213
Matt Spinler677381b2020-01-23 10:04:29 -0600214void DataInterface::readBMCFWVersionID()
215{
216 _bmcFWVersionID = getOSReleaseValue("VERSION_ID").value_or("");
217}
218
Matt Spinlerc8705e22019-09-11 12:36:07 -0500219} // namespace pels
220} // namespace openpower