blob: 77ee0b158816df2406a8c893940cfae8794e3d37 [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>
Alexander Hansende5e76f2025-02-20 16:30:11 +010010#include <xyz/openbmc_project/Software/Version/client.hpp>
Alexander Hansencc372352025-01-14 14:15:39 +010011#include <xyz/openbmc_project/State/Host/client.hpp>
12
13#include <cstdint>
14
15PHOSPHOR_LOG2_USING;
16
17using namespace phosphor::software::manager;
18
19SoftwareManager::SoftwareManager(sdbusplus::async::context& ctx,
20 const std::string& serviceNameSuffix) :
Alexander Hansende5e76f2025-02-20 16:30:11 +010021 ctx(ctx), serviceNameSuffix(serviceNameSuffix),
22 manager(ctx, sdbusplus::client::xyz::openbmc_project::software::Version<>::
23 namespace_path)
Alexander Hansencc372352025-01-14 14:15:39 +010024{
25 const std::string serviceNameFull =
26 "xyz.openbmc_project.Software." + serviceNameSuffix;
27
28 debug("requesting dbus name {BUSNAME}", "BUSNAME", serviceNameFull);
29
Alexander Hansende5e76f2025-02-20 16:30:11 +010030 ctx.request_name(serviceNameFull.c_str());
Alexander Hansencc372352025-01-14 14:15:39 +010031
Alexander Hansende5e76f2025-02-20 16:30:11 +010032 debug("Initialized SoftwareManager");
Alexander Hansencc372352025-01-14 14:15:39 +010033}
34
35// NOLINTBEGIN(readability-static-accessed-through-instance)
36sdbusplus::async::task<> SoftwareManager::initDevices(
37 const std::vector<std::string>& configurationInterfaces)
38// NOLINTEND(readability-static-accessed-through-instance)
39{
40 auto client = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>(ctx)
41 .service("xyz.openbmc_project.ObjectMapper")
42 .path("/xyz/openbmc_project/object_mapper");
43
Alexander Hansen0a457ff2025-02-25 16:13:47 +010044 auto res = co_await client.get_sub_tree("/xyz/openbmc_project/inventory", 0,
45 configurationInterfaces);
Alexander Hansencc372352025-01-14 14:15:39 +010046
47 for (auto& iface : configurationInterfaces)
48 {
49 debug("[config] looking for dbus interface {INTF}", "INTF", iface);
50 }
51
52 for (auto& [path, v] : res)
53 {
54 for (auto& [service, interfaceNames] : v)
55 {
56 std::string interfaceFound;
57
58 for (std::string& interfaceName : interfaceNames)
59 {
60 for (auto& iface : configurationInterfaces)
61 {
62 if (interfaceName == iface)
63 {
64 interfaceFound = interfaceName;
65 }
66 }
67 }
68
69 if (interfaceFound.empty())
70 {
71 continue;
72 }
73
74 debug(
75 "[config] found configuration interface at {SERVICE}, {OBJPATH}",
76 "SERVICE", service, "OBJPATH", path);
77
78 auto client =
79 sdbusplus::async::proxy().service(service).path(path).interface(
80 "org.freedesktop.DBus.Properties");
81
82 uint64_t vendorIANA = 0;
83 std::string compatible{};
84 std::string emConfigType{};
85 std::string emConfigName{};
86
Alexander Hansen4983b132025-02-26 16:55:14 +010087 const std::string ifaceFwInfoDef = interfaceFound + ".FirmwareInfo";
88
Alexander Hansencc372352025-01-14 14:15:39 +010089 try
90 {
91 {
92 auto propVendorIANA =
93 co_await client.call<std::variant<uint64_t>>(
Alexander Hansen4983b132025-02-26 16:55:14 +010094 ctx, "Get", ifaceFwInfoDef, "VendorIANA");
Alexander Hansencc372352025-01-14 14:15:39 +010095
96 vendorIANA = std::get<uint64_t>(propVendorIANA);
97 }
98 {
99 auto propCompatible =
100 co_await client.call<std::variant<std::string>>(
Alexander Hansen4983b132025-02-26 16:55:14 +0100101 ctx, "Get", ifaceFwInfoDef, "CompatibleHardware");
Alexander Hansencc372352025-01-14 14:15:39 +0100102
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");
Alexander Hansencc372352025-01-14 14:15:39 +0100134}