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
