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