blob: 351533fa191c77c3c174b46fe0fe996b03c605cb [file] [log] [blame]
Alexander Hansencc372352025-01-14 14:15:39 +01001#include "software_manager.hpp"
2
3#include <phosphor-logging/lg2.hpp>
4#include <sdbusplus/asio/object_server.hpp>
5#include <sdbusplus/async.hpp>
6#include <sdbusplus/async/context.hpp>
7#include <sdbusplus/bus.hpp>
8#include <xyz/openbmc_project/Association/Definitions/server.hpp>
9#include <xyz/openbmc_project/ObjectMapper/client.hpp>
10#include <xyz/openbmc_project/State/Host/client.hpp>
11
12#include <cstdint>
13
14PHOSPHOR_LOG2_USING;
15
16using namespace phosphor::software::manager;
17
18SoftwareManager::SoftwareManager(sdbusplus::async::context& ctx,
19 const std::string& serviceNameSuffix) :
20 ctx(ctx), serviceNameSuffix(serviceNameSuffix), manager(ctx, "/")
21{
22 debug("initialized SoftwareManager");
23}
24
25std::string SoftwareManager::setupBusName()
26{
27 const std::string serviceNameFull =
28 "xyz.openbmc_project.Software." + serviceNameSuffix;
29
30 debug("requesting dbus name {BUSNAME}", "BUSNAME", serviceNameFull);
31
32 ctx.get_bus().request_name(serviceNameFull.c_str());
33
34 return serviceNameFull;
35}
36
37// NOLINTBEGIN(readability-static-accessed-through-instance)
38sdbusplus::async::task<> SoftwareManager::initDevices(
39 const std::vector<std::string>& configurationInterfaces)
40// NOLINTEND(readability-static-accessed-through-instance)
41{
42 auto client = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>(ctx)
43 .service("xyz.openbmc_project.ObjectMapper")
44 .path("/xyz/openbmc_project/object_mapper");
45
Alexander Hansen0a457ff2025-02-25 16:13:47 +010046 auto res = co_await client.get_sub_tree("/xyz/openbmc_project/inventory", 0,
47 configurationInterfaces);
Alexander Hansencc372352025-01-14 14:15:39 +010048
49 for (auto& iface : configurationInterfaces)
50 {
51 debug("[config] looking for dbus interface {INTF}", "INTF", iface);
52 }
53
54 for (auto& [path, v] : res)
55 {
56 for (auto& [service, interfaceNames] : v)
57 {
58 std::string interfaceFound;
59
60 for (std::string& interfaceName : interfaceNames)
61 {
62 for (auto& iface : configurationInterfaces)
63 {
64 if (interfaceName == iface)
65 {
66 interfaceFound = interfaceName;
67 }
68 }
69 }
70
71 if (interfaceFound.empty())
72 {
73 continue;
74 }
75
76 debug(
77 "[config] found configuration interface at {SERVICE}, {OBJPATH}",
78 "SERVICE", service, "OBJPATH", path);
79
80 auto client =
81 sdbusplus::async::proxy().service(service).path(path).interface(
82 "org.freedesktop.DBus.Properties");
83
84 uint64_t vendorIANA = 0;
85 std::string compatible{};
86 std::string emConfigType{};
87 std::string emConfigName{};
88
89 try
90 {
91 {
92 auto propVendorIANA =
93 co_await client.call<std::variant<uint64_t>>(
94 ctx, "Get", interfaceFound, "VendorIANA");
95
96 vendorIANA = std::get<uint64_t>(propVendorIANA);
97 }
98 {
99 auto propCompatible =
100 co_await client.call<std::variant<std::string>>(
101 ctx, "Get", interfaceFound, "Compatible");
102
103 compatible = std::get<std::string>(propCompatible);
104 }
105 {
106 auto propEMConfigType =
107 co_await client.call<std::variant<std::string>>(
108 ctx, "Get", interfaceFound, "Type");
109
110 emConfigType = std::get<std::string>(propEMConfigType);
111 }
112 {
113 auto propEMConfigName =
114 co_await client.call<std::variant<std::string>>(
115 ctx, "Get", interfaceFound, "Name");
116
117 emConfigName = std::get<std::string>(propEMConfigName);
118 }
119 }
120 catch (std::exception& e)
121 {
122 error(e.what());
123 continue;
124 }
125
126 SoftwareConfig config(path, vendorIANA, compatible, emConfigType,
127 emConfigName);
128
129 co_await initDevice(service, path, config);
130 }
131 }
132
133 debug("[config] done with initial configuration");
134
135 setupBusName();
136}