blob: 78963a44f623f9cf785e7a2644067b00b729b069 [file] [log] [blame]
Matthew Bartha227a162020-08-05 10:51:45 -05001/**
Mike Cappsb2e9a4f2022-06-13 10:15:42 -04002 * Copyright © 2022 IBM Corporation
Matthew Bartha227a162020-08-05 10:51:45 -05003 *
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
Matthew Barthd9cb63b2021-03-24 14:36:49 -050018#include "action.hpp"
Matthew Barth44ab7692021-03-26 11:40:10 -050019#include "event.hpp"
Matthew Barthd9cb63b2021-03-24 14:36:49 -050020#include "group.hpp"
Matthew Barthacd737c2021-03-04 11:04:01 -060021#include "json_config.hpp"
Matthew Barth48f44da2021-05-27 15:43:34 -050022#include "power_state.hpp"
Matthew Barth06764942021-03-04 09:28:40 -060023#include "profile.hpp"
Matthew Barth9403a212021-05-17 09:31:50 -050024#include "sdbusplus.hpp"
Matthew Barthbd52ed02022-02-07 15:15:10 -060025#include "utils/flight_recorder.hpp"
Matthew Barthacd737c2021-03-04 11:04:01 -060026#include "zone.hpp"
Matthew Barth06764942021-03-04 09:28:40 -060027
Matthew Barth68ac0042021-06-01 15:38:36 -050028#include <fmt/format.h>
29
Matthew Bartha227a162020-08-05 10:51:45 -050030#include <nlohmann/json.hpp>
Matthew Barth68ac0042021-06-01 15:38:36 -050031#include <phosphor-logging/log.hpp>
Matthew Bartha227a162020-08-05 10:51:45 -050032#include <sdbusplus/bus.hpp>
Matthew Barth1542fb52021-06-10 14:09:09 -050033#include <sdbusplus/server/manager.hpp>
Matthew Barth06764942021-03-04 09:28:40 -060034#include <sdeventplus/event.hpp>
Matt Spinler2fc0a352021-10-04 15:10:57 -050035#include <sdeventplus/source/event.hpp>
Matthew Barthd9cb63b2021-03-24 14:36:49 -050036#include <sdeventplus/utility/timer.hpp>
37
38#include <chrono>
39#include <map>
40#include <memory>
41#include <optional>
42#include <tuple>
43#include <utility>
44#include <vector>
Matthew Bartha227a162020-08-05 10:51:45 -050045
46namespace phosphor::fan::control::json
47{
48
49using json = nlohmann::json;
Matthew Barth68ac0042021-06-01 15:38:36 -050050using namespace phosphor::logging;
Matthew Bartha227a162020-08-05 10:51:45 -050051
Matthew Barthacd737c2021-03-04 11:04:01 -060052/* Application name to be appended to the path for loading a JSON config file */
53constexpr auto confAppName = "control";
54
Matthew Barthd9cb63b2021-03-24 14:36:49 -050055/* Type of timers supported */
56enum class TimerType
57{
58 oneshot,
59 repeating,
60};
Mike Cappsb2e9a4f2022-06-13 10:15:42 -040061
Matthew Barthd9cb63b2021-03-24 14:36:49 -050062/**
63 * Package of data required when a timer expires
64 * Tuple constructed of:
65 * std::string = Timer package unique identifier
Matthew Barthd9cb63b2021-03-24 14:36:49 -050066 * std::vector<std::unique_ptr<ActionBase>> = List of pointers to actions
67 * that run when the timer expires
Matt Spinlerade0c372021-10-28 16:09:44 -050068 * const std::vector<Group> = List of groups
69 * bool = If groups should be preloaded before actions are run
Matthew Barthd9cb63b2021-03-24 14:36:49 -050070 */
Matthew Barth00f6aa02021-04-09 10:49:47 -050071using TimerPkg =
Matt Spinlerade0c372021-10-28 16:09:44 -050072 std::tuple<std::string, std::vector<std::unique_ptr<ActionBase>>&,
73 const std::vector<Group>&, bool>;
Matthew Barthd9cb63b2021-03-24 14:36:49 -050074/**
75 * Data associated with a running timer that's used when it expires
76 * Pair constructed of:
77 * TimerType = Type of timer to manage expired timer instances
78 * TimerPkg = Package of data required when the timer expires
79 */
80using TimerData = std::pair<TimerType, TimerPkg>;
81/* Dbus event timer */
82using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
83
Matthew Barthebabc042021-05-13 15:38:58 -050084/* Dbus signal object */
85constexpr auto Path = 0;
86constexpr auto Intf = 1;
87constexpr auto Prop = 2;
88using SignalObject = std::tuple<std::string, std::string, std::string>;
89/* Dbus signal actions */
Matt Spinlerd0ba86a2021-11-09 10:09:13 -060090using TriggerActions =
Matthew Barthc3a69082021-11-15 14:32:48 -060091 std::vector<std::reference_wrapper<std::unique_ptr<ActionBase>>>;
Matthew Barthebabc042021-05-13 15:38:58 -050092/**
93 * Signal handler function that handles parsing a signal's message for a
94 * particular signal object and stores the results in the manager
95 */
96using SignalHandler = std::function<bool(sdbusplus::message::message&,
97 const SignalObject&, Manager&)>;
98/**
99 * Package of data required when a signal is received
100 * Tuple constructed of:
101 * SignalHandler = Signal handler function
102 * SignalObject = Dbus signal object
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600103 * TriggerActions = List of actions that are run when the signal is received
Matthew Barthebabc042021-05-13 15:38:58 -0500104 */
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600105using SignalPkg = std::tuple<SignalHandler, SignalObject, TriggerActions>;
Matthew Barthebabc042021-05-13 15:38:58 -0500106/**
107 * Data associated to a subscribed signal
108 * Tuple constructed of:
Matthew Barthc024d782021-11-09 16:15:49 -0600109 * std::unique_ptr<std::vector<SignalPkg>> =
110 * Pointer to list of the signal's packages
Patrick Williams3ea9ec22021-11-19 12:21:08 -0600111 * std::unique_ptr<sdbusplus::bus::match_t> =
Matthew Barthebabc042021-05-13 15:38:58 -0500112 * Pointer to match holding the subscription to a signal
113 */
Matthew Barthc024d782021-11-09 16:15:49 -0600114using SignalData = std::tuple<std::unique_ptr<std::vector<SignalPkg>>,
Patrick Williams3ea9ec22021-11-19 12:21:08 -0600115 std::unique_ptr<sdbusplus::bus::match_t>>;
Matthew Barthebabc042021-05-13 15:38:58 -0500116
Matthew Bartha227a162020-08-05 10:51:45 -0500117/**
Mike Capps1a19ead2021-10-22 09:15:14 -0400118 * Package of data from a D-Bus call to get managed objects
119 * Tuple constructed of:
120 * std::map<Path, // D-Bus Path
121 * std::map<Intf, // D-Bus Interface
122 * std::map<Property, // D-Bus Property
123 * std::variant>>> // Variant value of that property
124 */
125using Path_v = sdbusplus::message::object_path;
126using Intf_v = std::string;
127using Prop_v = std::string;
128using ManagedObjects =
129 std::map<Path_v, std::map<Intf_v, std::map<Prop_v, PropertyVariantType>>>;
130
131/**
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600132 * Actions to run when a parameter trigger runs.
133 */
134using ParamTriggerData = std::vector<
135 std::reference_wrapper<const std::vector<std::unique_ptr<ActionBase>>>>;
136
137/**
Matthew Bartha227a162020-08-05 10:51:45 -0500138 * @class Manager - Represents the fan control manager's configuration
139 *
140 * A fan control manager configuration is optional, therefore the "manager.json"
141 * file is also optional. The manager configuration is used to populate
142 * fan control's manager parameters which are used in how the application
143 * operates, not in how the fans are controlled.
144 *
145 * When no manager configuration exists, the fan control application starts,
146 * processes any configured events and then begins controlling fans according
147 * to those events.
148 */
149class Manager
150{
151 public:
152 Manager() = delete;
153 Manager(const Manager&) = delete;
154 Manager(Manager&&) = delete;
155 Manager& operator=(const Manager&) = delete;
156 Manager& operator=(Manager&&) = delete;
157 ~Manager() = default;
158
159 /**
160 * Constructor
161 * Parses and populates the fan control manager attributes from a json file
162 *
Matthew Barth06764942021-03-04 09:28:40 -0600163 * @param[in] event - sdeventplus event loop
Matthew Bartha227a162020-08-05 10:51:45 -0500164 */
Matthew Barth9403a212021-05-17 09:31:50 -0500165 Manager(const sdeventplus::Event& event);
Matthew Bartha227a162020-08-05 10:51:45 -0500166
167 /**
Matthew Barthe91ac862021-05-25 16:22:17 -0500168 * @brief Callback function to handle receiving a HUP signal to reload the
169 * JSON configurations.
170 */
171 void sighupHandler(sdeventplus::source::Signal&,
172 const struct signalfd_siginfo*);
173
174 /**
Matt Spinler2fc0a352021-10-04 15:10:57 -0500175 * @brief Callback function to handle receiving a USR1 signal to dump
176 * the flight recorder.
177 */
178 void sigUsr1Handler(sdeventplus::source::Signal&,
179 const struct signalfd_siginfo*);
180
181 /**
Matthew Barthacd737c2021-03-04 11:04:01 -0600182 * @brief Get the active profiles of the system where an empty list
183 * represents that only configuration entries without a profile defined will
184 * be loaded.
185 *
186 * @return - The list of active profiles
187 */
188 static const std::vector<std::string>& getActiveProfiles();
189
190 /**
191 * @brief Load the configuration of a given JSON class object based on the
192 * active profiles
193 *
Matthew Barthacd737c2021-03-04 11:04:01 -0600194 * @param[in] isOptional - JSON configuration file is optional or not
Matthew Barth603ef162021-03-24 15:34:53 -0500195 * @param[in] args - Arguments to be forwarded to each instance of `T`
Matthew Barthe6d1f782021-05-14 12:52:20 -0500196 * (*Note that a sdbusplus bus object is required as the first argument)
Matthew Barthacd737c2021-03-04 11:04:01 -0600197 *
198 * @return Map of configuration entries
199 * Map of configuration keys to their corresponding configuration object
200 */
Matthew Barth603ef162021-03-24 15:34:53 -0500201 template <typename T, typename... Args>
Matthew Barthe6d1f782021-05-14 12:52:20 -0500202 static std::map<configKey, std::unique_ptr<T>> getConfig(bool isOptional,
203 Args&&... args)
Matthew Barthacd737c2021-03-04 11:04:01 -0600204 {
205 std::map<configKey, std::unique_ptr<T>> config;
206
Mike Capps808d7fe2022-06-13 10:12:16 -0400207 auto confFile = fan::JsonConfig::getConfFile(
208 confAppName, T::confFileName, isOptional);
209
Matthew Barthacd737c2021-03-04 11:04:01 -0600210 if (!confFile.empty())
211 {
Matthew Barthbd52ed02022-02-07 15:15:10 -0600212 FlightRecorder::instance().log(
213 "main", fmt::format("Loading configuration from {}",
214 confFile.string()));
Matthew Barthacd737c2021-03-04 11:04:01 -0600215 for (const auto& entry : fan::JsonConfig::load(confFile))
216 {
217 if (entry.contains("profiles"))
218 {
219 std::vector<std::string> profiles;
220 for (const auto& profile : entry["profiles"])
221 {
222 profiles.emplace_back(
223 profile.template get<std::string>());
224 }
225 // Do not create the object if its profiles are not in the
226 // list of active profiles
Matthew Barth42428052021-03-30 12:50:59 -0500227 if (!profiles.empty() &&
228 !std::any_of(profiles.begin(), profiles.end(),
Matthew Barthacd737c2021-03-04 11:04:01 -0600229 [](const auto& name) {
230 return std::find(
231 getActiveProfiles().begin(),
232 getActiveProfiles().end(),
233 name) !=
234 getActiveProfiles().end();
235 }))
236 {
237 continue;
238 }
239 }
Matthew Barth603ef162021-03-24 15:34:53 -0500240 auto obj =
241 std::make_unique<T>(entry, std::forward<Args>(args)...);
Matthew Barthacd737c2021-03-04 11:04:01 -0600242 config.emplace(
243 std::make_pair(obj->getName(), obj->getProfiles()),
244 std::move(obj));
245 }
Matthew Barth68ac0042021-06-01 15:38:36 -0500246 log<level::INFO>(
247 fmt::format("Configuration({}) loaded successfully",
248 T::confFileName)
249 .c_str());
Matthew Barthbd52ed02022-02-07 15:15:10 -0600250 FlightRecorder::instance().log(
251 "main", fmt::format("Configuration({}) loaded successfully",
252 T::confFileName));
Matthew Barthacd737c2021-03-04 11:04:01 -0600253 }
254 return config;
255 }
256
257 /**
Matthew Barth0206c722021-03-30 15:20:05 -0500258 * @brief Check if the given input configuration key matches with another
259 * configuration key that it's to be included in
260 *
261 * @param[in] input - Config key to be included in another config object
262 * @param[in] comp - Config key of the config object to compare with
263 *
264 * @return Whether the configuration object should be included
265 */
266 static bool inConfig(const configKey& input, const configKey& comp);
267
268 /**
Matthew Barth12cb1252021-03-08 16:47:30 -0600269 * @brief Check if the given path and inteface is owned by a dbus service
270 *
271 * @param[in] path - Dbus object path
272 * @param[in] intf - Dbus object interface
273 *
274 * @return - Whether the service has an owner for the given object path and
275 * interface
276 */
277 static bool hasOwner(const std::string& path, const std::string& intf);
278
279 /**
Matthew Barth6d8e2d32022-02-01 16:47:08 -0600280 * @brief Sets the dbus service owner state for all entries in the _servTree
281 * cache and removes associated objects from the _objects cache
282 *
283 * @param[in] serv - Dbus service name
284 * @param[in] hasOwner - Dbus service owner state
285 */
286 void setOwner(const std::string& serv, bool hasOwner);
287
288 /**
Matthew Barth4ca87fa2021-04-14 11:31:13 -0500289 * @brief Sets the dbus service owner state of a given object
290 *
291 * @param[in] path - Dbus object path
292 * @param[in] serv - Dbus service name
293 * @param[in] intf - Dbus object interface
294 * @param[in] isOwned - Dbus service owner state
295 */
296 void setOwner(const std::string& path, const std::string& serv,
297 const std::string& intf, bool isOwned);
298
299 /**
300 * @brief Add a set of services for a path and interface by retrieving all
301 * the path subtrees to the given depth from root for the interface
302 *
Matthew Barth4ca87fa2021-04-14 11:31:13 -0500303 * @param[in] intf - Interface to add services for
304 * @param[in] depth - Depth of tree traversal from root path
305 *
306 * @throws - DBusMethodError
307 * Throws a DBusMethodError when the `getSubTree` method call fails
308 */
Matthew Barth98f6fc12021-04-16 10:48:37 -0500309 static void addServices(const std::string& intf, int32_t depth);
Matthew Barth4ca87fa2021-04-14 11:31:13 -0500310
311 /**
312 * @brief Get the service for a given path and interface from cached
313 * dataset and attempt to add all the services for the given path/interface
314 * when it's not found
315 *
316 * @param[in] path - Path to get service for
317 * @param[in] intf - Interface to get service for
318 *
319 * @return - The now cached service name
320 *
321 * @throws - DBusMethodError
322 * Ripples up a DBusMethodError exception from calling addServices
323 */
324 static const std::string& getService(const std::string& path,
325 const std::string& intf);
326
327 /**
Matthew Barthf41e9472021-05-13 16:38:06 -0500328 * @brief Get all the object paths for a given service and interface from
329 * the cached dataset and try to add all the services for the given
330 * interface when no paths are found and then attempt to get all the object
331 * paths again
332 *
333 * @param[in] serv - Service name to get paths for
334 * @param[in] intf - Interface to get paths for
335 *
336 * @return The cached object paths
337 */
338 std::vector<std::string> getPaths(const std::string& serv,
339 const std::string& intf);
340
341 /**
342 * @brief Add objects to the cached dataset by first using
343 * `getManagedObjects` for the same service providing the given path and
344 * interface or just add the single object of the given path, interface, and
345 * property if that fails.
346 *
347 * @param[in] path - Dbus object's path
348 * @param[in] intf - Dbus object's interface
349 * @param[in] prop - Dbus object's property
350 *
351 * @throws - DBusMethodError
352 * Throws a DBusMethodError when the the service is failed to be found or
353 * when the `getManagedObjects` method call fails
354 */
355 void addObjects(const std::string& path, const std::string& intf,
Matt Spinler9ac325c2022-04-25 14:13:49 -0500356 const std::string& prop)
357 {
358 addObjects(path, intf, prop, std::string{});
359 }
360
361 /**
362 * @copydoc Manager::addObjects()
363 *
364 * If the service is known, then it can be used to add all objects
365 * in that service with the interface passed in to the cache instead of
366 * having to look it up. This is done so objects can still be
367 * added even when the D-Bus path passed in doesn't exist so it
368 * can't be used to get a service name.
369 *
370 * @param[in] path - Dbus object's path
371 * @param[in] intf - Dbus object's interface
372 * @param[in] prop - Dbus object's property
373 * @param[in] serviceName - The service of the path/intf/prop if known
374 */
375 void addObjects(const std::string& path, const std::string& intf,
376 const std::string& prop, const std::string& serviceName);
Matthew Barthf41e9472021-05-13 16:38:06 -0500377
378 /**
379 * @brief Get an object's property value
380 *
381 * @param[in] path - Dbus object's path
382 * @param[in] intf - Dbus object's interface
383 * @param[in] prop - Dbus object's property
384 */
385 const std::optional<PropertyVariantType>
386 getProperty(const std::string& path, const std::string& intf,
387 const std::string& prop);
388
389 /**
Matthew Barthbaeeb8f2021-05-13 16:03:54 -0500390 * @brief Set/update an object's property value
391 *
392 * @param[in] path - Dbus object's path
393 * @param[in] intf - Dbus object's interface
394 * @param[in] prop - Dbus object's property
395 * @param[in] value - Dbus object's property value
396 */
397 void setProperty(const std::string& path, const std::string& intf,
Mike Capps1a19ead2021-10-22 09:15:14 -0400398 const std::string& prop, PropertyVariantType value);
Matthew Barthbaeeb8f2021-05-13 16:03:54 -0500399
400 /**
Matthew Barthc2691402021-05-13 16:20:32 -0500401 * @brief Remove an object's interface
402 *
403 * @param[in] path - Dbus object's path
404 * @param[in] intf - Dbus object's interface
405 */
406 inline void removeInterface(const std::string& path,
407 const std::string& intf)
408 {
409 auto itPath = _objects.find(path);
410 if (itPath != std::end(_objects))
411 {
412 _objects[path].erase(intf);
413 }
414 }
415
416 /**
Matthew Barth07fecfc2021-01-29 09:04:43 -0600417 * @brief Get the object's property value as a variant
418 *
419 * @param[in] path - Path of the object containing the property
420 * @param[in] intf - Interface name containing the property
421 * @param[in] prop - Name of property
422 *
423 * @return - The object's property value as a variant
424 */
425 static inline auto getObjValueVariant(const std::string& path,
426 const std::string& intf,
427 const std::string& prop)
428 {
429 return _objects.at(path).at(intf).at(prop);
430 };
431
432 /**
Matthew Barthd9cb63b2021-03-24 14:36:49 -0500433 * @brief Add a dbus timer
434 *
435 * @param[in] type - Type of timer
436 * @param[in] interval - Timer interval in microseconds
437 * @param[in] pkg - Packaged data for when timer expires
438 */
439 void addTimer(const TimerType type,
440 const std::chrono::microseconds interval,
441 std::unique_ptr<TimerPkg> pkg);
442
443 /**
444 * @brief Callback when a timer expires
445 *
446 * @param[in] data - Data to be used when the timer expired
447 */
448 void timerExpired(TimerData& data);
449
450 /**
Matthew Barthebabc042021-05-13 15:38:58 -0500451 * @brief Get the signal data for a given match string
452 *
453 * @param[in] sigMatch - Signal match string
454 *
455 * @return - Reference to the signal data for the given match string
456 */
457 std::vector<SignalData>& getSignal(const std::string& sigMatch)
458 {
459 return _signals[sigMatch];
460 }
461
462 /**
463 * @brief Handle receiving signals
464 *
465 * @param[in] msg - Signal message containing the signal's data
466 * @param[in] pkgs - Signal packages associated to the signal being handled
467 */
468 void handleSignal(sdbusplus::message::message& msg,
Matthew Barthc024d782021-11-09 16:15:49 -0600469 const std::vector<SignalPkg>* pkgs);
Matthew Barthebabc042021-05-13 15:38:58 -0500470
471 /**
Matthew Bartheebde062021-04-14 12:48:52 -0500472 * @brief Get the sdbusplus bus object
473 */
474 inline auto& getBus()
475 {
476 return _bus;
477 }
478
479 /**
Matthew Barth48f44da2021-05-27 15:43:34 -0500480 * @brief Is the power state on
481 *
482 * @return Current power state of the system
483 */
484 inline bool isPowerOn() const
485 {
486 return _powerState->isPowerOn();
487 }
488
Matthew Barth3770a1d2021-06-10 15:09:37 -0500489 /**
490 * @brief Load all the fan control JSON configuration files
491 *
492 * This is where all the fan control JSON configuration files are parsed and
493 * loaded into their associated objects. Anything that needs to be done when
494 * the Manager object is constructed or handling a SIGHUP to reload the
495 * configurations needs to be done here.
496 */
497 void load();
498
Matt Spinlerd76351b2021-08-05 16:23:09 -0500499 /**
500 * @brief Sets a value in the parameter map.
501 *
Matt Spinler72c4af42021-11-29 14:40:17 -0600502 * If it's a std::nullopt, it will be deleted instead.
503 *
Matt Spinlerd76351b2021-08-05 16:23:09 -0500504 * @param[in] name - The parameter name
505 * @param[in] value - The parameter value
506 */
507 static void setParameter(const std::string& name,
Matt Spinler72c4af42021-11-29 14:40:17 -0600508 const std::optional<PropertyVariantType>& value)
Matt Spinlerd76351b2021-08-05 16:23:09 -0500509 {
Matt Spinler72c4af42021-11-29 14:40:17 -0600510 if (value)
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600511 {
Matt Spinler72c4af42021-11-29 14:40:17 -0600512 auto it = _parameters.find(name);
513 auto changed = (it == _parameters.end()) ||
514 ((it != _parameters.end()) && it->second != *value);
515 _parameters[name] = *value;
516
517 if (changed)
518 {
519 runParameterActions(name);
520 }
521 }
522 else
523 {
524 size_t deleted = _parameters.erase(name);
525
526 if (deleted)
527 {
528 runParameterActions(name);
529 }
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600530 }
Matt Spinlerd76351b2021-08-05 16:23:09 -0500531 }
532
533 /**
534 * @brief Returns a value from the parameter map
535 *
536 * @param[in] name - The parameter name
537 *
538 * @return The parameter value, or std::nullopt if not found
539 */
540 static std::optional<PropertyVariantType>
541 getParameter(const std::string& name)
542 {
543 auto it = _parameters.find(name);
544 if (it != _parameters.end())
545 {
546 return it->second;
547 }
548
549 return std::nullopt;
550 }
551
552 /**
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600553 * @brief Runs the actions registered to a parameter
554 * trigger with this name.
555 *
556 * @param[in] name - The parameter name
557 */
558 static void runParameterActions(const std::string& name);
559
560 /**
561 * @brief Adds a parameter trigger
562 *
563 * @param[in] name - The parameter name
564 * @param[in] actions - The actions to run on the trigger
565 */
566 static void
567 addParameterTrigger(const std::string& name,
568 std::vector<std::unique_ptr<ActionBase>>& actions);
569
Matt Spinler7787def2021-10-14 16:33:16 -0500570 /* The name of the dump file */
571 static const std::string dumpFile;
572
Matthew Bartha227a162020-08-05 10:51:45 -0500573 private:
Mike Capps1a19ead2021-10-22 09:15:14 -0400574 /**
575 * @brief Helper to detect when a property's double contains a NaN
576 * (not-a-number) value.
577 *
578 * @param[in] value - The property to test
579 */
580 static bool PropertyContainsNan(const PropertyVariantType& value)
581 {
582 return (std::holds_alternative<double>(value) &&
583 std::isnan(std::get<double>(value)));
584 }
585
586 /**
587 * @brief Insert managed objects into cache, but filter out properties
Matt Spinlerc2c2db72022-04-07 13:59:37 -0500588 * containing unwanted NaN (not-a-number) values and properties that
589 * are on D-Bus paths that aren't in an existing Group object.
Mike Capps1a19ead2021-10-22 09:15:14 -0400590 *
591 * @param[in] ref - The map of ManagedObjects to insert into cache
592 */
593 void insertFilteredObjects(ManagedObjects& ref);
594
Matthew Barth1542fb52021-06-10 14:09:09 -0500595 /* The sdbusplus bus object to use */
Matthew Barthacd737c2021-03-04 11:04:01 -0600596 sdbusplus::bus::bus& _bus;
597
Matthew Barth1542fb52021-06-10 14:09:09 -0500598 /* The sdeventplus even loop to use */
Matthew Barthacd737c2021-03-04 11:04:01 -0600599 sdeventplus::Event _event;
600
Matthew Barth1542fb52021-06-10 14:09:09 -0500601 /* The sdbusplus manager object to set the ObjectManager interface */
602 sdbusplus::server::manager::manager _mgr;
603
Matthew Barth3770a1d2021-06-10 15:09:37 -0500604 /* Whether loading the config files is allowed or not */
605 bool _loadAllowed;
606
Matthew Barth48f44da2021-05-27 15:43:34 -0500607 /* The system's power state determination object */
608 std::unique_ptr<PowerState> _powerState;
609
Matthew Barth06764942021-03-04 09:28:40 -0600610 /* List of profiles configured */
Matthew Barthacd737c2021-03-04 11:04:01 -0600611 std::map<configKey, std::unique_ptr<Profile>> _profiles;
Matthew Barth06764942021-03-04 09:28:40 -0600612
613 /* List of active profiles */
Matthew Barthacd737c2021-03-04 11:04:01 -0600614 static std::vector<std::string> _activeProfiles;
615
Matthew Barth4ca87fa2021-04-14 11:31:13 -0500616 /* Subtree map of paths to services of interfaces(with ownership state) */
617 static std::map<
618 std::string,
619 std::map<std::string, std::pair<bool, std::vector<std::string>>>>
Matthew Barth12cb1252021-03-08 16:47:30 -0600620 _servTree;
621
Matthew Barth07fecfc2021-01-29 09:04:43 -0600622 /* Object map of paths to interfaces of properties and their values */
623 static std::map<
624 std::string,
625 std::map<std::string, std::map<std::string, PropertyVariantType>>>
626 _objects;
627
Matthew Barthd9cb63b2021-03-24 14:36:49 -0500628 /* List of timers and their data to be processed when expired */
629 std::vector<std::pair<std::unique_ptr<TimerData>, Timer>> _timers;
630
Matthew Barthebabc042021-05-13 15:38:58 -0500631 /* Map of signal match strings to a list of signal handler data */
632 std::unordered_map<std::string, std::vector<SignalData>> _signals;
633
Matthew Barthacd737c2021-03-04 11:04:01 -0600634 /* List of zones configured */
635 std::map<configKey, std::unique_ptr<Zone>> _zones;
636
Matthew Barth44ab7692021-03-26 11:40:10 -0500637 /* List of events configured */
638 std::map<configKey, std::unique_ptr<Event>> _events;
639
Matt Spinler7787def2021-10-14 16:33:16 -0500640 /* The sdeventplus wrapper around sd_event_add_defer to dump debug
641 * data from the event loop after the USR1 signal. */
642 std::unique_ptr<sdeventplus::source::Defer> debugDumpEventSource;
Matt Spinler2fc0a352021-10-04 15:10:57 -0500643
Matthew Barthacd737c2021-03-04 11:04:01 -0600644 /**
Matt Spinlerd76351b2021-08-05 16:23:09 -0500645 * @brief A map of parameter names and values that are something
646 * other than just D-Bus property values that other actions
647 * can set and use.
648 */
649 static std::unordered_map<std::string, PropertyVariantType> _parameters;
650
651 /**
Matt Spinlerd0ba86a2021-11-09 10:09:13 -0600652 * @brief Map of parameter names to the actions to run when their
653 * values change.
654 */
655 static std::unordered_map<std::string, TriggerActions> _parameterTriggers;
656
657 /**
Matthew Barthb2cd93f2021-06-16 16:37:40 -0500658 * @brief Callback for power state changes
659 *
660 * @param[in] powerStateOn - Whether the power state is on or not
661 *
662 * Callback function bound to the PowerState object instance to handle each
663 * time the power state changes.
664 */
665 void powerStateChanged(bool powerStateOn);
666
667 /**
Matthew Barth4ca87fa2021-04-14 11:31:13 -0500668 * @brief Find the service name for a given path and interface from the
669 * cached dataset
670 *
671 * @param[in] path - Path to get service for
672 * @param[in] intf - Interface to get service for
673 *
674 * @return - The cached service name
675 */
676 static const std::string& findService(const std::string& path,
677 const std::string& intf);
678
679 /**
Matthew Barthf41e9472021-05-13 16:38:06 -0500680 * @brief Find all the paths for a given service and interface from the
681 * cached dataset
682 *
683 * @param[in] serv - Service name to get paths for
684 * @param[in] intf - Interface to get paths for
685 *
686 * @return - The cached object paths
687 */
688 std::vector<std::string> findPaths(const std::string& serv,
689 const std::string& intf);
690
691 /**
Matthew Barthacd737c2021-03-04 11:04:01 -0600692 * @brief Parse and set the configured profiles from the profiles JSON file
693 *
694 * Retrieves the optional profiles JSON configuration file, parses it, and
695 * creates a list of configured profiles available to the other
696 * configuration files. These profiles can be used to remove or include
697 * entries within the other configuration files.
698 */
699 void setProfiles();
Matt Spinler2fc0a352021-10-04 15:10:57 -0500700
701 /**
Matt Spinler7787def2021-10-14 16:33:16 -0500702 * @brief Callback from debugDumpEventSource to dump debug data
Matt Spinler2fc0a352021-10-04 15:10:57 -0500703 */
Matt Spinler7787def2021-10-14 16:33:16 -0500704 void dumpDebugData(sdeventplus::source::EventBase&);
Matt Spinlerb5c21a22021-10-14 16:52:12 -0500705
706 /**
707 * @brief Dump the _objects, _servTree, and _parameters maps to JSON
708 *
709 * @param[out] data - The JSON that will be filled in
710 */
711 void dumpCache(json& data);
Matt Spinlerade0c372021-10-28 16:09:44 -0500712
713 /**
Matthew Barth2f359f72022-02-15 10:00:26 -0600714 * @brief Add a list of groups to the cache dataset.
Matt Spinlerade0c372021-10-28 16:09:44 -0500715 *
Matthew Barth2f359f72022-02-15 10:00:26 -0600716 * @param[in] groups - The groups to add
Matt Spinlerade0c372021-10-28 16:09:44 -0500717 */
Matthew Barth2f359f72022-02-15 10:00:26 -0600718 void addGroups(const std::vector<Group>& groups);
Matthew Bartha227a162020-08-05 10:51:45 -0500719};
720
721} // namespace phosphor::fan::control::json