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 namespace manager_utils 28 { 29 30 inline void setServiceIdentification( 31 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 32 std::string_view serviceIdentification) 33 { 34 constexpr const size_t maxStrSize = 99; 35 constexpr const char* allowedChars = 36 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 _-"; 37 if (serviceIdentification.size() > maxStrSize) 38 { 39 messages::stringValueTooLong(asyncResp->res, "ServiceIdentification", 40 maxStrSize); 41 return; 42 } 43 if (serviceIdentification.find_first_not_of(allowedChars) != 44 std::string_view::npos) 45 { 46 messages::propertyValueError(asyncResp->res, "ServiceIdentification"); 47 return; 48 } 49 50 persistent_data::ConfigFile& config = persistent_data::getConfig(); 51 config.serviceIdentification = serviceIdentification; 52 config.writeData(); 53 messages::success(asyncResp->res); 54 } 55 56 inline void getServiceIdentification( 57 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 58 const bool isServiceRoot) 59 { 60 std::string_view serviceIdentification = 61 persistent_data::getConfig().serviceIdentification; 62 63 // This property shall not be present if its value is an empty string or 64 // null: Redfish Data Model Specification 6.125.3 65 if (isServiceRoot && serviceIdentification.empty()) 66 { 67 return; 68 } 69 asyncResp->res.jsonValue["ServiceIdentification"] = serviceIdentification; 70 } 71 72 inline void afterGetValidManagerPath( 73 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 74 const std::string& managerId, 75 const std::function< 76 void(const std::string& managerPath, 77 const dbus::utility::MapperServiceMap& serviceMap)>& callback, 78 const boost::system::error_code& ec, 79 const dbus::utility::MapperGetSubTreeResponse& subtree) 80 { 81 if (ec) 82 { 83 if (ec == boost::system::errc::io_error) 84 { 85 // Not found 86 BMCWEB_LOG_WARNING("Manager {} not found", managerId); 87 messages::resourceNotFound(asyncResp->res, "Manager", managerId); 88 return; 89 } 90 BMCWEB_LOG_ERROR("D-Bus response error {}", ec.value()); 91 messages::internalError(asyncResp->res); 92 return; 93 } 94 if (subtree.empty()) 95 { 96 BMCWEB_LOG_WARNING("Manager {} not found", managerId); 97 messages::resourceNotFound(asyncResp->res, "Manager", managerId); 98 return; 99 } 100 101 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME) 102 { 103 messages::resourceNotFound(asyncResp->res, "Manager", managerId); 104 return; 105 } 106 // Assume only 1 bmc D-Bus object 107 // Throw an error if there is more than 1 108 if (subtree.size() > 1) 109 { 110 BMCWEB_LOG_ERROR("Found more than 1 bmc D-Bus object!"); 111 messages::internalError(asyncResp->res); 112 return; 113 } 114 115 callback(subtree[0].first, subtree[0].second); 116 } 117 118 inline void getValidManagerPath( 119 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 120 const std::string& managerId, 121 std::function<void(const std::string& managerPath, 122 const dbus::utility::MapperServiceMap& serviceMap)>&& 123 callback) 124 { 125 dbus::utility::getSubTree( 126 "/xyz/openbmc_project/inventory", 0, bmcInterfaces, 127 [asyncResp, managerId, callback = std::move(callback)]( 128 const boost::system::error_code& ec, 129 const dbus::utility::MapperGetSubTreeResponse& subtree) { 130 afterGetValidManagerPath(asyncResp, managerId, callback, ec, 131 subtree); 132 }); 133 } 134 135 } // namespace manager_utils 136 137 } // namespace redfish 138