1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #include "utils/dbus_utils.hpp" 4 5 #include "async_resp.hpp" 6 #include "boost_formatters.hpp" 7 #include "error_messages.hpp" 8 #include "logging.hpp" 9 10 #include <systemd/sd-bus.h> 11 12 #include <boost/asio/error.hpp> 13 #include <boost/beast/http/status.hpp> 14 #include <boost/system/error_code.hpp> 15 #include <nlohmann/json.hpp> 16 #include <sdbusplus/message.hpp> 17 18 #include <memory> 19 #include <string> 20 #include <string_view> 21 22 namespace redfish 23 { 24 namespace details 25 { 26 27 void afterSetProperty( 28 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29 const std::string& redfishPropertyName, const nlohmann::json& propertyValue, 30 const boost::system::error_code& ec, const sdbusplus::message_t& msg) 31 { 32 if (ec) 33 { 34 if (ec.value() == boost::system::errc::permission_denied) 35 { 36 messages::insufficientPrivilege(asyncResp->res); 37 } 38 if (ec.value() == boost::asio::error::host_unreachable) 39 { 40 messages::resourceNotFound(asyncResp->res, "Set", 41 redfishPropertyName); 42 return; 43 } 44 const sd_bus_error* dbusError = msg.get_error(); 45 if (dbusError != nullptr) 46 { 47 std::string_view errorName(dbusError->name); 48 49 if (errorName == "xyz.openbmc_project.Common.Error.InvalidArgument") 50 { 51 BMCWEB_LOG_WARNING("DBUS response error: {}", ec); 52 messages::propertyValueIncorrect( 53 asyncResp->res, redfishPropertyName, propertyValue); 54 return; 55 } 56 if (errorName == 57 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady") 58 { 59 BMCWEB_LOG_WARNING( 60 "BMC not ready, operation not allowed right now"); 61 messages::serviceTemporarilyUnavailable(asyncResp->res, "10"); 62 return; 63 } 64 if (errorName == "xyz.openbmc_project.State.Host.Error.BMCNotReady") 65 { 66 BMCWEB_LOG_WARNING( 67 "BMC not ready, operation not allowed right now"); 68 messages::serviceTemporarilyUnavailable(asyncResp->res, "10"); 69 return; 70 } 71 if (errorName == "xyz.openbmc_project.Common.Error.NotAllowed") 72 { 73 messages::propertyNotWritable(asyncResp->res, 74 redfishPropertyName); 75 return; 76 } 77 if (errorName == "xyz.openbmc_project.Common.Error.Unavailable") 78 { 79 messages::propertyValueExternalConflict( 80 asyncResp->res, redfishPropertyName, propertyValue); 81 return; 82 } 83 } 84 BMCWEB_LOG_ERROR("D-Bus error setting Redfish Property {} ec={}", 85 redfishPropertyName, ec); 86 messages::internalError(asyncResp->res); 87 return; 88 } 89 // Only set 204 if another error hasn't already happened. 90 if (asyncResp->res.result() == boost::beast::http::status::ok) 91 { 92 asyncResp->res.result(boost::beast::http::status::no_content); 93 } 94 }; 95 96 void afterSetPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 97 const std::string& redfishActionName, 98 const std::string& redfishActionParameterName, 99 const boost::system::error_code& ec, 100 const sdbusplus::message_t& /*msg*/) 101 { 102 if (ec) 103 { 104 if (ec.value() == boost::asio::error::invalid_argument) 105 { 106 BMCWEB_LOG_WARNING( 107 "Resource {} is patched with invalid argument during action {}", 108 redfishActionParameterName, redfishActionName); 109 if (redfishActionParameterName.empty()) 110 { 111 messages::operationFailed(asyncResp->res); 112 } 113 else 114 { 115 messages::actionParameterValueError(asyncResp->res, 116 redfishActionParameterName, 117 redfishActionName); 118 } 119 return; 120 } 121 if (ec.value() == boost::asio::error::host_unreachable) 122 { 123 BMCWEB_LOG_WARNING( 124 "Resource {} is not found while performing action {}", 125 redfishActionParameterName, redfishActionName); 126 messages::resourceNotFound(asyncResp->res, "Actions", 127 redfishActionName); 128 return; 129 } 130 131 BMCWEB_LOG_ERROR("D-Bus error setting Redfish Property {} ec={}", 132 redfishActionParameterName, ec); 133 messages::internalError(asyncResp->res); 134 return; 135 } 136 // Only set success if another error hasn't already happened. 137 if (asyncResp->res.result() == boost::beast::http::status::ok) 138 { 139 messages::success(asyncResp->res); 140 } 141 }; 142 } // namespace details 143 } // namespace redfish 144