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 
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 
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