xref: /openbmc/bmcweb/redfish-core/src/utils/dbus_utils.cpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
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 
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)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::resourceInStandby(asyncResp->res);
80                 return;
81             }
82         }
83         BMCWEB_LOG_ERROR("D-Bus error setting Redfish Property {} ec={}",
84                          redfishPropertyName, ec);
85         messages::internalError(asyncResp->res);
86         return;
87     }
88     // Only set 204 if another error hasn't already happened.
89     if (asyncResp->res.result() == boost::beast::http::status::ok)
90     {
91         asyncResp->res.result(boost::beast::http::status::no_content);
92     }
93 };
94 
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 &)95 void afterSetPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
96                             const std::string& redfishActionName,
97                             const std::string& redfishActionParameterName,
98                             const boost::system::error_code& ec,
99                             const sdbusplus::message_t& /*msg*/)
100 {
101     if (ec)
102     {
103         if (ec.value() == boost::asio::error::invalid_argument)
104         {
105             BMCWEB_LOG_WARNING(
106                 "Resource {} is patched with invalid argument during action {}",
107                 redfishActionParameterName, redfishActionName);
108             if (redfishActionParameterName.empty())
109             {
110                 messages::operationFailed(asyncResp->res);
111             }
112             else
113             {
114                 messages::actionParameterValueError(asyncResp->res,
115                                                     redfishActionParameterName,
116                                                     redfishActionName);
117             }
118             return;
119         }
120         if (ec.value() == boost::asio::error::host_unreachable)
121         {
122             BMCWEB_LOG_WARNING(
123                 "Resource {} is not found while performing action {}",
124                 redfishActionParameterName, redfishActionName);
125             messages::resourceNotFound(asyncResp->res, "Actions",
126                                        redfishActionName);
127             return;
128         }
129 
130         BMCWEB_LOG_ERROR("D-Bus error setting Redfish Property {} ec={}",
131                          redfishActionParameterName, ec);
132         messages::internalError(asyncResp->res);
133         return;
134     }
135     // Only set success if another error hasn't already happened.
136     if (asyncResp->res.result() == boost::beast::http::status::ok)
137     {
138         messages::success(asyncResp->res);
139     }
140 };
141 } // namespace details
142 } // namespace redfish
143