diff --git a/features/google/google_service_root.hpp b/features/google/google_service_root.hpp
new file mode 100644
index 0000000..3d21af7
--- /dev/null
+++ b/features/google/google_service_root.hpp
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "dbus_utility.hpp"
+#include "error_messages.hpp"
+#include "http_request.hpp"
+#include "logging.hpp"
+#include "utils/collection.hpp"
+#include "utils/hex_utils.hpp"
+#include "utils/json_utils.hpp"
+
+#include <boost/beast/http/verb.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/url/format.hpp>
+#include <boost/url/url.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <array>
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace crow
+{
+namespace google_api
+{
+
+inline void handleGoogleV1Get(
+    const crow::Request& /*req*/,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#GoogleServiceRoot.v1_0_0.GoogleServiceRoot";
+    asyncResp->res.jsonValue["@odata.id"] = "/google/v1";
+    asyncResp->res.jsonValue["Id"] = "Google Rest RootService";
+    asyncResp->res.jsonValue["Name"] = "Google Service Root";
+    asyncResp->res.jsonValue["Version"] = "1.0.0";
+    asyncResp->res.jsonValue["RootOfTrustCollection"]["@odata.id"] =
+        "/google/v1/RootOfTrustCollection";
+}
+
+inline void handleRootOfTrustCollectionGet(
+    const crow::Request& /*req*/,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    asyncResp->res.jsonValue["@odata.id"] = "/google/v1/RootOfTrustCollection";
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#RootOfTrustCollection.RootOfTrustCollection";
+    const std::array<std::string_view, 1> interfaces{
+        "xyz.openbmc_project.Control.Hoth"};
+    redfish::collection_util::getCollectionMembers(
+        asyncResp, boost::urls::url("/google/v1/RootOfTrustCollection"),
+        interfaces, "/xyz/openbmc_project");
+}
+
+// Helper struct to identify a resolved D-Bus object interface
+struct ResolvedEntity
+{
+    std::string id;
+    std::string service;
+    std::string object;
+    std::string interface;
+};
+
+using ResolvedEntityHandler = std::function<void(
+    const std::string&, const std::shared_ptr<bmcweb::AsyncResp>&,
+    const ResolvedEntity&)>;
+
+inline void hothGetSubtreeCallback(
+    const std::string& command,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& rotId, const ResolvedEntityHandler& entityHandler,
+    const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree)
+{
+    if (ec)
+    {
+        redfish::messages::internalError(asyncResp->res);
+        return;
+    }
+    for (const auto& [path, services] : subtree)
+    {
+        sdbusplus::message::object_path objPath(path);
+        if (objPath.filename() != rotId || services.empty())
+        {
+            continue;
+        }
+
+        ResolvedEntity resolvedEntity = {
+            .id = rotId,
+            .service = services[0].first,
+            .object = path,
+            .interface = "xyz.openbmc_project.Control.Hoth"};
+        entityHandler(command, asyncResp, resolvedEntity);
+        return;
+    }
+
+    // Couldn't find an object with that name.  return an error
+    redfish::messages::resourceNotFound(asyncResp->res, "RootOfTrust", rotId);
+}
+
+inline void resolveRoT(const std::string& command,
+                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& rotId,
+                       ResolvedEntityHandler&& entityHandler)
+{
+    constexpr std::array<std::string_view, 1> hothIfaces = {
+        "xyz.openbmc_project.Control.Hoth"};
+    dbus::utility::getSubTree(
+        "/xyz/openbmc_project", 0, hothIfaces,
+        [command, asyncResp, rotId, entityHandler{std::move(entityHandler)}](
+            const boost::system::error_code& ec,
+            const dbus::utility::MapperGetSubTreeResponse& subtree) {
+            hothGetSubtreeCallback(command, asyncResp, rotId, entityHandler, ec,
+                                   subtree);
+        });
+}
+
+inline void populateRootOfTrustEntity(
+    const std::string& /*unused*/,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const ResolvedEntity& resolvedEntity)
+{
+    asyncResp->res.jsonValue["@odata.type"] = "#RootOfTrust.v1_0_0.RootOfTrust";
+    asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+        "/google/v1/RootOfTrustCollection/{}", resolvedEntity.id);
+
+    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+    asyncResp->res.jsonValue["Id"] = resolvedEntity.id;
+    // Need to fix this later to a stabler property.
+    asyncResp->res.jsonValue["Name"] = resolvedEntity.id;
+    asyncResp->res.jsonValue["Description"] = "Google Root Of Trust";
+    asyncResp->res.jsonValue["Actions"]["#RootOfTrust.SendCommand"]["target"] =
+        "/google/v1/RootOfTrustCollection/" + resolvedEntity.id +
+        "/Actions/RootOfTrust.SendCommand";
+
+    asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+        resolvedEntity.id;
+    asyncResp->res.jsonValue["Location"]["PartLocation"]["LocationType"] =
+        "Embedded";
+}
+
+inline void handleRootOfTrustGet(
+    const crow::Request& /*req*/,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& param)
+{
+    std::string emptyCommand;
+    resolveRoT(emptyCommand, asyncResp, param, populateRootOfTrustEntity);
+}
+
+inline void invocationCallback(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const boost::system::error_code& ec,
+    const std::vector<uint8_t>& responseBytes)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("RootOfTrust.Actions.SendCommand failed: {}",
+                         ec.message());
+        redfish::messages::internalError(asyncResp->res);
+        return;
+    }
+
+    asyncResp->res.jsonValue["CommandResponse"] =
+        bytesToHexString(responseBytes);
+}
+
+inline void invokeRoTCommand(
+    const std::string& command,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const ResolvedEntity& resolvedEntity)
+{
+    std::vector<uint8_t> bytes = hexStringToBytes(command);
+    if (bytes.empty())
+    {
+        BMCWEB_LOG_DEBUG("Invalid command: {}", command);
+        redfish::messages::actionParameterValueTypeError(command, "Command",
+                                                         "SendCommand");
+        return;
+    }
+
+    dbus::utility::async_method_call(
+        asyncResp,
+        [asyncResp{asyncResp}](const boost::system::error_code& ec,
+                               const std::vector<uint8_t>& responseBytes) {
+            invocationCallback(asyncResp, ec, responseBytes);
+        },
+        resolvedEntity.service, resolvedEntity.object, resolvedEntity.interface,
+        "SendHostCommand", bytes);
+}
+
+inline void handleRoTSendCommandPost(
+    const crow::Request& request,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& rotId)
+{
+    std::string command;
+    if (!redfish::json_util::readJsonAction(request, asyncResp->res, "Command",
+                                            command))
+    {
+        BMCWEB_LOG_DEBUG("Missing property Command.");
+        redfish::messages::actionParameterMissing(asyncResp->res, "SendCommand",
+                                                  "Command");
+        return;
+    }
+
+    resolveRoT(command, asyncResp, rotId, invokeRoTCommand);
+}
+
+inline void requestRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/google/v1/")
+        .methods(boost::beast::http::verb::get)(handleGoogleV1Get);
+
+    BMCWEB_ROUTE(app, "/google/v1/RootOfTrustCollection")
+        .privileges({{"ConfigureManager"}})
+        .methods(boost::beast::http::verb::get)(handleRootOfTrustCollectionGet);
+
+    BMCWEB_ROUTE(app, "/google/v1/RootOfTrustCollection/<str>")
+        .privileges({{"ConfigureManager"}})
+        .methods(boost::beast::http::verb::get)(handleRootOfTrustGet);
+
+    BMCWEB_ROUTE(
+        app,
+        "/google/v1/RootOfTrustCollection/<str>/Actions/RootOfTrust.SendCommand")
+        .privileges({{"ConfigureManager"}})
+        .methods(boost::beast::http::verb::post)(handleRoTSendCommandPost);
+}
+
+} // namespace google_api
+} // namespace crow
diff --git a/features/google/google_service_root_test.cpp b/features/google/google_service_root_test.cpp
new file mode 100644
index 0000000..c104494
--- /dev/null
+++ b/features/google/google_service_root_test.cpp
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#include "async_resp.hpp"
+#include "google_service_root.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+
+#include <boost/beast/http/verb.hpp>
+#include <nlohmann/json.hpp>
+
+#include <memory>
+#include <system_error>
+
+#include <gtest/gtest.h>
+
+namespace crow::google_api
+{
+namespace
+{
+
+void validateServiceRootGet(crow::Response& res)
+{
+    nlohmann::json& json = res.jsonValue;
+    EXPECT_EQ(json["@odata.id"], "/google/v1");
+    EXPECT_EQ(json["@odata.type"],
+              "#GoogleServiceRoot.v1_0_0.GoogleServiceRoot");
+    EXPECT_EQ(json["@odata.id"], "/google/v1");
+    EXPECT_EQ(json["Id"], "Google Rest RootService");
+    EXPECT_EQ(json["Name"], "Google Service Root");
+    EXPECT_EQ(json["Version"], "1.0.0");
+    EXPECT_EQ(json["RootOfTrustCollection"]["@odata.id"],
+              "/google/v1/RootOfTrustCollection");
+}
+
+TEST(HandleGoogleV1Get, OnSuccess)
+{
+    std::error_code ec;
+    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
+
+    asyncResp->res.setCompleteRequestHandler(validateServiceRootGet);
+
+    crow::Request dummyRequest{{boost::beast::http::verb::get, "", 11}, ec};
+    handleGoogleV1Get(dummyRequest, asyncResp);
+}
+
+} // namespace
+} // namespace crow::google_api
diff --git a/features/google/meson.build b/features/google/meson.build
new file mode 100644
index 0000000..5df3400
--- /dev/null
+++ b/features/google/meson.build
@@ -0,0 +1,2 @@
+incdir += include_directories('.')
+test_sources += files('google_service_root_test.cpp')
diff --git a/features/ibm/configfile_test.cpp b/features/ibm/configfile_test.cpp
new file mode 100644
index 0000000..b64a2d3
--- /dev/null
+++ b/features/ibm/configfile_test.cpp
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#include "http_response.hpp"
+#include "ibm_management_console_rest.hpp"
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+namespace crow
+{
+namespace ibm_mc
+{
+
+TEST(IsValidConfigFileName, FileNameValidCharReturnsTrue)
+{
+    crow::Response res;
+
+    EXPECT_TRUE(isValidConfigFileName("GoodConfigFile", res));
+}
+TEST(IsValidConfigFileName, FileNameInvalidCharReturnsFalse)
+{
+    crow::Response res;
+
+    EXPECT_FALSE(isValidConfigFileName("Bad@file", res));
+}
+TEST(IsValidConfigFileName, FileNameInvalidPathReturnsFalse)
+{
+    crow::Response res;
+
+    EXPECT_FALSE(isValidConfigFileName("/../../../../../etc/badpath", res));
+    EXPECT_FALSE(isValidConfigFileName("/../../etc/badpath", res));
+    EXPECT_FALSE(isValidConfigFileName("/mydir/configFile", res));
+}
+
+TEST(IsValidConfigFileName, EmptyFileNameReturnsFalse)
+{
+    crow::Response res;
+    EXPECT_FALSE(isValidConfigFileName("", res));
+}
+
+TEST(IsValidConfigFileName, SlashFileNameReturnsFalse)
+{
+    crow::Response res;
+    EXPECT_FALSE(isValidConfigFileName("/", res));
+}
+TEST(IsValidConfigFileName, FileNameMoreThan20CharReturnsFalse)
+{
+    crow::Response res;
+    EXPECT_FALSE(isValidConfigFileName("BadfileBadfileBadfile", res));
+}
+
+} // namespace ibm_mc
+} // namespace crow
diff --git a/features/ibm/ibm_management_console_rest.hpp b/features/ibm/ibm_management_console_rest.hpp
new file mode 100644
index 0000000..764e504
--- /dev/null
+++ b/features/ibm/ibm_management_console_rest.hpp
@@ -0,0 +1,486 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "http_request.hpp"
+#include "logging.hpp"
+#include "str_utility.hpp"
+#include "utils.hpp"
+#include "utils/json_utils.hpp"
+
+#include <boost/beast/core/string_type.hpp>
+#include <boost/beast/http/field.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/beast/http/verb.hpp>
+#include <nlohmann/json.hpp>
+
+#include <cstddef>
+#include <cstdint>
+#include <filesystem>
+#include <fstream>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <vector>
+
+namespace crow
+{
+namespace ibm_mc
+{
+constexpr const char* methodNotAllowedMsg = "Method Not Allowed";
+constexpr const char* resourceNotFoundMsg = "Resource Not Found";
+constexpr const char* contentNotAcceptableMsg = "Content Not Acceptable";
+constexpr const char* internalServerError = "Internal Server Error";
+
+constexpr size_t maxSaveareaDirSize =
+    25000000; // Allow save area dir size to be max 25MB
+constexpr size_t minSaveareaFileSize =
+    100;      // Allow save area file size of minimum 100B
+constexpr size_t maxSaveareaFileSize =
+    500000;   // Allow save area file size upto 500KB
+constexpr size_t maxBroadcastMsgSize =
+    1000;     // Allow Broadcast message size upto 1KB
+
+inline void handleFilePut(const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          const std::string& fileID)
+{
+    std::error_code ec;
+    // Check the content-type of the request
+    boost::beast::string_view contentType = req.getHeaderValue("content-type");
+    if (!bmcweb::asciiIEquals(contentType, "application/octet-stream"))
+    {
+        asyncResp->res.result(boost::beast::http::status::not_acceptable);
+        asyncResp->res.jsonValue["Description"] = contentNotAcceptableMsg;
+        return;
+    }
+    BMCWEB_LOG_DEBUG(
+        "File upload in application/octet-stream format. Continue..");
+
+    BMCWEB_LOG_DEBUG(
+        "handleIbmPut: Request to create/update the save-area file");
+    std::string_view path =
+        "/var/lib/bmcweb/ibm-management-console/configfiles";
+    if (!crow::ibm_utils::createDirectory(path))
+    {
+        asyncResp->res.result(boost::beast::http::status::not_found);
+        asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
+        return;
+    }
+
+    std::ofstream file;
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles");
+
+    // Get the current size of the savearea directory
+    std::filesystem::recursive_directory_iterator iter(loc, ec);
+    if (ec)
+    {
+        asyncResp->res.result(
+            boost::beast::http::status::internal_server_error);
+        asyncResp->res.jsonValue["Description"] = internalServerError;
+        BMCWEB_LOG_DEBUG("handleIbmPut: Failed to prepare save-area "
+                         "directory iterator. ec : {}",
+                         ec.message());
+        return;
+    }
+    std::uintmax_t saveAreaDirSize = 0;
+    for (const auto& it : iter)
+    {
+        if (!std::filesystem::is_directory(it, ec))
+        {
+            if (ec)
+            {
+                asyncResp->res.result(
+                    boost::beast::http::status::internal_server_error);
+                asyncResp->res.jsonValue["Description"] = internalServerError;
+                BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find save-area "
+                                 "directory . ec : {}",
+                                 ec.message());
+                return;
+            }
+            std::uintmax_t fileSize = std::filesystem::file_size(it, ec);
+            if (ec)
+            {
+                asyncResp->res.result(
+                    boost::beast::http::status::internal_server_error);
+                asyncResp->res.jsonValue["Description"] = internalServerError;
+                BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find save-area "
+                                 "file size inside the directory . ec : {}",
+                                 ec.message());
+                return;
+            }
+            saveAreaDirSize += fileSize;
+        }
+    }
+    BMCWEB_LOG_DEBUG("saveAreaDirSize: {}", saveAreaDirSize);
+
+    // Get the file size getting uploaded
+    const std::string& data = req.body();
+    BMCWEB_LOG_DEBUG("data length: {}", data.length());
+
+    if (data.length() < minSaveareaFileSize)
+    {
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        asyncResp->res.jsonValue["Description"] =
+            "File size is less than minimum allowed size[100B]";
+        return;
+    }
+    if (data.length() > maxSaveareaFileSize)
+    {
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        asyncResp->res.jsonValue["Description"] =
+            "File size exceeds maximum allowed size[500KB]";
+        return;
+    }
+
+    // Form the file path
+    loc /= fileID;
+    BMCWEB_LOG_DEBUG("Writing to the file: {}", loc.string());
+
+    // Check if the same file exists in the directory
+    bool fileExists = std::filesystem::exists(loc, ec);
+    if (ec)
+    {
+        asyncResp->res.result(
+            boost::beast::http::status::internal_server_error);
+        asyncResp->res.jsonValue["Description"] = internalServerError;
+        BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find if file exists. ec : {}",
+                         ec.message());
+        return;
+    }
+
+    std::uintmax_t newSizeToWrite = 0;
+    if (fileExists)
+    {
+        // File exists. Get the current file size
+        std::uintmax_t currentFileSize = std::filesystem::file_size(loc, ec);
+        if (ec)
+        {
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
+            asyncResp->res.jsonValue["Description"] = internalServerError;
+            BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find file size. ec : {}",
+                             ec.message());
+            return;
+        }
+        // Calculate the difference in the file size.
+        // If the data.length is greater than the existing file size, then
+        // calculate the difference. Else consider the delta size as zero -
+        // because there is no increase in the total directory size.
+        // We need to add the diff only if the incoming data is larger than the
+        // existing filesize
+        if (data.length() > currentFileSize)
+        {
+            newSizeToWrite = data.length() - currentFileSize;
+        }
+        BMCWEB_LOG_DEBUG("newSizeToWrite: {}", newSizeToWrite);
+    }
+    else
+    {
+        // This is a new file upload
+        newSizeToWrite = data.length();
+    }
+
+    // Calculate the total dir size before writing the new file
+    BMCWEB_LOG_DEBUG("total new size: {}", saveAreaDirSize + newSizeToWrite);
+
+    if ((saveAreaDirSize + newSizeToWrite) > maxSaveareaDirSize)
+    {
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        asyncResp->res.jsonValue["Description"] =
+            "File size does not fit in the savearea "
+            "directory maximum allowed size[25MB]";
+        return;
+    }
+
+    file.open(loc, std::ofstream::out);
+
+    // set the permission of the file to 600
+    std::filesystem::perms permission = std::filesystem::perms::owner_write |
+                                        std::filesystem::perms::owner_read;
+    std::filesystem::permissions(loc, permission);
+
+    if (file.fail())
+    {
+        BMCWEB_LOG_DEBUG("Error while opening the file for writing");
+        asyncResp->res.result(
+            boost::beast::http::status::internal_server_error);
+        asyncResp->res.jsonValue["Description"] =
+            "Error while creating the file";
+        return;
+    }
+    file << data;
+
+    // Push an event
+    if (fileExists)
+    {
+        BMCWEB_LOG_DEBUG("config file is updated");
+        asyncResp->res.jsonValue["Description"] = "File Updated";
+    }
+    else
+    {
+        BMCWEB_LOG_DEBUG("config file is created");
+        asyncResp->res.jsonValue["Description"] = "File Created";
+    }
+}
+
+inline void handleConfigFileList(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::vector<std::string> pathObjList;
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles");
+    if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
+    {
+        for (const auto& file : std::filesystem::directory_iterator(loc))
+        {
+            const std::filesystem::path& pathObj = file.path();
+            if (std::filesystem::is_regular_file(pathObj))
+            {
+                pathObjList.emplace_back(
+                    "/ibm/v1/Host/ConfigFiles/" + pathObj.filename().string());
+            }
+        }
+    }
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#IBMConfigFile.v1_0_0.IBMConfigFile";
+    asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/Host/ConfigFiles/";
+    asyncResp->res.jsonValue["Id"] = "ConfigFiles";
+    asyncResp->res.jsonValue["Name"] = "ConfigFiles";
+
+    asyncResp->res.jsonValue["Members"] = std::move(pathObjList);
+    asyncResp->res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"]["target"] =
+        "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll";
+}
+
+inline void deleteConfigFiles(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::error_code ec;
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles");
+    if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
+    {
+        std::filesystem::remove_all(loc, ec);
+        if (ec)
+        {
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
+            asyncResp->res.jsonValue["Description"] = internalServerError;
+            BMCWEB_LOG_DEBUG("deleteConfigFiles: Failed to delete the "
+                             "config files directory. ec : {}",
+                             ec.message());
+        }
+    }
+}
+
+inline void handleFileGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          const std::string& fileID)
+{
+    BMCWEB_LOG_DEBUG("HandleGet on SaveArea files on path: {}", fileID);
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles/" + fileID);
+    if (!std::filesystem::exists(loc) || !std::filesystem::is_regular_file(loc))
+    {
+        BMCWEB_LOG_WARNING("{} Not found", loc.string());
+        asyncResp->res.result(boost::beast::http::status::not_found);
+        asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
+        return;
+    }
+
+    std::ifstream readfile(loc.string());
+    if (!readfile)
+    {
+        BMCWEB_LOG_WARNING("{} Not found", loc.string());
+        asyncResp->res.result(boost::beast::http::status::not_found);
+        asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
+        return;
+    }
+
+    std::string contentDispositionParam =
+        "attachment; filename=\"" + fileID + "\"";
+    asyncResp->res.addHeader(boost::beast::http::field::content_disposition,
+                             contentDispositionParam);
+    std::string fileData;
+    fileData = {std::istreambuf_iterator<char>(readfile),
+                std::istreambuf_iterator<char>()};
+    asyncResp->res.jsonValue["Data"] = fileData;
+}
+
+inline void handleFileDelete(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& fileID)
+{
+    std::string filePath(
+        "/var/lib/bmcweb/ibm-management-console/configfiles/" + fileID);
+    BMCWEB_LOG_DEBUG("Removing the file : {}", filePath);
+    std::ifstream fileOpen(filePath.c_str());
+    if (static_cast<bool>(fileOpen))
+    {
+        if (remove(filePath.c_str()) == 0)
+        {
+            BMCWEB_LOG_DEBUG("File removed!");
+            asyncResp->res.jsonValue["Description"] = "File Deleted";
+        }
+        else
+        {
+            BMCWEB_LOG_ERROR("File not removed!");
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
+            asyncResp->res.jsonValue["Description"] = internalServerError;
+        }
+    }
+    else
+    {
+        BMCWEB_LOG_WARNING("File not found!");
+        asyncResp->res.result(boost::beast::http::status::not_found);
+        asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
+    }
+}
+
+inline void handleBroadcastService(
+    const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::string broadcastMsg;
+
+    if (!redfish::json_util::readJsonPatch(req, asyncResp->res, "Message",
+                                           broadcastMsg))
+    {
+        BMCWEB_LOG_DEBUG("Not a Valid JSON");
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        return;
+    }
+    if (broadcastMsg.size() > maxBroadcastMsgSize)
+    {
+        BMCWEB_LOG_ERROR("Message size exceeds maximum allowed size[1KB]");
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        return;
+    }
+}
+
+inline void handleFileUrl(const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          const std::string& fileID)
+{
+    if (req.method() == boost::beast::http::verb::put)
+    {
+        handleFilePut(req, asyncResp, fileID);
+        return;
+    }
+    if (req.method() == boost::beast::http::verb::get)
+    {
+        handleFileGet(asyncResp, fileID);
+        return;
+    }
+    if (req.method() == boost::beast::http::verb::delete_)
+    {
+        handleFileDelete(asyncResp, fileID);
+        return;
+    }
+}
+
+inline bool isValidConfigFileName(const std::string& fileName,
+                                  crow::Response& res)
+{
+    if (fileName.empty())
+    {
+        BMCWEB_LOG_ERROR("Empty filename");
+        res.jsonValue["Description"] = "Empty file path in the url";
+        return false;
+    }
+
+    // ConfigFile name is allowed to take upper and lowercase letters,
+    // numbers and hyphen
+    std::size_t found = fileName.find_first_not_of(
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-");
+    if (found != std::string::npos)
+    {
+        BMCWEB_LOG_ERROR("Unsupported character in filename: {}", fileName);
+        res.jsonValue["Description"] = "Unsupported character in filename";
+        return false;
+    }
+
+    // Check the filename length
+    if (fileName.length() > 20)
+    {
+        BMCWEB_LOG_ERROR("Name must be maximum 20 characters. "
+                         "Input filename length is: {}",
+                         fileName.length());
+        res.jsonValue["Description"] = "Filename must be maximum 20 characters";
+        return false;
+    }
+
+    return true;
+}
+
+inline void requestRoutes(App& app)
+{
+    // allowed only for admin
+    BMCWEB_ROUTE(app, "/ibm/v1/")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#ibmServiceRoot.v1_0_0.ibmServiceRoot";
+                asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/";
+                asyncResp->res.jsonValue["Id"] = "IBM Rest RootService";
+                asyncResp->res.jsonValue["Name"] = "IBM Service Root";
+                asyncResp->res.jsonValue["ConfigFiles"]["@odata.id"] =
+                    "/ibm/v1/Host/ConfigFiles";
+                asyncResp->res.jsonValue["BroadcastService"]["@odata.id"] =
+                    "/ibm/v1/HMC/BroadcastService";
+            });
+
+    BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                handleConfigFileList(asyncResp);
+            });
+
+    BMCWEB_ROUTE(app,
+                 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                deleteConfigFiles(asyncResp);
+            });
+
+    BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles/<str>")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::put, boost::beast::http::verb::get,
+                 boost::beast::http::verb::delete_)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& fileName) {
+                BMCWEB_LOG_DEBUG("ConfigFile : {}", fileName);
+                // Validate the incoming fileName
+                if (!isValidConfigFileName(fileName, asyncResp->res))
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
+                handleFileUrl(req, asyncResp, fileName);
+            });
+
+    BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                handleBroadcastService(req, asyncResp);
+            });
+}
+
+} // namespace ibm_mc
+} // namespace crow
diff --git a/features/ibm/meson.build b/features/ibm/meson.build
new file mode 100644
index 0000000..c73258f
--- /dev/null
+++ b/features/ibm/meson.build
@@ -0,0 +1,2 @@
+incdir += include_directories('.')
+test_sources += files('configfile_test.cpp')
diff --git a/features/ibm/utils.hpp b/features/ibm/utils.hpp
new file mode 100644
index 0000000..fe99f8e
--- /dev/null
+++ b/features/ibm/utils.hpp
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+
+#include "logging.hpp"
+
+#include <filesystem>
+#include <string_view>
+#include <system_error>
+
+namespace crow
+{
+namespace ibm_utils
+{
+
+inline bool createDirectory(std::string_view path)
+{
+    // Create persistent directory
+    std::error_code ec;
+
+    BMCWEB_LOG_DEBUG("Creating persistent directory : {}", path);
+
+    bool dirCreated = std::filesystem::create_directories(path, ec);
+
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("Failed to create persistent directory : {}", path);
+        return false;
+    }
+
+    if (dirCreated)
+    {
+        // set the permission of the directory to 700
+        BMCWEB_LOG_DEBUG("Setting the permission to 700");
+        std::filesystem::perms permission = std::filesystem::perms::owner_all;
+        std::filesystem::permissions(path, permission);
+    }
+    else
+    {
+        BMCWEB_LOG_DEBUG("{} already exists", path);
+    }
+    return true;
+}
+
+} // namespace ibm_utils
+} // namespace crow
diff --git a/features/kvm/kvm_websocket.hpp b/features/kvm/kvm_websocket.hpp
new file mode 100644
index 0000000..adf4c5e
--- /dev/null
+++ b/features/kvm/kvm_websocket.hpp
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+#include "app.hpp"
+#include "io_context_singleton.hpp"
+#include "logging.hpp"
+#include "websocket.hpp"
+
+#include <sys/types.h>
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/beast/core/flat_static_buffer.hpp>
+#include <boost/container/flat_map.hpp>
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+namespace crow
+{
+namespace obmc_kvm
+{
+
+static constexpr const uint maxSessions = 4;
+
+class KvmSession : public std::enable_shared_from_this<KvmSession>
+{
+  public:
+    explicit KvmSession(crow::websocket::Connection& connIn) :
+        conn(connIn), hostSocket(getIoContext())
+    {
+        boost::asio::ip::tcp::endpoint endpoint(
+            boost::asio::ip::make_address("127.0.0.1"), 5900);
+        hostSocket.async_connect(
+            endpoint, [this, &connIn](const boost::system::error_code& ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR(
+                        "conn:{}, Couldn't connect to KVM socket port: {}",
+                        logPtr(&conn), ec);
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        connIn.close("Error in connecting to KVM port");
+                    }
+                    return;
+                }
+
+                doRead();
+            });
+    }
+
+    void onMessage(const std::string& data)
+    {
+        if (data.length() > inputBuffer.capacity())
+        {
+            BMCWEB_LOG_ERROR("conn:{}, Buffer overrun when writing {} bytes",
+                             logPtr(&conn), data.length());
+            conn.close("Buffer overrun");
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG("conn:{}, Read {} bytes from websocket", logPtr(&conn),
+                         data.size());
+        size_t copied = boost::asio::buffer_copy(
+            inputBuffer.prepare(data.size()), boost::asio::buffer(data));
+        BMCWEB_LOG_DEBUG("conn:{}, Committing {} bytes from websocket",
+                         logPtr(&conn), copied);
+        inputBuffer.commit(copied);
+
+        BMCWEB_LOG_DEBUG("conn:{}, inputbuffer size {}", logPtr(&conn),
+                         inputBuffer.size());
+        doWrite();
+    }
+
+  protected:
+    void doRead()
+    {
+        std::size_t bytes = outputBuffer.capacity() - outputBuffer.size();
+        BMCWEB_LOG_DEBUG("conn:{}, Reading {} from kvm socket", logPtr(&conn),
+                         bytes);
+        hostSocket.async_read_some(
+            outputBuffer.prepare(outputBuffer.capacity() - outputBuffer.size()),
+            [this, weak(weak_from_this())](const boost::system::error_code& ec,
+                                           std::size_t bytesRead) {
+                auto self = weak.lock();
+                if (self == nullptr)
+                {
+                    return;
+                }
+                BMCWEB_LOG_DEBUG("conn:{}, read done.  Read {} bytes",
+                                 logPtr(&conn), bytesRead);
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR(
+                        "conn:{}, Couldn't read from KVM socket port: {}",
+                        logPtr(&conn), ec);
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        conn.close("Error in connecting to KVM port");
+                    }
+                    return;
+                }
+
+                outputBuffer.commit(bytesRead);
+                std::string_view payload(
+                    static_cast<const char*>(outputBuffer.data().data()),
+                    bytesRead);
+                BMCWEB_LOG_DEBUG("conn:{}, Sending payload size {}",
+                                 logPtr(&conn), payload.size());
+                conn.sendBinary(payload);
+                outputBuffer.consume(bytesRead);
+
+                doRead();
+            });
+    }
+
+    void doWrite()
+    {
+        if (doingWrite)
+        {
+            BMCWEB_LOG_DEBUG("conn:{}, Already writing.  Bailing out",
+                             logPtr(&conn));
+            return;
+        }
+        if (inputBuffer.size() == 0)
+        {
+            BMCWEB_LOG_DEBUG("conn:{}, inputBuffer empty.  Bailing out",
+                             logPtr(&conn));
+            return;
+        }
+
+        doingWrite = true;
+        hostSocket.async_write_some(
+            inputBuffer.data(),
+            [this, weak(weak_from_this())](const boost::system::error_code& ec,
+                                           std::size_t bytesWritten) {
+                auto self = weak.lock();
+                if (self == nullptr)
+                {
+                    return;
+                }
+                BMCWEB_LOG_DEBUG("conn:{}, Wrote {}bytes", logPtr(&conn),
+                                 bytesWritten);
+                doingWrite = false;
+                inputBuffer.consume(bytesWritten);
+
+                if (ec == boost::asio::error::eof)
+                {
+                    conn.close("KVM socket port closed");
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR("conn:{}, Error in KVM socket write {}",
+                                     logPtr(&conn), ec);
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        conn.close("Error in reading to host port");
+                    }
+                    return;
+                }
+
+                doWrite();
+            });
+    }
+
+    crow::websocket::Connection& conn;
+    boost::asio::ip::tcp::socket hostSocket;
+    boost::beast::flat_static_buffer<1024UL * 50UL> outputBuffer;
+    boost::beast::flat_static_buffer<1024UL> inputBuffer;
+    bool doingWrite{false};
+};
+
+using SessionMap = boost::container::flat_map<crow::websocket::Connection*,
+                                              std::shared_ptr<KvmSession>>;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static SessionMap sessions;
+
+inline void requestRoutes(App& app)
+{
+    sessions.reserve(maxSessions);
+
+    BMCWEB_ROUTE(app, "/kvm/0")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .websocket()
+        .onopen([](crow::websocket::Connection& conn) {
+            BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));
+
+            if (sessions.size() == maxSessions)
+            {
+                conn.close("Max sessions are already connected");
+                return;
+            }
+
+            sessions[&conn] = std::make_shared<KvmSession>(conn);
+        })
+        .onclose([](crow::websocket::Connection& conn, const std::string&) {
+            sessions.erase(&conn);
+        })
+        .onmessage([](crow::websocket::Connection& conn,
+                      const std::string& data, bool) {
+            if (sessions[&conn])
+            {
+                sessions[&conn]->onMessage(data);
+            }
+        });
+}
+
+} // namespace obmc_kvm
+} // namespace crow
diff --git a/features/kvm/meson.build b/features/kvm/meson.build
new file mode 100644
index 0000000..ab60765
--- /dev/null
+++ b/features/kvm/meson.build
@@ -0,0 +1 @@
+incdir += include_directories('.')
diff --git a/features/meson.build b/features/meson.build
new file mode 100644
index 0000000..ff01c88
--- /dev/null
+++ b/features/meson.build
@@ -0,0 +1,7 @@
+subdir('google')
+subdir('ibm')
+subdir('kvm')
+subdir('openbmc_rest')
+subdir('serial')
+subdir('virtual_media')
+subdir('webui_login')
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
diff --git a/features/redfish b/features/redfish
new file mode 120000
index 0000000..635be9a
--- /dev/null
+++ b/features/redfish
@@ -0,0 +1 @@
+../redfish-core
\ No newline at end of file
diff --git a/features/serial/meson.build b/features/serial/meson.build
new file mode 100644
index 0000000..ab60765
--- /dev/null
+++ b/features/serial/meson.build
@@ -0,0 +1 @@
+incdir += include_directories('.')
diff --git a/features/serial/obmc_console.hpp b/features/serial/obmc_console.hpp
new file mode 100644
index 0000000..40b72fe
--- /dev/null
+++ b/features/serial/obmc_console.hpp
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+#include "app.hpp"
+#include "dbus_utility.hpp"
+#include "io_context_singleton.hpp"
+#include "logging.hpp"
+#include "websocket.hpp"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+#include <boost/beast/core/error.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/system/error_code.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <array>
+#include <cstddef>
+#include <functional>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace crow
+{
+namespace obmc_console
+{
+
+// Update this value each time we add new console route.
+static constexpr const uint maxSessions = 32;
+
+class ConsoleHandler : public std::enable_shared_from_this<ConsoleHandler>
+{
+  public:
+    ConsoleHandler(boost::asio::io_context& ioc,
+                   crow::websocket::Connection& connIn) :
+        hostSocket(ioc), conn(connIn)
+    {}
+
+    ~ConsoleHandler() = default;
+
+    ConsoleHandler(const ConsoleHandler&) = delete;
+    ConsoleHandler(ConsoleHandler&&) = delete;
+    ConsoleHandler& operator=(const ConsoleHandler&) = delete;
+    ConsoleHandler& operator=(ConsoleHandler&&) = delete;
+
+    void doWrite()
+    {
+        if (doingWrite)
+        {
+            BMCWEB_LOG_DEBUG("Already writing.  Bailing out");
+            return;
+        }
+
+        if (inputBuffer.empty())
+        {
+            BMCWEB_LOG_DEBUG("Outbuffer empty.  Bailing out");
+            return;
+        }
+
+        doingWrite = true;
+        hostSocket.async_write_some(
+            boost::asio::buffer(inputBuffer.data(), inputBuffer.size()),
+            [weak(weak_from_this())](const boost::beast::error_code& ec,
+                                     std::size_t bytesWritten) {
+                std::shared_ptr<ConsoleHandler> self = weak.lock();
+                if (self == nullptr)
+                {
+                    return;
+                }
+
+                self->doingWrite = false;
+                self->inputBuffer.erase(0, bytesWritten);
+
+                if (ec == boost::asio::error::eof)
+                {
+                    self->conn.close("Error in reading to host port");
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR("Error in host serial write {}",
+                                     ec.message());
+                    return;
+                }
+                self->doWrite();
+            });
+    }
+
+    static void afterSendEx(const std::weak_ptr<ConsoleHandler>& weak)
+    {
+        std::shared_ptr<ConsoleHandler> self = weak.lock();
+        if (self == nullptr)
+        {
+            return;
+        }
+        self->doRead();
+    }
+
+    void doRead()
+    {
+        BMCWEB_LOG_DEBUG("Reading from socket");
+        hostSocket.async_read_some(
+            boost::asio::buffer(outputBuffer),
+            [this, weakSelf(weak_from_this())](
+                const boost::system::error_code& ec, std::size_t bytesRead) {
+                BMCWEB_LOG_DEBUG("read done.  Read {} bytes", bytesRead);
+                std::shared_ptr<ConsoleHandler> self = weakSelf.lock();
+                if (self == nullptr)
+                {
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR("Couldn't read from host serial port: {}",
+                                     ec.message());
+                    conn.close("Error connecting to host port");
+                    return;
+                }
+                std::string_view payload(outputBuffer.data(), bytesRead);
+                self->conn.sendEx(
+                    crow::websocket::MessageType::Binary, payload,
+                    std::bind_front(afterSendEx, weak_from_this()));
+            });
+    }
+
+    bool connect(int fd)
+    {
+        boost::system::error_code ec;
+        boost::asio::local::stream_protocol proto;
+
+        hostSocket.assign(proto, fd, ec);
+
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR(
+                "Failed to assign the DBUS socket Socket assign error: {}",
+                ec.message());
+            return false;
+        }
+
+        conn.resumeRead();
+        doWrite();
+        doRead();
+        return true;
+    }
+
+    boost::asio::local::stream_protocol::socket hostSocket;
+
+    std::array<char, 4096> outputBuffer{};
+
+    std::string inputBuffer;
+    bool doingWrite = false;
+    crow::websocket::Connection& conn;
+};
+
+using ObmcConsoleMap = boost::container::flat_map<
+    crow::websocket::Connection*, std::shared_ptr<ConsoleHandler>, std::less<>,
+    std::vector<std::pair<crow::websocket::Connection*,
+                          std::shared_ptr<ConsoleHandler>>>>;
+
+inline ObmcConsoleMap& getConsoleHandlerMap()
+{
+    static ObmcConsoleMap map;
+    return map;
+}
+
+// Remove connection from the connection map and if connection map is empty
+// then remove the handler from handlers map.
+inline void onClose(crow::websocket::Connection& conn, const std::string& err)
+{
+    BMCWEB_LOG_INFO("Closing websocket. Reason: {}", err);
+
+    auto iter = getConsoleHandlerMap().find(&conn);
+    if (iter == getConsoleHandlerMap().end())
+    {
+        BMCWEB_LOG_CRITICAL("Unable to find connection {}", logPtr(&conn));
+        return;
+    }
+    BMCWEB_LOG_DEBUG("Remove connection {} from obmc console", logPtr(&conn));
+
+    // Removed last connection so remove the path
+    getConsoleHandlerMap().erase(iter);
+}
+
+inline void connectConsoleSocket(crow::websocket::Connection& conn,
+                                 const boost::system::error_code& ec,
+                                 const sdbusplus::message::unix_fd& unixfd)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR(
+            "Failed to call console Connect() method DBUS error: {}",
+            ec.message());
+        conn.close("Failed to connect");
+        return;
+    }
+
+    // Look up the handler
+    auto iter = getConsoleHandlerMap().find(&conn);
+    if (iter == getConsoleHandlerMap().end())
+    {
+        BMCWEB_LOG_ERROR("Connection was already closed");
+        return;
+    }
+
+    int fd = dup(unixfd);
+    if (fd == -1)
+    {
+        BMCWEB_LOG_ERROR("Failed to dup the DBUS unixfd error");
+        conn.close("Internal error");
+        return;
+    }
+
+    BMCWEB_LOG_DEBUG("Console duped FD: {}", fd);
+
+    if (!iter->second->connect(fd))
+    {
+        close(fd);
+        conn.close("Internal Error");
+    }
+}
+
+inline void processConsoleObject(
+    crow::websocket::Connection& conn, const std::string& consoleObjPath,
+    const boost::system::error_code& ec,
+    const ::dbus::utility::MapperGetObject& objInfo)
+{
+    // Look up the handler
+    auto iter = getConsoleHandlerMap().find(&conn);
+    if (iter == getConsoleHandlerMap().end())
+    {
+        BMCWEB_LOG_ERROR("Connection was already closed");
+        return;
+    }
+
+    if (ec)
+    {
+        BMCWEB_LOG_WARNING("getDbusObject() for consoles failed. DBUS error:{}",
+                           ec.message());
+        conn.close("getDbusObject() for consoles failed.");
+        return;
+    }
+
+    const auto valueIface = objInfo.begin();
+    if (valueIface == objInfo.end())
+    {
+        BMCWEB_LOG_WARNING("getDbusObject() returned unexpected size: {}",
+                           objInfo.size());
+        conn.close("getDbusObject() returned unexpected size");
+        return;
+    }
+
+    const std::string& consoleService = valueIface->first;
+    BMCWEB_LOG_DEBUG("Looking up unixFD for Service {} Path {}", consoleService,
+                     consoleObjPath);
+    // Call Connect() method to get the unix FD
+    dbus::utility::async_method_call(
+        [&conn](const boost::system::error_code& ec1,
+                const sdbusplus::message::unix_fd& unixfd) {
+            connectConsoleSocket(conn, ec1, unixfd);
+        },
+        consoleService, consoleObjPath, "xyz.openbmc_project.Console.Access",
+        "Connect");
+}
+
+// Query consoles from DBUS and find the matching to the
+// rules string.
+inline void onOpen(crow::websocket::Connection& conn)
+{
+    std::string consoleLeaf;
+
+    BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));
+
+    if (getConsoleHandlerMap().size() >= maxSessions)
+    {
+        conn.close("Max sessions are already connected");
+        return;
+    }
+
+    std::shared_ptr<ConsoleHandler> handler =
+        std::make_shared<ConsoleHandler>(getIoContext(), conn);
+    getConsoleHandlerMap().emplace(&conn, handler);
+
+    conn.deferRead();
+
+    // Keep old path for backward compatibility
+    if (conn.url().path() == "/console0")
+    {
+        consoleLeaf = "default";
+    }
+    else
+    {
+        // Get the console id from console router path and prepare the console
+        // object path and console service.
+        consoleLeaf = conn.url().segments().back();
+    }
+    std::string consolePath =
+        sdbusplus::message::object_path("/xyz/openbmc_project/console") /
+        consoleLeaf;
+
+    BMCWEB_LOG_DEBUG("Console Object path = {} Request target = {}",
+                     consolePath, conn.url().path());
+
+    // mapper call lambda
+    constexpr std::array<std::string_view, 1> interfaces = {
+        "xyz.openbmc_project.Console.Access"};
+
+    dbus::utility::getDbusObject(
+        consolePath, interfaces,
+        [&conn, consolePath](const boost::system::error_code& ec,
+                             const ::dbus::utility::MapperGetObject& objInfo) {
+            processConsoleObject(conn, consolePath, ec, objInfo);
+        });
+}
+
+inline void onMessage(crow::websocket::Connection& conn,
+                      const std::string& data, bool /*isBinary*/)
+{
+    auto handler = getConsoleHandlerMap().find(&conn);
+    if (handler == getConsoleHandlerMap().end())
+    {
+        BMCWEB_LOG_CRITICAL("Unable to find connection {}", logPtr(&conn));
+        return;
+    }
+    handler->second->inputBuffer += data;
+    handler->second->doWrite();
+}
+
+inline void requestRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/console0")
+        .privileges({{"OpenBMCHostConsole"}})
+        .websocket()
+        .onopen(onOpen)
+        .onclose(onClose)
+        .onmessage(onMessage);
+
+    BMCWEB_ROUTE(app, "/console/<str>")
+        .privileges({{"OpenBMCHostConsole"}})
+        .websocket()
+        .onopen(onOpen)
+        .onclose(onClose)
+        .onmessage(onMessage);
+}
+} // namespace obmc_console
+} // namespace crow
diff --git a/features/virtual_media/meson.build b/features/virtual_media/meson.build
new file mode 100644
index 0000000..ab60765
--- /dev/null
+++ b/features/virtual_media/meson.build
@@ -0,0 +1 @@
+incdir += include_directories('.')
diff --git a/features/virtual_media/vm_websocket.hpp b/features/virtual_media/vm_websocket.hpp
new file mode 100644
index 0000000..b930b64
--- /dev/null
+++ b/features/virtual_media/vm_websocket.hpp
@@ -0,0 +1,626 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+
+#include "bmcweb_config.h"
+
+#include "app.hpp"
+#include "dbus_utility.hpp"
+#include "io_context_singleton.hpp"
+#include "logging.hpp"
+#include "websocket.hpp"
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+#include <boost/asio/readable_pipe.hpp>
+#include <boost/asio/writable_pipe.hpp>
+#include <boost/beast/core/buffers_to_string.hpp>
+#include <boost/beast/core/error.hpp>
+#include <boost/beast/core/flat_static_buffer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/process/v2/process.hpp>
+#include <boost/process/v2/stdio.hpp>
+#include <sdbusplus/message/native_types.hpp>
+#include <sdbusplus/unpack_properties.hpp>
+
+#include <cerrno>
+#include <csignal>
+#include <cstddef>
+#include <filesystem>
+#include <format>
+#include <functional>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <system_error>
+#include <utility>
+
+namespace crow
+{
+
+namespace obmc_vm
+{
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static crow::websocket::Connection* session = nullptr;
+
+// The max network block device buffer size is 128kb plus 16bytes
+// for the message header:
+// https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md#simple-reply-message
+static constexpr auto nbdBufferSize = (128 * 1024 + 16) * 4;
+
+class Handler : public std::enable_shared_from_this<Handler>
+{
+  public:
+    Handler(const std::string& media, boost::asio::io_context& ios) :
+        pipeOut(ios), pipeIn(ios),
+        proxy(ios, "/usr/bin/nbd-proxy", {media},
+              boost::process::v2::process_stdio{
+                  .in = pipeIn, .out = pipeOut, .err = nullptr})
+    {}
+
+    ~Handler() = default;
+
+    Handler(const Handler&) = delete;
+    Handler(Handler&&) = delete;
+    Handler& operator=(const Handler&) = delete;
+    Handler& operator=(Handler&&) = delete;
+
+    void doClose()
+    {
+        // boost::process::child::terminate uses SIGKILL, need to send SIGTERM
+        // to allow the proxy to stop nbd-client and the USB device gadget.
+        // NOLINTNEXTLINE(misc-include-cleaner)
+        int rc = kill(proxy.id(), SIGTERM);
+        if (rc != 0)
+        {
+            BMCWEB_LOG_ERROR("Failed to terminate nbd-proxy: {}", errno);
+            return;
+        }
+
+        proxy.wait();
+    }
+
+    void connect()
+    {
+        std::error_code ec;
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("Couldn't connect to nbd-proxy: {}", ec.message());
+            if (session != nullptr)
+            {
+                session->close("Error connecting to nbd-proxy");
+            }
+            return;
+        }
+        doWrite();
+        doRead();
+    }
+
+    void doWrite()
+    {
+        if (doingWrite)
+        {
+            BMCWEB_LOG_DEBUG("Already writing.  Bailing out");
+            return;
+        }
+
+        if (inputBuffer.size() == 0)
+        {
+            BMCWEB_LOG_DEBUG("inputBuffer empty.  Bailing out");
+            return;
+        }
+
+        doingWrite = true;
+        pipeIn.async_write_some(
+            inputBuffer.data(),
+            [this, self(shared_from_this())](const boost::beast::error_code& ec,
+                                             std::size_t bytesWritten) {
+                BMCWEB_LOG_DEBUG("Wrote {}bytes", bytesWritten);
+                doingWrite = false;
+                inputBuffer.consume(bytesWritten);
+
+                if (session == nullptr)
+                {
+                    return;
+                }
+                if (ec == boost::asio::error::eof)
+                {
+                    session->close("VM socket port closed");
+                    return;
+                }
+                if (ec)
+                {
+                    session->close("Error in writing to proxy port");
+                    BMCWEB_LOG_ERROR("Error in VM socket write {}", ec);
+                    return;
+                }
+                doWrite();
+            });
+    }
+
+    void doRead()
+    {
+        std::size_t bytes = outputBuffer.capacity() - outputBuffer.size();
+
+        pipeOut.async_read_some(
+            outputBuffer.prepare(bytes),
+            [this, self(shared_from_this())](
+                const boost::system::error_code& ec, std::size_t bytesRead) {
+                BMCWEB_LOG_DEBUG("Read done.  Read {} bytes", bytesRead);
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR("Couldn't read from VM port: {}", ec);
+                    if (session != nullptr)
+                    {
+                        session->close("Error in connecting to VM port");
+                    }
+                    return;
+                }
+                if (session == nullptr)
+                {
+                    return;
+                }
+
+                outputBuffer.commit(bytesRead);
+                std::string_view payload(
+                    static_cast<const char*>(outputBuffer.data().data()),
+                    bytesRead);
+                session->sendBinary(payload);
+                outputBuffer.consume(bytesRead);
+
+                doRead();
+            });
+    }
+
+    boost::asio::readable_pipe pipeOut;
+    boost::asio::writable_pipe pipeIn;
+    boost::process::v2::process proxy;
+    bool doingWrite{false};
+
+    boost::beast::flat_static_buffer<nbdBufferSize> outputBuffer;
+    boost::beast::flat_static_buffer<nbdBufferSize> inputBuffer;
+};
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static std::shared_ptr<Handler> handler;
+
+} // namespace obmc_vm
+
+namespace nbd_proxy
+{
+using boost::asio::local::stream_protocol;
+
+// The max network block device buffer size is 128kb plus 16bytes
+// for the message header:
+// https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md#simple-reply-message
+static constexpr auto nbdBufferSize = (128 * 1024 + 16) * 4;
+
+struct NbdProxyServer : std::enable_shared_from_this<NbdProxyServer>
+{
+    NbdProxyServer(crow::websocket::Connection& connIn,
+                   const std::string& socketIdIn,
+                   const std::string& endpointIdIn, const std::string& pathIn) :
+        socketId(socketIdIn), endpointId(endpointIdIn), path(pathIn),
+
+        peerSocket(getIoContext()),
+        acceptor(getIoContext(), stream_protocol::endpoint(socketId)),
+        connection(connIn)
+    {}
+
+    NbdProxyServer(const NbdProxyServer&) = delete;
+    NbdProxyServer(NbdProxyServer&&) = delete;
+    NbdProxyServer& operator=(const NbdProxyServer&) = delete;
+    NbdProxyServer& operator=(NbdProxyServer&&) = delete;
+
+    ~NbdProxyServer()
+    {
+        BMCWEB_LOG_DEBUG("NbdProxyServer destructor");
+
+        BMCWEB_LOG_DEBUG("peerSocket->close()");
+        boost::system::error_code ec;
+        peerSocket.close(ec);
+
+        BMCWEB_LOG_DEBUG("std::filesystem::remove({})", socketId);
+        std::error_code ec2;
+        std::filesystem::remove(socketId.c_str(), ec2);
+        if (ec2)
+        {
+            BMCWEB_LOG_DEBUG("Failed to remove file, ignoring");
+        }
+
+        dbus::utility::async_method_call(
+            dbus::utility::logError, "xyz.openbmc_project.VirtualMedia", path,
+            "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
+    }
+
+    std::string getEndpointId() const
+    {
+        return endpointId;
+    }
+
+    static void afterMount(const std::weak_ptr<NbdProxyServer>& weak,
+                           const boost::system::error_code& ec,
+                           bool /*isBinary*/)
+    {
+        std::shared_ptr<NbdProxyServer> self = weak.lock();
+        if (self == nullptr)
+        {
+            return;
+        }
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("DBus error: cannot call mount method = {}",
+                             ec.message());
+
+            self->connection.close("Failed to mount media");
+            return;
+        }
+    }
+
+    static void afterAccept(const std::weak_ptr<NbdProxyServer>& weak,
+                            const boost::system::error_code& ec,
+                            stream_protocol::socket socket)
+    {
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("UNIX socket: async_accept error = {}",
+                             ec.message());
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG("Connection opened");
+        std::shared_ptr<NbdProxyServer> self = weak.lock();
+        if (self == nullptr)
+        {
+            return;
+        }
+
+        self->connection.resumeRead();
+        self->peerSocket = std::move(socket);
+        //  Start reading from socket
+        self->doRead();
+    }
+
+    void run()
+    {
+        acceptor.async_accept(
+            std::bind_front(&NbdProxyServer::afterAccept, weak_from_this()));
+
+        dbus::utility::async_method_call(
+            [weak{weak_from_this()}](const boost::system::error_code& ec,
+                                     bool isBinary) {
+                afterMount(weak, ec, isBinary);
+            },
+            "xyz.openbmc_project.VirtualMedia", path,
+            "xyz.openbmc_project.VirtualMedia.Proxy", "Mount");
+    }
+
+    void send(std::string_view buffer, std::function<void()>&& onDone)
+    {
+        size_t copied = boost::asio::buffer_copy(
+            ws2uxBuf.prepare(buffer.size()), boost::asio::buffer(buffer));
+        ws2uxBuf.commit(copied);
+
+        doWrite(std::move(onDone));
+    }
+
+  private:
+    static void afterSendEx(const std::weak_ptr<NbdProxyServer>& weak)
+    {
+        std::shared_ptr<NbdProxyServer> self2 = weak.lock();
+        if (self2 != nullptr)
+        {
+            self2->ux2wsBuf.consume(self2->ux2wsBuf.size());
+            self2->doRead();
+        }
+    }
+
+    void afterRead(const std::weak_ptr<NbdProxyServer>& weak,
+                   const boost::system::error_code& ec, size_t bytesRead)
+    {
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("UNIX socket: async_read_some error = {}",
+                             ec.message());
+            return;
+        }
+        std::shared_ptr<NbdProxyServer> self = weak.lock();
+        if (self == nullptr)
+        {
+            return;
+        }
+
+        // Send to websocket
+        self->ux2wsBuf.commit(bytesRead);
+        self->connection.sendEx(
+            crow::websocket::MessageType::Binary,
+            boost::beast::buffers_to_string(self->ux2wsBuf.data()),
+            std::bind_front(&NbdProxyServer::afterSendEx, weak_from_this()));
+    }
+
+    void doRead()
+    {
+        // Trigger async read
+        peerSocket.async_read_some(ux2wsBuf.prepare(nbdBufferSize),
+                                   std::bind_front(&NbdProxyServer::afterRead,
+                                                   this, weak_from_this()));
+    }
+
+    static void afterWrite(const std::weak_ptr<NbdProxyServer>& weak,
+                           std::function<void()>&& onDone,
+                           const boost::system::error_code& ec,
+                           size_t bytesWritten)
+    {
+        std::shared_ptr<NbdProxyServer> self = weak.lock();
+        if (self == nullptr)
+        {
+            return;
+        }
+
+        self->ws2uxBuf.consume(bytesWritten);
+        self->uxWriteInProgress = false;
+
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("UNIX: async_write error = {}", ec.message());
+            self->connection.close("Internal error");
+            return;
+        }
+
+        // Retrigger doWrite if there is something in buffer
+        if (self->ws2uxBuf.size() > 0)
+        {
+            self->doWrite(std::move(onDone));
+            return;
+        }
+        onDone();
+    }
+
+    void doWrite(std::function<void()>&& onDone)
+    {
+        if (uxWriteInProgress)
+        {
+            BMCWEB_LOG_ERROR("Write in progress");
+            return;
+        }
+
+        if (ws2uxBuf.size() == 0)
+        {
+            BMCWEB_LOG_ERROR("No data to write to UNIX socket");
+            return;
+        }
+
+        uxWriteInProgress = true;
+        peerSocket.async_write_some(
+            ws2uxBuf.data(),
+            std::bind_front(&NbdProxyServer::afterWrite, weak_from_this(),
+                            std::move(onDone)));
+    }
+
+    // Keeps UNIX socket endpoint file path
+    const std::string socketId;
+    const std::string endpointId;
+    const std::string path;
+
+    bool uxWriteInProgress = false;
+
+    // UNIX => WebSocket buffer
+    boost::beast::flat_static_buffer<nbdBufferSize> ux2wsBuf;
+
+    // WebSocket => UNIX buffer
+    boost::beast::flat_static_buffer<nbdBufferSize> ws2uxBuf;
+
+    // The socket used to communicate with the client.
+    stream_protocol::socket peerSocket;
+
+    // Default acceptor for UNIX socket
+    stream_protocol::acceptor acceptor;
+
+    crow::websocket::Connection& connection;
+};
+
+using SessionMap = boost::container::flat_map<crow::websocket::Connection*,
+                                              std::shared_ptr<NbdProxyServer>>;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static SessionMap sessions;
+
+inline void afterGetSocket(
+    crow::websocket::Connection& conn,
+    const sdbusplus::message::object_path& path,
+    const boost::system::error_code& ec,
+    const dbus::utility::DBusPropertiesMap& propertiesList)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("DBus getAllProperties error: {}", ec.message());
+        conn.close("Internal Error");
+        return;
+    }
+    std::string endpointId;
+    std::string socket;
+
+    bool success = sdbusplus::unpackPropertiesNoThrow(
+        redfish::dbus_utils::UnpackErrorPrinter(), propertiesList, "EndpointId",
+        endpointId, "Socket", socket);
+
+    if (!success)
+    {
+        BMCWEB_LOG_ERROR("Failed to unpack properties");
+        conn.close("Internal Error");
+        return;
+    }
+
+    for (const auto& session : sessions)
+    {
+        if (session.second->getEndpointId() == conn.url().path())
+        {
+            BMCWEB_LOG_ERROR("Cannot open new connection - socket is in use");
+            conn.close("Slot is in use");
+            return;
+        }
+    }
+
+    // If the socket file exists (i.e. after bmcweb crash),
+    // we cannot reuse it.
+    std::error_code ec2;
+    std::filesystem::remove(socket.c_str(), ec2);
+    // Ignore failures.  File might not exist.
+
+    sessions[&conn] =
+        std::make_shared<NbdProxyServer>(conn, socket, endpointId, path);
+    sessions[&conn]->run();
+}
+
+inline void onOpen(crow::websocket::Connection& conn)
+{
+    BMCWEB_LOG_DEBUG("nbd-proxy.onopen({})", logPtr(&conn));
+
+    if (conn.url().segments().size() < 2)
+    {
+        BMCWEB_LOG_ERROR("Invalid path - \"{}\"", conn.url().path());
+        conn.close("Internal error");
+        return;
+    }
+
+    std::string index = conn.url().segments().back();
+    std::string path =
+        std::format("/xyz/openbmc_project/VirtualMedia/Proxy/Slot_{}", index);
+
+    dbus::utility::getAllProperties(
+        "xyz.openbmc_project.VirtualMedia", path,
+        "xyz.openbmc_project.VirtualMedia.MountPoint",
+        [&conn, path](const boost::system::error_code& ec,
+                      const dbus::utility::DBusPropertiesMap& propertiesList) {
+            afterGetSocket(conn, path, ec, propertiesList);
+        });
+
+    // We need to wait for dbus and the websockets to hook up before data is
+    // sent/received.  Tell the core to hold off messages until the sockets are
+    // up
+    conn.deferRead();
+}
+
+inline void onClose(crow::websocket::Connection& conn,
+                    const std::string& reason)
+{
+    BMCWEB_LOG_DEBUG("nbd-proxy.onclose(reason = '{}')", reason);
+    auto session = sessions.find(&conn);
+    if (session == sessions.end())
+    {
+        BMCWEB_LOG_DEBUG("No session to close");
+        return;
+    }
+    // Remove reference to session in global map
+    sessions.erase(session);
+}
+
+inline void onMessage(crow::websocket::Connection& conn, std::string_view data,
+                      crow::websocket::MessageType /*type*/,
+                      std::function<void()>&& whenComplete)
+{
+    BMCWEB_LOG_DEBUG("nbd-proxy.onMessage(len = {})", data.size());
+
+    // Acquire proxy from sessions
+    auto session = sessions.find(&conn);
+    if (session == sessions.end() || session->second == nullptr)
+    {
+        whenComplete();
+        return;
+    }
+
+    session->second->send(data, std::move(whenComplete));
+}
+} // namespace nbd_proxy
+
+namespace obmc_vm
+{
+
+inline void requestRoutes(App& app)
+{
+    static_assert(
+        !(BMCWEB_VM_WEBSOCKET && BMCWEB_VM_NBDPROXY),
+        "nbd proxy cannot be turned on at the same time as vm websocket.");
+
+    if constexpr (BMCWEB_VM_NBDPROXY)
+    {
+        BMCWEB_ROUTE(app, "/nbd/<str>")
+            .privileges({{"ConfigureComponents", "ConfigureManager"}})
+            .websocket()
+            .onopen(nbd_proxy::onOpen)
+            .onclose(nbd_proxy::onClose)
+            .onmessageex(nbd_proxy::onMessage);
+
+        BMCWEB_ROUTE(app, "/vm/0/0")
+            .privileges({{"ConfigureComponents", "ConfigureManager"}})
+            .websocket()
+            .onopen(nbd_proxy::onOpen)
+            .onclose(nbd_proxy::onClose)
+            .onmessageex(nbd_proxy::onMessage);
+    }
+    if constexpr (BMCWEB_VM_WEBSOCKET)
+    {
+        BMCWEB_ROUTE(app, "/vm/0/0")
+            .privileges({{"ConfigureComponents", "ConfigureManager"}})
+            .websocket()
+            .onopen([](crow::websocket::Connection& conn) {
+                BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));
+
+                if (session != nullptr)
+                {
+                    conn.close("Session already connected");
+                    return;
+                }
+
+                if (handler != nullptr)
+                {
+                    conn.close("Handler already running");
+                    return;
+                }
+
+                session = &conn;
+
+                // media is the last digit of the endpoint /vm/0/0. A future
+                // enhancement can include supporting different endpoint values.
+                const char* media = "0";
+                handler = std::make_shared<Handler>(media, getIoContext());
+                handler->connect();
+            })
+            .onclose([](crow::websocket::Connection& conn,
+                        const std::string& /*reason*/) {
+                if (&conn != session)
+                {
+                    return;
+                }
+
+                session = nullptr;
+                handler->doClose();
+                handler->inputBuffer.clear();
+                handler->outputBuffer.clear();
+                handler.reset();
+            })
+            .onmessage([](crow::websocket::Connection& conn,
+                          const std::string& data, bool) {
+                if (data.length() > handler->inputBuffer.capacity() -
+                                        handler->inputBuffer.size())
+                {
+                    BMCWEB_LOG_ERROR("Buffer overrun when writing {} bytes",
+                                     data.length());
+                    conn.close("Buffer overrun");
+                    return;
+                }
+
+                size_t copied = boost::asio::buffer_copy(
+                    handler->inputBuffer.prepare(data.size()),
+                    boost::asio::buffer(data));
+                handler->inputBuffer.commit(copied);
+                handler->doWrite();
+            });
+    }
+}
+
+} // namespace obmc_vm
+
+} // namespace crow
diff --git a/features/webui_login/login_routes.hpp b/features/webui_login/login_routes.hpp
new file mode 100644
index 0000000..4b4a621
--- /dev/null
+++ b/features/webui_login/login_routes.hpp
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "cookies.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+#include "logging.hpp"
+#include "multipart_parser.hpp"
+#include "pam_authenticate.hpp"
+#include "sessions.hpp"
+
+#include <security/_pam_types.h>
+
+#include <boost/beast/http/fields.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/beast/http/verb.hpp>
+#include <nlohmann/json.hpp>
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <string_view>
+
+namespace crow
+{
+
+namespace login_routes
+{
+
+inline void handleLogin(const crow::Request& req,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    MultipartParser parser;
+    std::string_view contentType = req.getHeaderValue("content-type");
+    std::string_view username;
+    std::string_view password;
+
+    // This object needs to be declared at this scope so the strings
+    // within it are not destroyed before we can use them
+    nlohmann::json loginCredentials;
+    // Check if auth was provided by a payload
+    if (contentType.starts_with("application/json"))
+    {
+        loginCredentials = nlohmann::json::parse(req.body(), nullptr, false);
+        if (loginCredentials.is_discarded())
+        {
+            BMCWEB_LOG_DEBUG("Bad json in request");
+            asyncResp->res.result(boost::beast::http::status::bad_request);
+            return;
+        }
+
+        // check for username/password in the root object
+        // THis method is how intel APIs authenticate
+        nlohmann::json::iterator userIt = loginCredentials.find("username");
+        nlohmann::json::iterator passIt = loginCredentials.find("password");
+        if (userIt != loginCredentials.end() &&
+            passIt != loginCredentials.end())
+        {
+            const std::string* userStr = userIt->get_ptr<const std::string*>();
+            const std::string* passStr = passIt->get_ptr<const std::string*>();
+            if (userStr != nullptr && passStr != nullptr)
+            {
+                username = *userStr;
+                password = *passStr;
+            }
+        }
+        else
+        {
+            // Openbmc appears to push a data object that contains the
+            // same keys (username and password), attempt to use that
+            auto dataIt = loginCredentials.find("data");
+            if (dataIt != loginCredentials.end())
+            {
+                // Some apis produce an array of value ["username",
+                // "password"]
+                if (dataIt->is_array())
+                {
+                    if (dataIt->size() == 2)
+                    {
+                        nlohmann::json::iterator userIt2 = dataIt->begin();
+                        nlohmann::json::iterator passIt2 = dataIt->begin() + 1;
+                        if (userIt2 != dataIt->end() &&
+                            passIt2 != dataIt->end())
+                        {
+                            const std::string* userStr =
+                                userIt2->get_ptr<const std::string*>();
+                            const std::string* passStr =
+                                passIt2->get_ptr<const std::string*>();
+                            if (userStr != nullptr && passStr != nullptr)
+                            {
+                                username = *userStr;
+                                password = *passStr;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    nlohmann::json::object_t* obj =
+                        dataIt->get_ptr<nlohmann::json::object_t*>();
+                    if (obj != nullptr)
+                    {
+                        nlohmann::json::object_t::iterator userIt2 =
+                            obj->find("username");
+                        nlohmann::json::object_t::iterator passIt2 =
+                            obj->find("password");
+                        if (userIt2 != obj->end() && passIt2 != obj->end())
+                        {
+                            const std::string* userStr =
+                                userIt2->second.get_ptr<const std::string*>();
+                            const std::string* passStr =
+                                passIt2->second.get_ptr<const std::string*>();
+                            if (userStr != nullptr && passStr != nullptr)
+                            {
+                                username = *userStr;
+                                password = *passStr;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    else if (contentType.starts_with("multipart/form-data"))
+    {
+        ParserError ec = parser.parse(req);
+        if (ec != ParserError::PARSER_SUCCESS)
+        {
+            // handle error
+            BMCWEB_LOG_ERROR("MIME parse failed, ec : {}",
+                             static_cast<int>(ec));
+            asyncResp->res.result(boost::beast::http::status::bad_request);
+            return;
+        }
+
+        for (const FormPart& formpart : parser.mime_fields)
+        {
+            boost::beast::http::fields::const_iterator it =
+                formpart.fields.find("Content-Disposition");
+            if (it == formpart.fields.end())
+            {
+                BMCWEB_LOG_ERROR("Couldn't find Content-Disposition");
+                asyncResp->res.result(boost::beast::http::status::bad_request);
+                continue;
+            }
+
+            BMCWEB_LOG_INFO("Parsing value {}", it->value());
+
+            if (it->value() == "form-data; name=\"username\"")
+            {
+                username = formpart.content;
+            }
+            else if (it->value() == "form-data; name=\"password\"")
+            {
+                password = formpart.content;
+            }
+            else
+            {
+                BMCWEB_LOG_INFO("Extra format, ignore it.{}", it->value());
+            }
+        }
+    }
+    else
+    {
+        // check if auth was provided as a headers
+        username = req.getHeaderValue("username");
+        password = req.getHeaderValue("password");
+    }
+
+    if (!username.empty() && !password.empty())
+    {
+        int pamrc = pamAuthenticateUser(username, password, std::nullopt);
+        bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
+        if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
+        {
+            asyncResp->res.result(boost::beast::http::status::unauthorized);
+        }
+        else
+        {
+            auto session =
+                persistent_data::SessionStore::getInstance()
+                    .generateUserSession(username, req.ipAddress, std::nullopt,
+                                         persistent_data::SessionType::Session,
+                                         isConfigureSelfOnly);
+
+            bmcweb::setSessionCookies(asyncResp->res, *session);
+
+            // if content type is json, assume json token
+            asyncResp->res.jsonValue["token"] = session->sessionToken;
+        }
+    }
+    else
+    {
+        BMCWEB_LOG_DEBUG("Couldn't interpret password");
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+    }
+}
+
+inline void handleLogout(const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    const auto& session = req.session;
+    if (session != nullptr)
+    {
+        asyncResp->res.jsonValue["data"] =
+            "User '" + session->username + "' logged out";
+        asyncResp->res.jsonValue["message"] = "200 OK";
+        asyncResp->res.jsonValue["status"] = "ok";
+
+        bmcweb::clearSessionCookies(asyncResp->res);
+        persistent_data::SessionStore::getInstance().removeSession(session);
+    }
+}
+
+inline void requestRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/login")
+        .methods(boost::beast::http::verb::post)(handleLogin);
+
+    BMCWEB_ROUTE(app, "/logout")
+        .methods(boost::beast::http::verb::post)(handleLogout);
+}
+} // namespace login_routes
+} // namespace crow
diff --git a/features/webui_login/meson.build b/features/webui_login/meson.build
new file mode 100644
index 0000000..ab60765
--- /dev/null
+++ b/features/webui_login/meson.build
@@ -0,0 +1 @@
+incdir += include_directories('.')
