diff --git a/features/openbmc_rest/dbus_monitor.hpp b/features/openbmc_rest/dbus_monitor.hpp
new file mode 100644
index 0000000..050bd34
--- /dev/null
+++ b/features/openbmc_rest/dbus_monitor.hpp
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+#include "app.hpp"
+#include "dbus_singleton.hpp"
+#include "logging.hpp"
+#include "openbmc_dbus_rest.hpp"
+#include "websocket.hpp"
+
+#include <systemd/sd-bus.h>
+
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <memory>
+#include <regex>
+#include <string>
+#include <vector>
+
+namespace crow
+{
+namespace dbus_monitor
+{
+
+struct DbusWebsocketSession
+{
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
+    boost::container::flat_set<std::string, std::less<>,
+                               std::vector<std::string>>
+        interfaces;
+};
+
+using SessionMap = boost::container::flat_map<crow::websocket::Connection*,
+                                              DbusWebsocketSession>;
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static SessionMap sessions;
+
+inline int onPropertyUpdate(sd_bus_message* m, void* userdata,
+                            sd_bus_error* retError)
+{
+    if (retError == nullptr || (sd_bus_error_is_set(retError) != 0))
+    {
+        BMCWEB_LOG_ERROR("Got sdbus error on match");
+        return 0;
+    }
+    crow::websocket::Connection* connection =
+        static_cast<crow::websocket::Connection*>(userdata);
+    auto thisSession = sessions.find(connection);
+    if (thisSession == sessions.end())
+    {
+        BMCWEB_LOG_ERROR("Couldn't find dbus connection {}",
+                         logPtr(connection));
+        return 0;
+    }
+    sdbusplus::message_t message(m);
+    nlohmann::json json;
+    json["event"] = message.get_member();
+    json["path"] = message.get_path();
+    if (strcmp(message.get_member(), "PropertiesChanged") == 0)
+    {
+        nlohmann::json data;
+        int r = openbmc_mapper::convertDBusToJSON("sa{sv}as", message, data);
+        if (r < 0)
+        {
+            BMCWEB_LOG_ERROR("convertDBusToJSON failed with {}", r);
+            return 0;
+        }
+        if (!data.is_array())
+        {
+            BMCWEB_LOG_ERROR("No data in PropertiesChanged signal");
+            return 0;
+        }
+
+        // data is type sa{sv}as and is an array[3] of string, object, array
+        json["interface"] = data[0];
+        json["properties"] = data[1];
+    }
+    else if (strcmp(message.get_member(), "InterfacesAdded") == 0)
+    {
+        nlohmann::json data;
+        int r = openbmc_mapper::convertDBusToJSON("oa{sa{sv}}", message, data);
+        if (r < 0)
+        {
+            BMCWEB_LOG_ERROR("convertDBusToJSON failed with {}", r);
+            return 0;
+        }
+        nlohmann::json::array_t* arr = data.get_ptr<nlohmann::json::array_t*>();
+        if (arr == nullptr)
+        {
+            BMCWEB_LOG_ERROR("No data in InterfacesAdded signal");
+            return 0;
+        }
+        if (arr->size() < 2)
+        {
+            BMCWEB_LOG_ERROR("No data in InterfacesAdded signal");
+            return 0;
+        }
+
+        nlohmann::json::object_t* obj =
+            (*arr)[1].get_ptr<nlohmann::json::object_t*>();
+        if (obj == nullptr)
+        {
+            BMCWEB_LOG_ERROR("No data in InterfacesAdded signal");
+            return 0;
+        }
+        // data is type oa{sa{sv}} which is an array[2] of string, object
+        for (const auto& entry : *obj)
+        {
+            auto it = thisSession->second.interfaces.find(entry.first);
+            if (it != thisSession->second.interfaces.end())
+            {
+                json["interfaces"][entry.first] = entry.second;
+            }
+        }
+    }
+    else
+    {
+        BMCWEB_LOG_CRITICAL("message {} was unexpected", message.get_member());
+        return 0;
+    }
+
+    connection->sendText(
+        json.dump(2, ' ', true, nlohmann::json::error_handler_t::replace));
+    return 0;
+}
+
+inline void requestRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/subscribe")
+        .privileges({{"Login"}})
+        .websocket()
+        .onopen([](crow::websocket::Connection& conn) {
+            BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));
+            sessions.try_emplace(&conn);
+        })
+        .onclose([](crow::websocket::Connection& conn, const std::string&) {
+            sessions.erase(&conn);
+        })
+        .onmessage([](crow::websocket::Connection& conn,
+                      const std::string& data, bool) {
+            const auto sessionPair = sessions.find(&conn);
+            if (sessionPair == sessions.end())
+            {
+                conn.close("Internal error");
+            }
+            DbusWebsocketSession& thisSession = sessionPair->second;
+            BMCWEB_LOG_DEBUG("Connection {} received {}", logPtr(&conn), data);
+            nlohmann::json j = nlohmann::json::parse(data, nullptr, false);
+            if (j.is_discarded())
+            {
+                BMCWEB_LOG_ERROR("Unable to parse json data for monitor");
+                conn.close("Unable to parse json request");
+                return;
+            }
+            nlohmann::json::iterator interfaces = j.find("interfaces");
+            if (interfaces != j.end())
+            {
+                thisSession.interfaces.reserve(interfaces->size());
+                for (auto& interface : *interfaces)
+                {
+                    const std::string* str =
+                        interface.get_ptr<const std::string*>();
+                    if (str != nullptr)
+                    {
+                        thisSession.interfaces.insert(*str);
+                    }
+                }
+            }
+
+            nlohmann::json::iterator paths = j.find("paths");
+            if (paths == j.end())
+            {
+                BMCWEB_LOG_ERROR("Unable to find paths in json data");
+                conn.close("Unable to find paths in json data");
+                return;
+            }
+
+            size_t interfaceCount = thisSession.interfaces.size();
+            if (interfaceCount == 0)
+            {
+                interfaceCount = 1;
+            }
+
+            // These regexes derived on the rules here:
+            // https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names
+            static std::regex validPath("^/([A-Za-z0-9_]+/?)*$");
+            static std::regex validInterface(
+                "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$");
+
+            for (const auto& thisPath : *paths)
+            {
+                const std::string* thisPathString =
+                    thisPath.get_ptr<const std::string*>();
+                if (thisPathString == nullptr)
+                {
+                    BMCWEB_LOG_ERROR("subscribe path isn't a string?");
+                    conn.close();
+                    return;
+                }
+                if (!std::regex_match(*thisPathString, validPath))
+                {
+                    BMCWEB_LOG_ERROR("Invalid path name {}", *thisPathString);
+                    conn.close();
+                    return;
+                }
+                std::string propertiesMatchString =
+                    ("type='signal',"
+                     "interface='org.freedesktop.DBus.Properties',"
+                     "path_namespace='" +
+                     *thisPathString +
+                     "',"
+                     "member='PropertiesChanged'");
+                // If interfaces weren't specified, add a single match for all
+                // interfaces
+                if (thisSession.interfaces.empty())
+                {
+                    BMCWEB_LOG_DEBUG("Creating match {}",
+                                     propertiesMatchString);
+
+                    thisSession.matches.emplace_back(
+                        std::make_unique<sdbusplus::bus::match_t>(
+                            *crow::connections::systemBus,
+                            propertiesMatchString, onPropertyUpdate, &conn));
+                }
+                else
+                {
+                    // If interfaces were specified, add a match for each
+                    // interface
+                    for (const std::string& interface : thisSession.interfaces)
+                    {
+                        if (!std::regex_match(interface, validInterface))
+                        {
+                            BMCWEB_LOG_ERROR("Invalid interface name {}",
+                                             interface);
+                            conn.close();
+                            return;
+                        }
+                        std::string ifaceMatchString = propertiesMatchString;
+                        ifaceMatchString += ",arg0='";
+                        ifaceMatchString += interface;
+                        ifaceMatchString += "'";
+                        BMCWEB_LOG_DEBUG("Creating match {}", ifaceMatchString);
+                        thisSession.matches.emplace_back(
+                            std::make_unique<sdbusplus::bus::match_t>(
+                                *crow::connections::systemBus, ifaceMatchString,
+                                onPropertyUpdate, &conn));
+                    }
+                }
+                std::string objectManagerMatchString =
+                    ("type='signal',"
+                     "interface='org.freedesktop.DBus.ObjectManager',"
+                     "path_namespace='" +
+                     *thisPathString +
+                     "',"
+                     "member='InterfacesAdded'");
+                BMCWEB_LOG_DEBUG("Creating match {}", objectManagerMatchString);
+                thisSession.matches.emplace_back(
+                    std::make_unique<sdbusplus::bus::match_t>(
+                        *crow::connections::systemBus, objectManagerMatchString,
+                        onPropertyUpdate, &conn));
+            }
+        });
+}
+} // namespace dbus_monitor
+} // namespace crow
diff --git a/features/openbmc_rest/image_upload.hpp b/features/openbmc_rest/image_upload.hpp
new file mode 100644
index 0000000..f6a0dfc
--- /dev/null
+++ b/features/openbmc_rest/image_upload.hpp
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "dbus_singleton.hpp"
+#include "dbus_utility.hpp"
+#include "http_request.hpp"
+#include "io_context_singleton.hpp"
+#include "logging.hpp"
+#include "ossl_random.hpp"
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/beast/http/verb.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <algorithm>
+#include <chrono>
+#include <cstdio>
+#include <fstream>
+#include <functional>
+#include <memory>
+#include <ranges>
+#include <string>
+
+namespace crow
+{
+namespace image_upload
+{
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static std::unique_ptr<sdbusplus::bus::match_t> fwUpdateMatcher;
+
+inline void uploadImageHandler(
+    const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    // Only allow one FW update at a time
+    if (fwUpdateMatcher != nullptr)
+    {
+        asyncResp->res.addHeader("Retry-After", "30");
+        asyncResp->res.result(boost::beast::http::status::service_unavailable);
+        return;
+    }
+    // Make this const static so it survives outside this method
+    static boost::asio::steady_timer timeout(getIoContext(),
+                                             std::chrono::seconds(5));
+
+    timeout.expires_after(std::chrono::seconds(15));
+
+    auto timeoutHandler = [asyncResp](const boost::system::error_code& ec) {
+        fwUpdateMatcher = nullptr;
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            // expected, we were canceled before the timer completed.
+            return;
+        }
+        BMCWEB_LOG_ERROR("Timed out waiting for Version interface");
+
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("Async_wait failed {}", ec);
+            return;
+        }
+
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        asyncResp->res.jsonValue["data"]["description"] =
+            "Version already exists or failed to be extracted";
+        asyncResp->res.jsonValue["message"] = "400 Bad Request";
+        asyncResp->res.jsonValue["status"] = "error";
+    };
+
+    std::function<void(sdbusplus::message_t&)> callback =
+        [asyncResp](sdbusplus::message_t& m) {
+            BMCWEB_LOG_DEBUG("Match fired");
+
+            sdbusplus::message::object_path path;
+            dbus::utility::DBusInterfacesMap interfaces;
+            m.read(path, interfaces);
+
+            if (std::ranges::find_if(interfaces, [](const auto& i) {
+                    return i.first == "xyz.openbmc_project.Software.Version";
+                }) != interfaces.end())
+            {
+                timeout.cancel();
+                std::string leaf = path.filename();
+                if (leaf.empty())
+                {
+                    leaf = path.str;
+                }
+
+                asyncResp->res.jsonValue["data"] = leaf;
+                asyncResp->res.jsonValue["message"] = "200 OK";
+                asyncResp->res.jsonValue["status"] = "ok";
+                BMCWEB_LOG_DEBUG("ending response");
+                fwUpdateMatcher = nullptr;
+            }
+        };
+    fwUpdateMatcher = std::make_unique<sdbusplus::bus::match_t>(
+        *crow::connections::systemBus,
+        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+        "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
+        callback);
+
+    std::string filepath("/tmp/images/" + bmcweb::getRandomUUID());
+    BMCWEB_LOG_DEBUG("Writing file to {}", filepath);
+    std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
+                                    std::ofstream::trunc);
+    out << req.body();
+    out.close();
+    timeout.async_wait(timeoutHandler);
+}
+
+inline void requestRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/upload/image/<str>")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::post, boost::beast::http::verb::put)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string&) { uploadImageHandler(req, asyncResp); });
+
+    BMCWEB_ROUTE(app, "/upload/image")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::post, boost::beast::http::verb::put)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                uploadImageHandler(req, asyncResp);
+            });
+}
+} // namespace image_upload
+} // namespace crow
diff --git a/features/openbmc_rest/meson.build b/features/openbmc_rest/meson.build
new file mode 100644
index 0000000..cfceb79
--- /dev/null
+++ b/features/openbmc_rest/meson.build
@@ -0,0 +1,2 @@
+incdir += include_directories('.')
+test_sources += files('openbmc_dbus_rest_test.cpp')
diff --git a/features/openbmc_rest/openbmc_dbus_rest.hpp b/features/openbmc_rest/openbmc_dbus_rest.hpp
new file mode 100644
index 0000000..d2bd48f8
--- /dev/null
+++ b/features/openbmc_rest/openbmc_dbus_rest.hpp
@@ -0,0 +1,2650 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
+
+#pragma once
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "boost_formatters.hpp"
+#include "dbus_singleton.hpp"
+#include "dbus_utility.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+#include "json_formatters.hpp"
+#include "logging.hpp"
+#include "parsing.hpp"
+#include "str_utility.hpp"
+
+#include <systemd/sd-bus-protocol.h>
+#include <systemd/sd-bus.h>
+#include <tinyxml2.h>
+
+#include <boost/beast/http/field.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/beast/http/verb.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/system/error_code.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <algorithm>
+#include <array>
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <filesystem>
+#include <functional>
+#include <initializer_list>
+#include <limits>
+#include <map>
+#include <memory>
+#include <ranges>
+#include <regex>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+#include <variant>
+#include <vector>
+
+namespace crow
+{
+namespace openbmc_mapper
+{
+const constexpr char* notFoundMsg = "404 Not Found";
+const constexpr char* badReqMsg = "400 Bad Request";
+const constexpr char* methodNotAllowedMsg = "405 Method Not Allowed";
+const constexpr char* forbiddenMsg = "403 Forbidden";
+const constexpr char* unsupportedMediaMsg = "415 Unsupported Media Type";
+const constexpr char* methodFailedMsg = "500 Method Call Failed";
+const constexpr char* methodOutputFailedMsg = "500 Method Output Error";
+const constexpr char* notFoundDesc =
+    "org.freedesktop.DBus.Error.FileNotFound: path or object not found";
+const constexpr char* propNotFoundDesc =
+    "The specified property cannot be found";
+const constexpr char* noJsonDesc = "No JSON object could be decoded";
+const constexpr char* invalidContentType =
+    "Content-type header is missing or invalid";
+const constexpr char* methodNotFoundDesc =
+    "The specified method cannot be found";
+const constexpr char* methodNotAllowedDesc = "Method not allowed";
+const constexpr char* forbiddenPropDesc =
+    "The specified property cannot be created";
+const constexpr char* forbiddenResDesc =
+    "The specified resource cannot be created";
+
+inline bool validateFilename(const std::string& filename)
+{
+    static std::regex validFilename(R"(^[\w\- ]+(\.?[\w\- ]*)$)");
+
+    return std::regex_match(filename, validFilename);
+}
+
+inline void setErrorResponse(crow::Response& res,
+                             boost::beast::http::status result,
+                             const std::string& desc, std::string_view msg)
+{
+    res.result(result);
+    res.jsonValue["data"]["description"] = desc;
+    res.jsonValue["message"] = msg;
+    res.jsonValue["status"] = "error";
+}
+
+inline void introspectObjects(
+    const std::string& processName, const std::string& objectPath,
+    const std::shared_ptr<bmcweb::AsyncResp>& transaction)
+{
+    if (transaction->res.jsonValue.is_null())
+    {
+        transaction->res.jsonValue["status"] = "ok";
+        transaction->res.jsonValue["bus_name"] = processName;
+        transaction->res.jsonValue["objects"] = nlohmann::json::array();
+    }
+
+    dbus::utility::async_method_call(
+        [transaction, processName{std::string(processName)},
+         objectPath{std::string(objectPath)}](
+            const boost::system::error_code& ec,
+            const std::string& introspectXml) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR(
+                    "Introspect call failed with error: {} on process: {} path: {}",
+                    ec.message(), processName, objectPath);
+                return;
+            }
+            nlohmann::json::object_t object;
+            object["path"] = objectPath;
+
+            transaction->res.jsonValue["objects"].emplace_back(
+                std::move(object));
+
+            tinyxml2::XMLDocument doc;
+
+            doc.Parse(introspectXml.c_str());
+            tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
+            if (pRoot == nullptr)
+            {
+                BMCWEB_LOG_ERROR("XML document failed to parse {} {}",
+                                 processName, objectPath);
+            }
+            else
+            {
+                tinyxml2::XMLElement* node = pRoot->FirstChildElement("node");
+                while (node != nullptr)
+                {
+                    const char* childPath = node->Attribute("name");
+                    if (childPath != nullptr)
+                    {
+                        std::string newpath;
+                        if (objectPath != "/")
+                        {
+                            newpath += objectPath;
+                        }
+                        newpath += std::string("/") + childPath;
+                        // introspect the subobjects as well
+                        introspectObjects(processName, newpath, transaction);
+                    }
+
+                    node = node->NextSiblingElement("node");
+                }
+            }
+        },
+        processName, objectPath, "org.freedesktop.DBus.Introspectable",
+        "Introspect");
+}
+
+inline void getPropertiesForEnumerate(
+    const std::string& objectPath, const std::string& service,
+    const std::string& interface,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    BMCWEB_LOG_DEBUG("getPropertiesForEnumerate {} {} {}", objectPath, service,
+                     interface);
+
+    dbus::utility::getAllProperties(
+        service, objectPath, interface,
+        [asyncResp, objectPath, service,
+         interface](const boost::system::error_code& ec,
+                    const dbus::utility::DBusPropertiesMap& propertiesList) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR(
+                    "GetAll on path {} iface {} service {} failed with code {}",
+                    objectPath, interface, service, ec);
+                return;
+            }
+
+            nlohmann::json& dataJson = asyncResp->res.jsonValue["data"];
+            nlohmann::json& objectJson = dataJson[objectPath];
+            if (objectJson.is_null())
+            {
+                objectJson = nlohmann::json::object();
+            }
+
+            for (const auto& [name, value] : propertiesList)
+            {
+                nlohmann::json& propertyJson = objectJson[name];
+                std::visit([&propertyJson](auto&& val) { propertyJson = val; },
+                           value);
+            }
+        });
+}
+
+// Find any results that weren't picked up by ObjectManagers, to be
+// called after all ObjectManagers are searched for and called.
+inline void findRemainingObjectsForEnumerate(
+    const std::string& objectPath,
+    const std::shared_ptr<dbus::utility::MapperGetSubTreeResponse>& subtree,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    BMCWEB_LOG_DEBUG("findRemainingObjectsForEnumerate");
+    const nlohmann::json& dataJson = asyncResp->res.jsonValue["data"];
+
+    for (const auto& [path, interface_map] : *subtree)
+    {
+        if (path == objectPath)
+        {
+            // An enumerate does not return the target path's properties
+            continue;
+        }
+        if (!dataJson.contains(path))
+        {
+            for (const auto& [service, interfaces] : interface_map)
+            {
+                for (const auto& interface : interfaces)
+                {
+                    if (!interface.starts_with("org.freedesktop.DBus"))
+                    {
+                        getPropertiesForEnumerate(path, service, interface,
+                                                  asyncResp);
+                    }
+                }
+            }
+        }
+    }
+}
+
+struct InProgressEnumerateData
+{
+    InProgressEnumerateData(
+        const std::string& objectPathIn,
+        const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
+        objectPath(objectPathIn), asyncResp(asyncRespIn)
+    {}
+
+    ~InProgressEnumerateData()
+    {
+        try
+        {
+            findRemainingObjectsForEnumerate(objectPath, subtree, asyncResp);
+        }
+        catch (...)
+        {
+            BMCWEB_LOG_CRITICAL(
+                "findRemainingObjectsForEnumerate threw exception");
+        }
+    }
+
+    InProgressEnumerateData(const InProgressEnumerateData&) = delete;
+    InProgressEnumerateData(InProgressEnumerateData&&) = delete;
+    InProgressEnumerateData& operator=(const InProgressEnumerateData&) = delete;
+    InProgressEnumerateData& operator=(InProgressEnumerateData&&) = delete;
+    const std::string objectPath;
+    std::shared_ptr<dbus::utility::MapperGetSubTreeResponse> subtree;
+    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
+};
+
+inline void getManagedObjectsForEnumerate(
+    const std::string& objectName, const std::string& objectManagerPath,
+    const std::string& connectionName,
+    const std::shared_ptr<InProgressEnumerateData>& transaction)
+{
+    BMCWEB_LOG_DEBUG(
+        "getManagedObjectsForEnumerate {} object_manager_path {} connection_name {}",
+        objectName, objectManagerPath, connectionName);
+    sdbusplus::message::object_path path(objectManagerPath);
+    dbus::utility::getManagedObjects(
+        connectionName, path,
+        [transaction, objectName,
+         connectionName](const boost::system::error_code& ec,
+                         const dbus::utility::ManagedObjectType& objects) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR(
+                    "GetManagedObjects on path {} on connection {} failed with code {}",
+                    objectName, connectionName, ec);
+                return;
+            }
+
+            nlohmann::json& dataJson =
+                transaction->asyncResp->res.jsonValue["data"];
+
+            for (const auto& objectPath : objects)
+            {
+                if (objectPath.first.str.starts_with(objectName))
+                {
+                    BMCWEB_LOG_DEBUG("Reading object {}", objectPath.first.str);
+                    nlohmann::json& objectJson = dataJson[objectPath.first.str];
+                    if (objectJson.is_null())
+                    {
+                        objectJson = nlohmann::json::object();
+                    }
+                    for (const auto& interface : objectPath.second)
+                    {
+                        for (const auto& property : interface.second)
+                        {
+                            nlohmann::json& propertyJson =
+                                objectJson[property.first];
+                            std::visit(
+                                [&propertyJson](auto&& val) {
+                                    if constexpr (
+                                        std::is_same_v<
+                                            std::decay_t<decltype(val)>,
+                                            sdbusplus::message::unix_fd>)
+                                    {
+                                        propertyJson = val.fd;
+                                    }
+                                    else
+                                    {
+                                        propertyJson = val;
+                                    }
+                                },
+                                property.second);
+                        }
+                    }
+                }
+                for (const auto& interface : objectPath.second)
+                {
+                    if (interface.first == "org.freedesktop.DBus.ObjectManager")
+                    {
+                        getManagedObjectsForEnumerate(
+                            objectPath.first.str, objectPath.first.str,
+                            connectionName, transaction);
+                    }
+                }
+            }
+        });
+}
+
+inline void findObjectManagerPathForEnumerate(
+    const std::string& objectName, const std::string& connectionName,
+    const std::shared_ptr<InProgressEnumerateData>& transaction)
+{
+    BMCWEB_LOG_DEBUG("Finding objectmanager for path {} on connection:{}",
+                     objectName, connectionName);
+    dbus::utility::async_method_call(
+        [transaction, objectName, connectionName](
+            const boost::system::error_code& ec,
+            const dbus::utility::MapperGetAncestorsResponse& objects) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR("GetAncestors on path {} failed with code {}",
+                                 objectName, ec);
+                return;
+            }
+
+            for (const auto& pathGroup : objects)
+            {
+                for (const auto& connectionGroup : pathGroup.second)
+                {
+                    if (connectionGroup.first == connectionName)
+                    {
+                        // Found the object manager path for this resource.
+                        getManagedObjectsForEnumerate(
+                            objectName, pathGroup.first, connectionName,
+                            transaction);
+                        return;
+                    }
+                }
+            }
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetAncestors", objectName,
+        std::array<const char*, 1>{"org.freedesktop.DBus.ObjectManager"});
+}
+
+// Uses GetObject to add the object info about the target /enumerate path to
+// the results of GetSubTree, as GetSubTree will not return info for the
+// target path, and then continues on enumerating the rest of the tree.
+inline void getObjectAndEnumerate(
+    const std::shared_ptr<InProgressEnumerateData>& transaction)
+{
+    dbus::utility::getDbusObject(
+        transaction->objectPath, {},
+        [transaction](const boost::system::error_code& ec,
+                      const dbus::utility::MapperGetObject& objects) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR("GetObject for path {} failed with code {}",
+                                 transaction->objectPath, ec);
+                return;
+            }
+
+            BMCWEB_LOG_DEBUG("GetObject for {} has {} entries",
+                             transaction->objectPath, objects.size());
+            if (!objects.empty())
+            {
+                transaction->subtree->emplace_back(transaction->objectPath,
+                                                   objects);
+            }
+
+            // Map indicating connection name, and the path where the object
+            // manager exists
+            boost::container::flat_map<
+                std::string, std::string, std::less<>,
+                std::vector<std::pair<std::string, std::string>>>
+                connections;
+
+            for (const auto& object : *(transaction->subtree))
+            {
+                for (const auto& connection : object.second)
+                {
+                    for (const auto& interface : connection.second)
+                    {
+                        BMCWEB_LOG_DEBUG("{} has interface {}",
+                                         connection.first, interface);
+                        if (interface == "org.freedesktop.DBus.ObjectManager")
+                        {
+                            BMCWEB_LOG_DEBUG("found object manager path {}",
+                                             object.first);
+                            connections[connection.first] = object.first;
+                        }
+                    }
+                }
+            }
+            BMCWEB_LOG_DEBUG("Got {} connections", connections.size());
+
+            for (const auto& connection : connections)
+            {
+                // If we already know where the object manager is, we don't
+                // need to search for it, we can call directly in to
+                // getManagedObjects
+                if (!connection.second.empty())
+                {
+                    getManagedObjectsForEnumerate(
+                        transaction->objectPath, connection.second,
+                        connection.first, transaction);
+                }
+                else
+                {
+                    // otherwise we need to find the object manager path
+                    // before we can continue
+                    findObjectManagerPathForEnumerate(
+                        transaction->objectPath, connection.first, transaction);
+                }
+            }
+        });
+}
+
+// Structure for storing data on an in progress action
+struct InProgressActionData
+{
+    explicit InProgressActionData(
+        const std::shared_ptr<bmcweb::AsyncResp>& res) : asyncResp(res)
+    {}
+    ~InProgressActionData()
+    {
+        // Methods could have been called across different owners
+        // and interfaces, where some calls failed and some passed.
+        //
+        // The rules for this are:
+        // * if no method was called - error
+        // * if a method failed and none passed - error
+        //   (converse: if at least one method passed - OK)
+        // * for the method output:
+        //   * if output processing didn't fail, return the data
+
+        // Only deal with method returns if nothing failed earlier
+        if (asyncResp->res.result() == boost::beast::http::status::ok)
+        {
+            if (!methodPassed)
+            {
+                if (!methodFailed)
+                {
+                    setErrorResponse(asyncResp->res,
+                                     boost::beast::http::status::not_found,
+                                     methodNotFoundDesc, notFoundMsg);
+                }
+            }
+            else
+            {
+                if (outputFailed)
+                {
+                    setErrorResponse(
+                        asyncResp->res,
+                        boost::beast::http::status::internal_server_error,
+                        "Method output failure", methodOutputFailedMsg);
+                }
+                else
+                {
+                    asyncResp->res.jsonValue["status"] = "ok";
+                    asyncResp->res.jsonValue["message"] = "200 OK";
+                    asyncResp->res.jsonValue["data"] = methodResponse;
+                }
+            }
+        }
+    }
+    InProgressActionData(const InProgressActionData&) = delete;
+    InProgressActionData(InProgressActionData&&) = delete;
+    InProgressActionData& operator=(const InProgressActionData&) = delete;
+    InProgressActionData& operator=(InProgressActionData&&) = delete;
+
+    void setErrorStatus(const std::string& desc)
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, desc,
+                         badReqMsg);
+    }
+    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
+    std::string path;
+    std::string methodName;
+    std::string interfaceName;
+    bool methodPassed = false;
+    bool methodFailed = false;
+    bool outputFailed = false;
+    bool convertedToArray = false;
+    nlohmann::json methodResponse;
+    nlohmann::json arguments;
+};
+
+inline std::vector<std::string> dbusArgSplit(const std::string& string)
+{
+    std::vector<std::string> ret;
+    if (string.empty())
+    {
+        return ret;
+    }
+    ret.emplace_back("");
+    int containerDepth = 0;
+
+    for (std::string::const_iterator character = string.begin();
+         character != string.end(); character++)
+    {
+        ret.back() += *character;
+        switch (*character)
+        {
+            case ('a'):
+                break;
+            case ('('):
+            case ('{'):
+                containerDepth++;
+                break;
+            case ('}'):
+            case (')'):
+                containerDepth--;
+                if (containerDepth == 0)
+                {
+                    if (character + 1 != string.end())
+                    {
+                        ret.emplace_back("");
+                    }
+                }
+                break;
+            default:
+                if (containerDepth == 0)
+                {
+                    if (character + 1 != string.end())
+                    {
+                        ret.emplace_back("");
+                    }
+                }
+                break;
+        }
+    }
+
+    return ret;
+}
+
+inline int convertJsonToDbus(sd_bus_message* m, const std::string& argType,
+                             const nlohmann::json& inputJson)
+{
+    int r = 0;
+    BMCWEB_LOG_DEBUG("Converting {} to type: {}", inputJson, argType);
+    const std::vector<std::string> argTypes = dbusArgSplit(argType);
+
+    // Assume a single object for now.
+    const nlohmann::json* j = &inputJson;
+    nlohmann::json::const_iterator jIt = inputJson.begin();
+
+    for (const std::string& argCode : argTypes)
+    {
+        // If we are decoding multiple objects, grab the pointer to the
+        // iterator, and increment it for the next loop
+        if (argTypes.size() > 1)
+        {
+            if (jIt == inputJson.end())
+            {
+                return -2;
+            }
+            j = &*jIt;
+            jIt++;
+        }
+        const int64_t* intValue = j->get_ptr<const int64_t*>();
+        const std::string* stringValue = j->get_ptr<const std::string*>();
+        const double* doubleValue = j->get_ptr<const double*>();
+        const bool* b = j->get_ptr<const bool*>();
+        int64_t v = 0;
+        double d = 0.0;
+
+        // Do some basic type conversions that make sense.  uint can be
+        // converted to int.  int and uint can be converted to double
+        if (intValue == nullptr)
+        {
+            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
+            if (uintValue != nullptr)
+            {
+                v = static_cast<int64_t>(*uintValue);
+                intValue = &v;
+            }
+        }
+        if (doubleValue == nullptr)
+        {
+            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
+            if (uintValue != nullptr)
+            {
+                d = static_cast<double>(*uintValue);
+                doubleValue = &d;
+            }
+        }
+        if (doubleValue == nullptr)
+        {
+            if (intValue != nullptr)
+            {
+                d = static_cast<double>(*intValue);
+                doubleValue = &d;
+            }
+        }
+
+        if (argCode == "s")
+        {
+            if (stringValue == nullptr)
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(
+                m, argCode[0], static_cast<const void*>(stringValue->data()));
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode == "i")
+        {
+            if (intValue == nullptr)
+            {
+                return -1;
+            }
+            if ((*intValue < std::numeric_limits<int32_t>::lowest()) ||
+                (*intValue > std::numeric_limits<int32_t>::max()))
+            {
+                return -ERANGE;
+            }
+            int32_t i = static_cast<int32_t>(*intValue);
+            r = sd_bus_message_append_basic(m, argCode[0], &i);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode == "b")
+        {
+            // lots of ways bool could be represented here.  Try them all
+            int boolInt = 0;
+            if (intValue != nullptr)
+            {
+                if (*intValue == 1)
+                {
+                    boolInt = 1;
+                }
+                else if (*intValue == 0)
+                {
+                    boolInt = 0;
+                }
+                else
+                {
+                    return -ERANGE;
+                }
+            }
+            else if (b != nullptr)
+            {
+                boolInt = *b ? 1 : 0;
+            }
+            else if (stringValue != nullptr)
+            {
+                if (!stringValue->empty())
+                {
+                    if (stringValue->front() == 't' ||
+                        stringValue->front() == 'T')
+                    {
+                        boolInt = 1;
+                    }
+                }
+            }
+            else
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, argCode[0], &boolInt);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode == "n")
+        {
+            if (intValue == nullptr)
+            {
+                return -1;
+            }
+            if ((*intValue < std::numeric_limits<int16_t>::lowest()) ||
+                (*intValue > std::numeric_limits<int16_t>::max()))
+            {
+                return -ERANGE;
+            }
+            int16_t n = static_cast<int16_t>(*intValue);
+            r = sd_bus_message_append_basic(m, argCode[0], &n);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode == "x")
+        {
+            if (intValue == nullptr)
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, argCode[0], intValue);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode == "y")
+        {
+            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
+            if (uintValue == nullptr)
+            {
+                return -1;
+            }
+            if (*uintValue > std::numeric_limits<uint8_t>::max())
+            {
+                return -ERANGE;
+            }
+            uint8_t y = static_cast<uint8_t>(*uintValue);
+            r = sd_bus_message_append_basic(m, argCode[0], &y);
+        }
+        else if (argCode == "q")
+        {
+            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
+            if (uintValue == nullptr)
+            {
+                return -1;
+            }
+            if (*uintValue > std::numeric_limits<uint16_t>::max())
+            {
+                return -ERANGE;
+            }
+            uint16_t q = static_cast<uint16_t>(*uintValue);
+            r = sd_bus_message_append_basic(m, argCode[0], &q);
+        }
+        else if (argCode == "u")
+        {
+            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
+            if (uintValue == nullptr)
+            {
+                return -1;
+            }
+            if (*uintValue > std::numeric_limits<uint32_t>::max())
+            {
+                return -ERANGE;
+            }
+            uint32_t u = static_cast<uint32_t>(*uintValue);
+            r = sd_bus_message_append_basic(m, argCode[0], &u);
+        }
+        else if (argCode == "t")
+        {
+            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
+            if (uintValue == nullptr)
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, argCode[0], uintValue);
+        }
+        else if (argCode == "d")
+        {
+            if (doubleValue == nullptr)
+            {
+                return -1;
+            }
+            if ((*doubleValue < std::numeric_limits<double>::lowest()) ||
+                (*doubleValue > std::numeric_limits<double>::max()))
+            {
+                return -ERANGE;
+            }
+            r = sd_bus_message_append_basic(m, argCode[0], doubleValue);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode.starts_with("a"))
+        {
+            std::string containedType = argCode.substr(1);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY,
+                                              containedType.c_str());
+            if (r < 0)
+            {
+                return r;
+            }
+
+            for (const auto& it : *j)
+            {
+                r = convertJsonToDbus(m, containedType, it);
+                if (r < 0)
+                {
+                    return r;
+                }
+            }
+            sd_bus_message_close_container(m);
+        }
+        else if (argCode.starts_with("v"))
+        {
+            std::string containedType = argCode.substr(1);
+            BMCWEB_LOG_DEBUG("variant type: {} appending variant of type: {}",
+                             argCode, containedType);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT,
+                                              containedType.c_str());
+            if (r < 0)
+            {
+                return r;
+            }
+
+            r = convertJsonToDbus(m, containedType, inputJson);
+            if (r < 0)
+            {
+                return r;
+            }
+
+            r = sd_bus_message_close_container(m);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (argCode.starts_with("(") && argCode.ends_with(")"))
+        {
+            std::string containedType = argCode.substr(1, argCode.size() - 2);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT,
+                                              containedType.c_str());
+            if (r < 0)
+            {
+                return r;
+            }
+
+            nlohmann::json::const_iterator it = j->begin();
+            for (const std::string& argCode2 : dbusArgSplit(containedType))
+            {
+                if (it == j->end())
+                {
+                    return -1;
+                }
+                r = convertJsonToDbus(m, argCode2, *it);
+                if (r < 0)
+                {
+                    return r;
+                }
+                it++;
+            }
+            r = sd_bus_message_close_container(m);
+        }
+        else if (argCode.starts_with("{") && argCode.ends_with("}"))
+        {
+            std::string containedType = argCode.substr(1, argCode.size() - 2);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_DICT_ENTRY,
+                                              containedType.c_str());
+            if (r < 0)
+            {
+                return r;
+            }
+
+            std::vector<std::string> codes = dbusArgSplit(containedType);
+            if (codes.size() != 2)
+            {
+                return -1;
+            }
+            const std::string& keyType = codes[0];
+            const std::string& valueType = codes[1];
+            const nlohmann::json::object_t* arr =
+                j->get_ptr<const nlohmann::json::object_t*>();
+            if (arr == nullptr)
+            {
+                return -1;
+            }
+            for (const auto& it : *arr)
+            {
+                r = convertJsonToDbus(m, keyType, it.first);
+                if (r < 0)
+                {
+                    return r;
+                }
+
+                r = convertJsonToDbus(m, valueType, it.second);
+                if (r < 0)
+                {
+                    return r;
+                }
+            }
+            r = sd_bus_message_close_container(m);
+        }
+        else
+        {
+            return -2;
+        }
+        if (r < 0)
+        {
+            return r;
+        }
+
+        if (argTypes.size() > 1)
+        {
+            jIt++;
+        }
+    }
+
+    return r;
+}
+
+template <typename T>
+int readMessageItem(const std::string& typeCode, sdbusplus::message_t& m,
+                    nlohmann::json& data)
+{
+    T value;
+    // When T == char*, this warning fires.  Unclear how to resolve
+    // Given that sd-bus takes a void pointer to a char*, and that's
+    // Not something we can fix.
+    // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
+    int r = sd_bus_message_read_basic(m.get(), typeCode.front(), &value);
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_read_basic on type {} failed!",
+                         typeCode);
+        return r;
+    }
+
+    data = value;
+    return 0;
+}
+
+int convertDBusToJSON(const std::string& returnType, sdbusplus::message_t& m,
+                      nlohmann::json& response);
+
+inline int readDictEntryFromMessage(const std::string& typeCode,
+                                    sdbusplus::message_t& m,
+                                    nlohmann::json& object)
+{
+    std::vector<std::string> types = dbusArgSplit(typeCode);
+    if (types.size() != 2)
+    {
+        BMCWEB_LOG_ERROR("wrong number contained types in dictionary: {}",
+                         types.size());
+        return -1;
+    }
+
+    int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_DICT_ENTRY,
+                                           typeCode.c_str());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_enter_container with rc {}", r);
+        return r;
+    }
+
+    nlohmann::json key;
+    r = convertDBusToJSON(types[0], m, key);
+    if (r < 0)
+    {
+        return r;
+    }
+
+    const std::string* keyPtr = key.get_ptr<const std::string*>();
+    if (keyPtr == nullptr)
+    {
+        // json doesn't support non-string keys.  If we hit this condition,
+        // convert the result to a string so we can proceed
+        key = key.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+        keyPtr = key.get_ptr<const std::string*>();
+        // in theory this can't fail now, but lets be paranoid about it
+        // anyway
+        if (keyPtr == nullptr)
+        {
+            return -1;
+        }
+    }
+    nlohmann::json& value = object[*keyPtr];
+
+    r = convertDBusToJSON(types[1], m, value);
+    if (r < 0)
+    {
+        return r;
+    }
+
+    r = sd_bus_message_exit_container(m.get());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_exit_container failed");
+        return r;
+    }
+
+    return 0;
+}
+
+inline int readArrayFromMessage(const std::string& typeCode,
+                                sdbusplus::message_t& m, nlohmann::json& data)
+{
+    if (typeCode.size() < 2)
+    {
+        BMCWEB_LOG_ERROR("Type code {} too small for an array", typeCode);
+        return -1;
+    }
+
+    std::string containedType = typeCode.substr(1);
+
+    int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_ARRAY,
+                                           containedType.c_str());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_enter_container failed with rc {}", r);
+        return r;
+    }
+
+    bool dict = containedType.starts_with("{") && containedType.ends_with("}");
+
+    if (dict)
+    {
+        // Remove the { }
+        containedType = containedType.substr(1, containedType.size() - 2);
+        data = nlohmann::json::object();
+    }
+    else
+    {
+        data = nlohmann::json::array();
+    }
+
+    while (true)
+    {
+        r = sd_bus_message_at_end(m.get(), 0);
+        if (r < 0)
+        {
+            BMCWEB_LOG_ERROR("sd_bus_message_at_end failed");
+            return r;
+        }
+
+        if (r > 0)
+        {
+            break;
+        }
+
+        // Dictionaries are only ever seen in an array
+        if (dict)
+        {
+            r = readDictEntryFromMessage(containedType, m, data);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else
+        {
+            data.push_back(nlohmann::json());
+
+            r = convertDBusToJSON(containedType, m, data.back());
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+    }
+
+    r = sd_bus_message_exit_container(m.get());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_exit_container failed");
+        return r;
+    }
+
+    return 0;
+}
+
+inline int readStructFromMessage(const std::string& typeCode,
+                                 sdbusplus::message_t& m, nlohmann::json& data)
+{
+    if (typeCode.size() < 3)
+    {
+        BMCWEB_LOG_ERROR("Type code {} too small for a struct", typeCode);
+        return -1;
+    }
+
+    std::string containedTypes = typeCode.substr(1, typeCode.size() - 2);
+    std::vector<std::string> types = dbusArgSplit(containedTypes);
+
+    int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_STRUCT,
+                                           containedTypes.c_str());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_enter_container failed with rc {}", r);
+        return r;
+    }
+
+    for (const std::string& type : types)
+    {
+        data.push_back(nlohmann::json());
+        r = convertDBusToJSON(type, m, data.back());
+        if (r < 0)
+        {
+            return r;
+        }
+    }
+
+    r = sd_bus_message_exit_container(m.get());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_exit_container failed");
+        return r;
+    }
+    return 0;
+}
+
+inline int readVariantFromMessage(sdbusplus::message_t& m, nlohmann::json& data)
+{
+    const char* containerType = nullptr;
+    int r = sd_bus_message_peek_type(m.get(), nullptr, &containerType);
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_peek_type failed");
+        return r;
+    }
+
+    r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_VARIANT,
+                                       containerType);
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_enter_container failed with rc {}", r);
+        return r;
+    }
+
+    r = convertDBusToJSON(containerType, m, data);
+    if (r < 0)
+    {
+        return r;
+    }
+
+    r = sd_bus_message_exit_container(m.get());
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR("sd_bus_message_enter_container failed");
+        return r;
+    }
+
+    return 0;
+}
+
+inline int convertDBusToJSON(const std::string& returnType,
+                             sdbusplus::message_t& m, nlohmann::json& response)
+{
+    int r = 0;
+    const std::vector<std::string> returnTypes = dbusArgSplit(returnType);
+
+    for (const std::string& typeCode : returnTypes)
+    {
+        nlohmann::json* thisElement = &response;
+        if (returnTypes.size() > 1)
+        {
+            response.push_back(nlohmann::json{});
+            thisElement = &response.back();
+        }
+
+        if (typeCode == "s" || typeCode == "g" || typeCode == "o")
+        {
+            r = readMessageItem<char*>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "b")
+        {
+            r = readMessageItem<int>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+
+            *thisElement = static_cast<bool>(thisElement->get<int>());
+        }
+        else if (typeCode == "u")
+        {
+            r = readMessageItem<uint32_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "i")
+        {
+            r = readMessageItem<int32_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "x")
+        {
+            r = readMessageItem<int64_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "t")
+        {
+            r = readMessageItem<uint64_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "n")
+        {
+            r = readMessageItem<int16_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "q")
+        {
+            r = readMessageItem<uint16_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "y")
+        {
+            r = readMessageItem<uint8_t>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "d")
+        {
+            r = readMessageItem<double>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "h")
+        {
+            r = readMessageItem<int>(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode.starts_with("a"))
+        {
+            r = readArrayFromMessage(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode.starts_with("(") && typeCode.ends_with(")"))
+        {
+            r = readStructFromMessage(typeCode, m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode.starts_with("v"))
+        {
+            r = readVariantFromMessage(m, *thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else
+        {
+            BMCWEB_LOG_ERROR("Invalid D-Bus signature type {}", typeCode);
+            return -2;
+        }
+    }
+
+    return 0;
+}
+
+inline void handleMethodResponse(
+    const std::shared_ptr<InProgressActionData>& transaction,
+    sdbusplus::message_t& m, const std::string& returnType)
+{
+    nlohmann::json data;
+
+    int r = convertDBusToJSON(returnType, m, data);
+    if (r < 0)
+    {
+        transaction->outputFailed = true;
+        return;
+    }
+
+    if (data.is_null())
+    {
+        return;
+    }
+
+    if (transaction->methodResponse.is_null())
+    {
+        transaction->methodResponse = std::move(data);
+        return;
+    }
+
+    // If they're both dictionaries or arrays, merge into one.
+    // Otherwise, make the results an array with every result
+    // an entry.  Could also just fail in that case, but it
+    // seems better to get the data back somehow.
+    nlohmann::json::object_t* dataobj =
+        data.get_ptr<nlohmann::json::object_t*>();
+
+    nlohmann::json::object_t* methodResponseObj =
+        transaction->methodResponse.get_ptr<nlohmann::json::object_t*>();
+    if (methodResponseObj != nullptr && dataobj != nullptr)
+    {
+        for (auto& obj : *dataobj)
+        {
+            // Note: Will overwrite the data for a duplicate key
+            methodResponseObj->emplace(obj.first, std::move(obj.second));
+        }
+        return;
+    }
+
+    nlohmann::json::array_t* dataarr = data.get_ptr<nlohmann::json::array_t*>();
+    nlohmann::json::array_t* methodResponseArr =
+        transaction->methodResponse.get_ptr<nlohmann::json::array_t*>();
+    if (methodResponseArr != nullptr && dataarr != nullptr)
+    {
+        for (auto& obj : *dataarr)
+        {
+            methodResponseArr->emplace_back(std::move(obj));
+        }
+        return;
+    }
+
+    if (!transaction->convertedToArray)
+    {
+        // They are different types. May as well turn them into an array
+        nlohmann::json j = std::move(transaction->methodResponse);
+        transaction->methodResponse = nlohmann::json::array();
+        transaction->methodResponse.emplace_back(std::move(j));
+        transaction->methodResponse.emplace_back(std::move(data));
+        transaction->convertedToArray = true;
+    }
+    else
+    {
+        transaction->methodResponse.emplace_back(std::move(data));
+    }
+}
+
+inline void findActionOnInterface(
+    const std::shared_ptr<InProgressActionData>& transaction,
+    const std::string& connectionName)
+{
+    BMCWEB_LOG_DEBUG("findActionOnInterface for connection {}", connectionName);
+    dbus::utility::async_method_call(
+        [transaction, connectionName{std::string(connectionName)}](
+            const boost::system::error_code& ec,
+            const std::string& introspectXml) {
+            BMCWEB_LOG_DEBUG("got xml:\n {}", introspectXml);
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR(
+                    "Introspect call failed with error: {} on process: {}",
+                    ec.message(), connectionName);
+                return;
+            }
+            tinyxml2::XMLDocument doc;
+
+            doc.Parse(introspectXml.data(), introspectXml.size());
+            tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
+            if (pRoot == nullptr)
+            {
+                BMCWEB_LOG_ERROR("XML document failed to parse {}",
+                                 connectionName);
+                return;
+            }
+            tinyxml2::XMLElement* interfaceNode =
+                pRoot->FirstChildElement("interface");
+            while (interfaceNode != nullptr)
+            {
+                const char* thisInterfaceName =
+                    interfaceNode->Attribute("name");
+                if (thisInterfaceName != nullptr)
+                {
+                    if (!transaction->interfaceName.empty() &&
+                        (transaction->interfaceName != thisInterfaceName))
+                    {
+                        interfaceNode =
+                            interfaceNode->NextSiblingElement("interface");
+                        continue;
+                    }
+
+                    tinyxml2::XMLElement* methodNode =
+                        interfaceNode->FirstChildElement("method");
+                    while (methodNode != nullptr)
+                    {
+                        const char* thisMethodName =
+                            methodNode->Attribute("name");
+                        BMCWEB_LOG_DEBUG("Found method: {}", thisMethodName);
+                        if (thisMethodName != nullptr &&
+                            thisMethodName == transaction->methodName)
+                        {
+                            BMCWEB_LOG_DEBUG(
+                                "Found method named {} on interface {}",
+                                thisMethodName, thisInterfaceName);
+                            sdbusplus::message_t m =
+                                crow::connections::systemBus->new_method_call(
+                                    connectionName.c_str(),
+                                    transaction->path.c_str(),
+                                    thisInterfaceName,
+                                    transaction->methodName.c_str());
+
+                            tinyxml2::XMLElement* argumentNode =
+                                methodNode->FirstChildElement("arg");
+
+                            std::string returnType;
+
+                            // Find the output type
+                            while (argumentNode != nullptr)
+                            {
+                                const char* argDirection =
+                                    argumentNode->Attribute("direction");
+                                const char* argType =
+                                    argumentNode->Attribute("type");
+                                if (argDirection != nullptr &&
+                                    argType != nullptr &&
+                                    std::string(argDirection) == "out")
+                                {
+                                    returnType = argType;
+                                    break;
+                                }
+                                argumentNode =
+                                    argumentNode->NextSiblingElement("arg");
+                            }
+
+                            auto argIt = transaction->arguments.begin();
+
+                            argumentNode = methodNode->FirstChildElement("arg");
+
+                            while (argumentNode != nullptr)
+                            {
+                                const char* argDirection =
+                                    argumentNode->Attribute("direction");
+                                const char* argType =
+                                    argumentNode->Attribute("type");
+                                if (argDirection != nullptr &&
+                                    argType != nullptr &&
+                                    std::string(argDirection) == "in")
+                                {
+                                    if (argIt == transaction->arguments.end())
+                                    {
+                                        transaction->setErrorStatus(
+                                            "Invalid method args");
+                                        return;
+                                    }
+                                    if (convertJsonToDbus(m.get(),
+                                                          std::string(argType),
+                                                          *argIt) < 0)
+                                    {
+                                        transaction->setErrorStatus(
+                                            "Invalid method arg type");
+                                        return;
+                                    }
+
+                                    argIt++;
+                                }
+                                argumentNode =
+                                    argumentNode->NextSiblingElement("arg");
+                            }
+
+                            crow::connections::systemBus->async_send(
+                                m, [transaction, returnType](
+                                       const boost::system::error_code& ec2,
+                                       sdbusplus::message_t& m2) {
+                                    if (ec2)
+                                    {
+                                        transaction->methodFailed = true;
+                                        const sd_bus_error* e = m2.get_error();
+
+                                        if (e != nullptr)
+                                        {
+                                            setErrorResponse(
+                                                transaction->asyncResp->res,
+                                                boost::beast::http::status::
+                                                    bad_request,
+                                                e->name, e->message);
+                                        }
+                                        else
+                                        {
+                                            setErrorResponse(
+                                                transaction->asyncResp->res,
+                                                boost::beast::http::status::
+                                                    bad_request,
+                                                "Method call failed",
+                                                methodFailedMsg);
+                                        }
+                                        return;
+                                    }
+                                    transaction->methodPassed = true;
+
+                                    handleMethodResponse(transaction, m2,
+                                                         returnType);
+                                });
+                            break;
+                        }
+                        methodNode = methodNode->NextSiblingElement("method");
+                    }
+                }
+                interfaceNode = interfaceNode->NextSiblingElement("interface");
+            }
+        },
+        connectionName, transaction->path,
+        "org.freedesktop.DBus.Introspectable", "Introspect");
+}
+
+inline void handleAction(const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                         const std::string& objectPath,
+                         const std::string& methodName)
+{
+    BMCWEB_LOG_DEBUG("handleAction on path: {} and method {}", objectPath,
+                     methodName);
+    nlohmann::json requestDbusData;
+
+    JsonParseResult ret = parseRequestAsJson(req, requestDbusData);
+    if (ret == JsonParseResult::BadContentType)
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::unsupported_media_type,
+                         invalidContentType, unsupportedMediaMsg);
+        return;
+    }
+    if (ret != JsonParseResult::Success)
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
+        return;
+    }
+    nlohmann::json::iterator data = requestDbusData.find("data");
+    if (data == requestDbusData.end())
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
+        return;
+    }
+
+    if (!data->is_array())
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
+        return;
+    }
+    auto transaction = std::make_shared<InProgressActionData>(asyncResp);
+
+    transaction->path = objectPath;
+    transaction->methodName = methodName;
+    transaction->arguments = std::move(*data);
+    dbus::utility::getDbusObject(
+        objectPath, {},
+        [transaction](
+            const boost::system::error_code& ec,
+            const std::vector<std::pair<std::string, std::vector<std::string>>>&
+                interfaceNames) {
+            if (ec || interfaceNames.empty())
+            {
+                BMCWEB_LOG_ERROR("Can't find object");
+                setErrorResponse(transaction->asyncResp->res,
+                                 boost::beast::http::status::not_found,
+                                 notFoundDesc, notFoundMsg);
+                return;
+            }
+
+            BMCWEB_LOG_DEBUG("GetObject returned {} object(s)",
+                             interfaceNames.size());
+
+            for (const std::pair<std::string, std::vector<std::string>>&
+                     object : interfaceNames)
+            {
+                findActionOnInterface(transaction, object.first);
+            }
+        });
+}
+
+inline void handleDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                         const std::string& objectPath)
+{
+    BMCWEB_LOG_DEBUG("handleDelete on path: {}", objectPath);
+
+    dbus::utility::getDbusObject(
+        objectPath, {},
+        [asyncResp, objectPath](
+            const boost::system::error_code& ec,
+            const std::vector<std::pair<std::string, std::vector<std::string>>>&
+                interfaceNames) {
+            if (ec || interfaceNames.empty())
+            {
+                BMCWEB_LOG_ERROR("Can't find object");
+                setErrorResponse(asyncResp->res,
+                                 boost::beast::http::status::method_not_allowed,
+                                 methodNotAllowedDesc, methodNotAllowedMsg);
+                return;
+            }
+
+            auto transaction =
+                std::make_shared<InProgressActionData>(asyncResp);
+            transaction->path = objectPath;
+            transaction->methodName = "Delete";
+            transaction->interfaceName = "xyz.openbmc_project.Object.Delete";
+
+            for (const std::pair<std::string, std::vector<std::string>>&
+                     object : interfaceNames)
+            {
+                findActionOnInterface(transaction, object.first);
+            }
+        });
+}
+
+inline void handleList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& objectPath, int32_t depth = 0)
+{
+    dbus::utility::getSubTreePaths(
+        objectPath, depth, {},
+        [asyncResp](
+            const boost::system::error_code& ec,
+            const dbus::utility::MapperGetSubTreePathsResponse& objectPaths) {
+            if (ec)
+            {
+                setErrorResponse(asyncResp->res,
+                                 boost::beast::http::status::not_found,
+                                 notFoundDesc, notFoundMsg);
+            }
+            else
+            {
+                asyncResp->res.jsonValue["status"] = "ok";
+                asyncResp->res.jsonValue["message"] = "200 OK";
+                asyncResp->res.jsonValue["data"] = objectPaths;
+            }
+        });
+}
+
+inline void handleEnumerate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                            const std::string& objectPath)
+{
+    BMCWEB_LOG_DEBUG("Doing enumerate on {}", objectPath);
+
+    asyncResp->res.jsonValue["message"] = "200 OK";
+    asyncResp->res.jsonValue["status"] = "ok";
+    asyncResp->res.jsonValue["data"] = nlohmann::json::object();
+
+    dbus::utility::getSubTree(
+        objectPath, 0, {},
+        [objectPath, asyncResp](
+            const boost::system::error_code& ec,
+            const dbus::utility::MapperGetSubTreeResponse& objectNames) {
+            auto transaction = std::make_shared<InProgressEnumerateData>(
+                objectPath, asyncResp);
+
+            transaction->subtree =
+                std::make_shared<dbus::utility::MapperGetSubTreeResponse>(
+                    objectNames);
+
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR("GetSubTree failed on {}",
+                                 transaction->objectPath);
+                setErrorResponse(transaction->asyncResp->res,
+                                 boost::beast::http::status::not_found,
+                                 notFoundDesc, notFoundMsg);
+                return;
+            }
+
+            // Add the data for the path passed in to the results
+            // as if GetSubTree returned it, and continue on enumerating
+            getObjectAndEnumerate(transaction);
+        });
+}
+
+inline void handleGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                      std::string& objectPath, std::string& destProperty)
+{
+    BMCWEB_LOG_DEBUG("handleGet: {} prop:{}", objectPath, destProperty);
+    std::shared_ptr<std::string> propertyName =
+        std::make_shared<std::string>(std::move(destProperty));
+
+    std::shared_ptr<std::string> path =
+        std::make_shared<std::string>(std::move(objectPath));
+
+    dbus::utility::getDbusObject(
+        *path, {},
+        [asyncResp, path,
+         propertyName](const boost::system::error_code& ec,
+                       const dbus::utility::MapperGetObject& objectNames) {
+            if (ec || objectNames.empty())
+            {
+                setErrorResponse(asyncResp->res,
+                                 boost::beast::http::status::not_found,
+                                 notFoundDesc, notFoundMsg);
+                return;
+            }
+            std::shared_ptr<nlohmann::json> response =
+                std::make_shared<nlohmann::json>(nlohmann::json::object());
+            for (const std::pair<std::string, std::vector<std::string>>&
+                     connection : objectNames)
+            {
+                const std::vector<std::string>& interfaceNames =
+                    connection.second;
+
+                if (interfaceNames.empty())
+                {
+                    // mapper allows empty interfaces in case an
+                    // object does not implement any interface.
+                    continue;
+                }
+
+                for (const std::string& interface : interfaceNames)
+                {
+                    sdbusplus::message_t m =
+                        crow::connections::systemBus->new_method_call(
+                            connection.first.c_str(), path->c_str(),
+                            "org.freedesktop.DBus.Properties", "GetAll");
+                    m.append(interface);
+                    crow::connections::systemBus->async_send(
+                        m, [asyncResp, response,
+                            propertyName](const boost::system::error_code& ec2,
+                                          sdbusplus::message_t& msg) {
+                            if (ec2)
+                            {
+                                BMCWEB_LOG_ERROR("Bad dbus request error: {}",
+                                                 ec2);
+                            }
+                            else
+                            {
+                                nlohmann::json properties;
+                                int r =
+                                    convertDBusToJSON("a{sv}", msg, properties);
+                                if (r < 0)
+                                {
+                                    BMCWEB_LOG_ERROR(
+                                        "convertDBusToJSON failed");
+                                }
+                                else
+                                {
+                                    nlohmann::json::object_t* obj =
+                                        properties.get_ptr<
+                                            nlohmann::json::object_t*>();
+                                    if (obj == nullptr)
+                                    {
+                                        return;
+                                    }
+                                    for (auto& prop : *obj)
+                                    {
+                                        // if property name is empty, or
+                                        // matches our search query, add it
+                                        // to the response json
+
+                                        if (propertyName->empty())
+                                        {
+                                            (*response)[prop.first] =
+                                                std::move(prop.second);
+                                        }
+                                        else if (prop.first == *propertyName)
+                                        {
+                                            *response = std::move(prop.second);
+                                        }
+                                    }
+                                }
+                            }
+                            if (response.use_count() == 1)
+                            {
+                                if (!propertyName->empty() && response->empty())
+                                {
+                                    setErrorResponse(
+                                        asyncResp->res,
+                                        boost::beast::http::status::not_found,
+                                        propNotFoundDesc, notFoundMsg);
+                                }
+                                else
+                                {
+                                    asyncResp->res.jsonValue["status"] = "ok";
+                                    asyncResp->res.jsonValue["message"] =
+                                        "200 OK";
+                                    asyncResp->res.jsonValue["data"] =
+                                        *response;
+                                }
+                            }
+                        });
+                }
+            }
+        });
+}
+
+struct AsyncPutRequest
+{
+    explicit AsyncPutRequest(const std::shared_ptr<bmcweb::AsyncResp>& resIn) :
+        asyncResp(resIn)
+    {}
+    ~AsyncPutRequest()
+    {
+        if (asyncResp->res.jsonValue.empty())
+        {
+            setErrorResponse(asyncResp->res,
+                             boost::beast::http::status::forbidden,
+                             forbiddenMsg, forbiddenPropDesc);
+        }
+    }
+
+    AsyncPutRequest(const AsyncPutRequest&) = delete;
+    AsyncPutRequest(AsyncPutRequest&&) = delete;
+    AsyncPutRequest& operator=(const AsyncPutRequest&) = delete;
+    AsyncPutRequest& operator=(AsyncPutRequest&&) = delete;
+
+    void setErrorStatus(const std::string& desc)
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::internal_server_error,
+                         desc, badReqMsg);
+    }
+
+    const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
+    std::string objectPath;
+    std::string propertyName;
+    nlohmann::json propertyValue;
+};
+
+inline void handlePut(const crow::Request& req,
+                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                      const std::string& objectPath,
+                      const std::string& destProperty)
+{
+    if (destProperty.empty())
+    {
+        setErrorResponse(asyncResp->res, boost::beast::http::status::forbidden,
+                         forbiddenResDesc, forbiddenMsg);
+        return;
+    }
+    nlohmann::json requestDbusData;
+
+    JsonParseResult ret = parseRequestAsJson(req, requestDbusData);
+    if (ret == JsonParseResult::BadContentType)
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::unsupported_media_type,
+                         invalidContentType, unsupportedMediaMsg);
+        return;
+    }
+
+    if (ret != JsonParseResult::Success)
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
+        return;
+    }
+
+    auto propertyIt = requestDbusData.find("data");
+    if (propertyIt == requestDbusData.end())
+    {
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
+        return;
+    }
+    const nlohmann::json& propertySetValue = *propertyIt;
+    auto transaction = std::make_shared<AsyncPutRequest>(asyncResp);
+    transaction->objectPath = objectPath;
+    transaction->propertyName = destProperty;
+    transaction->propertyValue = propertySetValue;
+
+    dbus::utility::getDbusObject(
+        transaction->objectPath, {},
+        [transaction](const boost::system::error_code& ec2,
+                      const dbus::utility::MapperGetObject& objectNames) {
+            if (!ec2 && objectNames.empty())
+            {
+                setErrorResponse(transaction->asyncResp->res,
+                                 boost::beast::http::status::not_found,
+                                 propNotFoundDesc, notFoundMsg);
+                return;
+            }
+
+            for (const std::pair<std::string, std::vector<std::string>>&
+                     connection : objectNames)
+            {
+                const std::string& connectionName = connection.first;
+
+                dbus::utility::async_method_call(
+                    [connectionName{std::string(connectionName)},
+                     transaction](const boost::system::error_code& ec3,
+                                  const std::string& introspectXml) {
+                        if (ec3)
+                        {
+                            BMCWEB_LOG_ERROR(
+                                "Introspect call failed with error: {} on process: {}",
+                                ec3.message(), connectionName);
+                            transaction->setErrorStatus("Unexpected Error");
+                            return;
+                        }
+                        tinyxml2::XMLDocument doc;
+
+                        doc.Parse(introspectXml.c_str());
+                        tinyxml2::XMLNode* pRoot =
+                            doc.FirstChildElement("node");
+                        if (pRoot == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR("XML document failed to parse: {}",
+                                             introspectXml);
+                            transaction->setErrorStatus("Unexpected Error");
+                            return;
+                        }
+                        tinyxml2::XMLElement* ifaceNode =
+                            pRoot->FirstChildElement("interface");
+                        while (ifaceNode != nullptr)
+                        {
+                            const char* interfaceName =
+                                ifaceNode->Attribute("name");
+                            BMCWEB_LOG_DEBUG("found interface {}",
+                                             interfaceName);
+                            tinyxml2::XMLElement* propNode =
+                                ifaceNode->FirstChildElement("property");
+                            while (propNode != nullptr)
+                            {
+                                const char* propertyName =
+                                    propNode->Attribute("name");
+                                if (propertyName == nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG(
+                                        "Couldn't find name property");
+                                    continue;
+                                }
+                                BMCWEB_LOG_DEBUG("Found property {}",
+                                                 propertyName);
+                                if (propertyName == transaction->propertyName)
+                                {
+                                    const char* argType =
+                                        propNode->Attribute("type");
+                                    if (argType != nullptr)
+                                    {
+                                        sdbusplus::message_t m =
+                                            crow::connections::systemBus
+                                                ->new_method_call(
+                                                    connectionName.c_str(),
+                                                    transaction->objectPath
+                                                        .c_str(),
+                                                    "org.freedesktop.DBus."
+                                                    "Properties",
+                                                    "Set");
+                                        m.append(interfaceName,
+                                                 transaction->propertyName);
+                                        int r = sd_bus_message_open_container(
+                                            m.get(), SD_BUS_TYPE_VARIANT,
+                                            argType);
+                                        if (r < 0)
+                                        {
+                                            transaction->setErrorStatus(
+                                                "Unexpected Error");
+                                            return;
+                                        }
+                                        r = convertJsonToDbus(
+                                            m.get(), argType,
+                                            transaction->propertyValue);
+                                        if (r < 0)
+                                        {
+                                            if (r == -ERANGE)
+                                            {
+                                                transaction->setErrorStatus(
+                                                    "Provided property value "
+                                                    "is out of range for the "
+                                                    "property type");
+                                            }
+                                            else
+                                            {
+                                                transaction->setErrorStatus(
+                                                    "Invalid arg type");
+                                            }
+                                            return;
+                                        }
+                                        r = sd_bus_message_close_container(
+                                            m.get());
+                                        if (r < 0)
+                                        {
+                                            transaction->setErrorStatus(
+                                                "Unexpected Error");
+                                            return;
+                                        }
+                                        crow::connections::systemBus
+                                            ->async_send(
+                                                m,
+                                                [transaction](
+                                                    const boost::system::
+                                                        error_code& ec,
+                                                    sdbusplus::message_t& m2) {
+                                                    BMCWEB_LOG_DEBUG("sent");
+                                                    if (ec)
+                                                    {
+                                                        const sd_bus_error* e =
+                                                            m2.get_error();
+                                                        setErrorResponse(
+                                                            transaction
+                                                                ->asyncResp
+                                                                ->res,
+                                                            boost::beast::http::
+                                                                status::
+                                                                    forbidden,
+                                                            (e) != nullptr
+                                                                ? e->name
+                                                                : ec.category()
+                                                                      .name(),
+                                                            (e) != nullptr
+                                                                ? e->message
+                                                                : ec.message());
+                                                    }
+                                                    else
+                                                    {
+                                                        transaction->asyncResp
+                                                            ->res.jsonValue
+                                                                ["status"] =
+                                                            "ok";
+                                                        transaction->asyncResp
+                                                            ->res.jsonValue
+                                                                ["message"] =
+                                                            "200 OK";
+                                                        transaction->asyncResp
+                                                            ->res
+                                                            .jsonValue["data"] =
+                                                            nullptr;
+                                                    }
+                                                });
+                                    }
+                                }
+                                propNode =
+                                    propNode->NextSiblingElement("property");
+                            }
+                            ifaceNode =
+                                ifaceNode->NextSiblingElement("interface");
+                        }
+                    },
+                    connectionName, transaction->objectPath,
+                    "org.freedesktop.DBus.Introspectable", "Introspect");
+            }
+        });
+}
+
+inline void handleDBusUrl(const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          std::string& objectPath)
+{
+    // If accessing a single attribute, fill in and update objectPath,
+    // otherwise leave destProperty blank
+    std::string destProperty;
+    const char* attrSeperator = "/attr/";
+    size_t attrPosition = objectPath.find(attrSeperator);
+    if (attrPosition != std::string::npos)
+    {
+        destProperty = objectPath.substr(attrPosition + strlen(attrSeperator),
+                                         objectPath.length());
+        objectPath.resize(attrPosition);
+    }
+
+    if (req.method() == boost::beast::http::verb::post)
+    {
+        constexpr const char* actionSeperator = "/action/";
+        size_t actionPosition = objectPath.find(actionSeperator);
+        if (actionPosition != std::string::npos)
+        {
+            std::string postProperty =
+                objectPath.substr((actionPosition + strlen(actionSeperator)),
+                                  objectPath.length());
+            objectPath.resize(actionPosition);
+            handleAction(req, asyncResp, objectPath, postProperty);
+            return;
+        }
+    }
+    else if (req.method() == boost::beast::http::verb::get)
+    {
+        if (objectPath.ends_with("/enumerate"))
+        {
+            objectPath.erase(objectPath.end() - sizeof("enumerate"),
+                             objectPath.end());
+            handleEnumerate(asyncResp, objectPath);
+        }
+        else if (objectPath.ends_with("/list"))
+        {
+            objectPath.erase(objectPath.end() - sizeof("list"),
+                             objectPath.end());
+            handleList(asyncResp, objectPath);
+        }
+        else
+        {
+            // Trim any trailing "/" at the end
+            if (objectPath.ends_with("/"))
+            {
+                objectPath.pop_back();
+                handleList(asyncResp, objectPath, 1);
+            }
+            else
+            {
+                handleGet(asyncResp, objectPath, destProperty);
+            }
+        }
+        return;
+    }
+    else if (req.method() == boost::beast::http::verb::put)
+    {
+        handlePut(req, asyncResp, objectPath, destProperty);
+        return;
+    }
+    else if (req.method() == boost::beast::http::verb::delete_)
+    {
+        handleDelete(asyncResp, objectPath);
+        return;
+    }
+
+    setErrorResponse(asyncResp->res,
+                     boost::beast::http::status::method_not_allowed,
+                     methodNotAllowedDesc, methodNotAllowedMsg);
+}
+
+inline void handleBusSystemPost(
+    const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& processName, const std::string& requestedPath)
+{
+    std::vector<std::string> strs;
+
+    bmcweb::split(strs, requestedPath, '/');
+    std::string objectPath;
+    std::string interfaceName;
+    std::string methodName;
+    auto it = strs.begin();
+    if (it == strs.end())
+    {
+        objectPath = "/";
+    }
+    while (it != strs.end())
+    {
+        // Check if segment contains ".".  If it does, it must be an
+        // interface
+        if (it->find(".") != std::string::npos)
+        {
+            break;
+            // This check is necessary as the trailing slash gets
+            // parsed as part of our <path> specifier above, which
+            // causes the normal trailing backslash redirector to
+            // fail.
+        }
+        if (!it->empty())
+        {
+            objectPath += "/" + *it;
+        }
+        it++;
+    }
+    if (it != strs.end())
+    {
+        interfaceName = *it;
+        it++;
+
+        // after interface, we might have a method name
+        if (it != strs.end())
+        {
+            methodName = *it;
+            it++;
+        }
+    }
+    if (it != strs.end())
+    {
+        // if there is more levels past the method name, something
+        // went wrong, return not found
+        asyncResp->res.result(boost::beast::http::status::not_found);
+        return;
+    }
+    if (interfaceName.empty())
+    {
+        dbus::utility::async_method_call(
+            [asyncResp, processName,
+             objectPath](const boost::system::error_code& ec,
+                         const std::string& introspectXml) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR(
+                        "Introspect call failed with error: {} on process: {} path: {}",
+                        ec.message(), processName, objectPath);
+                    return;
+                }
+                tinyxml2::XMLDocument doc;
+
+                doc.Parse(introspectXml.c_str());
+                tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
+                if (pRoot == nullptr)
+                {
+                    BMCWEB_LOG_ERROR("XML document failed to parse {} {}",
+                                     processName, objectPath);
+                    asyncResp->res.jsonValue["status"] = "XML parse error";
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
+
+                BMCWEB_LOG_DEBUG("{}", introspectXml);
+                asyncResp->res.jsonValue["status"] = "ok";
+                asyncResp->res.jsonValue["bus_name"] = processName;
+                asyncResp->res.jsonValue["object_path"] = objectPath;
+
+                nlohmann::json& interfacesArray =
+                    asyncResp->res.jsonValue["interfaces"];
+                interfacesArray = nlohmann::json::array();
+                tinyxml2::XMLElement* interface =
+                    pRoot->FirstChildElement("interface");
+
+                while (interface != nullptr)
+                {
+                    const char* ifaceName = interface->Attribute("name");
+                    if (ifaceName != nullptr)
+                    {
+                        nlohmann::json::object_t interfaceObj;
+                        interfaceObj["name"] = ifaceName;
+                        interfacesArray.emplace_back(std::move(interfaceObj));
+                    }
+
+                    interface = interface->NextSiblingElement("interface");
+                }
+            },
+            processName, objectPath, "org.freedesktop.DBus.Introspectable",
+            "Introspect");
+    }
+    else if (methodName.empty())
+    {
+        dbus::utility::async_method_call(
+            [asyncResp, processName, objectPath,
+             interfaceName](const boost::system::error_code& ec,
+                            const std::string& introspectXml) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR(
+                        "Introspect call failed with error: {} on process: {} path: {}",
+                        ec.message(), processName, objectPath);
+                    return;
+                }
+                tinyxml2::XMLDocument doc;
+
+                doc.Parse(introspectXml.data(), introspectXml.size());
+                tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
+                if (pRoot == nullptr)
+                {
+                    BMCWEB_LOG_ERROR("XML document failed to parse {} {}",
+                                     processName, objectPath);
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
+
+                asyncResp->res.jsonValue["status"] = "ok";
+                asyncResp->res.jsonValue["bus_name"] = processName;
+                asyncResp->res.jsonValue["interface"] = interfaceName;
+                asyncResp->res.jsonValue["object_path"] = objectPath;
+
+                nlohmann::json& methodsArray =
+                    asyncResp->res.jsonValue["methods"];
+                methodsArray = nlohmann::json::array();
+
+                nlohmann::json& signalsArray =
+                    asyncResp->res.jsonValue["signals"];
+                signalsArray = nlohmann::json::array();
+
+                nlohmann::json& propertiesObj =
+                    asyncResp->res.jsonValue["properties"];
+                propertiesObj = nlohmann::json::object();
+
+                // if we know we're the only call, build the
+                // json directly
+                tinyxml2::XMLElement* interface =
+                    pRoot->FirstChildElement("interface");
+                while (interface != nullptr)
+                {
+                    const char* ifaceName = interface->Attribute("name");
+
+                    if (ifaceName != nullptr && ifaceName == interfaceName)
+                    {
+                        break;
+                    }
+
+                    interface = interface->NextSiblingElement("interface");
+                }
+                if (interface == nullptr)
+                {
+                    // if we got to the end of the list and
+                    // never found a match, throw 404
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+
+                tinyxml2::XMLElement* methods =
+                    interface->FirstChildElement("method");
+                while (methods != nullptr)
+                {
+                    nlohmann::json argsArray = nlohmann::json::array();
+                    tinyxml2::XMLElement* arg =
+                        methods->FirstChildElement("arg");
+                    while (arg != nullptr)
+                    {
+                        nlohmann::json thisArg;
+                        for (const char* fieldName : std::array<const char*, 3>{
+                                 "name", "direction", "type"})
+                        {
+                            const char* fieldValue = arg->Attribute(fieldName);
+                            if (fieldValue != nullptr)
+                            {
+                                thisArg[fieldName] = fieldValue;
+                            }
+                        }
+                        argsArray.emplace_back(std::move(thisArg));
+                        arg = arg->NextSiblingElement("arg");
+                    }
+
+                    const char* name = methods->Attribute("name");
+                    if (name != nullptr)
+                    {
+                        std::string uri;
+                        uri.reserve(14 + processName.size() +
+                                    objectPath.size() + interfaceName.size() +
+                                    strlen(name));
+                        uri += "/bus/system/";
+                        uri += processName;
+                        uri += objectPath;
+                        uri += "/";
+                        uri += interfaceName;
+                        uri += "/";
+                        uri += name;
+
+                        nlohmann::json::object_t object;
+                        object["name"] = name;
+                        object["uri"] = std::move(uri);
+                        object["args"] = argsArray;
+
+                        methodsArray.emplace_back(std::move(object));
+                    }
+                    methods = methods->NextSiblingElement("method");
+                }
+                tinyxml2::XMLElement* signals =
+                    interface->FirstChildElement("signal");
+                while (signals != nullptr)
+                {
+                    nlohmann::json argsArray = nlohmann::json::array();
+
+                    tinyxml2::XMLElement* arg =
+                        signals->FirstChildElement("arg");
+                    while (arg != nullptr)
+                    {
+                        const char* name = arg->Attribute("name");
+                        const char* type = arg->Attribute("type");
+                        if (name != nullptr && type != nullptr)
+                        {
+                            nlohmann::json::object_t params;
+                            params["name"] = name;
+                            params["type"] = type;
+                            argsArray.push_back(std::move(params));
+                        }
+                        arg = arg->NextSiblingElement("arg");
+                    }
+                    const char* name = signals->Attribute("name");
+                    if (name != nullptr)
+                    {
+                        nlohmann::json::object_t object;
+                        object["name"] = name;
+                        object["args"] = argsArray;
+                        signalsArray.emplace_back(std::move(object));
+                    }
+
+                    signals = signals->NextSiblingElement("signal");
+                }
+
+                tinyxml2::XMLElement* property =
+                    interface->FirstChildElement("property");
+                while (property != nullptr)
+                {
+                    const char* name = property->Attribute("name");
+                    const char* type = property->Attribute("type");
+                    if (type != nullptr && name != nullptr)
+                    {
+                        sdbusplus::message_t m =
+                            crow::connections::systemBus->new_method_call(
+                                processName.c_str(), objectPath.c_str(),
+                                "org.freedesktop."
+                                "DBus."
+                                "Properties",
+                                "Get");
+                        m.append(interfaceName, name);
+                        nlohmann::json& propertyItem = propertiesObj[name];
+                        crow::connections::systemBus->async_send(
+                            m, [&propertyItem,
+                                asyncResp](const boost::system::error_code& ec2,
+                                           sdbusplus::message_t& msg) {
+                                if (ec2)
+                                {
+                                    return;
+                                }
+
+                                int r =
+                                    convertDBusToJSON("v", msg, propertyItem);
+                                if (r < 0)
+                                {
+                                    BMCWEB_LOG_ERROR(
+                                        "Couldn't convert vector to json");
+                                }
+                            });
+                    }
+                    property = property->NextSiblingElement("property");
+                }
+            },
+            processName, objectPath, "org.freedesktop.DBus.Introspectable",
+            "Introspect");
+    }
+    else
+    {
+        if (req.method() != boost::beast::http::verb::post)
+        {
+            asyncResp->res.result(boost::beast::http::status::not_found);
+            return;
+        }
+
+        nlohmann::json requestDbusData;
+        JsonParseResult ret = parseRequestAsJson(req, requestDbusData);
+        if (ret == JsonParseResult::BadContentType)
+        {
+            setErrorResponse(asyncResp->res,
+                             boost::beast::http::status::unsupported_media_type,
+                             invalidContentType, unsupportedMediaMsg);
+            return;
+        }
+        if (ret != JsonParseResult::Success)
+        {
+            setErrorResponse(asyncResp->res,
+                             boost::beast::http::status::bad_request,
+                             noJsonDesc, badReqMsg);
+            return;
+        }
+
+        if (!requestDbusData.is_array())
+        {
+            asyncResp->res.result(boost::beast::http::status::bad_request);
+            return;
+        }
+        auto transaction = std::make_shared<InProgressActionData>(asyncResp);
+
+        transaction->path = objectPath;
+        transaction->methodName = methodName;
+        transaction->arguments = std::move(requestDbusData);
+
+        findActionOnInterface(transaction, processName);
+    }
+}
+
+inline void requestRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/bus/")
+        .privileges({{"Login"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                nlohmann::json::array_t buses;
+                nlohmann::json& bus = buses.emplace_back();
+                bus["name"] = "system";
+                asyncResp->res.jsonValue["busses"] = std::move(buses);
+                asyncResp->res.jsonValue["status"] = "ok";
+            });
+
+    BMCWEB_ROUTE(app, "/bus/system/")
+        .privileges({{"Login"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                auto myCallback = [asyncResp](
+                                      const boost::system::error_code& ec,
+                                      std::vector<std::string>& names) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR("Dbus call failed with code {}", ec);
+                        asyncResp->res.result(
+                            boost::beast::http::status::internal_server_error);
+                    }
+                    else
+                    {
+                        std::ranges::sort(names);
+                        asyncResp->res.jsonValue["status"] = "ok";
+                        auto& objectsSub = asyncResp->res.jsonValue["objects"];
+                        for (const auto& name : names)
+                        {
+                            nlohmann::json::object_t object;
+                            object["name"] = name;
+                            objectsSub.emplace_back(std::move(object));
+                        }
+                    }
+                };
+                dbus::utility::async_method_call(
+                    std::move(myCallback), "org.freedesktop.DBus", "/",
+                    "org.freedesktop.DBus", "ListNames");
+            });
+
+    BMCWEB_ROUTE(app, "/list/")
+        .privileges({{"Login"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                handleList(asyncResp, "/");
+            });
+
+    BMCWEB_ROUTE(app, "/xyz/<path>")
+        .privileges({{"Login"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& path) {
+                std::string objectPath = "/xyz/" + path;
+                handleDBusUrl(req, asyncResp, objectPath);
+            });
+
+    BMCWEB_ROUTE(app, "/xyz/<path>")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
+                 boost::beast::http::verb::delete_)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& path) {
+                std::string objectPath = "/xyz/" + path;
+                handleDBusUrl(req, asyncResp, objectPath);
+            });
+
+    BMCWEB_ROUTE(app, "/org/<path>")
+        .privileges({{"Login"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& path) {
+                std::string objectPath = "/org/" + path;
+                handleDBusUrl(req, asyncResp, objectPath);
+            });
+
+    BMCWEB_ROUTE(app, "/org/<path>")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
+                 boost::beast::http::verb::delete_)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& path) {
+                std::string objectPath = "/org/" + path;
+                handleDBusUrl(req, asyncResp, objectPath);
+            });
+
+    BMCWEB_ROUTE(app, "/download/dump/<str>/")
+        .privileges({{"ConfigureManager"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& dumpId) {
+                if (!validateFilename(dumpId))
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
+                std::filesystem::path loc(
+                    "/var/lib/phosphor-debug-collector/dumps");
+
+                loc /= dumpId;
+
+                if (!std::filesystem::exists(loc) ||
+                    !std::filesystem::is_directory(loc))
+                {
+                    BMCWEB_LOG_ERROR("{}Not found", loc.string());
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+                std::filesystem::directory_iterator files(loc);
+
+                for (const auto& file : files)
+                {
+                    if (asyncResp->res.openFile(file) !=
+                        crow::OpenCode::Success)
+                    {
+                        continue;
+                    }
+
+                    asyncResp->res.addHeader(
+                        boost::beast::http::field::content_type,
+                        "application/octet-stream");
+
+                    // Assuming only one dump file will be present in the dump
+                    // id directory
+                    std::string dumpFileName = file.path().filename().string();
+
+                    // Filename should be in alphanumeric, dot and underscore
+                    // Its based on phosphor-debug-collector application
+                    // dumpfile format
+                    static std::regex dumpFileRegex("[a-zA-Z0-9\\._]+");
+                    if (!std::regex_match(dumpFileName, dumpFileRegex))
+                    {
+                        BMCWEB_LOG_ERROR("Invalid dump filename {}",
+                                         dumpFileName);
+                        asyncResp->res.result(
+                            boost::beast::http::status::not_found);
+                        return;
+                    }
+                    std::string contentDispositionParam =
+                        "attachment; filename=\"" + dumpFileName + "\"";
+
+                    asyncResp->res.addHeader(
+                        boost::beast::http::field::content_disposition,
+                        contentDispositionParam);
+
+                    return;
+                }
+                asyncResp->res.result(boost::beast::http::status::not_found);
+                return;
+            });
+
+    BMCWEB_ROUTE(app, "/bus/system/<str>/")
+        .privileges({{"Login"}})
+
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& connection) {
+                introspectObjects(connection, "/", asyncResp);
+            });
+
+    BMCWEB_ROUTE(app, "/bus/system/<str>/<path>")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::get,
+                 boost::beast::http::verb::post)(handleBusSystemPost);
+}
+} // namespace openbmc_mapper
+} // namespace crow
diff --git a/features/openbmc_rest/openbmc_dbus_rest_test.cpp b/features/openbmc_rest/openbmc_dbus_rest_test.cpp
new file mode 100644
index 0000000..1bc320e
--- /dev/null
+++ b/features/openbmc_rest/openbmc_dbus_rest_test.cpp
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#include "openbmc_dbus_rest.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace crow::openbmc_mapper
+{
+namespace
+{
+
+using ::testing::ElementsAre;
+// Also see redfish-core/ut/configfile_test.cpp
+TEST(OpenbmcDbusRestTest, ValidFilenameGood)
+{
+    EXPECT_TRUE(validateFilename("GoodConfigFile"));
+    EXPECT_TRUE(validateFilename("_Underlines_"));
+    EXPECT_TRUE(validateFilename("8675309"));
+    EXPECT_TRUE(validateFilename("-Dashes-"));
+    EXPECT_TRUE(validateFilename("With Spaces"));
+    EXPECT_TRUE(validateFilename("One.Dot"));
+    EXPECT_TRUE(validateFilename("trailingdot."));
+    EXPECT_TRUE(validateFilename("-_ o _-"));
+    EXPECT_TRUE(validateFilename(" "));
+    EXPECT_TRUE(validateFilename(" ."));
+}
+
+// There is no length test yet because validateFilename() does not care yet
+TEST(OpenbmcDbusRestTest, ValidFilenameBad)
+{
+    EXPECT_FALSE(validateFilename(""));
+    EXPECT_FALSE(validateFilename("Bad@file"));
+    EXPECT_FALSE(validateFilename("/../../../../../etc/badpath"));
+    EXPECT_FALSE(validateFilename("/../../etc/badpath"));
+    EXPECT_FALSE(validateFilename("/mydir/configFile"));
+    EXPECT_FALSE(validateFilename("/"));
+    EXPECT_FALSE(validateFilename(".leadingdot"));
+    EXPECT_FALSE(validateFilename("Two..Dots"));
+    EXPECT_FALSE(validateFilename("../../../../../../etc/shadow"));
+    EXPECT_FALSE(validateFilename("."));
+}
+
+TEST(OpenBmcDbusTest, TestArgSplit)
+{
+    // test the basic types
+    EXPECT_THAT(dbusArgSplit("x"), ElementsAre("x"));
+    EXPECT_THAT(dbusArgSplit("y"), ElementsAre("y"));
+    EXPECT_THAT(dbusArgSplit("b"), ElementsAre("b"));
+    EXPECT_THAT(dbusArgSplit("n"), ElementsAre("n"));
+    EXPECT_THAT(dbusArgSplit("q"), ElementsAre("q"));
+    EXPECT_THAT(dbusArgSplit("i"), ElementsAre("i"));
+    EXPECT_THAT(dbusArgSplit("u"), ElementsAre("u"));
+    EXPECT_THAT(dbusArgSplit("x"), ElementsAre("x"));
+    EXPECT_THAT(dbusArgSplit("t"), ElementsAre("t"));
+    EXPECT_THAT(dbusArgSplit("d"), ElementsAre("d"));
+    EXPECT_THAT(dbusArgSplit("h"), ElementsAre("h"));
+    // test arrays
+    EXPECT_THAT(dbusArgSplit("ai"), ElementsAre("ai"));
+    EXPECT_THAT(dbusArgSplit("ax"), ElementsAre("ax"));
+    // test tuples
+    EXPECT_THAT(dbusArgSplit("(sss)"), ElementsAre("(sss)"));
+    EXPECT_THAT(dbusArgSplit("(sss)b"), ElementsAre("(sss)", "b"));
+    EXPECT_THAT(dbusArgSplit("b(sss)"), ElementsAre("b", "(sss)"));
+
+    // Test nested types
+    EXPECT_THAT(dbusArgSplit("a{si}b"), ElementsAre("a{si}", "b"));
+    EXPECT_THAT(dbusArgSplit("a(sss)b"), ElementsAre("a(sss)", "b"));
+    EXPECT_THAT(dbusArgSplit("aa{si}b"), ElementsAre("aa{si}", "b"));
+    EXPECT_THAT(dbusArgSplit("i{si}b"), ElementsAre("i", "{si}", "b"));
+}
+} // namespace
+} // namespace crow::openbmc_mapper
