xref: /openbmc/bmcweb/redfish-core/include/utils/manager_utils.hpp (revision a9bf68b93dd31e0163227819ce1dcfe5ce06b975)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 #pragma once
4 
5 #include "bmcweb_config.h"
6 
7 #include "async_resp.hpp"
8 #include "dbus_utility.hpp"
9 #include "error_messages.hpp"
10 #include "logging.hpp"
11 #include "persistent_data.hpp"
12 
13 #include <nlohmann/json.hpp>
14 
15 #include <array>
16 #include <cstddef>
17 #include <functional>
18 #include <memory>
19 #include <string_view>
20 #include <utility>
21 
22 namespace redfish
23 {
24 
25 constexpr std::array<std::string_view, 1> bmcInterfaces = {
26     "xyz.openbmc_project.Inventory.Item.Bmc"};
27 
28 namespace manager_utils
29 {
30 
setServiceIdentification(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,std::string_view serviceIdentification)31 inline void setServiceIdentification(
32     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
33     std::string_view serviceIdentification)
34 {
35     constexpr const size_t maxStrSize = 99;
36     constexpr const char* allowedChars =
37         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 _-";
38     if (serviceIdentification.size() > maxStrSize)
39     {
40         messages::stringValueTooLong(asyncResp->res, "ServiceIdentification",
41                                      maxStrSize);
42         return;
43     }
44     if (serviceIdentification.find_first_not_of(allowedChars) !=
45         std::string_view::npos)
46     {
47         messages::propertyValueError(asyncResp->res, "ServiceIdentification");
48         return;
49     }
50 
51     persistent_data::ConfigFile& config = persistent_data::getConfig();
52     config.serviceIdentification = serviceIdentification;
53     config.writeData();
54     messages::success(asyncResp->res);
55 }
56 
getServiceIdentification(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const bool isServiceRoot)57 inline void getServiceIdentification(
58     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
59     const bool isServiceRoot)
60 {
61     std::string_view serviceIdentification =
62         persistent_data::getConfig().serviceIdentification;
63 
64     // This property shall not be present if its value is an empty string or
65     // null: Redfish Data Model Specification 6.125.3
66     if (isServiceRoot && serviceIdentification.empty())
67     {
68         return;
69     }
70     asyncResp->res.jsonValue["ServiceIdentification"] = serviceIdentification;
71 }
72 
afterGetValidManagerPath(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & managerId,const std::function<void (const boost::system::error_code &,const std::string & managerPath,const dbus::utility::MapperServiceMap & serviceMap)> & callback,const boost::system::error_code & ec,const dbus::utility::MapperGetSubTreeResponse & subtree)73 inline void afterGetValidManagerPath(
74     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
75     const std::string& managerId,
76     const std::function<
77         void(const boost::system::error_code&, const std::string& managerPath,
78              const dbus::utility::MapperServiceMap& serviceMap)>& callback,
79     const boost::system::error_code& ec,
80     const dbus::utility::MapperGetSubTreeResponse& subtree)
81 {
82     if (ec || subtree.empty())
83     {
84         // Pass the empty managerPath & serviceMap
85         callback(ec, {}, {});
86         return;
87     }
88 
89     // Assume only 1 bmc D-Bus object
90     // Throw an error if there is more than 1
91     if (subtree.size() > 1)
92     {
93         BMCWEB_LOG_ERROR("Found more than 1 bmc D-Bus object!");
94         messages::internalError(asyncResp->res);
95         return;
96     }
97 
98     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
99     {
100         // Treat it as NotFound
101         callback(ec, {}, {});
102         return;
103     }
104 
105     callback(ec, subtree[0].first, subtree[0].second);
106 }
107 
getValidManagerPath(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & managerId,std::function<void (const boost::system::error_code &,const std::string & managerPath,const dbus::utility::MapperServiceMap & serviceMap)> && callback)108 inline void getValidManagerPath(
109     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
110     const std::string& managerId,
111     std::function<
112         void(const boost::system::error_code&, const std::string& managerPath,
113              const dbus::utility::MapperServiceMap& serviceMap)>&& callback)
114 {
115     dbus::utility::getSubTree(
116         "/xyz/openbmc_project/inventory", 0, bmcInterfaces,
117         [asyncResp, managerId, callback = std::move(callback)](
118             const boost::system::error_code& ec,
119             const dbus::utility::MapperGetSubTreeResponse& subtree) {
120             afterGetValidManagerPath(asyncResp, managerId, callback, ec,
121                                      subtree);
122         });
123 }
124 
125 } // namespace manager_utils
126 
127 } // namespace redfish
128