xref: /openbmc/bmcweb/redfish-core/include/utils/asset_utils.hpp (revision 1ac7f6cf1e1338a5345f15b8c9183f6e6c0107fa)
1*1ac7f6cfSMyung Bae // SPDX-License-Identifier: Apache-2.0
2*1ac7f6cfSMyung Bae // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3*1ac7f6cfSMyung Bae #pragma once
4*1ac7f6cfSMyung Bae 
5*1ac7f6cfSMyung Bae #include "async_resp.hpp"
6*1ac7f6cfSMyung Bae #include "dbus_utility.hpp"
7*1ac7f6cfSMyung Bae #include "error_messages.hpp"
8*1ac7f6cfSMyung Bae #include "logging.hpp"
9*1ac7f6cfSMyung Bae #include "utils/dbus_utils.hpp"
10*1ac7f6cfSMyung Bae 
11*1ac7f6cfSMyung Bae #include <asm-generic/errno.h>
12*1ac7f6cfSMyung Bae 
13*1ac7f6cfSMyung Bae #include <boost/system/error_code.hpp>
14*1ac7f6cfSMyung Bae #include <nlohmann/json.hpp>
15*1ac7f6cfSMyung Bae #include <sdbusplus/unpack_properties.hpp>
16*1ac7f6cfSMyung Bae 
17*1ac7f6cfSMyung Bae #include <functional>
18*1ac7f6cfSMyung Bae #include <memory>
19*1ac7f6cfSMyung Bae #include <ranges>
20*1ac7f6cfSMyung Bae #include <string>
21*1ac7f6cfSMyung Bae 
22*1ac7f6cfSMyung Bae namespace redfish
23*1ac7f6cfSMyung Bae {
24*1ac7f6cfSMyung Bae namespace asset_utils
25*1ac7f6cfSMyung Bae {
26*1ac7f6cfSMyung Bae 
27*1ac7f6cfSMyung Bae inline void extractAssetInfo(
28*1ac7f6cfSMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29*1ac7f6cfSMyung Bae     const nlohmann::json::json_pointer& jsonKeyName,
30*1ac7f6cfSMyung Bae     const dbus::utility::DBusPropertiesMap& assetList,
31*1ac7f6cfSMyung Bae     bool includeSparePartNumber = false)
32*1ac7f6cfSMyung Bae {
33*1ac7f6cfSMyung Bae     const std::string* manufacturer = nullptr;
34*1ac7f6cfSMyung Bae     const std::string* model = nullptr;
35*1ac7f6cfSMyung Bae     const std::string* partNumber = nullptr;
36*1ac7f6cfSMyung Bae     const std::string* serialNumber = nullptr;
37*1ac7f6cfSMyung Bae     const std::string* sparePartNumber = nullptr;
38*1ac7f6cfSMyung Bae 
39*1ac7f6cfSMyung Bae     const bool success = sdbusplus::unpackPropertiesNoThrow(
40*1ac7f6cfSMyung Bae         dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
41*1ac7f6cfSMyung Bae         manufacturer, "Model", model, "PartNumber", partNumber, "SerialNumber",
42*1ac7f6cfSMyung Bae         serialNumber, "SparePartNumber", sparePartNumber);
43*1ac7f6cfSMyung Bae     if (!success)
44*1ac7f6cfSMyung Bae     {
45*1ac7f6cfSMyung Bae         messages::internalError(asyncResp->res);
46*1ac7f6cfSMyung Bae         return;
47*1ac7f6cfSMyung Bae     }
48*1ac7f6cfSMyung Bae 
49*1ac7f6cfSMyung Bae     nlohmann::json& assetData = asyncResp->res.jsonValue[jsonKeyName];
50*1ac7f6cfSMyung Bae 
51*1ac7f6cfSMyung Bae     if (manufacturer != nullptr)
52*1ac7f6cfSMyung Bae     {
53*1ac7f6cfSMyung Bae         assetData["Manufacturer"] = *manufacturer;
54*1ac7f6cfSMyung Bae     }
55*1ac7f6cfSMyung Bae     if (model != nullptr)
56*1ac7f6cfSMyung Bae     {
57*1ac7f6cfSMyung Bae         assetData["Model"] = *model;
58*1ac7f6cfSMyung Bae     }
59*1ac7f6cfSMyung Bae     if (partNumber != nullptr)
60*1ac7f6cfSMyung Bae     {
61*1ac7f6cfSMyung Bae         assetData["PartNumber"] = *partNumber;
62*1ac7f6cfSMyung Bae     }
63*1ac7f6cfSMyung Bae     if (serialNumber != nullptr)
64*1ac7f6cfSMyung Bae     {
65*1ac7f6cfSMyung Bae         assetData["SerialNumber"] = *serialNumber;
66*1ac7f6cfSMyung Bae     }
67*1ac7f6cfSMyung Bae     // SparePartNumber is optional on D-Bus so skip if it is empty
68*1ac7f6cfSMyung Bae     if (includeSparePartNumber && sparePartNumber != nullptr &&
69*1ac7f6cfSMyung Bae         !sparePartNumber->empty())
70*1ac7f6cfSMyung Bae     {
71*1ac7f6cfSMyung Bae         assetData["SparePartNumber"] = *sparePartNumber;
72*1ac7f6cfSMyung Bae     }
73*1ac7f6cfSMyung Bae }
74*1ac7f6cfSMyung Bae 
75*1ac7f6cfSMyung Bae inline void getAssetInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
76*1ac7f6cfSMyung Bae                          const std::string& serviceName,
77*1ac7f6cfSMyung Bae                          const std::string& dbusPath,
78*1ac7f6cfSMyung Bae                          const nlohmann::json::json_pointer& jsonKeyName,
79*1ac7f6cfSMyung Bae                          bool includeSparePartNumber = false)
80*1ac7f6cfSMyung Bae {
81*1ac7f6cfSMyung Bae     dbus::utility::getAllProperties(
82*1ac7f6cfSMyung Bae         serviceName, dbusPath, "xyz.openbmc_project.Inventory.Decorator.Asset",
83*1ac7f6cfSMyung Bae         [asyncResp, jsonKeyName, includeSparePartNumber](
84*1ac7f6cfSMyung Bae             const boost::system::error_code& ec,
85*1ac7f6cfSMyung Bae             const dbus::utility::DBusPropertiesMap& assetList) {
86*1ac7f6cfSMyung Bae             if (ec)
87*1ac7f6cfSMyung Bae             {
88*1ac7f6cfSMyung Bae                 if (ec.value() != EBADR)
89*1ac7f6cfSMyung Bae                 {
90*1ac7f6cfSMyung Bae                     BMCWEB_LOG_ERROR("DBUS response error for Properties {}",
91*1ac7f6cfSMyung Bae                                      ec.value());
92*1ac7f6cfSMyung Bae                     messages::internalError(asyncResp->res);
93*1ac7f6cfSMyung Bae                 }
94*1ac7f6cfSMyung Bae                 return;
95*1ac7f6cfSMyung Bae             }
96*1ac7f6cfSMyung Bae             extractAssetInfo(asyncResp, jsonKeyName, assetList,
97*1ac7f6cfSMyung Bae                              includeSparePartNumber);
98*1ac7f6cfSMyung Bae         });
99*1ac7f6cfSMyung Bae }
100*1ac7f6cfSMyung Bae 
101*1ac7f6cfSMyung Bae } // namespace asset_utils
102*1ac7f6cfSMyung Bae } // namespace redfish
103