Add the function to process the "PUT" method from client.
The request URL starts with "/xyz/openbmc_project/..." which follows the rule of IBM
The "PUT" function will help process "hostpoweron","hostpoweroff"... functions from WebUI
Change-Id: Ibe86295507764c8192b34726ae36b21ad01ac0d4
Signed-off-by: shiyilei <yilei.shi@intel.com>
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 4e29805..9e5e540 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -17,7 +17,7 @@
// multiple requests to be running at once
std::atomic<std::size_t> outstanding_async_calls(0);
nlohmann::json object_paths;
-
+bool property_matched=false;
void introspect_objects(crow::response &res, std::string process_name,
std::string path) {
dbus::endpoint introspect_endpoint(
@@ -128,8 +128,9 @@
"", static_cast<int32_t>(99), std::array<std::string, 0>());
});
- CROW_ROUTE(app, "/xyz/<path>")
- .methods("GET"_method)([](const crow::request &req, crow::response &res,
+ CROW_ROUTE(app, "/xyz/<path>")
+ .methods("GET"_method,
+ "PUT"_method)([](const crow::request &req, crow::response &res,
const std::string &path) {
if (outstanding_async_calls != 0) {
res.code = 500;
@@ -139,13 +140,46 @@
}
using GetObjectType =
std::vector<std::pair<std::string, std::vector<std::string>>>;
+ std::string object_path;
+ std::string dest_property;
+ std::string property_set_value;
+ size_t attr_position = path.find("/attr/");
+ if (attr_position == path.npos)
+ object_path = "/xyz/" + path;
+ else {
+ object_path = "/xyz/" + path.substr(0, attr_position);
+ dest_property =
+ path.substr((attr_position + strlen("/attr/")), path.length());
+ auto request_dbus_data =
+ nlohmann::json::parse(req.body, nullptr, false);
+ if (request_dbus_data.is_discarded()) {
+ res.code = 400;
+ res.end();
+ return;
+ }
- std::string object_path = "/xyz/" + path;
+ auto property_value_it = request_dbus_data.find("data");
+ if (property_value_it == request_dbus_data.end()) {
+ res.code = 400;
+ res.end();
+ return;
+ }
+
+ property_set_value = property_value_it->get<const std::string>();
+ if (property_set_value.empty()) {
+ res.code = 400;
+ res.end();
+ return;
+ }
+ }
+
crow::connections::system_bus->async_method_call(
// object_path intentially captured by value
- [&, object_path](const boost::system::error_code ec,
- const GetObjectType &object_names) {
-
+ [
+ &, object_path, dest_property{std::move(dest_property)},
+ property_set_value{std::move(property_set_value)}
+ ](const boost::system::error_code ec,
+ const GetObjectType &object_names) {
if (ec) {
res.code = 500;
res.end();
@@ -156,37 +190,109 @@
res.end();
return;
}
-
- for (auto &interface : object_names[0].second) {
- outstanding_async_calls++;
- crow::connections::system_bus->async_method_call(
- [&](const boost::system::error_code ec,
+ if (req.method == "GET"_method) {
+ for (auto &interface : object_names[0].second) {
+ outstanding_async_calls++;
+ crow::connections::system_bus->async_method_call(
+ [&](const boost::system::error_code ec,
+ const std::vector<std::pair<
+ std::string, dbus::dbus_variant>> &properties) {
+ outstanding_async_calls--;
+ if (ec) {
+ std::cerr << "Bad dbus request error: " << ec;
+ } else {
+ for (auto &property : properties) {
+ boost::apply_visitor(
+ [&](auto val) {
+ object_paths[property.first] = val;
+ },
+ property.second);
+ }
+ }
+ if (outstanding_async_calls == 0) {
+ nlohmann::json j{{"status", "ok"},
+ {"message", "200 OK"},
+ {"data", object_paths}};
+ res.body = j.dump();
+ res.end();
+ object_paths.clear();
+ }
+ },
+ {object_names[0].first, object_path,
+ "org.freedesktop.DBus.Properties", "GetAll"},
+ interface);
+ }
+ } else if (req.method == "PUT"_method) {
+ for (auto &interface : object_names[0].second) {
+ outstanding_async_calls++;
+ crow::connections::system_bus->async_method_call(
+ [
+ &, interface{std::move(interface)},
+ object_names{std::move(object_names)},
+ object_path{std::move(object_path)},
+ dest_property{std::move(dest_property)},
+ property_set_value{std::move(property_set_value)}
+ ](const boost::system::error_code ec,
const std::vector<std::pair<
std::string, dbus::dbus_variant>> &properties) {
- outstanding_async_calls--;
- if (ec) {
- std::cerr << "Bad dbus request error: " << ec;
- } else {
- for (auto &property : properties) {
- boost::apply_visitor(
- [&](auto val) {
- object_paths[property.first] = val;
- },
- property.second);
+ outstanding_async_calls--;
+ if (ec) {
+ std::cerr << "Bad dbus request error: " << ec;
+ } else {
+ for (auto &property : properties) {
+ // search all the properties in the interfaces
+ if (dest_property.compare(property.first) == 0) {
+ // find the matched property in the interface
+ property_matched = true;
+ dbus::dbus_variant property_value(
+ property_set_value); // create the dbus
+ // variant for dbus call
+ crow::connections::system_bus->async_method_call(
+ [&](const boost::system::error_code ec) {
+ // use the method "Set" to set the property
+ // value
+ if (ec) {
+ std::cerr << "Bad dbus request error: "
+ << ec;
+ res.code = 500;
+ res.end();
+ } else {
+ // find the matched property and send the
+ // response
+ res.json_value = {{"status", "ok"},
+ {"message", "200 OK"},
+ {"data", NULL}};
+ res.end();
+ return;
+ }
+ },
+ {object_names[0].first, object_path,
+ "org.freedesktop.DBus.Properties", "Set"},
+ interface, dest_property, property_value);
+ }
+ }
+ if (outstanding_async_calls == 0) {
+ // all search has been finished
+ if (property_matched == false) {
+ nlohmann::json j{{"status", "error"},
+ {"message", "403 Forbidden"},
+ {"data",
+ {{"message",
+ "The specified property "
+ "cannot be created: " +
+ dest_property}}}};
+ res.json_value = j;
+ res.end();
+ return;
+ } else
+ property_matched = false;
+ }
}
- }
- if (outstanding_async_calls == 0) {
- nlohmann::json j{{"status", "ok"},
- {"message", "200 OK"},
- {"data", object_paths}};
- res.body = j.dump();
- res.end();
- object_paths.clear();
- }
- },
- {object_names[0].first, object_path,
- "org.freedesktop.DBus.Properties", "GetAll"},
- interface);
+ },
+ {object_names[0].first, object_path,
+ "org.freedesktop.DBus.Properties", "GetAll"},
+ interface);
+ }
}
},
{"xyz.openbmc_project.ObjectMapper",
@@ -194,6 +300,7 @@
"xyz.openbmc_project.ObjectMapper", "GetObject"},
object_path, std::array<std::string, 0>());
});
+
CROW_ROUTE(app, "/bus/system/<str>/")
.methods("GET"_method)([](const crow::request &req, crow::response &res,
const std::string &connection) {