Move bmcweb over to sdbusplus
This patchset moves bmcweb from using boost-dbus over entirely to
sdbusplus. This has some nice improvements in performance (about 30%
of CPU cycles saved in dbus transactions), as well as makes this
project manuver closer to the upstream way of thinking.
Changes to bmcweb are largely ceremonial, and fall into a few
categories:
1. Moves async_method_call instances to the new format, and deletes any
use of the "endpoint" object in leiu of the sdbusplus style interface
2. sdbus object_path object doesn't allow access to the string
directly, so code that uses it moves to explicit casts.
3. The mapbox variant, while attempting to recreate boost::variant,
misses a T* get<T*>() method implementation, which allows using variant
without exceptions. Currently, there is an overload for
mapbox::get_ptr implementation which replecates the functionality.
Tested by: Booting the bmcweb on a target, iterating through redfish
basic phosphor-webui usage, and websockets usage
Change-Id: I2d95882908d6eb6dba00b9219a221dd96449ca7b
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 869fc48..3ff1182 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,7 +63,8 @@
endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if(NOT ${YOCTO_DEPENDENCIES}) # Download and unpack googletest at configure time
- configure_file(CMakeLists.txt.in 3rdparty/CMakeLists.txt)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in
+ 3rdparty/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3rdparty)
execute_process(COMMAND ${CMAKE_COMMAND} --build .
@@ -80,8 +81,20 @@
add_definitions(-DBOOST_NO_TYPEID)
# set(Boost_USE_STATIC_LIBS ON)
-find_package(Boost 1.64 REQUIRED)
-include_directories(${Boost_INCLUDE_DIRS})
+#find_package(Boost 1.66 REQUIRED)
+include_directories(${CMAKE_BINARY_DIR}/boost-src)
+
+# sdbusplus
+if(NOT ${YOCTO_DEPENDENCIES})
+ include_directories(${CMAKE_BINARY_DIR}/sdbusplus-src
+ ${CMAKE_BINARY_DIR}/prefix/include)
+ set(WANT_TRANSACTION 0)
+
+ configure_file(${CMAKE_BINARY_DIR}/sdbusplus-src/sdbusplus/server.hpp.in
+ ${CMAKE_BINARY_DIR}/prefix/include/sdbusplus/server.hpp @ONLY)
+ configure_file(${CMAKE_BINARY_DIR}/sdbusplus-src/sdbusplus/bus.hpp.in
+ ${CMAKE_BINARY_DIR}/prefix/include/sdbusplus/bus.hpp @ONLY)
+endif()
# Openssl
find_package(OpenSSL REQUIRED)
@@ -96,6 +109,9 @@
add_definitions(-DCROW_ENABLE_DEBUG)
endif(CMAKE_BUILD_TYPE MATCHES Debug)
+#add_definitions(-DCROW_ENABLE_LOGGING)
+#add_definitions(-DCROW_ENABLE_DEBUG)
+
add_definitions(-DCROW_ENABLE_SSL)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/crow/include)
@@ -113,9 +129,6 @@
add_definitions("-Wno-attributes")
-# Boost-dbus
-find_package(boost-dbus REQUIRED)
-
# tinyxml2
find_package(tinyxml2 REQUIRED)
@@ -168,7 +181,6 @@
target_link_libraries(webtest ${GMOCK_LIBRARIES})
target_link_libraries(webtest pthread)
- target_link_libraries(webtest boost-dbus)
target_link_libraries(webtest ${OPENSSL_LIBRARIES})
target_link_libraries(webtest ${ZLIB_LIBRARIES})
target_link_libraries(webtest pam)
@@ -182,7 +194,6 @@
# bmcweb
add_executable(bmcweb ${WEBSERVER_MAIN} ${HDR_FILES} ${SRC_FILES})
-target_link_libraries(bmcweb boost-dbus)
target_link_libraries(bmcweb pthread)
target_link_libraries(bmcweb ${OPENSSL_LIBRARIES})
target_link_libraries(bmcweb ${ZLIB_LIBRARIES})
@@ -190,6 +201,7 @@
target_link_libraries(bmcweb -lsystemd)
target_link_libraries(bmcweb -lstdc++fs)
target_link_libraries(bmcweb tinyxml2)
+target_link_libraries(bmcweb sdbusplus)
install(TARGETS bmcweb DESTINATION bin)
add_executable(getvideo src/getvideo_main.cpp)
diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in
index ccce7d8..7025398 100644
--- a/CMakeLists.txt.in
+++ b/CMakeLists.txt.in
@@ -2,6 +2,29 @@
include(ExternalProject)
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/prefix)
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/prefix/include)
+
+
+# add back GIT_TAG in with the correct SHA1 once
+# https://gerrit.openbmc-project.xyz/#/c/10278/ is merged
+#GIT_TAG
+#2a3af936625bc66cfc6bae1952b57138f141377e
+ExternalProject_Add(
+ sdbusplus
+ GIT_REPOSITORY
+ "https://gerrit.openbmc-project.xyz/openbmc/sdbusplus"
+ GIT_TAG
+ fce038ad5ac9f458b03d55b441253a9c05dadc3e
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/sdbusplus-src"
+ BINARY_DIR "${CMAKE_BINARY_DIR}/sdbusplus-build"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND cp -r "${CMAKE_BINARY_DIR}/sdbusplus-src/sdbusplus"
+ "${CMAKE_BINARY_DIR}/prefix/include"
+)
+
ExternalProject_Add(
tinyxml2
GIT_REPOSITORY
@@ -26,17 +49,6 @@
)
ExternalProject_Add(
- boost-dbus
- GIT_REPOSITORY
- "ssh://git-amr-2.devtools.intel.com:29418/openbmc-boost-dbus"
- GIT_TAG
- 895ef1b67f3aaac3808296e4729b991fcf276832
- SOURCE_DIR "${CMAKE_BINARY_DIR}/boost-dbus-src"
- BINARY_DIR "${CMAKE_BINARY_DIR}/boost-dbus-build"
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix -DBOOST_DBUS_BUILD_UT=OFF
-)
-
-ExternalProject_Add(
gtest
GIT_REPOSITORY
"https://github.com/google/googletest.git"
@@ -46,4 +58,4 @@
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix
-)
\ No newline at end of file
+)
diff --git a/include/dbus_monitor.hpp b/include/dbus_monitor.hpp
index 0306183..ab7ebef 100644
--- a/include/dbus_monitor.hpp
+++ b/include/dbus_monitor.hpp
@@ -1,7 +1,6 @@
#pragma once
-#include <dbus/filter.hpp>
-#include <dbus/match.hpp>
#include <dbus_singleton.hpp>
+#include <sdbusplus/bus/match.hpp>
#include <crow/app.h>
#include <boost/container/flat_map.hpp>
@@ -9,34 +8,38 @@
namespace dbus_monitor {
struct DbusWebsocketSession {
- std::vector<std::unique_ptr<dbus::match>> matches;
- std::vector<dbus::filter> filters;
+ std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
};
static boost::container::flat_map<crow::websocket::connection*,
DbusWebsocketSession>
sessions;
-void on_property_update(dbus::filter& filter, boost::system::error_code ec,
- dbus::message s) {
- if (!ec) {
- std::string object_name;
- std::vector<std::pair<std::string, dbus::dbus_variant>> values;
- s.unpack(object_name, values);
- nlohmann::json j;
- for (auto& value : values) {
- boost::apply_visitor([&](auto val) { j[s.get_path()] = val; },
- value.second);
- }
- auto data_to_send = j.dump();
-
- for (auto& session : sessions) {
- session.first->send_text(data_to_send);
- }
+int on_property_update(sd_bus_message* m, void* userdata,
+ sd_bus_error* ret_error) {
+ if (ret_error == nullptr || sd_bus_error_is_set(ret_error)) {
+ CROW_LOG_ERROR << "Sdbus error in on_property_update";
+ return 0;
}
- filter.async_dispatch([&](boost::system::error_code ec, dbus::message s) {
- on_property_update(filter, ec, s);
- });
+ sdbusplus::message::message message(m);
+ std::string object_name;
+ std::vector<
+ std::pair<std::string, sdbusplus::message::variant<
+ std::string, bool, int64_t, uint64_t, double>>>
+ values;
+ message.read(object_name, values);
+ nlohmann::json j;
+ const std::string& path = message.get_path();
+ for (auto& value : values) {
+ mapbox::util::apply_visitor([&](auto&& val) { j[path] = val; },
+ value.second);
+ }
+ std::string data_to_send = j.dump();
+
+ for (const std::pair<crow::websocket::connection*, DbusWebsocketSession>&
+ session : sessions) {
+ session.first->send_text(data_to_send);
+ }
};
template <typename... Middlewares>
@@ -56,19 +59,10 @@
"interface='org.freedesktop.DBus.Properties',"
"path_namespace='" +
path_namespace + "'");
- sessions[&conn].matches.push_back(std::make_unique<dbus::match>(
- crow::connections::system_bus, std::move(match_string)));
-
- sessions[&conn].filters.emplace_back(
- crow::connections::system_bus, [path_namespace](dbus::message m) {
- return m.get_member() == "PropertiesChanged" &&
- boost::starts_with(m.get_path(), path_namespace);
- });
- auto& this_filter = sessions[&conn].filters.back();
- this_filter.async_dispatch(
- [&](boost::system::error_code ec, dbus::message s) {
- on_property_update(this_filter, ec, s);
- });
+ sessions[&conn].matches.emplace_back(
+ std::make_unique<sdbusplus::bus::match::match>(
+ *crow::connections::system_bus, match_string,
+ on_property_update));
})
.onclose([&](crow::websocket::connection& conn,
@@ -78,5 +72,5 @@
CROW_LOG_ERROR << "Got unexpected message from client on sensorws";
});
}
-} // namespace redfish
+} // namespace dbus_monitor
} // namespace crow
diff --git a/include/dbus_singleton.hpp b/include/dbus_singleton.hpp
index e2fd2d6..e6be81b 100644
--- a/include/dbus_singleton.hpp
+++ b/include/dbus_singleton.hpp
@@ -1,10 +1,21 @@
#pragma once
-#include <dbus/connection.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <iostream>
+
+namespace mapbox {
+template <typename T, typename... Types>
+const T* get_ptr(const mapbox::util::variant<Types...>& v) {
+ if (v.template is<std::remove_const_t<T>>()) {
+ return &v.template get_unchecked<std::remove_const_t<T>>();
+ } else {
+ return nullptr;
+ }
+}
+} // namespace mapbox
namespace crow {
namespace connections {
+static std::shared_ptr<sdbusplus::asio::connection> system_bus;
-static std::shared_ptr<dbus::connection> system_bus;
-
-} // namespace dbus
-} // namespace crow
\ No newline at end of file
+} // namespace connections
+} // namespace crow
diff --git a/include/intel_oem.hpp b/include/intel_oem.hpp
index e821807..f2dc163 100644
--- a/include/intel_oem.hpp
+++ b/include/intel_oem.hpp
@@ -10,24 +10,29 @@
template <typename... Middlewares>
void request_routes(Crow<Middlewares...>& app) {
CROW_ROUTE(app, "/intel/firmwareupload")
- .methods("POST"_method)([](const crow::request& req) {
+ .methods(
+ "POST"_method)([](const crow::request& req, crow::response& res) {
std::string filepath("/tmp/fw_update_image");
std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
std::ofstream::trunc);
out << req.body;
out.close();
+ crow::connections::system_bus->async_method_call(
+ [&](boost::system::error_code ec) {
+ std::cout << "async_method_call callback\n";
+ if (ec) {
+ std::cerr << "error with async_method_call \n";
+ res.json_value["status"] = "Upload failed";
+ } else {
+ res.json_value["status"] = "Upload Successful";
+ }
+ res.end();
+ },
+ "xyz.openbmc_project.fwupdate1.server",
+ "/xyz/openbmc_project/fwupdate1", "xyz.openbmc_project.fwupdate1",
+ "start", "file://" + filepath);
- auto m = dbus::message::new_call(
- {"xyz.openbmc_project.fwupdate1.server",
- "/xyz/openbmc_project/fwupdate1", "xyz.openbmc_project.fwupdate1"},
- "start");
-
- m.pack(std::string("file://") + filepath);
- crow::connections::system_bus->send(m);
- nlohmann::json j;
- j["status"] = "Upload Successful";
- return j;
});
}
-} // namespace redfish
+} // namespace intel_oem
} // namespace crow
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index d42c04b..4257127 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -1,11 +1,6 @@
#include <crow/app.h>
#include <tinyxml2.h>
-#include <dbus/connection.hpp>
-#include <dbus/endpoint.hpp>
-#include <dbus/filter.hpp>
-#include <dbus/match.hpp>
-#include <dbus/message.hpp>
#include <dbus_singleton.hpp>
#include <boost/container/flat_set.hpp>
@@ -15,12 +10,11 @@
void introspect_objects(crow::response &res, std::string process_name,
std::string path,
std::shared_ptr<nlohmann::json> transaction) {
- dbus::endpoint introspect_endpoint(
- process_name, path, "org.freedesktop.DBus.Introspectable", "Introspect");
crow::connections::system_bus->async_method_call(
- [&, process_name{std::move(process_name)}, object_path{std::move(path)} ](
- const boost::system::error_code ec,
- const std::string &introspect_xml) {
+ [
+ &res, transaction, process_name{std::move(process_name)},
+ object_path{std::move(path)}
+ ](const boost::system::error_code ec, const std::string &introspect_xml) {
if (ec) {
CROW_LOG_ERROR << "Introspect call failed with error: "
<< ec.message() << " on process: " << process_name
@@ -35,7 +29,7 @@
tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
if (pRoot == nullptr) {
CROW_LOG_ERROR << "XML document failed to parse " << process_name
- << " " << path << "\n";
+ << " " << object_path << "\n";
} else {
tinyxml2::XMLElement *node = pRoot->FirstChildElement("node");
@@ -61,14 +55,23 @@
res.end();
}
},
- introspect_endpoint);
+ process_name, path, "org.freedesktop.DBus.Introspectable", "Introspect");
}
-using ManagedObjectType = std::vector<std::pair<
- dbus::object_path, boost::container::flat_map<
- std::string, boost::container::flat_map<
- std::string, dbus::dbus_variant>>>>;
-void get_manged_objects_for_enumerate(
+// A smattering of common types to unpack. TODO(ed) this should really iterate
+// the sdbusplus object directly and build the json response
+using DbusRestVariantType = sdbusplus::message::variant<
+ std::vector<std::tuple<std::string, std::string, std::string>>, std::string,
+ int64_t, uint64_t, double, int32_t, uint32_t, int16_t, uint16_t, uint8_t,
+ bool>;
+
+using ManagedObjectType = std::vector<std::pair<
+ sdbusplus::message::object_path,
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, DbusRestVariantType>>>>;
+
+void get_managed_objects_for_enumerate(
const std::string &object_name, const std::string &connection_name,
crow::response &res, std::shared_ptr<nlohmann::json> transaction) {
crow::connections::system_bus->async_method_call(
@@ -78,13 +81,29 @@
CROW_LOG_ERROR << ec;
} else {
nlohmann::json &data_json = *transaction;
+
for (auto &object_path : objects) {
- nlohmann::json &object_json = data_json[object_path.first.value];
+ CROW_LOG_DEBUG << "Reading object "
+ << static_cast<const std::string&>(object_path.first);
+ nlohmann::json &object_json =
+ data_json[static_cast<const std::string&>(object_path.first)];
+ if (object_json.is_null()) {
+ object_json = nlohmann::json::object();
+ }
for (const auto &interface : object_path.second) {
for (const auto &property : interface.second) {
- boost::apply_visitor(
- [&](auto &&val) { object_json[property.first] = val; },
+ nlohmann::json &property_json = object_json[property.first];
+ mapbox::util::apply_visitor(
+ [&property_json](auto &&val) { property_json = val; },
property.second);
+
+ // dbus-rest represents booleans as 1 or 0, implement to match
+ // TODO(ed) see if dbus-rest should be changed
+ const bool *property_bool =
+ property_json.get_ptr<const bool *>();
+ if (property_bool != nullptr) {
+ property_json = *property_bool ? 1 : 0;
+ }
}
}
}
@@ -97,9 +116,9 @@
res.end();
}
},
- {connection_name, object_name, "org.freedesktop.DBus.ObjectManager",
- "GetManagedObjects"});
-} // namespace openbmc_mapper
+ connection_name, object_name, "org.freedesktop.DBus.ObjectManager",
+ "GetManagedObjects");
+}
using GetSubTreeType = std::vector<
std::pair<std::string,
@@ -132,14 +151,14 @@
auto transaction =
std::make_shared<nlohmann::json>(nlohmann::json::object());
for (const std::string &connection : connections) {
- get_manged_objects_for_enumerate(object_path, connection, res,
- transaction);
+ get_managed_objects_for_enumerate(object_path, connection, res,
+ transaction);
}
},
- {"xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree"},
- object_path, (int32_t)0, std::array<std::string, 0>());
+ "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree", object_path, (int32_t)0,
+ std::array<std::string, 0>());
}
template <typename... Middlewares>
@@ -151,33 +170,32 @@
CROW_ROUTE(app, "/bus/system/")
.methods("GET"_method)([](const crow::request &req, crow::response &res) {
+
+ auto myCallback = [&res](const boost::system::error_code ec,
+ std::vector<std::string> &names) {
+ if (ec) {
+ res.code = 500;
+ } else {
+ std::sort(names.begin(), names.end());
+ nlohmann::json j{{"status", "ok"}};
+ auto &objects_sub = j["objects"];
+ for (auto &name : names) {
+ objects_sub.push_back({{"name", name}});
+ }
+ res.json_value = std::move(j);
+ }
+ res.end();
+ };
crow::connections::system_bus->async_method_call(
- [&](const boost::system::error_code ec,
- std::vector<std::string> &names) {
-
- if (ec) {
- res.code = 500;
- } else {
- std::sort(names.begin(), names.end());
- nlohmann::json j{{"status", "ok"}};
- auto &objects_sub = j["objects"];
- for (auto &name : names) {
- objects_sub.push_back({{"name", name}});
- }
- res.json_value = std::move(j);
- }
- res.end();
- },
- {"org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames"});
-
+ std::move(myCallback), "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "ListNames");
});
CROW_ROUTE(app, "/list/")
.methods("GET"_method)([](const crow::request &req, crow::response &res) {
crow::connections::system_bus->async_method_call(
- [&](const boost::system::error_code ec,
- const std::vector<std::string> &object_paths) {
-
+ [&res](const boost::system::error_code ec,
+ const std::vector<std::string> &object_paths) {
if (ec) {
res.code = 500;
} else {
@@ -187,10 +205,10 @@
}
res.end();
},
- {"xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"},
- "", static_cast<int32_t>(99), std::array<std::string, 0>());
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "",
+ static_cast<int32_t>(99), std::array<std::string, 0>());
});
CROW_ROUTE(app, "/xyz/<path>")
@@ -242,9 +260,9 @@
crow::connections::system_bus->async_method_call(
[
- &, object_path{std::move(object_path)},
- dest_property{std::move(dest_property)},
- property_set_value{std::move(property_set_value)}, transaction
+ &res, &req, object_path{std::move(object_path)},
+ dest_property{std::move(dest_property)},
+ property_set_value{std::move(property_set_value)}, transaction
](const boost::system::error_code ec,
const GetObjectType &object_names) {
if (ec) {
@@ -260,17 +278,17 @@
if (req.method == "GET"_method) {
for (auto &interface : object_names[0].second) {
crow::connections::system_bus->async_method_call(
- [&](const boost::system::error_code ec,
+ [&res, transaction](
+ const boost::system::error_code ec,
const std::vector<std::pair<
- std::string, dbus::dbus_variant>> &properties) {
+ std::string, DbusRestVariantType>> &properties) {
if (ec) {
CROW_LOG_ERROR << "Bad dbus request error: " << ec;
} else {
for (auto &property : properties) {
- boost::apply_visitor(
- [&](auto val) {
- (*transaction)[property.first] = val;
- },
+ nlohmann::json &it = (*transaction)[property.first];
+ mapbox::util::apply_visitor(
+ [&it](auto &&val) { it = val; },
property.second);
}
}
@@ -282,9 +300,8 @@
res.end();
}
},
- {object_names[0].first, object_path,
- "org.freedesktop.DBus.Properties", "GetAll"},
- interface);
+ 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) {
@@ -298,18 +315,19 @@
transaction
](const boost::system::error_code ec,
const boost::container::flat_map<
- std::string, dbus::dbus_variant> &properties) {
+ std::string, DbusRestVariantType> &properties) {
if (ec) {
CROW_LOG_ERROR << "Bad dbus request error: " << ec;
} else {
auto it = properties.find(dest_property);
if (it != properties.end()) {
// find the matched property in the interface
- dbus::dbus_variant property_value(
- property_set_value); // create the dbus
- // variant for dbus call
+ DbusRestVariantType 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) {
+ [transaction](
+ const boost::system::error_code ec) {
// use the method "Set" to set the property
// value
if (ec) {
@@ -323,8 +341,8 @@
{"data", nullptr}};
},
- {object_names[0].first, object_path,
- "org.freedesktop.DBus.Properties", "Set"},
+ object_names[0].first, object_path,
+ "org.freedesktop.DBus.Properties", "Set",
interface, dest_property, property_value);
}
}
@@ -350,16 +368,15 @@
return;
}
},
- {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",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetObject"},
- object_path, std::array<std::string, 0>());
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject", object_path,
+ std::array<std::string, 0>());
});
CROW_ROUTE(app, "/bus/system/<str>/")
@@ -413,9 +430,6 @@
res.end();
return;
}
- dbus::endpoint introspect_endpoint(
- process_name, object_path, "org.freedesktop.DBus.Introspectable",
- "Introspect");
if (interface_name.empty()) {
crow::connections::system_bus->async_method_call(
[
@@ -459,7 +473,8 @@
}
res.end();
},
- introspect_endpoint);
+ process_name, object_path, "org.freedesktop.DBus.Introspectable",
+ "Introspect");
} else {
crow::connections::system_bus->async_method_call(
[
@@ -566,10 +581,11 @@
}
res.end();
},
- introspect_endpoint);
+ process_name, object_path, "org.freedesktop.DBus.Introspectable",
+ "Introspect");
}
});
-}
+} // namespace openbmc_mapper
} // namespace openbmc_mapper
} // namespace crow
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index c28208d..03b9051 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -1,10 +1,6 @@
#pragma once
-#include <dbus/connection.hpp>
-#include <dbus/endpoint.hpp>
-#include <dbus/filter.hpp>
-#include <dbus/match.hpp>
-#include <dbus/message.hpp>
+#include <dbus_singleton.hpp>
#include <persistent_data_middleware.hpp>
#include <token_authorization_middleware.hpp>
#include <fstream>
@@ -43,10 +39,13 @@
return result;
}
+// GetManagedObjects unpack type. Observe that variant has only one bool type,
+// because we don't actually use the values it provides
using ManagedObjectType = std::vector<std::pair<
- dbus::object_path, boost::container::flat_map<
- std::string, boost::container::flat_map<
- std::string, dbus::dbus_variant>>>>;
+ sdbusplus::message::object_path,
+ boost::container::flat_map<
+ std::string, boost::container::flat_map<
+ std::string, sdbusplus::message::variant<bool>>>>>;
template <typename... Middlewares>
void request_routes(Crow<Middlewares...>& app) {
@@ -79,7 +78,8 @@
nlohmann::json member_array = nlohmann::json::array();
int user_index = 0;
for (auto& user : users) {
- const std::string& path = user.first.value;
+ const std::string& path =
+ static_cast<std::string>(user.first);
std::size_t last_index = path.rfind("/");
if (last_index == std::string::npos) {
last_index = 0;
@@ -94,8 +94,8 @@
}
res.end();
},
- {"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
});
CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
@@ -110,7 +110,8 @@
res.code = 500;
} else {
for (auto& user : users) {
- const std::string& path = user.first.value;
+ const std::string& path =
+ static_cast<std::string>(user.first);
std::size_t last_index = path.rfind("/");
if (last_index == std::string::npos) {
last_index = 0;
@@ -145,8 +146,8 @@
}
res.end();
},
- {"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
});
}
} // namespace redfish
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index 59e9cca..07540d4 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -173,7 +173,8 @@
bool is_on_whitelist(const crow::request& req) const {
// it's allowed to GET root node without authentication
if ("GET"_method == req.method) {
- if (req.url == "/redfish/v1") {
+ CROW_LOG_DEBUG << "TESTING ROUTE " << req.url;
+ if (req.url == "/redfish/v1" || req.url == "/redfish/v1/") {
return true;
} else if (crow::webassets::routes.find(req.url) !=
crow::webassets::routes.end()) {
@@ -183,7 +184,8 @@
// it's allowed to POST on session collection & login without authentication
if ("POST"_method == req.method) {
- if ((req.url == "/redfish/v1/SessionService/Sessions") ||
+ if ((req.url == "/redfish/v1/SessionService/Sessions" ||
+ req.url == "/redfish/v1/SessionService/Sessions/") ||
(req.url == "/login") || (req.url == "/logout")) {
return true;
}
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index c7f7b95..7db9357 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -24,14 +24,16 @@
* DBus types primitives for several generic DBus interfaces
* TODO(Pawel) consider move this to separate file into boost::dbus
*/
-using ManagedObjectsType = std::vector<
- std::pair<dbus::object_path,
- std::vector<std::pair<
- std::string,
- std::vector<std::pair<std::string, dbus::dbus_variant>>>>>>;
+// Note, this is not a very useful variant, but because it isn't used to get
+// values, it should be as simple as possible
+// TODO(ed) invent a nullvariant type
+using VariantType = sdbusplus::message::variant<std::string>;
+using ManagedObjectsType = std::vector<std::pair<
+ sdbusplus::message::object_path,
+ std::vector<std::pair<std::string,
+ std::vector<std::pair<std::string, VariantType>>>>>>;
-using PropertiesType =
- boost::container::flat_map<std::string, dbus::dbus_variant>;
+using PropertiesType = boost::container::flat_map<std::string, VariantType>;
/**
* OnDemandChassisProvider
@@ -79,7 +81,8 @@
{"serial_number", "SerialNumber"}}}) {
PropertiesType::const_iterator it = properties.find(p.first);
if (it != properties.end()) {
- const std::string *s = boost::get<std::string>(&it->second);
+ const std::string *s =
+ mapbox::get_ptr<const std::string>(it->second);
if (s != nullptr) {
output[p.second] = *s;
}
@@ -88,9 +91,9 @@
// Callback with success, and hopefully data.
callback(true, output);
},
- {"xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
- "org.freedesktop.DBus.Properties", "GetAll"},
+ "xyz.openbmc_project.EntityManager",
+ "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
+ "org.freedesktop.DBus.Properties", "GetAll",
"xyz.openbmc_project.Configuration.Chassis");
}
@@ -126,7 +129,7 @@
if (interface.first ==
"xyz.openbmc_project.Configuration.Chassis") {
// Cut out everything until last "/", ...
- const std::string &chassis_id = objpath.first.value;
+ const std::string &chassis_id = objpath.first.str;
std::size_t last_pos = chassis_id.rfind("/");
if (last_pos != std::string::npos) {
// and put it into output vector.
@@ -138,9 +141,9 @@
// Finally make a callback with useful data
callback(true, chassis_list);
},
- {"xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.EntityManager",
+ "/xyz/openbmc_project/Inventory/Item/Chassis",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
};
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 88ce9f2..ea465fb 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -24,14 +24,19 @@
* DBus types primitives for several generic DBus interfaces
* TODO(Pawel) consider move this to separate file into boost::dbus
*/
-using PropertiesMapType =
- boost::container::flat_map<std::string, dbus::dbus_variant>;
+using PropertiesMapType = boost::container::flat_map<
+ std::string,
+ sdbusplus::message::variant<std::string, bool, uint8_t, int16_t, uint16_t,
+ int32_t, uint32_t, int64_t, uint64_t, double>>;
using GetManagedObjectsType = boost::container::flat_map<
- dbus::object_path,
- boost::container::flat_map<std::string, PropertiesMapType>>;
-
-using GetAllPropertiesType = PropertiesMapType;
+ sdbusplus::message::object_path,
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<
+ std::string, sdbusplus::message::variant<
+ std::string, bool, uint8_t, int16_t, uint16_t,
+ int32_t, uint32_t, int64_t, uint64_t, double>>>>;
/**
* Structure for keeping IPv4 data required by Redfish
@@ -76,8 +81,8 @@
// Helper function that allows to extract GetAllPropertiesType from
// GetManagedObjectsType, based on object path, and interface name
const PropertiesMapType *extractInterfaceProperties(
- const dbus::object_path &objpath, const std::string &interface,
- const GetManagedObjectsType &dbus_data) {
+ const sdbusplus::message::object_path &objpath,
+ const std::string &interface, const GetManagedObjectsType &dbus_data) {
const auto &dbus_obj = dbus_data.find(objpath);
if (dbus_obj != dbus_data.end()) {
const auto &iface = dbus_obj->second.find(interface);
@@ -89,22 +94,22 @@
}
// Helper Wrapper that does inline object_path conversion from string
- // into dbus::object_path type
+ // into sdbusplus::message::object_path type
inline const PropertiesMapType *extractInterfaceProperties(
const std::string &objpath, const std::string &interface,
const GetManagedObjectsType &dbus_data) {
- const auto &dbus_obj = dbus::object_path{objpath};
+ const auto &dbus_obj = sdbusplus::message::object_path{objpath};
return extractInterfaceProperties(dbus_obj, interface, dbus_data);
}
// Helper function that allows to get pointer to the property from
// GetAllPropertiesType native, or extracted by GetAllPropertiesType
template <typename T>
- inline const T *extractProperty(const PropertiesMapType &properties,
- const std::string &name) {
+ inline T const *const extractProperty(const PropertiesMapType &properties,
+ const std::string &name) {
const auto &property = properties.find(name);
if (property != properties.end()) {
- return boost::get<T>(&property->second);
+ return mapbox::get_ptr<const T>(property->second);
}
return nullptr;
}
@@ -177,7 +182,7 @@
for (auto &objpath : dbus_data) {
// Check if proper patter for object path appears
if (boost::starts_with(
- objpath.first.value,
+ static_cast<std::string>(objpath.first),
"/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/")) {
// and get approrpiate interface
const auto &interface =
@@ -244,7 +249,7 @@
this, ethiface_id{std::move(ethiface_id)},
callback{std::move(callback)}
](const boost::system::error_code error_code,
- const GetManagedObjectsType &resp) {
+ GetManagedObjectsType &resp) {
EthernetInterfaceData eth_data{};
std::vector<IPv4AddressData> ipv4_data;
@@ -273,8 +278,8 @@
// Finally make a callback with useful data
callback(true, eth_data, ipv4_data);
},
- {"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
/**
@@ -288,7 +293,7 @@
crow::connections::system_bus->async_method_call(
[ this, callback{std::move(callback)} ](
const boost::system::error_code error_code,
- const GetManagedObjectsType &resp) {
+ GetManagedObjectsType &resp) {
// Callback requires vector<string> to retrieve all available ethernet
// interfaces
std::vector<std::string> iface_list;
@@ -310,8 +315,9 @@
// this is what we're looking for.
if (interface.first ==
"xyz.openbmc_project.Network.EthernetInterface") {
- // Cut out everything until last "/", ...
- const std::string &iface_id = objpath.first.value;
+ // Cut out everyting until last "/", ...
+ const std::string iface_id =
+ static_cast<std::string>(objpath.first);
std::size_t last_pos = iface_id.rfind("/");
if (last_pos != std::string::npos) {
// and put it into output vector.
@@ -323,8 +329,8 @@
// Finally make a callback with useful data
callback(true, iface_list);
},
- {"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
};
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index 1410122..581eb03 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -95,10 +95,10 @@
}
}
- std::map<int, std::string> portToProtocolMap{
+ boost::container::flat_map<int, std::string> portToProtocolMap{
{22, "SSH"}, {80, "HTTP"}, {443, "HTTPS"}, {623, "IPMI"}, {1900, "SSDP"}};
- std::set<int> listeningPorts;
+ boost::container::flat_set<int> listeningPorts;
};
} // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index f427909..b0cbbe1 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -21,8 +21,6 @@
#include <boost/algorithm/string/split.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/range/algorithm/replace_copy_if.hpp>
-#include <boost/variant.hpp>
-#include <boost/variant/get.hpp>
namespace redfish {
@@ -32,11 +30,12 @@
std::pair<std::string,
std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+using SensorVariant = sdbusplus::message::variant<int64_t, double>;
+
using ManagedObjectsVectorType = std::vector<std::pair<
- dbus::object_path,
+ sdbusplus::message::object_path,
boost::container::flat_map<
- std::string,
- boost::container::flat_map<dbus::string, dbus::dbus_variant>>>>;
+ std::string, boost::container::flat_map<std::string, SensorVariant>>>>;
/**
* AsyncResp
@@ -83,9 +82,6 @@
const std::string path = "/xyz/openbmc_project/Sensors";
const std::array<std::string, 1> interfaces = {
"xyz.openbmc_project.Sensor.Value"};
- const dbus::endpoint object_mapper(
- "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree");
// Response handler for parsing objects subtree
auto resp_handler = [ callback{std::move(callback)}, asyncResp, sensorNames ](
@@ -136,8 +132,10 @@
};
// Make call to ObjectMapper to find all sensors objects
- crow::connections::system_bus->async_method_call(resp_handler, object_mapper,
- path, 2, interfaces);
+ crow::connections::system_bus->async_method_call(
+ resp_handler, "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
+ "GetSubTree", path, 2, interfaces);
}
/**
@@ -149,10 +147,6 @@
void getChassis(const std::shared_ptr<AsyncResp>& asyncResp,
Callback&& callback) {
CROW_LOG_DEBUG << "getChassis Done";
- const dbus::endpoint entityManager = {
- "xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"};
// Process response from EntityManager and extract chassis data
auto resp_handler = [ callback{std::move(callback)}, asyncResp ](
@@ -170,10 +164,11 @@
CROW_LOG_DEBUG << "Chassis Prefix " << chassis_prefix;
bool foundChassis = false;
for (const auto& objDictEntry : resp) {
- if (boost::starts_with(objDictEntry.first.value, chassis_prefix)) {
+ if (boost::starts_with(static_cast<std::string>(objDictEntry.first),
+ chassis_prefix)) {
foundChassis = true;
const std::string sensorName =
- objDictEntry.first.value.substr(chassis_prefix.size());
+ std::string(objDictEntry.first).substr(chassis_prefix.size());
// Make sure this isn't a subobject (like a threshold)
const std::size_t sensorPos = sensorName.find('/');
if (sensorPos == std::string::npos) {
@@ -194,7 +189,10 @@
};
// Make call to EntityManager to find all chassis objects
- crow::connections::system_bus->async_method_call(resp_handler, entityManager);
+ crow::connections::system_bus->async_method_call(
+ resp_handler, "xyz.openbmc_project.EntityManager",
+ "/xyz/openbmc_project/Inventory/Item/Chassis",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}
/**
@@ -209,8 +207,7 @@
void objectInterfacesToJson(
const std::string& sensorName, const std::string& sensorType,
const boost::container::flat_map<
- std::string,
- boost::container::flat_map<dbus::string, dbus::dbus_variant>>&
+ std::string, boost::container::flat_map<std::string, SensorVariant>>&
interfacesDict,
nlohmann::json& sensor_json) {
// We need a value interface before we can do anything with it
@@ -226,7 +223,8 @@
auto scale_it = value_it->second.find("Scale");
// If a scale exists, pull value as int64, and use the scaling.
if (scale_it != value_it->second.end()) {
- const int64_t* int64Value = boost::get<int64_t>(&scale_it->second);
+ const int64_t* int64Value =
+ mapbox::get_ptr<const int64_t>(scale_it->second);
if (int64Value != nullptr) {
scaleMultiplier = *int64Value;
}
@@ -289,10 +287,12 @@
if (interfaceProperties != interfacesDict.end()) {
auto value_it = interfaceProperties->second.find(std::get<1>(p));
if (value_it != interfaceProperties->second.end()) {
- const dbus::dbus_variant& valueVariant = value_it->second;
+ const SensorVariant& valueVariant = value_it->second;
nlohmann::json& value_it = sensor_json[std::get<2>(p)];
+
// Attempt to pull the int64 directly
- const int64_t* int64Value = boost::get<int64_t>(&valueVariant);
+ const int64_t* int64Value =
+ mapbox::get_ptr<const int64_t>(valueVariant);
if (int64Value != nullptr) {
if (forceToInt || scaleMultiplier >= 0) {
@@ -303,7 +303,7 @@
}
}
// Attempt to pull the float directly
- const double* doubleValue = boost::get<double>(&valueVariant);
+ const double* doubleValue = mapbox::get_ptr<const double>(valueVariant);
if (doubleValue != nullptr) {
if (!forceToInt) {
@@ -342,7 +342,8 @@
// Go through all objects and update response with
// sensor data
for (const auto& objDictEntry : resp) {
- const std::string& objPath = objDictEntry.first.value;
+ const std::string& objPath =
+ static_cast<std::string>(objDictEntry.first);
CROW_LOG_DEBUG << "getManagedObjectsCb parsing object "
<< objPath;
if (!boost::starts_with(objPath, DBUS_SENSOR_PREFIX)) {
@@ -406,11 +407,9 @@
}
};
- dbus::endpoint ep(connection, "/xyz/openbmc_project/Sensors",
- "org.freedesktop.DBus.ObjectManager",
- "GetManagedObjects");
crow::connections::system_bus->async_method_call(
- getManagedObjectsCb, ep);
+ getManagedObjectsCb, connection, "/xyz/openbmc_project/Sensors",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
};
// Get connections and then pass it to get sensors
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 16180ae..7531503 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,11 +1,13 @@
#include <systemd/sd-daemon.h>
-#include <dbus/connection.hpp>
#include <dbus_monitor.hpp>
#include <dbus_singleton.hpp>
#include <intel_oem.hpp>
#include <openbmc_dbus_rest.hpp>
#include <persistent_data_middleware.hpp>
#include <redfish_v1.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server.hpp>
#include <security_headers_middleware.hpp>
#include <ssl_key_handler.hpp>
#include <token_authorization_middleware.hpp>
@@ -73,12 +75,11 @@
CROW_LOG_INFO << "bmcweb (" << __DATE__ << ": " << __TIME__ << ')';
setup_socket(app);
- // Start dbus connection
crow::connections::system_bus =
- std::make_shared<dbus::connection>(*io, dbus::bus::system);
-
+ std::make_shared<sdbusplus::asio::connection>(*io);
redfish::RedfishService redfish(app);
app.run();
io->run();
+
}