Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 1 | /** |
| 2 | * Copyright © 2020 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 | */ |
| 16 | #pragma once |
| 17 | |
| 18 | #include "sdbusplus.hpp" |
| 19 | |
| 20 | #include <nlohmann/json.hpp> |
| 21 | #include <phosphor-logging/log.hpp> |
| 22 | #include <sdbusplus/bus.hpp> |
| 23 | #include <sdeventplus/source/signal.hpp> |
| 24 | |
| 25 | #include <filesystem> |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 26 | #include <format> |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 27 | #include <fstream> |
| 28 | |
| 29 | namespace phosphor::fan |
| 30 | { |
| 31 | |
| 32 | namespace fs = std::filesystem; |
| 33 | using json = nlohmann::json; |
| 34 | using namespace phosphor::logging; |
| 35 | |
| 36 | constexpr auto confOverridePath = "/etc/phosphor-fan-presence"; |
| 37 | constexpr auto confBasePath = "/usr/share/phosphor-fan-presence"; |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 38 | constexpr auto confCompatServ = "xyz.openbmc_project.EntityManager"; |
Matthew Barth | fcbdc0e | 2020-10-28 14:11:07 -0500 | [diff] [blame] | 39 | constexpr auto confCompatIntf = |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 40 | "xyz.openbmc_project.Inventory.Decorator.Compatible"; |
Matthew Barth | fcbdc0e | 2020-10-28 14:11:07 -0500 | [diff] [blame] | 41 | constexpr auto confCompatProp = "Names"; |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 42 | |
Matthew Barth | 6eb603e | 2021-09-01 09:01:57 -0500 | [diff] [blame] | 43 | /** |
| 44 | * @class NoConfigFound - A no JSON configuration found exception |
| 45 | * |
| 46 | * A no JSON configuration found exception that is used to denote that a JSON |
| 47 | * configuration has not been found yet. |
| 48 | */ |
| 49 | class NoConfigFound : public std::runtime_error |
| 50 | { |
| 51 | public: |
| 52 | NoConfigFound() = delete; |
| 53 | NoConfigFound(const NoConfigFound&) = delete; |
| 54 | NoConfigFound(NoConfigFound&&) = delete; |
| 55 | NoConfigFound& operator=(const NoConfigFound&) = delete; |
| 56 | NoConfigFound& operator=(NoConfigFound&&) = delete; |
| 57 | ~NoConfigFound() = default; |
| 58 | |
| 59 | /** |
| 60 | * @brief No JSON configuration found exception object |
| 61 | * |
| 62 | * When attempting to find the JSON configuration file(s), a NoConfigFound |
| 63 | * exception can be thrown to denote that at that time finding/loading the |
| 64 | * JSON configuration file(s) for a fan application failed. Details on what |
| 65 | * application and JSON configuration file that failed to be found will be |
| 66 | * logged resulting in the application being terminated. |
| 67 | * |
| 68 | * @param[in] details - Additional details |
| 69 | */ |
| 70 | NoConfigFound(const std::string& appName, const std::string& fileName) : |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 71 | std::runtime_error(std::format("JSON configuration not found [Could " |
Matthew Barth | 6eb603e | 2021-09-01 09:01:57 -0500 | [diff] [blame] | 72 | "not find fan {} conf file {}]", |
| 73 | appName, fileName) |
| 74 | .c_str()) |
| 75 | {} |
| 76 | }; |
| 77 | |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 78 | class JsonConfig |
| 79 | { |
| 80 | public: |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 81 | /** |
Matthew Barth | d80c875 | 2021-06-01 14:46:02 -0500 | [diff] [blame] | 82 | * @brief Get the object paths with the compatible interface |
| 83 | * |
| 84 | * Retrieve all the object paths implementing the compatible interface for |
| 85 | * configuration file loading. |
| 86 | */ |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 87 | std::vector<std::string>& getCompatObjPaths() |
Matthew Barth | d80c875 | 2021-06-01 14:46:02 -0500 | [diff] [blame] | 88 | { |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 89 | using SubTreeMap = |
| 90 | std::map<std::string, |
| 91 | std::map<std::string, std::vector<std::string>>>; |
| 92 | SubTreeMap subTreeObjs = util::SDBusPlus::getSubTreeRaw( |
Matthew Barth | d80c875 | 2021-06-01 14:46:02 -0500 | [diff] [blame] | 93 | util::SDBusPlus::getBus(), "/", confCompatIntf, 0); |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 94 | |
| 95 | static std::vector<std::string> paths; |
| 96 | for (auto& [path, serviceMap] : subTreeObjs) |
| 97 | { |
| 98 | // Only save objects under confCompatServ |
| 99 | if (serviceMap.find(confCompatServ) != serviceMap.end()) |
| 100 | { |
| 101 | paths.emplace_back(path); |
| 102 | } |
| 103 | } |
Matthew Barth | d80c875 | 2021-06-01 14:46:02 -0500 | [diff] [blame] | 104 | return paths; |
| 105 | } |
| 106 | |
| 107 | /** |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 108 | * @brief Constructor |
| 109 | * |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 110 | * Attempts to set the list of compatible values from the compatible |
| 111 | * interface and call the fan app's function to load its config file(s). If |
| 112 | * the compatible interface is not found, it subscribes to the |
| 113 | * interfacesAdded signal for that interface on the compatible service |
| 114 | * defined above. |
| 115 | * |
| 116 | * @param[in] func - Fan app function to call to load its config file(s) |
| 117 | */ |
| 118 | JsonConfig(std::function<void()> func) : _loadFunc(func) |
| 119 | { |
Matthew Barth | 8d1193c | 2021-09-14 10:36:06 -0500 | [diff] [blame] | 120 | std::vector<std::string> compatObjPaths; |
| 121 | |
Patrick Williams | 3ea9ec2 | 2021-11-19 12:21:08 -0600 | [diff] [blame] | 122 | _match = std::make_unique<sdbusplus::bus::match_t>( |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 123 | util::SDBusPlus::getBus(), |
| 124 | sdbusplus::bus::match::rules::interfacesAdded() + |
| 125 | sdbusplus::bus::match::rules::sender(confCompatServ), |
| 126 | std::bind(&JsonConfig::compatIntfAdded, this, |
| 127 | std::placeholders::_1)); |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 128 | |
Matthew Barth | 8d1193c | 2021-09-14 10:36:06 -0500 | [diff] [blame] | 129 | try |
| 130 | { |
| 131 | compatObjPaths = getCompatObjPaths(); |
| 132 | } |
| 133 | catch (const util::DBusMethodError&) |
| 134 | { |
| 135 | // Compatible interface does not exist on any dbus object yet |
| 136 | } |
| 137 | |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 138 | if (!compatObjPaths.empty()) |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 139 | { |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 140 | for (auto& path : compatObjPaths) |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 141 | { |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 142 | try |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 143 | { |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 144 | // Retrieve json config compatible relative path |
| 145 | // locations (last one found will be what's used if more |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 146 | // than one dbus object implementing the compatible |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 147 | // interface exists). |
| 148 | _confCompatValues = |
| 149 | util::SDBusPlus::getProperty<std::vector<std::string>>( |
| 150 | util::SDBusPlus::getBus(), path, confCompatIntf, |
| 151 | confCompatProp); |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 152 | } |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 153 | catch (const util::DBusError&) |
| 154 | { |
| 155 | // Compatible property unavailable on this dbus object |
| 156 | // path's compatible interface, ignore |
| 157 | } |
| 158 | } |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 159 | try |
| 160 | { |
| 161 | _loadFunc(); |
| 162 | } |
| 163 | catch (const NoConfigFound&) |
| 164 | { |
| 165 | // The Decorator.Compatible interface is not unique to one |
| 166 | // single object on DBus so this should not be treated as a |
| 167 | // failure, wait for interfacesAdded signal. |
| 168 | } |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 169 | } |
| 170 | else |
| 171 | { |
| 172 | // Check if required config(s) are found not needing the |
| 173 | // compatible interface, otherwise this is intended to catch the |
| 174 | // exception thrown by the getConfFile function when the |
| 175 | // required config file was not found. This would then result in |
| 176 | // waiting for the compatible interfacesAdded signal |
| 177 | try |
| 178 | { |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 179 | _loadFunc(); |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 180 | } |
Matthew Barth | 6eb603e | 2021-09-01 09:01:57 -0500 | [diff] [blame] | 181 | catch (const NoConfigFound&) |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 182 | { |
Matthew Barth | 1689cb6 | 2021-08-27 12:34:36 -0500 | [diff] [blame] | 183 | // Wait for compatible interfacesAdded signal |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 184 | } |
| 185 | } |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 186 | } |
| 187 | |
| 188 | /** |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 189 | * @brief InterfacesAdded callback function for the compatible interface. |
| 190 | * |
| 191 | * @param[in] msg - The D-Bus message contents |
| 192 | * |
| 193 | * If the compatible interface is found, it uses the compatible property on |
| 194 | * the interface to set the list of compatible values to be used when |
| 195 | * attempting to get a configuration file. Once the list of compatible |
| 196 | * values has been updated, it calls the load function. |
| 197 | */ |
Patrick Williams | cb356d4 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 198 | void compatIntfAdded(sdbusplus::message_t& msg) |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 199 | { |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 200 | if (!_compatibleName.empty()) |
| 201 | { |
| 202 | // Do not process the interfaceAdded signal if one compatible name |
| 203 | // has been successfully used to get config files |
| 204 | return; |
| 205 | } |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 206 | sdbusplus::message::object_path op; |
| 207 | std::map<std::string, |
| 208 | std::map<std::string, std::variant<std::vector<std::string>>>> |
| 209 | intfProps; |
| 210 | |
| 211 | msg.read(op, intfProps); |
| 212 | |
| 213 | if (intfProps.find(confCompatIntf) == intfProps.end()) |
| 214 | { |
| 215 | return; |
| 216 | } |
| 217 | |
| 218 | const auto& props = intfProps.at(confCompatIntf); |
| 219 | // Only one dbus object with the compatible interface is used at a time |
| 220 | _confCompatValues = |
| 221 | std::get<std::vector<std::string>>(props.at(confCompatProp)); |
| 222 | _loadFunc(); |
| 223 | } |
| 224 | |
| 225 | /** |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 226 | * Get the json configuration file. The first location found to contain |
| 227 | * the json config file for the given fan application is used from the |
| 228 | * following locations in order. |
| 229 | * 1.) From the confOverridePath location |
Matthew Barth | b67089b | 2021-06-10 14:32:00 -0500 | [diff] [blame] | 230 | * 2.) From the default confBasePath location |
| 231 | * 3.) From config file found using an entry from a list obtained from an |
Matthew Barth | fcbdc0e | 2020-10-28 14:11:07 -0500 | [diff] [blame] | 232 | * interface's property as a relative path extension on the base path where: |
| 233 | * interface = Interface set in confCompatIntf with the property |
| 234 | * property = Property set in confCompatProp containing a list of |
| 235 | * subdirectories in priority order to find a config |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 236 | * |
| 237 | * @brief Get the configuration file to be used |
| 238 | * |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 239 | * @param[in] appName - The phosphor-fan-presence application name |
| 240 | * @param[in] fileName - Application's configuration file's name |
Matthew Barth | b599102 | 2020-08-05 11:08:50 -0500 | [diff] [blame] | 241 | * @param[in] isOptional - Config file is optional, default to 'false' |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 242 | * |
| 243 | * @return filesystem path |
| 244 | * The filesystem path to the configuration file to use |
| 245 | */ |
Mike Capps | 808d7fe | 2022-06-13 10:12:16 -0400 | [diff] [blame] | 246 | static const fs::path getConfFile(const std::string& appName, |
Matthew Barth | b599102 | 2020-08-05 11:08:50 -0500 | [diff] [blame] | 247 | const std::string& fileName, |
| 248 | bool isOptional = false) |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 249 | { |
| 250 | // Check override location |
| 251 | fs::path confFile = fs::path{confOverridePath} / appName / fileName; |
| 252 | if (fs::exists(confFile)) |
| 253 | { |
| 254 | return confFile; |
| 255 | } |
| 256 | |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 257 | // If the default file is there, use it |
Matthew Barth | fcbdc0e | 2020-10-28 14:11:07 -0500 | [diff] [blame] | 258 | confFile = fs::path{confBasePath} / appName / fileName; |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 259 | if (fs::exists(confFile)) |
| 260 | { |
| 261 | return confFile; |
| 262 | } |
Matthew Barth | fcbdc0e | 2020-10-28 14:11:07 -0500 | [diff] [blame] | 263 | |
Matthew Barth | b67089b | 2021-06-10 14:32:00 -0500 | [diff] [blame] | 264 | // Look for a config file at each entry relative to the base |
| 265 | // path and use the first one found |
Patrick Williams | dfddd64 | 2024-08-16 15:21:51 -0400 | [diff] [blame] | 266 | auto it = std::find_if( |
| 267 | _confCompatValues.begin(), _confCompatValues.end(), |
| 268 | [&confFile, &appName, &fileName](const auto& value) { |
| 269 | confFile = fs::path{confBasePath} / appName / value / fileName; |
| 270 | _compatibleName = value; |
| 271 | return fs::exists(confFile); |
| 272 | }); |
Matthew Barth | b67089b | 2021-06-10 14:32:00 -0500 | [diff] [blame] | 273 | if (it == _confCompatValues.end()) |
| 274 | { |
| 275 | confFile.clear(); |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 276 | _compatibleName.clear(); |
Matthew Barth | b67089b | 2021-06-10 14:32:00 -0500 | [diff] [blame] | 277 | } |
| 278 | |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 279 | if (confFile.empty() && !isOptional) |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 280 | { |
Matthew Barth | 6eb603e | 2021-09-01 09:01:57 -0500 | [diff] [blame] | 281 | throw NoConfigFound(appName, fileName); |
Matthew Barth | b599102 | 2020-08-05 11:08:50 -0500 | [diff] [blame] | 282 | } |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 283 | |
| 284 | return confFile; |
| 285 | } |
| 286 | |
| 287 | /** |
| 288 | * @brief Load the JSON config file |
| 289 | * |
| 290 | * @param[in] confFile - File system path of the configuration file to load |
| 291 | * |
| 292 | * @return Parsed JSON object |
| 293 | * The parsed JSON configuration file object |
| 294 | */ |
| 295 | static const json load(const fs::path& confFile) |
| 296 | { |
| 297 | std::ifstream file; |
| 298 | json jsonConf; |
| 299 | |
Matthew Barth | b599102 | 2020-08-05 11:08:50 -0500 | [diff] [blame] | 300 | if (!confFile.empty() && fs::exists(confFile)) |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 301 | { |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 302 | log<level::INFO>( |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 303 | std::format("Loading configuration from {}", confFile.string()) |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 304 | .c_str()); |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 305 | file.open(confFile); |
| 306 | try |
| 307 | { |
Matthew Barth | de72d5d | 2021-07-16 10:39:42 -0500 | [diff] [blame] | 308 | // Enable ignoring `//` or `/* */` comments |
| 309 | jsonConf = json::parse(file, nullptr, true, true); |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 310 | } |
Patrick Williams | ddb773b | 2021-10-06 11:24:49 -0500 | [diff] [blame] | 311 | catch (const std::exception& e) |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 312 | { |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 313 | log<level::ERR>( |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 314 | std::format( |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 315 | "Failed to parse JSON config file: {}, error: {}", |
| 316 | confFile.string(), e.what()) |
| 317 | .c_str()); |
| 318 | throw std::runtime_error( |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 319 | std::format( |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 320 | "Failed to parse JSON config file: {}, error: {}", |
| 321 | confFile.string(), e.what()) |
| 322 | .c_str()); |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 323 | } |
| 324 | } |
| 325 | else |
| 326 | { |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 327 | log<level::ERR>(std::format("Unable to open JSON config file: {}", |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 328 | confFile.string()) |
| 329 | .c_str()); |
| 330 | throw std::runtime_error( |
Patrick Williams | fbf4703 | 2023-07-17 12:27:34 -0500 | [diff] [blame] | 331 | std::format("Unable to open JSON config file: {}", |
Matthew Barth | 1826c73 | 2020-08-28 08:40:59 -0500 | [diff] [blame] | 332 | confFile.string()) |
| 333 | .c_str()); |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 334 | } |
| 335 | |
| 336 | return jsonConf; |
| 337 | } |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 338 | |
Matt Spinler | d4c7fb7 | 2021-11-09 16:03:50 -0600 | [diff] [blame] | 339 | /** |
| 340 | * @brief Return the compatible values property |
| 341 | * |
| 342 | * @return const std::vector<std::string>& - The values |
| 343 | */ |
| 344 | static const std::vector<std::string>& getCompatValues() |
| 345 | { |
| 346 | return _confCompatValues; |
| 347 | } |
| 348 | |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 349 | private: |
Matthew Barth | b370ab3 | 2021-06-10 14:38:02 -0500 | [diff] [blame] | 350 | /* Load function to call for a fan app to load its config file(s). */ |
| 351 | std::function<void()> _loadFunc; |
| 352 | |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 353 | /** |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 354 | * @brief The interfacesAdded match that is used to wait |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 355 | * for the Inventory.Decorator.Compatible interface to show up. |
Matt Spinler | 59850df | 2021-01-06 16:56:06 -0600 | [diff] [blame] | 356 | */ |
Patrick Williams | 3ea9ec2 | 2021-11-19 12:21:08 -0600 | [diff] [blame] | 357 | std::unique_ptr<sdbusplus::bus::match_t> _match; |
Matthew Barth | b67089b | 2021-06-10 14:32:00 -0500 | [diff] [blame] | 358 | |
| 359 | /** |
| 360 | * @brief List of compatible values from the compatible interface |
| 361 | * |
| 362 | * Only supports a single instance of the compatible interface on a dbus |
| 363 | * object. If more than one dbus object exists with the compatible |
| 364 | * interface, the last one found will be the list of compatible values used. |
| 365 | */ |
| 366 | inline static std::vector<std::string> _confCompatValues; |
Chau Ly | b99ce0e | 2023-11-30 08:06:00 +0000 | [diff] [blame] | 367 | |
| 368 | /** |
| 369 | * @brief The compatible value that is currently used to load configuration |
| 370 | * |
| 371 | * The value extracted from the achieved property value list that is used |
| 372 | * as a sub-folder to append to the configuration location and really |
| 373 | * contains the configruation files |
| 374 | */ |
| 375 | |
| 376 | inline static std::string _compatibleName; |
Matthew Barth | 11547c9 | 2020-05-05 10:34:27 -0500 | [diff] [blame] | 377 | }; |
| 378 | |
| 379 | } // namespace phosphor::fan |