blob: fd3a4671454b2d985abb5ed106df7dd00eefcaf0 [file] [log] [blame]
Alexander Hansen0119cd72025-01-14 14:15:39 +01001#pragma once
2
3#include "device.hpp"
4#include "sdbusplus/async/proxy.hpp"
5
6#include <boost/asio/steady_timer.hpp>
7#include <phosphor-logging/lg2.hpp>
8#include <sdbusplus/asio/connection.hpp>
9#include <sdbusplus/asio/object_server.hpp>
10#include <sdbusplus/async/context.hpp>
11#include <sdbusplus/timer.hpp>
12
13#include <string>
14
15// This is the base class for the code updater
16// Every code updater can inherit from this
17class SoftwareManager
18{
19 public:
20 SoftwareManager(sdbusplus::async::context& ctx,
21 const std::string& busNameSuffix, bool dryRun);
22
23 // @param state desired powerstate (true means on)
24 // @returns true on success
25 sdbusplus::async::task<bool> setHostPowerstate(bool state);
26
27 // @returns true when powered
28 // @returns std::nullopt on failure to query power state
29 sdbusplus::async::task<std::optional<bool>> getHostPowerstate();
30
31 // Fetches initial configuration from dbus.
32 // This should be called once by a code updater at startup.
33 // It will call 'getInitialConfigurationSingleDevice' for each device
34 // configured
35 // @param configurationInterfaces the dbus interfaces from which to fetch
36 // configuration
37 sdbusplus::async::task<> getInitialConfiguration(
38 const std::vector<std::string>& configurationInterfaces);
39
40 // request the bus name on dbus after all configuration has been parsed
41 // and the devices have been initialized
42 // @returns the name on dbus
43 std::string setupBusName();
44
45 // set of devices found through configuration and probing
46 std::set<std::unique_ptr<Device>> devices;
47
48 protected:
49 const bool dryRun;
50
51 template <typename T>
52 sdbusplus::async::task<std::optional<T>>
53 dbusGetRequiredConfigurationProperty(
54 const std::string& service, const std::string& path,
55 const std::string& property, DeviceConfig& config)
56 {
57 std::string configIface =
58 "xyz.openbmc_project.Configuration." + config.configType;
59 std::optional<T> res = co_await dbusGetRequiredProperty<T>(
60 service, path, configIface, property);
61 co_return res;
62 }
63
64 // this variant also logs the error
65 template <typename T>
66 sdbusplus::async::task<std::optional<T>> dbusGetRequiredProperty(
67 const std::string& service, const std::string& path,
68 const std::string& intf, const std::string& property)
69 {
70 std::optional<T> opt =
71 co_await dbusGetProperty<T>(service, path, intf, property);
72 if (!opt.has_value())
73 {
74 lg2::error(
75 "[config] missing property {PROPERTY} on path {PATH}, interface {INTF}",
76 "PROPERTY", property, "PATH", path, "INTF", intf);
77 }
78 co_return opt;
79 }
80
81 template <typename T>
82 sdbusplus::async::task<std::optional<T>>
83 dbusGetProperty(const std::string& service, const std::string& path,
84 const std::string& intf, const std::string& property)
85 {
86 auto client =
87 sdbusplus::async::proxy().service(service).path(path).interface(
88 "org.freedesktop.DBus.Properties");
89
90 try
91 {
92 std::variant<T> result = co_await client.call<std::variant<T>>(
93 ctx, "Get", intf, property);
94
95 T res = std::get<T>(result);
96 co_return res;
97 }
98 catch (std::exception& e)
99 {
100 co_return std::nullopt;
101 }
102 }
103
104 // This function receives a dbus name and object path for a single device,
105 // which was configured.
106 // The component code updater overrides this function and may create a
107 // device instance internally, or reject the configuration as invalid.
108 // @param service The dbus name where our configuration is
109 // @param config The common configuration properties which are shared
110 // by all devices.
111 // Also includes the object path to fetch other
112 // configuration properties.
113 virtual sdbusplus::async::task<> getInitialConfigurationSingleDevice(
114 const std::string& service, const std::string& path,
115 DeviceConfig& config) = 0;
116
117 sdbusplus::async::context& ctx;
118
119 private:
120 // this is appended to the common prefix to construct the dbus name
121 std::string busNameSuffix;
122
123 sdbusplus::server::manager_t manager;
124
125 friend Software;
126 friend Device;
127};