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