| #pragma once |
| |
| #include "device.hpp" |
| #include "sdbusplus/async/proxy.hpp" |
| |
| #include <boost/asio/steady_timer.hpp> |
| #include <phosphor-logging/lg2.hpp> |
| #include <sdbusplus/asio/connection.hpp> |
| #include <sdbusplus/asio/object_server.hpp> |
| #include <sdbusplus/async/context.hpp> |
| #include <sdbusplus/timer.hpp> |
| |
| #include <string> |
| |
| // This is the base class for the code updater |
| // Every code updater can inherit from this |
| class SoftwareManager |
| { |
| public: |
| SoftwareManager(sdbusplus::async::context& ctx, |
| const std::string& busNameSuffix, bool dryRun); |
| |
| // @param state desired powerstate (true means on) |
| // @returns true on success |
| sdbusplus::async::task<bool> setHostPowerstate(bool state); |
| |
| // @returns true when powered |
| // @returns std::nullopt on failure to query power state |
| sdbusplus::async::task<std::optional<bool>> getHostPowerstate(); |
| |
| // Fetches initial configuration from dbus. |
| // This should be called once by a code updater at startup. |
| // It will call 'getInitialConfigurationSingleDevice' for each device |
| // configured |
| // @param configurationInterfaces the dbus interfaces from which to fetch |
| // configuration |
| sdbusplus::async::task<> getInitialConfiguration( |
| const std::vector<std::string>& configurationInterfaces); |
| |
| // request the bus name on dbus after all configuration has been parsed |
| // and the devices have been initialized |
| // @returns the name on dbus |
| std::string setupBusName(); |
| |
| // set of devices found through configuration and probing |
| std::set<std::unique_ptr<Device>> devices; |
| |
| protected: |
| const bool dryRun; |
| |
| template <typename T> |
| sdbusplus::async::task<std::optional<T>> |
| dbusGetRequiredConfigurationProperty( |
| const std::string& service, const std::string& path, |
| const std::string& property, DeviceConfig& config) |
| { |
| std::string configIface = |
| "xyz.openbmc_project.Configuration." + config.configType; |
| std::optional<T> res = co_await dbusGetRequiredProperty<T>( |
| service, path, configIface, property); |
| co_return res; |
| } |
| |
| // this variant also logs the error |
| template <typename T> |
| sdbusplus::async::task<std::optional<T>> dbusGetRequiredProperty( |
| const std::string& service, const std::string& path, |
| const std::string& intf, const std::string& property) |
| { |
| std::optional<T> opt = |
| co_await dbusGetProperty<T>(service, path, intf, property); |
| if (!opt.has_value()) |
| { |
| lg2::error( |
| "[config] missing property {PROPERTY} on path {PATH}, interface {INTF}", |
| "PROPERTY", property, "PATH", path, "INTF", intf); |
| } |
| co_return opt; |
| } |
| |
| template <typename T> |
| sdbusplus::async::task<std::optional<T>> |
| dbusGetProperty(const std::string& service, const std::string& path, |
| const std::string& intf, const std::string& property) |
| { |
| auto client = |
| sdbusplus::async::proxy().service(service).path(path).interface( |
| "org.freedesktop.DBus.Properties"); |
| |
| try |
| { |
| std::variant<T> result = co_await client.call<std::variant<T>>( |
| ctx, "Get", intf, property); |
| |
| T res = std::get<T>(result); |
| co_return res; |
| } |
| catch (std::exception& e) |
| { |
| co_return std::nullopt; |
| } |
| } |
| |
| // This function receives a dbus name and object path for a single device, |
| // which was configured. |
| // The component code updater overrides this function and may create a |
| // device instance internally, or reject the configuration as invalid. |
| // @param service The dbus name where our configuration is |
| // @param config The common configuration properties which are shared |
| // by all devices. |
| // Also includes the object path to fetch other |
| // configuration properties. |
| virtual sdbusplus::async::task<> getInitialConfigurationSingleDevice( |
| const std::string& service, const std::string& path, |
| DeviceConfig& config) = 0; |
| |
| sdbusplus::async::context& ctx; |
| |
| private: |
| // this is appended to the common prefix to construct the dbus name |
| std::string busNameSuffix; |
| |
| sdbusplus::server::manager_t manager; |
| |
| friend Software; |
| friend Device; |
| }; |