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