diff --git a/transport/rmcpbridge/.clang-format b/transport/rmcpbridge/.clang-format
new file mode 100644
index 0000000..e5530e6
--- /dev/null
+++ b/transport/rmcpbridge/.clang-format
@@ -0,0 +1,136 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:  Align
+AlignTrailingComments:
+  Kind: Always
+  OverEmptyLines: 1
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Empty
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: true
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakBeforeMultilineStrings: false
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: None
+BraceWrapping:
+  AfterCaseLabel:  true
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterExternBlock: true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  BeforeCatch:     true
+  BeforeElse:      true
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction:   false
+  SplitEmptyRecord:     false
+  SplitEmptyNamespace:  false
+BreakAfterAttributes: Never
+BreakAfterReturnType: Automatic
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+BreakInheritanceList: AfterColon
+BreakStringLiterals: false
+BreakTemplateDeclarations: Yes
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeBlocks: Regroup
+IncludeCategories:
+  - Regex:           '^[<"](gtest|gmock)'
+    Priority:        7
+  - Regex:           '^"config.h"'
+    Priority:        -1
+  - Regex:           '^".*\.h"'
+    Priority:        1
+  - Regex:           '^".*\.hpp"'
+    Priority:        2
+  - Regex:           '^<.*\.h>'
+    Priority:        3
+  - Regex:           '^<.*\.hpp>'
+    Priority:        4
+  - Regex:           '^<.*'
+    Priority:        5
+  - Regex:           '.*'
+    Priority:        6
+IndentCaseLabels: true
+IndentExternBlock: NoIndent
+IndentRequiresClause: true
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+InsertNewlineAtEOF: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+LambdaBodyIndentation: Signature
+LineEnding: LF
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 25
+PenaltyBreakBeforeFirstCallParameter: 50
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 150
+PenaltyIndentedWhitespace: 1
+PointerAlignment: Left
+QualifierAlignment: Left
+ReferenceAlignment: Left
+ReflowComments:  true
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: Keyword
+SortIncludes: CaseSensitive
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: Never
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Latest
+TabWidth:        4
+UseTab:          Never
+...
+
diff --git a/transport/rmcpbridge/.clang-tidy b/transport/rmcpbridge/.clang-tidy
new file mode 100644
index 0000000..4b6eca0
--- /dev/null
+++ b/transport/rmcpbridge/.clang-tidy
@@ -0,0 +1,7 @@
+Checks: '
+    -*,
+    bugprone-unchecked-optional-access,
+    readability-identifier-naming
+'
+WarningsAsErrors: '*'
+HeaderFilterRegex: '(?!^subprojects).*'
diff --git a/transport/rmcpbridge/.gitignore b/transport/rmcpbridge/.gitignore
new file mode 100644
index 0000000..51ef08e
--- /dev/null
+++ b/transport/rmcpbridge/.gitignore
@@ -0,0 +1,3 @@
+/build*/
+/subprojects/*
+!subprojects/*.wrap
diff --git a/transport/rmcpbridge/LICENSE b/transport/rmcpbridge/LICENSE
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/transport/rmcpbridge/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/transport/rmcpbridge/OWNERS b/transport/rmcpbridge/OWNERS
new file mode 100644
index 0000000..05f2bbe
--- /dev/null
+++ b/transport/rmcpbridge/OWNERS
@@ -0,0 +1,48 @@
+# OWNERS
+# ------
+#
+# The OWNERS file maintains the list of individuals responsible for various
+# parts of this repository, including code review and approval.  We use the
+# Gerrit 'owners' plugin, which consumes this file, along with some extra
+# keywords for our own purposes and tooling.
+#
+# For details on the configuration used by 'owners' see:
+#  https://gerrit.googlesource.com/plugins/owners/+/refs/heads/master/owners/src/main/resources/Documentation/config.md
+#
+# An OWNERS file must be in the root of a repository but may also be present
+# in any subdirectory.  The contents of the subdirectory OWNERS file are
+# combined with parent directories unless 'inherit: false' is set.
+#
+# The owners file is YAML and has [up to] 4 top-level keywords.
+#   * owners: A list of individuals who have approval authority on the
+#     repository.
+#
+#   * reviewers: A list of individuals who have requested review notification
+#     on the repository.
+#
+#   * matchers: A list of specific file/path matchers for granular 'owners' and
+#     'reviewers'.  See 'owners' plugin documentation.
+#
+#   * openbmc: A list of openbmc-specific meta-data about owners and reviewers.
+#     - name: preferred name of the individual.
+#     - email: preferred email address of the individual.
+#     - discord: Discord nickname of the individual.
+#
+# It is expected that these 4 sections will be listed in the order above and
+# data within them will be kept sorted.
+
+owners:
+- rushtotom@gmail.com
+- vernon.mauery@gmail.com
+
+reviewers:
+
+matchers:
+
+openbmc:
+- name: Tom Joseph
+  email: rushtotom@gmail.com
+  discord: tomjose
+- name: Vernon Mauery
+  email: vernon.mauery@gmail.com
+  discord: vmauery
diff --git a/transport/rmcpbridge/README.md b/transport/rmcpbridge/README.md
new file mode 100644
index 0000000..89aba20
--- /dev/null
+++ b/transport/rmcpbridge/README.md
@@ -0,0 +1,13 @@
+# phosphor-net-ipmid
+
+## To Build
+
+To build this package, do the following steps:
+
+```sh
+1. ./bootstrap.sh
+2. ./configure ${CONFIGURE_FLAGS}
+3. make
+```
+
+To clean the repository run `./bootstrap.sh clean`.
diff --git a/transport/rmcpbridge/auth_algo.cpp b/transport/rmcpbridge/auth_algo.cpp
new file mode 100644
index 0000000..23cefda
--- /dev/null
+++ b/transport/rmcpbridge/auth_algo.cpp
@@ -0,0 +1,90 @@
+#include "auth_algo.hpp"
+
+#include <error.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+#include <string.h>
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace cipher
+{
+
+namespace rakp_auth
+{
+
+std::vector<uint8_t> AlgoSHA1::generateHMAC(
+    const std::vector<uint8_t>& input) const
+{
+    std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+
+    if (HMAC(EVP_sha1(), userKey.data(), userKey.size(), input.data(),
+             input.size(), output.data(), &mdLen) == NULL)
+    {
+        lg2::error("Generate HMAC failed: {ERROR}", "ERROR", strerror(errno));
+        output.resize(0);
+    }
+
+    return output;
+}
+
+std::vector<uint8_t> AlgoSHA1::generateICV(
+    const std::vector<uint8_t>& input) const
+{
+    std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+
+    if (HMAC(EVP_sha1(), sessionIntegrityKey.data(), SHA_DIGEST_LENGTH,
+             input.data(), input.size(), output.data(), &mdLen) == NULL)
+    {
+        lg2::error("Generate Session Integrity Key failed: {ERROR}", "ERROR",
+                   strerror(errno));
+        output.resize(0);
+    }
+    output.resize(integrityCheckValueLength);
+
+    return output;
+}
+
+std::vector<uint8_t> AlgoSHA256::generateHMAC(
+    const std::vector<uint8_t>& input) const
+{
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+
+    if (HMAC(EVP_sha256(), userKey.data(), userKey.size(), input.data(),
+             input.size(), output.data(), &mdLen) == NULL)
+    {
+        lg2::error("Generate HMAC_SHA256 failed: {ERROR}", "ERROR",
+                   strerror(errno));
+        output.resize(0);
+    }
+
+    return output;
+}
+
+std::vector<uint8_t> AlgoSHA256::generateICV(
+    const std::vector<uint8_t>& input) const
+{
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+
+    if (HMAC(EVP_sha256(), sessionIntegrityKey.data(),
+             sessionIntegrityKey.size(), input.data(), input.size(),
+             output.data(), &mdLen) == NULL)
+    {
+        lg2::error(
+            "Generate HMAC_SHA256_128 Integrity Check Value failed: {ERROR}",
+            "ERROR", strerror(errno));
+        output.resize(0);
+    }
+    output.resize(integrityCheckValueLength);
+
+    return output;
+}
+
+} // namespace rakp_auth
+
+} // namespace cipher
diff --git a/transport/rmcpbridge/auth_algo.hpp b/transport/rmcpbridge/auth_algo.hpp
new file mode 100644
index 0000000..e179d72
--- /dev/null
+++ b/transport/rmcpbridge/auth_algo.hpp
@@ -0,0 +1,219 @@
+#pragma once
+
+#include "crypt_algo.hpp"
+#include "integrity_algo.hpp"
+
+#include <array>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+namespace cipher
+{
+namespace rakp_auth
+{
+constexpr size_t USER_KEY_MAX_LENGTH = 20;
+constexpr size_t BMC_RANDOM_NUMBER_LEN = 16;
+constexpr size_t REMOTE_CONSOLE_RANDOM_NUMBER_LEN = 16;
+
+/**
+ * @enum RAKP Authentication Algorithms
+ *
+ * RMCP+ Authenticated Key-Exchange Protocol (RAKP)
+ *
+ * RAKP-None is not supported as per the following recommendation
+ * (https://www.us-cert.gov/ncas/alerts/TA13-207A)
+ * ("cipher 0" is an option enabled by default on many IPMI enabled devices that
+ * allows authentication to be bypassed.  Disable "cipher 0" to prevent
+ * attackers from bypassing authentication and sending arbitrary IPMI commands.)
+ */
+enum class Algorithms : uint8_t
+{
+    RAKP_NONE = 0,    // Mandatory (implemented, not supported)
+    RAKP_HMAC_SHA1,   // Mandatory (implemented, default choice in ipmitool)
+    RAKP_HMAC_MD5,    // Optional (not implemented)
+    RAKP_HMAC_SHA256, // Optional (implemented, best available)
+    // Reserved used to indicate an invalid authentication algorithm
+    RAKP_HMAC_INVALID = 0xB0
+};
+
+/**
+ * @class Interface
+ *
+ * Interface is the base class for the Authentication Algorithms.
+ * The Authentication Algorithm specifies the type of authentication “handshake”
+ * process that is used and identifies any particular variations of hashing or
+ * signature algorithm that is used as part of the process.
+ *
+ */
+class Interface
+{
+  public:
+    explicit Interface(integrity::Algorithms intAlgo,
+                       crypt::Algorithms cryptAlgo) :
+        intAlgo(intAlgo), cryptAlgo(cryptAlgo)
+    {}
+
+    Interface() = delete;
+    virtual ~Interface() = default;
+    Interface(const Interface&) = default;
+    Interface& operator=(const Interface&) = default;
+    Interface(Interface&&) = default;
+    Interface& operator=(Interface&&) = default;
+
+    /**
+     * @brief Generate the Hash Message Authentication Code
+     *
+     * This API is invoked to generate the Key Exchange Authentication Code
+     * in the RAKP2 and RAKP4 sequence and for generating the Session
+     * Integrity Key.
+     *
+     * @param input message
+     *
+     * @return hash output
+     *
+     * @note The user key which is the secret key for the hash operation
+     *        needs to be set before this operation.
+     */
+    std::vector<uint8_t> virtual generateHMAC(
+        const std::vector<uint8_t>& input) const = 0;
+
+    /**
+     * @brief Generate the Integrity Check Value
+     *
+     * This API is invoked in the RAKP4 sequence for generating the
+     * Integrity Check Value.
+     *
+     * @param input message
+     *
+     * @return hash output
+     *
+     * @note The session integrity key which is the secret key for the
+     *        hash operation needs to be set before this operation.
+     */
+    std::vector<uint8_t> virtual generateICV(
+        const std::vector<uint8_t>& input) const = 0;
+
+    /**
+     * @brief Check if the Authentication algorithm is supported
+     *
+     * @param[in] algo - authentication algorithm
+     *
+     * @return true if algorithm is supported else false
+     *
+     */
+    static bool isAlgorithmSupported(Algorithms algo)
+    {
+        if (algo == Algorithms::RAKP_HMAC_SHA256)
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    // User Key is hardcoded to PASSW0RD till the IPMI User account
+    // management is in place.
+    std::array<uint8_t, USER_KEY_MAX_LENGTH> userKey = {"0penBmc"};
+
+    // Managed System Random Number
+    std::array<uint8_t, BMC_RANDOM_NUMBER_LEN> bmcRandomNum;
+
+    // Remote Console Random Number
+    std::array<uint8_t, REMOTE_CONSOLE_RANDOM_NUMBER_LEN> rcRandomNum;
+
+    // Session Integrity Key
+    std::vector<uint8_t> sessionIntegrityKey;
+
+    /**
+     * Integrity Algorithm is activated and set in the session data only
+     * once the session setup is succeeded in the RAKP34 command. But the
+     * integrity algorithm is negotiated in the Open Session Request command
+     * . So the integrity algorithm successfully negotiated is stored
+     * in the authentication algorithm's instance.
+     */
+    integrity::Algorithms intAlgo;
+
+    /**
+     * Confidentiality Algorithm is activated and set in the session data
+     * only once the session setup is succeeded in the RAKP34 command. But
+     * the confidentiality algorithm is negotiated in the Open Session
+     * Request command. So the confidentiality algorithm successfully
+     * negotiated is stored in the authentication algorithm's instance.
+     */
+    crypt::Algorithms cryptAlgo;
+};
+
+/**
+ * @class AlgoSHA1
+ *
+ * RAKP-HMAC-SHA1 specifies the use of RAKP messages for the key exchange
+ * portion of establishing the session, and that HMAC-SHA1 (per [RFC2104]) is
+ * used to create 20-byte Key Exchange Authentication Code fields in RAKP
+ * Message 2 and RAKP Message 3. HMAC-SHA1-96(per [RFC2404]) is used for
+ * generating a 12-byte Integrity Check Value field for RAKP Message 4.
+ */
+
+class AlgoSHA1 : public Interface
+{
+  public:
+    static constexpr size_t integrityCheckValueLength = 12;
+
+    explicit AlgoSHA1(integrity::Algorithms intAlgo,
+                      crypt::Algorithms cryptAlgo) :
+        Interface(intAlgo, cryptAlgo)
+    {}
+
+    AlgoSHA1() = delete;
+    ~AlgoSHA1() = default;
+    AlgoSHA1(const AlgoSHA1&) = default;
+    AlgoSHA1& operator=(const AlgoSHA1&) = default;
+    AlgoSHA1(AlgoSHA1&&) = default;
+    AlgoSHA1& operator=(AlgoSHA1&&) = default;
+
+    std::vector<uint8_t> generateHMAC(
+        const std::vector<uint8_t>& input) const override;
+
+    std::vector<uint8_t> generateICV(
+        const std::vector<uint8_t>& input) const override;
+};
+
+/**
+ * @class AlgoSHA256
+ *
+ * RAKP-HMAC-SHA256 specifies the use of RAKP messages for the key exchange
+ * portion of establishing the session, and that HMAC-SHA256 (per [FIPS 180-2]
+ * and [RFC4634] and is used to create a 32-byte Key Exchange Authentication
+ * Code fields in RAKP Message 2 and RAKP Message 3. HMAC-SHA256-128 (per
+ * [RFC4868]) is used for generating a 16-byte Integrity Check Value field for
+ * RAKP Message 4.
+ */
+
+class AlgoSHA256 : public Interface
+{
+  public:
+    static constexpr size_t integrityCheckValueLength = 16;
+
+    explicit AlgoSHA256(integrity::Algorithms intAlgo,
+                        crypt::Algorithms cryptAlgo) :
+        Interface(intAlgo, cryptAlgo)
+    {}
+
+    ~AlgoSHA256() = default;
+    AlgoSHA256(const AlgoSHA256&) = default;
+    AlgoSHA256& operator=(const AlgoSHA256&) = default;
+    AlgoSHA256(AlgoSHA256&&) = default;
+    AlgoSHA256& operator=(AlgoSHA256&&) = default;
+
+    std::vector<uint8_t> generateHMAC(
+        const std::vector<uint8_t>& input) const override;
+
+    std::vector<uint8_t> generateICV(
+        const std::vector<uint8_t>& input) const override;
+};
+
+} // namespace rakp_auth
+
+} // namespace cipher
diff --git a/transport/rmcpbridge/comm_module.cpp b/transport/rmcpbridge/comm_module.cpp
new file mode 100644
index 0000000..e34ab26
--- /dev/null
+++ b/transport/rmcpbridge/comm_module.cpp
@@ -0,0 +1,72 @@
+#include "comm_module.hpp"
+
+#include "command/channel_auth.hpp"
+#include "command/open_session.hpp"
+#include "command/rakp12.hpp"
+#include "command/rakp34.hpp"
+#include "command/session_cmds.hpp"
+#include "command_table.hpp"
+#include "session.hpp"
+
+#include <algorithm>
+#include <cstring>
+#include <iomanip>
+
+namespace command
+{
+
+void sessionSetupCommands()
+{
+    static const command::CmdDetails commands[] = {
+        // Open Session Request/Response
+        {{(static_cast<uint32_t>(message::PayloadType::OPEN_SESSION_REQUEST)
+           << 16)},
+         &openSession,
+         session::Privilege::HIGHEST_MATCHING,
+         true},
+        // RAKP1 & RAKP2 Message
+        {{(static_cast<uint32_t>(message::PayloadType::RAKP1) << 16)},
+         &RAKP12,
+         session::Privilege::HIGHEST_MATCHING,
+         true},
+        // RAKP3 & RAKP4 Message
+        {{(static_cast<uint32_t>(message::PayloadType::RAKP3) << 16)},
+         &RAKP34,
+         session::Privilege::HIGHEST_MATCHING,
+         true},
+        // Get Channel Authentication Capabilities Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(command::NetFns::APP) | 0x38},
+         &GetChannelCapabilities,
+         session::Privilege::HIGHEST_MATCHING,
+         true},
+        // Get Channel Cipher Suites Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(::command::NetFns::APP) | 0x54},
+         &getChannelCipherSuites,
+         session::Privilege::HIGHEST_MATCHING,
+         true},
+        // Set Session Privilege Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(command::NetFns::APP) | 0x3B},
+         &setSessionPrivilegeLevel,
+         session::Privilege::USER,
+         false},
+        // Close Session Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(command::NetFns::APP) | 0x3C},
+         &closeSession,
+         session::Privilege::CALLBACK,
+         false},
+    };
+
+    for (auto& iter : commands)
+    {
+        command::Table::get().registerCommand(
+            iter.command,
+            std::make_unique<command::NetIpmidEntry>(
+                iter.command, iter.functor, iter.privilege, iter.sessionless));
+    }
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/comm_module.hpp b/transport/rmcpbridge/comm_module.hpp
new file mode 100644
index 0000000..c67b413
--- /dev/null
+++ b/transport/rmcpbridge/comm_module.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <cstdint>
+
+namespace command
+{
+
+/**
+ * @brief RMCP+ and RAKP Message Status Codes
+ */
+enum class RAKP_ReturnCode : uint8_t
+{
+    NO_ERROR,                    //!< No errors
+    INSUFFICIENT_RESOURCE,       //!< Insufficient resources to create a session
+    INVALID_SESSION_ID,          //!< Invalid Session ID
+    INVALID_PAYLOAD_TYPE,        //!< Invalid payload type
+    INVALID_AUTH_ALGO,           //!< Invalid authentication algorithm
+    INVALID_INTEGRITY_ALGO,      //!< Invalid integrity algorithm
+    NO_MATCH_AUTH_PAYLOAD,       //!< No matching authentication payload
+    NO_MATCH_INTEGRITY_PAYLOAD,  //!< No matching integrity payload
+    INACTIVE_SESSIONID,          //!< Inactive Session ID
+    INACTIVE_ROLE,               //!< Invalid role
+    UNAUTH_ROLE_PRIV,            //!< Unauthorized role or privilege requested
+    INSUFFICIENT_RESOURCES_ROLE, //!< Insufficient resources to create a session
+    INVALID_NAME_LENGTH,         //!< Invalid name length
+    UNAUTH_NAME,                 //!< Unauthorized name
+    UNAUTH_GUID,                 //!< Unauthorized GUID
+    INVALID_INTEGRITY_VALUE,     //!< Invalid integrity check value
+    INVALID_CONF_ALGO,           //!< Invalid confidentiality algorithm
+    NO_CIPHER_SUITE_MATCH,       //!< No Cipher Suite match with security algos
+    ILLEGAL_PARAMETER,           //!< Illegal or unrecognized parameter
+};
+
+/**
+ * @brief Register Session Setup commands to the Command Table
+ */
+void sessionSetupCommands();
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/channel_auth.cpp b/transport/rmcpbridge/command/channel_auth.cpp
new file mode 100644
index 0000000..ba101e4
--- /dev/null
+++ b/transport/rmcpbridge/command/channel_auth.cpp
@@ -0,0 +1,288 @@
+#include "channel_auth.hpp"
+
+#include <errno.h>
+#include <ipmid/api.h>
+
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <user_channel/channel_layer.hpp>
+#include <user_channel/user_layer.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <fstream>
+#include <set>
+#include <string>
+
+namespace command
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using Json = nlohmann::json;
+
+std::vector<uint8_t> GetChannelCapabilities(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& /* handler */)
+{
+    auto request =
+        reinterpret_cast<const GetChannelCapabilitiesReq*>(inPayload.data());
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+    constexpr unsigned int channelMask = 0x0f;
+    uint8_t chNum = ipmi::convertCurrentChannelNum(
+        request->channelNumber & channelMask, getInterfaceIndex());
+
+    if (!ipmi::isValidChannel(chNum) ||
+        (ipmi::EChannelSessSupported::none ==
+         ipmi::getChannelSessionSupport(chNum)) ||
+        !ipmi::isValidPrivLimit(request->reqMaxPrivLevel))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_INVALID_FIELD_REQUEST};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(GetChannelCapabilitiesResp));
+    auto response =
+        reinterpret_cast<GetChannelCapabilitiesResp*>(outPayload.data());
+
+    // A canned response, since there is no user and channel management.
+    response->completionCode = IPMI_CC_OK;
+
+    response->channelNumber = chNum;
+
+    response->ipmiVersion = 1; // IPMI v2.0 extended capabilities available.
+    response->reserved1 = 0;
+    response->oem = 0;
+    response->straightKey = 0;
+    response->reserved2 = 0;
+    response->md5 = 0;
+    response->md2 = 0;
+
+    response->reserved3 = 0;
+    response->KGStatus = 0;       // KG is set to default
+    response->perMessageAuth = 0; // Per-message Authentication is enabled
+    response->userAuth = 0;       // User Level Authentication is enabled
+    uint8_t maxChUsers = 0;
+    uint8_t enabledUsers = 0;
+    uint8_t fixedUsers = 0;
+    ipmi::ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers);
+
+    response->nonNullUsers = enabledUsers > 0 ? 1 : 0; // Non-null usernames
+    response->nullUsers = 0;      // Null usernames disabled
+    response->anonymousLogin = 0; // Anonymous Login disabled
+
+    response->reserved4 = 0;
+    response->extCapabilities = 0x2; // Channel supports IPMI v2.0 connections
+
+    response->oemID[0] = 0;
+    response->oemID[1] = 0;
+    response->oemID[2] = 0;
+    response->oemAuxillary = 0;
+    return outPayload;
+}
+
+static constexpr const char* configFile =
+    "/usr/share/ipmi-providers/cipher_list.json";
+static constexpr const char* cipher = "cipher";
+static constexpr uint8_t stdCipherSuite = 0xC0;
+static constexpr uint8_t oemCipherSuite = 0xC1;
+static constexpr const char* oem = "oemiana";
+static constexpr const char* auth = "authentication";
+static constexpr const char* integrity = "integrity";
+static constexpr uint8_t integrityTag = 0x40;
+static constexpr const char* conf = "confidentiality";
+static constexpr uint8_t confTag = 0x80;
+
+/** @brief Get the supported Cipher records
+ *
+ * The cipher records are read from the JSON file and converted into
+ * 1. cipher suite record format mentioned in the IPMI specification. The
+ * records can be either OEM or standard cipher. Each json entry is parsed and
+ * converted into the cipher record format and pushed into the vector.
+ * 2. Algorithms listed in vector format
+ *
+ * @return pair of vector containing 1. all the cipher suite records. 2.
+ * Algorithms supported
+ *
+ */
+static std::pair<std::vector<uint8_t>, std::vector<uint8_t>> getCipherRecords()
+{
+    std::vector<uint8_t> cipherRecords;
+    std::vector<uint8_t> supportedAlgorithmRecords;
+    // create set to get the unique supported algorithms
+    std::set<uint8_t> supportedAlgorithmSet;
+
+    std::ifstream jsonFile(configFile);
+    if (!jsonFile.is_open())
+    {
+        lg2::error("Channel Cipher suites file not found: {ERROR}", "ERROR",
+                   strerror(errno));
+        elog<InternalFailure>();
+    }
+
+    auto data = Json::parse(jsonFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        lg2::error("Parsing channel cipher suites JSON failed: {ERROR}",
+                   "ERROR", strerror(errno));
+        elog<InternalFailure>();
+    }
+
+    for (const auto& record : data)
+    {
+        if (record.find(oem) != record.end())
+        {
+            // OEM cipher suite - 0xC1
+            cipherRecords.push_back(oemCipherSuite);
+            // Cipher Suite ID
+            cipherRecords.push_back(record.value(cipher, 0));
+            // OEM IANA - 3 bytes
+            cipherRecords.push_back(record.value(oem, 0));
+            cipherRecords.push_back(record.value(oem, 0) >> 8);
+            cipherRecords.push_back(record.value(oem, 0) >> 16);
+        }
+        else
+        {
+            // Standard cipher suite - 0xC0
+            cipherRecords.push_back(stdCipherSuite);
+            // Cipher Suite ID
+            cipherRecords.push_back(record.value(cipher, 0));
+        }
+
+        // Authentication algorithm number
+        cipherRecords.push_back(record.value(auth, 0));
+        supportedAlgorithmSet.insert(record.value(auth, 0));
+
+        // Integrity algorithm number
+        cipherRecords.push_back(record.value(integrity, 0) | integrityTag);
+        supportedAlgorithmSet.insert(record.value(integrity, 0) | integrityTag);
+
+        // Confidentiality algorithm number
+        cipherRecords.push_back(record.value(conf, 0) | confTag);
+        supportedAlgorithmSet.insert(record.value(conf, 0) | confTag);
+    }
+
+    // copy the set to supportedAlgorithmRecord which is vector based.
+    std::copy(supportedAlgorithmSet.begin(), supportedAlgorithmSet.end(),
+              std::back_inserter(supportedAlgorithmRecords));
+
+    return std::make_pair(cipherRecords, supportedAlgorithmRecords);
+}
+
+/** @brief this command is used to look up what authentication, integrity,
+ *  confidentiality algorithms are supported.
+ *
+ *  @ param inPayload - vector of input data
+ *  @ param handler - pointer to handler
+ *
+ *  @returns ipmi completion code plus response data
+ *   - vector of response data: cc, channel, record data
+ **/
+std::vector<uint8_t> getChannelCipherSuites(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& /* handler */)
+{
+    const auto errorResponse = [](uint8_t cc) {
+        std::vector<uint8_t> rsp(1);
+        rsp[0] = cc;
+        return rsp;
+    };
+
+    static constexpr size_t getChannelCipherSuitesReqLen = 3;
+    if (inPayload.size() != getChannelCipherSuitesReqLen)
+    {
+        return errorResponse(IPMI_CC_REQ_DATA_LEN_INVALID);
+    }
+
+    static constexpr uint8_t channelMask = 0x0f;
+    uint8_t channelNumber = inPayload[0] & channelMask;
+    if (channelNumber != inPayload[0])
+    {
+        return errorResponse(IPMI_CC_INVALID_FIELD_REQUEST);
+    }
+    static constexpr uint8_t payloadMask = 0x3f;
+    uint8_t payloadType = inPayload[1] & payloadMask;
+    if (payloadType != inPayload[1])
+    {
+        return errorResponse(IPMI_CC_INVALID_FIELD_REQUEST);
+    }
+    static constexpr uint8_t indexMask = 0x3f;
+    uint8_t listIndex = inPayload[2] & indexMask;
+    static constexpr uint8_t algoSelectShift = 7;
+    uint8_t algoSelectBit = inPayload[2] >> algoSelectShift;
+    if ((listIndex | (algoSelectBit << algoSelectShift)) != inPayload[2])
+    {
+        return errorResponse(IPMI_CC_INVALID_FIELD_REQUEST);
+    }
+
+    static std::vector<uint8_t> cipherRecords;
+    static std::vector<uint8_t> supportedAlgorithms;
+    static bool recordInit = false;
+
+    uint8_t rspChannel =
+        ipmi::convertCurrentChannelNum(channelNumber, getInterfaceIndex());
+
+    if (!ipmi::isValidChannel(rspChannel))
+    {
+        return errorResponse(IPMI_CC_INVALID_FIELD_REQUEST);
+    }
+    if (!ipmi::isValidPayloadType(static_cast<ipmi::PayloadType>(payloadType)))
+    {
+        lg2::debug("Get channel cipher suites - Invalid payload type: {ERROR}",
+                   "ERROR", strerror(errno));
+        constexpr uint8_t ccPayloadTypeNotSupported = 0x80;
+        return errorResponse(ccPayloadTypeNotSupported);
+    }
+
+    if (!recordInit)
+    {
+        try
+        {
+            std::tie(cipherRecords, supportedAlgorithms) = getCipherRecords();
+            recordInit = true;
+        }
+        catch (const std::exception& e)
+        {
+            return errorResponse(IPMI_CC_UNSPECIFIED_ERROR);
+        }
+    }
+
+    const std::vector<uint8_t>& records =
+        algoSelectBit ? cipherRecords : supportedAlgorithms;
+    static constexpr auto respSize = 16;
+
+    // Session support is available in active LAN channels.
+    if ((ipmi::getChannelSessionSupport(rspChannel) ==
+         ipmi::EChannelSessSupported::none) ||
+        !(ipmi::doesDeviceExist(rspChannel)))
+    {
+        lg2::debug("Get channel cipher suites - Device does not exist:{ERROR}",
+                   "ERROR", strerror(errno));
+        return errorResponse(IPMI_CC_INVALID_FIELD_REQUEST);
+    }
+
+    // List index(00h-3Fh), 0h selects the first set of 16, 1h selects the next
+    // set of 16 and so on.
+
+    // Calculate the number of record data bytes to be returned.
+    auto start =
+        std::min(static_cast<size_t>(listIndex) * respSize, records.size());
+    auto end = std::min((static_cast<size_t>(listIndex) * respSize) + respSize,
+                        records.size());
+    auto size = end - start;
+
+    std::vector<uint8_t> rsp;
+    rsp.push_back(IPMI_CC_OK);
+    rsp.push_back(rspChannel);
+    std::copy_n(records.data() + start, size, std::back_inserter(rsp));
+
+    return rsp;
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/channel_auth.hpp b/transport/rmcpbridge/command/channel_auth.hpp
new file mode 100644
index 0000000..059d0c7
--- /dev/null
+++ b/transport/rmcpbridge/command/channel_auth.hpp
@@ -0,0 +1,143 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <vector>
+
+namespace command
+{
+
+/**
+ * @struct GetChannelCapabilitiesReq
+ *
+ * IPMI Request data for Get Channel Authentication Capabilities command
+ */
+struct GetChannelCapabilitiesReq
+{
+    uint8_t channelNumber;
+    uint8_t reqMaxPrivLevel;
+} __attribute__((packed));
+
+/**
+ * @struct GetChannelCapabilitiesResp
+ *
+ * IPMI Response data for Get Channel Authentication Capabilities command
+ */
+struct GetChannelCapabilitiesResp
+{
+    uint8_t completionCode; // Completion Code
+
+    uint8_t channelNumber;  // Channel number that the request was
+    // received on
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t none:1;
+    uint8_t md2:1;
+    uint8_t md5:1;
+    uint8_t reserved2:1;
+    uint8_t straightKey:1; // Straight password/key support
+    // Support OEM identified by the IANA OEM ID in RMCP+ ping response
+    uint8_t oem:1;
+    uint8_t reserved1:1;
+    uint8_t ipmiVersion:1; // 0b = IPMIV1.5 support only, 1B = IPMI V2.0
+    // support
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t ipmiVersion:1; // 0b = IPMIV1.5 support only, 1B = IPMI V2.0
+    // support
+    uint8_t reserved1:1;
+    // Support OEM identified by the IANA OEM ID in RMCP+ ping response
+    uint8_t oem:1;
+    uint8_t straightKey:1; // Straight password/key support
+    uint8_t reserved2:1;
+    uint8_t md5:1;
+    uint8_t md2:1;
+    uint8_t none:1;
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    // Anonymous login status for anonymous login enabled/disabled
+    uint8_t anonymousLogin:1;
+    // Anonymous login status for null usernames enabled/disabled
+    uint8_t nullUsers:1;
+    // Anonymous login status for non-null usernames enabled/disabled
+    uint8_t nonNullUsers:1;
+    uint8_t userAuth:1;       // User level authentication status
+    uint8_t perMessageAuth:1; // Per-message authentication support
+    // Two key login status . only for IPMI V2.0 RMCP+ RAKP
+    uint8_t KGStatus:1;
+    uint8_t reserved3:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved3:2;
+    // Two key login status . only for IPMI V2.0 RMCP+ RAKP
+    uint8_t KGStatus:1;
+    uint8_t perMessageAuth:1; // Per-message authentication support
+    uint8_t userAuth:1;       // User level authentication status
+    // Anonymous login status for non-null usernames enabled/disabled
+    uint8_t nonNullUsers:1;
+    // Anonymous login status for null usernames enabled/disabled
+    uint8_t nullUsers:1;
+    // Anonymous login status for anonymous login enabled/disabled
+    uint8_t anonymousLogin:1;
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    // Extended capabilities will be present only if IPMI version is V2.0
+    uint8_t extCapabilities:2; // Channel support for IPMI V2.0 connections
+    uint8_t reserved4:6;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    // Extended capabilities will be present only if IPMI version is V2.0
+    uint8_t reserved4:6;
+    uint8_t extCapabilities:2; // Channel support for IPMI V2.0 connections
+#endif
+
+    // Below 4 bytes will all the 0's if no OEM authentication type available.
+    uint8_t oemID[3];     // IANA enterprise number for OEM/organization
+    uint8_t oemAuxillary; // Addition OEM specific information..
+} __attribute__((packed));
+
+/**
+ * @brief Get Channel Authentication Capabilities
+ *
+ * This message exchange provides a way for a remote console to discover what
+ * IPMI version is supported i.e. whether or not the BMC supports the IPMI
+ * v2.0 / RMCP+ packet format. It also provides information that the remote
+ * console can use to determine whether anonymous, “one-key”, or “two-key”
+ * logins are used.This information can guide a remote console in how it
+ * presents queries to users for username and password information. This is a
+ * ‘session-less’ command that the BMC accepts in both IPMI v1.5 and v2.0/RMCP+
+ * packet formats.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> GetChannelCapabilities(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler);
+
+/**
+ * @brief Get Channel Cipher Suites
+ *
+ * This command is used to look up what authentication, integrity, and
+ * confidentiality algorithms are supported. The algorithms are used in
+ * combination as ‘Cipher Suites’. This command only applies to implementations
+ * that support IPMI v2.0/RMCP+ sessions. This command can be executed prior to
+ * establishing a session with the BMC.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> getChannelCipherSuites(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler);
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/guid.cpp b/transport/rmcpbridge/command/guid.cpp
new file mode 100644
index 0000000..485d6b6
--- /dev/null
+++ b/transport/rmcpbridge/command/guid.cpp
@@ -0,0 +1,153 @@
+#include "guid.hpp"
+
+#include <ipmid/api.h>
+
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <sstream>
+#include <string>
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+static std::optional<command::Guid> guid;
+
+namespace command
+{
+
+std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
+
+static constexpr auto propInterface = "xyz.openbmc_project.Common.UUID";
+static constexpr auto uuidProperty = "UUID";
+static constexpr auto subtreePath = "/xyz/openbmc_project/inventory";
+
+static void rfcToGuid(std::string rfc4122, Guid& uuid)
+{
+    using Argument = xyz::openbmc_project::Common::InvalidArgument;
+    // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+    // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
+    // order
+    // Ex: 0x2332fc2c40e66298e511f2782395a361
+    constexpr size_t uuidHexLength = (2 * BMC_GUID_LEN);
+    constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
+
+    if (rfc4122.size() == uuidRfc4122Length)
+    {
+        rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
+                      rfc4122.end());
+    }
+    if (rfc4122.size() != uuidHexLength)
+    {
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+                              Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+    }
+    for (size_t ind = 0; ind < uuidHexLength; ind += 2)
+    {
+        long b;
+        try
+        {
+            b = std::stoul(rfc4122.substr(ind, 2), nullptr, 16);
+        }
+        catch (const std::exception& e)
+        {
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+                                  Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+        }
+
+        uuid[BMC_GUID_LEN - (ind / 2) - 1] = static_cast<uint8_t>(b);
+    }
+    return;
+}
+
+// Canned System GUID for when the Chassis DBUS object is not populated
+static constexpr Guid fakeGuid = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+                                  0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
+                                  0x0D, 0x0E, 0x0F, 0x10};
+const Guid& getSystemGUID()
+{
+    if (guid.has_value())
+    {
+        return guid.value();
+    }
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    ipmi::Value propValue;
+    try
+    {
+        const auto& [objPath, service] =
+            ipmi::getDbusObject(bus, propInterface, subtreePath);
+        // Read UUID property value from bmcObject
+        // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+        propValue = ipmi::getDbusProperty(bus, service, objPath, propInterface,
+                                          uuidProperty);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed in reading BMC UUID property: {ERROR}", "ERROR", e);
+        return fakeGuid;
+    }
+
+    std::string rfc4122Uuid = std::get<std::string>(propValue);
+    try
+    {
+        // convert to IPMI format
+        Guid tmpGuid{};
+        rfcToGuid(rfc4122Uuid, tmpGuid);
+        guid = tmpGuid;
+    }
+    catch (const InvalidArgument& e)
+    {
+        lg2::error("Failed in parsing BMC UUID property: {VALUE}", "VALUE",
+                   rfc4122Uuid.c_str());
+        return fakeGuid;
+    }
+    return guid.value();
+}
+
+void registerGUIDChangeCallback()
+{
+    if (matchPtr == nullptr)
+    {
+        using namespace sdbusplus::bus::match::rules;
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+        try
+        {
+            matchPtr = std::make_unique<sdbusplus::bus::match_t>(
+                bus, propertiesChangedNamespace(subtreePath, propInterface),
+                [](sdbusplus::message_t& m) {
+                    try
+                    {
+                        std::string iface{};
+                        std::map<std::string, ipmi::Value> pdict{};
+                        m.read(iface, pdict);
+                        if (iface != propInterface)
+                        {
+                            return;
+                        }
+                        auto guidStr = std::get<std::string>(pdict.at("UUID"));
+                        Guid tmpGuid{};
+                        rfcToGuid(guidStr, tmpGuid);
+                        guid = tmpGuid;
+                    }
+                    catch (const std::exception& e)
+                    {
+                        // signal contained invalid guid; ignore it
+                        lg2::error(
+                            "Failed to parse propertiesChanged signal: {ERROR}",
+                            "ERROR", e);
+                    }
+                });
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Failed to create dbus match: {ERROR}", "ERROR", e);
+        }
+    }
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/guid.hpp b/transport/rmcpbridge/command/guid.hpp
new file mode 100644
index 0000000..3bd8597
--- /dev/null
+++ b/transport/rmcpbridge/command/guid.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "comm_module.hpp"
+
+#include <sdbusplus/bus/match.hpp>
+
+#include <cstddef>
+#include <vector>
+
+namespace command
+{
+
+constexpr size_t BMC_GUID_LEN = 16;
+
+using Guid = std::array<uint8_t, BMC_GUID_LEN>;
+
+/**
+ * @brief Get System GUID
+ *
+ * @return If UUID is successfully read from the Chassis DBUS object, then the
+ *         GUID is returned, else a canned GUID is returned
+ */
+const Guid& getSystemGUID();
+
+/**
+ *  @brief Register the callback to update the cache when the GUID changes
+ */
+void registerGUIDChangeCallback();
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/open_session.cpp b/transport/rmcpbridge/command/open_session.cpp
new file mode 100644
index 0000000..9d5fc49
--- /dev/null
+++ b/transport/rmcpbridge/command/open_session.cpp
@@ -0,0 +1,118 @@
+#include "open_session.hpp"
+
+#include "comm_module.hpp"
+#include "endian.hpp"
+#include "sessions_manager.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace command
+{
+
+std::vector<uint8_t> openSession(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& /* handler */)
+{
+    auto request =
+        reinterpret_cast<const OpenSessionRequest*>(inPayload.data());
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
+    auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
+
+    // Per the IPMI Spec, messageTag and remoteConsoleSessionID are always
+    // returned
+    response->messageTag = request->messageTag;
+    response->remoteConsoleSessionID = request->remoteConsoleSessionID;
+
+    // Check for valid Authentication Algorithms
+    if (!cipher::rakp_auth::Interface::isAlgorithmSupported(
+            static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo)))
+    {
+        response->status_code =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
+        return outPayload;
+    }
+
+    // Check for valid Integrity Algorithms
+    if (!cipher::integrity::Interface::isAlgorithmSupported(
+            static_cast<cipher::integrity::Algorithms>(request->intAlgo)))
+    {
+        response->status_code =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
+        return outPayload;
+    }
+
+    session::Privilege priv;
+
+    // 0h in the requested maximum privilege role field indicates highest level
+    // matching proposed algorithms. The maximum privilege level the session
+    // can take is set to Administrator level. In the RAKP12 command sequence
+    // the session maximum privilege role is set again based on the user's
+    // permitted privilege level.
+    if (!request->maxPrivLevel)
+    {
+        priv = session::Privilege::ADMIN;
+    }
+    else
+    {
+        priv = static_cast<session::Privilege>(request->maxPrivLevel);
+    }
+
+    // Check for valid Confidentiality Algorithms
+    if (!cipher::crypt::Interface::isAlgorithmSupported(
+            static_cast<cipher::crypt::Algorithms>(request->confAlgo)))
+    {
+        response->status_code =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
+        return outPayload;
+    }
+
+    std::shared_ptr<session::Session> session;
+    try
+    {
+        // Start an IPMI session
+        session = session::Manager::get().startSession(
+            endian::from_ipmi<>(request->remoteConsoleSessionID), priv,
+            static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo),
+            static_cast<cipher::integrity::Algorithms>(request->intAlgo),
+            static_cast<cipher::crypt::Algorithms>(request->confAlgo));
+    }
+    catch (const std::exception& e)
+    {
+        response->status_code =
+            static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
+        lg2::error("openSession : Problem opening a session: {ERROR}", "ERROR",
+                   e);
+        return outPayload;
+    }
+
+    response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
+    response->maxPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel);
+    response->managedSystemSessionID =
+        endian::to_ipmi<>(session->getBMCSessionID());
+
+    response->authPayload = request->authPayload;
+    response->authPayloadLen = request->authPayloadLen;
+    response->authAlgo = request->authAlgo;
+
+    response->intPayload = request->intPayload;
+    response->intPayloadLen = request->intPayloadLen;
+    response->intAlgo = request->intAlgo;
+
+    response->confPayload = request->confPayload;
+    response->confPayloadLen = request->confPayloadLen;
+    response->confAlgo = request->confAlgo;
+
+    session->updateLastTransactionTime();
+
+    // Session state is Setup in progress
+    session->state(static_cast<uint8_t>(session::State::setupInProgress));
+    return outPayload;
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/open_session.hpp b/transport/rmcpbridge/command/open_session.hpp
new file mode 100644
index 0000000..2e17bf3
--- /dev/null
+++ b/transport/rmcpbridge/command/open_session.hpp
@@ -0,0 +1,180 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <vector>
+
+namespace command
+{
+
+/**
+ * @struct OpenSessionRequest
+ *
+ * IPMI Payload for RMCP+ Open Session Request
+ */
+struct OpenSessionRequest
+{
+    uint8_t messageTag; // Message tag from request buffer
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t maxPrivLevel:4; // Requested maximum privilege level
+    uint8_t reserved1:4;    // Reserved for future definition
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1:4;    // Reserved for future definition
+    uint8_t maxPrivLevel:4; // Requested maximum privilege level
+
+#endif
+
+    uint16_t reserved2;
+    uint32_t remoteConsoleSessionID;
+
+    uint8_t authPayload;
+    uint16_t reserved3;
+    uint8_t authPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t authAlgo:6;
+    uint8_t reserved4:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved4:2;
+    uint8_t authAlgo:6;
+#endif
+
+    uint8_t reserved5;
+    uint16_t reserved6;
+
+    uint8_t intPayload;
+    uint16_t reserved7;
+    uint8_t intPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t intAlgo:6;
+    uint8_t reserved8:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved8:2;
+    uint8_t intAlgo:6;
+#endif
+
+    uint8_t reserved9;
+    uint16_t reserved10;
+
+    uint8_t confPayload;
+    uint16_t reserved11;
+    uint8_t confPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t confAlgo:6;
+    uint8_t reserved12:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved12:2;
+    uint8_t confAlgo:6;
+#endif
+
+    uint8_t reserved13;
+    uint16_t reserved14;
+} __attribute__((packed));
+
+/**
+ * @struct OpenSessionResponse
+ *
+ * IPMI Payload for RMCP+ Open Session Response
+ */
+struct OpenSessionResponse
+{
+    uint8_t messageTag;
+    uint8_t status_code;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t maxPrivLevel:4;
+    uint8_t reserved1:4;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1:4;
+    uint8_t maxPrivLevel:4;
+#endif
+
+    uint8_t reserved2;
+    uint32_t remoteConsoleSessionID;
+    uint32_t managedSystemSessionID;
+
+    uint8_t authPayload;
+    uint16_t reserved3;
+    uint8_t authPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t authAlgo:6;
+    uint8_t reserved4:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved4:2;
+    uint8_t authAlgo:6;
+#endif
+
+    uint8_t reserved5;
+    uint16_t reserved6;
+
+    uint8_t intPayload;
+    uint16_t reserved7;
+    uint8_t intPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t intAlgo:6;
+    uint8_t reserved8:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved8:2;
+    uint8_t intAlgo:6;
+
+#endif
+
+    uint8_t reserved9;
+    uint16_t reserved10;
+
+    uint8_t confPayload;
+    uint16_t reserved11;
+    uint8_t confPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t confAlgo:6;
+    uint8_t reserved12:2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved12:2;
+    uint8_t confAlgo:6;
+#endif
+
+    uint8_t reserved13;
+    uint16_t reserved14;
+} __attribute__((packed));
+
+/**
+ * @brief RMCP+ Open Session Request, RMCP+ Open Session Response
+ *
+ * The RMCP+ Open Session request and response messages are used to enable a
+ * remote console to discover what Cipher Suite(s) can be used for establishing
+ * a session at a requested maximum privilege level. These messages are also
+ * used for transferring the sessions IDs that the remote console and BMC wish
+ *  to for the session once it’s been activated, and to track each party during
+ *  the exchange of messages used for establishing the session.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload,
+                                 std::shared_ptr<message::Handler>& handler);
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/payload_cmds.cpp b/transport/rmcpbridge/command/payload_cmds.cpp
new file mode 100644
index 0000000..ea517e8
--- /dev/null
+++ b/transport/rmcpbridge/command/payload_cmds.cpp
@@ -0,0 +1,283 @@
+#include "payload_cmds.hpp"
+
+#include "sessions_manager.hpp"
+#include "sol/sol_manager.hpp"
+#include "sol_cmds.hpp"
+
+#include <ipmid/api.h>
+
+#include <ipmid/api-types.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+namespace sol
+{
+
+namespace command
+{
+
+std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
+                                     std::shared_ptr<message::Handler>& handler)
+{
+    auto request =
+        reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data());
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
+    auto response =
+        reinterpret_cast<ActivatePayloadResponse*>(outPayload.data());
+
+    response->completionCode = IPMI_CC_OK;
+
+    // SOL is the payload currently supported for activation.
+    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
+    {
+        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        return outPayload;
+    }
+
+    sol::Manager::get().updateSOLParameter(ipmi::convertCurrentChannelNum(
+        ipmi::currentChNum, getInterfaceIndex()));
+    if (!sol::Manager::get().enable)
+    {
+        response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
+        return outPayload;
+    }
+
+    // Only one instance of SOL is currently supported.
+    if (request->payloadInstance != 1)
+    {
+        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        return outPayload;
+    }
+
+    auto session = session::Manager::get().getSession(handler->sessionID);
+
+    if (!request->encryption && session->isCryptAlgoEnabled())
+    {
+        response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
+        return outPayload;
+    }
+
+    if (session->currentPrivilege() <
+        static_cast<uint8_t>(sol::Manager::get().solMinPrivilege))
+    {
+        response->completionCode = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+        return outPayload;
+    }
+
+    // Is SOL Payload enabled for this user & channel.
+    auto userId = ipmi::ipmiUserGetUserId(session->userName);
+    ipmi::PayloadAccess payloadAccess = {};
+    if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
+                                            payloadAccess) != IPMI_CC_OK) ||
+        !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
+            message::PayloadType::SOL)]))
+    {
+        response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
+        return outPayload;
+    }
+
+    auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
+    if (status)
+    {
+        response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
+        return outPayload;
+    }
+
+    // Set the current command's socket channel to the session
+    handler->setChannelInSession();
+
+    // Start the SOL payload
+    try
+    {
+        sol::Manager::get().startPayloadInstance(request->payloadInstance,
+                                                 handler->sessionID);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to start SOL payload: {ERROR}", "ERROR", e);
+        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
+        return outPayload;
+    }
+
+    response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
+    response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
+    response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
+
+    // VLAN addressing is not used
+    response->vlanNum = 0xFFFF;
+
+    return outPayload;
+}
+
+std::vector<uint8_t> deactivatePayload(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler)
+{
+    auto request =
+        reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
+    auto response =
+        reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
+    response->completionCode = IPMI_CC_OK;
+
+    // SOL is the payload currently supported for deactivation
+    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
+    {
+        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        return outPayload;
+    }
+
+    // Only one instance of SOL is supported
+    if (request->payloadInstance != 1)
+    {
+        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        return outPayload;
+    }
+
+    auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
+    if (!status)
+    {
+        response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
+        return outPayload;
+    }
+
+    auto currentSession =
+        session::Manager::get().getSession(handler->sessionID);
+    auto solSessionID =
+        sol::Manager::get().getContext(request->payloadInstance).sessionID;
+    auto solActiveSession =
+        sol::Manager::get().getContext(request->payloadInstance).session;
+    // The session owner or the ADMIN could deactivate the session
+    if (currentSession->userName != solActiveSession->userName &&
+        currentSession->currentPrivilege() !=
+            static_cast<uint8_t>(session::Privilege::ADMIN))
+    {
+        response->completionCode = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+        return outPayload;
+    }
+
+    try
+    {
+        sol::Manager::get().stopPayloadInstance(request->payloadInstance);
+
+        try
+        {
+            activating(request->payloadInstance, solSessionID);
+        }
+        catch (const std::exception& e)
+        {
+            lg2::info("Failed to call the activating method: {ERROR}", "ERROR",
+                      e);
+            /*
+             * In case session has been closed (like in the case of inactivity
+             * timeout), then activating function would throw an exception,
+             * since solSessionID is not found. As session is already closed,
+             * returning IPMI status code for Payload already deactivated
+             * as BMC automatically deactivates all active payloads when
+             * session is terminated.
+             */
+            response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
+            return outPayload;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to call the getContext method: {ERROR}", "ERROR", e);
+        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
+        return outPayload;
+    }
+
+    return outPayload;
+}
+
+std::vector<uint8_t> getPayloadStatus(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& /* handler */)
+{
+    auto request =
+        reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
+    auto response =
+        reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
+
+    // SOL is the payload currently supported for payload status
+    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
+    {
+        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
+        return outPayload;
+    }
+
+    response->completionCode = IPMI_CC_OK;
+
+    constexpr size_t maxSolPayloadInstances = 1;
+    response->capacity = maxSolPayloadInstances;
+
+    // Currently we support only one SOL session
+    response->instance1 = sol::Manager::get().isPayloadActive(1);
+
+    return outPayload;
+}
+
+std::vector<uint8_t> getPayloadInfo(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& /* handler */)
+{
+    auto request =
+        reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
+
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
+    auto response =
+        reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
+
+    // SOL is the payload currently supported for payload status & only one
+    // instance of SOL is supported.
+    if (static_cast<uint8_t>(message::PayloadType::SOL) !=
+            request->payloadType ||
+        request->payloadInstance != 1)
+    {
+        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        return outPayload;
+    }
+    auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
+
+    if (status)
+    {
+        auto& context =
+            sol::Manager::get().getContext(request->payloadInstance);
+        response->sessionID = context.sessionID;
+    }
+    else
+    {
+        // No active payload - return session id as 0
+        response->sessionID = 0;
+    }
+    response->completionCode = IPMI_CC_OK;
+    return outPayload;
+}
+
+} // namespace command
+
+} // namespace sol
diff --git a/transport/rmcpbridge/command/payload_cmds.hpp b/transport/rmcpbridge/command/payload_cmds.hpp
new file mode 100644
index 0000000..37e071f
--- /dev/null
+++ b/transport/rmcpbridge/command/payload_cmds.hpp
@@ -0,0 +1,296 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <vector>
+
+namespace sol
+{
+
+namespace command
+{
+
+constexpr uint8_t IPMI_CC_PAYLOAD_ALREADY_ACTIVE = 0x80;
+constexpr uint8_t IPMI_CC_PAYLOAD_TYPE_DISABLED = 0x81;
+constexpr uint8_t IPMI_CC_PAYLOAD_ACTIVATION_LIMIT = 0x82;
+constexpr uint8_t IPMI_CC_PAYLOAD_WITH_ENCRYPTION = 0x83;
+constexpr uint8_t IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION = 0x84;
+
+/** @struct ActivatePayloadRequest
+ *
+ *  IPMI payload for Activate Payload command request.
+ */
+struct ActivatePayloadRequest
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t payloadType:6; //!< Payload type.
+    uint8_t reserved1:2;   //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1:2;   //!< Payload type.
+    uint8_t payloadType:6; //!< Payload type.
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t payloadInstance:4; //!< Payload instance.
+    uint8_t reserved2:4;       //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved2:4;       //!< Reserved.
+    uint8_t payloadInstance:4; //!< Payload instance.
+#endif
+
+    /** @brief The following Auxiliary Request Data applies only for payload
+     *         SOL only.
+     */
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t reserved4:1;  //!< Reserved.
+    uint8_t handshake:1;  //!< SOL startup handshake.
+    uint8_t alert:2;      //!< Shared serial alert behavior.
+    uint8_t reserved3:1;  //!< Reserved.
+    uint8_t testMode:1;   //!< Test mode.
+    uint8_t auth:1;       //!< If true, activate payload with authentication.
+    uint8_t encryption:1; //!< If true, activate payload with encryption.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t encryption:1; //!< If true, activate payload with encryption.
+    uint8_t auth:1;       //!< If true, activate payload with authentication.
+    uint8_t testMode:1;   //!< Test mode.
+    uint8_t reserved3:1;  //!< Reserved.
+    uint8_t alert:2;      //!< Shared serial alert behavior.
+    uint8_t handshake:1;  //!< SOL startup handshake.
+    uint8_t reserved4:1;  //!< Reserved.
+#endif
+
+    uint8_t reserved5; //!< Reserved.
+    uint8_t reserved6; //!< Reserved.
+    uint8_t reserved7; //!< Reserved.
+} __attribute__((packed));
+
+/** @struct ActivatePayloadResponse
+ *
+ *  IPMI payload for Activate Payload command response.
+ */
+struct ActivatePayloadResponse
+{
+    uint8_t completionCode; //!< Completion code.
+    uint8_t reserved1;      //!< Reserved.
+    uint8_t reserved2;      //!< Reserved.
+    uint8_t reserved3;      //!< Reserved.
+
+    // Test Mode
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t testMode:1;  //!< Test mode.
+    uint8_t reserved4:7; //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved4:7; //!< Reserved.
+    uint8_t testMode:1;  //!< Test mode.
+#endif
+
+    uint16_t inPayloadSize;  //!< Inbound payload size
+    uint16_t outPayloadSize; //!< Outbound payload size.
+    uint16_t portNum;        //!< Payload UDP port number.
+    uint16_t vlanNum;        //!< Payload VLAN number.
+} __attribute__((packed));
+
+/** @brief Activate Payload Command.
+ *
+ *  This command is used for activating and deactivating a payload type under a
+ *  given IPMI session. The UDP Port number for SOL is the same as the port that
+ *  was used to establish the IPMI session.
+ *
+ *  @param[in] inPayload - Request data for the command.
+ *  @param[in] handler - Reference to the message handler.
+ *
+ *  @return Response data for the command
+ */
+std::vector<uint8_t> activatePayload(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler);
+
+constexpr uint8_t IPMI_CC_PAYLOAD_DEACTIVATED = 0x80;
+
+/** @struct DeactivatePayloadRequest
+ *
+ *  IPMI payload for Deactivate Payload command request.
+ */
+struct DeactivatePayloadRequest
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t payloadType:6; //!< Payload type.
+    uint8_t reserved1:2;   //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1:2;   //!< Payload type.
+    uint8_t payloadType:6; //!< Reserved.
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t payloadInstance:4; //!< Payload instance.
+    uint8_t reserved2:4;       //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved2:4;       //!< Reserved.
+    uint8_t payloadInstance:4; //!< Payload instance.
+#endif
+
+    /** @brief No auxiliary data for payload type SOL */
+    uint8_t auxData1; //!< Auxiliary data 1
+    uint8_t auxData2; //!< Auxiliary data 2
+    uint8_t auxData3; //!< Auxiliary data 3
+    uint8_t auxData4; //!< Auxiliary data 4
+} __attribute__((packed));
+
+/** @struct DeactivatePayloadResponse
+ *
+ * IPMI payload for Deactivate Payload Command response.
+ */
+struct DeactivatePayloadResponse
+{
+    uint8_t completionCode; //!< Completion code
+} __attribute__((packed));
+
+/** @brief Deactivate Payload Command.
+ *
+ *  This command is used to terminate use of a given payload on an IPMI session.
+ *  This type of traffic then becomes freed for activation by another session,
+ *  or for possible re-activation under the present session.The Deactivate
+ *  Payload command does not cause the session to be terminated. The Close
+ *  Session command should be used for that purpose. A remote console
+ *  terminating a application does not need to explicitly deactivate payload(s)
+ *  prior to session. When a session terminates all payloads that were active
+ *  under that session are automatically deactivated by the BMC.
+ *
+ * @param[in] inPayload - Request data for the command.
+ * @param[in] handler - Reference to the message handler.
+ *
+ * @return Response data for the command.
+ */
+std::vector<uint8_t> deactivatePayload(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler);
+
+/** @struct GetPayloadStatusRequest
+ *
+ *  IPMI payload for Get Payload Activation Status command request.
+ */
+struct GetPayloadStatusRequest
+{
+    uint8_t payloadType; //!< Payload type
+} __attribute__((packed));
+
+/** @struct GetPayloadStatusResponse
+ *
+ *  IPMI payload for Get Payload Activation Status command response.
+ */
+struct GetPayloadStatusResponse
+{
+    uint8_t completionCode; //!< Completion code.
+
+    uint8_t capacity;       //!< Instance capacity.
+
+    /* @brief Activation Status. */
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t instance1:1; //!< If true, Instance 1 is activated.
+    uint8_t instance2:1; //!< If true, Instance 2 is activated.
+    uint8_t instance3:1; //!< If true, Instance 3 is activated.
+    uint8_t instance4:1; //!< If true, Instance 4 is activated.
+    uint8_t instance5:1; //!< If true, Instance 5 is activated.
+    uint8_t instance6:1; //!< If true, Instance 6 is activated.
+    uint8_t instance7:1; //!< If true, Instance 7 is activated.
+    uint8_t instance8:1; //!< If true, Instance 8 is activated.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t instance8:1; //!< If true, Instance 8 is activated.
+    uint8_t instance7:1; //!< If true, Instance 7 is activated.
+    uint8_t instance6:1; //!< If true, Instance 6 is activated.
+    uint8_t instance5:1; //!< If true, Instance 5 is activated.
+    uint8_t instance4:1; //!< If true, Instance 4 is activated.
+    uint8_t instance3:1; //!< If true, Instance 3 is activated.
+    uint8_t instance2:1; //!< If true, Instance 2 is activated.
+    uint8_t instance1:1; //!< If true, Instance 1 is activated.
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t instance9:1;  //!< If true, Instance 9 is activated.
+    uint8_t instance10:1; //!< If true, Instance 10 is activated.
+    uint8_t instance11:1; //!< If true, Instance 11 is activated.
+    uint8_t instance12:1; //!< If true, Instance 12 is activated.
+    uint8_t instance13:1; //!< If true, Instance 13 is activated.
+    uint8_t instance14:1; //!< If true, Instance 14 is activated.
+    uint8_t instance15:1; //!< If true, Instance 15 is activated.
+    uint8_t instance16:1; //!< If true, Instance 16 is activated.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t instance16:1; //!< If true, Instance 16 is activated.
+    uint8_t instance15:1; //!< If true, Instance 15 is activated.
+    uint8_t instance14:1; //!< If true, Instance 14 is activated.
+    uint8_t instance13:1; //!< If true, Instance 13 is activated.
+    uint8_t instance12:1; //!< If true, Instance 12 is activated.
+    uint8_t instance11:1; //!< If true, Instance 11 is activated.
+    uint8_t instance10:1; //!< If true, Instance 10 is activated.
+    uint8_t instance9:1;  //!< If true, Instance 9 is activated.
+#endif
+} __attribute__((packed));
+
+/** @brief Get Payload Activation Status Command.
+ *
+ *  This command returns how many instances of a given payload type are
+ *  presently activated, and how many total instances can be activated.
+ *
+ *  @param[in] inPayload - Request Data for the command.
+ *  @param[in] handler - Reference to the Message Handler.
+ *
+ *  @return Response data for the command
+ */
+std::vector<uint8_t> getPayloadStatus(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler);
+
+/** @struct GetPayloadInfoRequest
+ *
+ *  IPMI payload for Get Payload Instance info command request.
+ */
+struct GetPayloadInfoRequest
+{
+    uint8_t payloadType;     //!< Payload type
+    uint8_t payloadInstance; //!< Payload instance
+} __attribute__((packed));
+
+/** @struct GetPayloadInfoResponse
+ *
+ *  IPMI payload for Get Payload Instance info command response.
+ */
+struct GetPayloadInfoResponse
+{
+    uint8_t completionCode; //!< Completion code.
+    uint32_t sessionID;     //!< Session ID
+    uint8_t portNumber;     //!< Port number
+    uint8_t reserved[7];    //!< Reserved
+} __attribute__((packed));
+
+/** @brief Get Payload Instance Info Command.
+ *
+ *  This command returns information about a specific instance of a payload
+ *  type. Session ID is returned by this command
+ *
+ *  @param[in] inPayload - Request Data for the command.
+ *  @param[in] handler - Reference to the Message Handler.
+ *
+ *  @return Response data for the command
+ */
+std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
+                                    std::shared_ptr<message::Handler>& handler);
+
+} // namespace command
+
+} // namespace sol
diff --git a/transport/rmcpbridge/command/rakp12.cpp b/transport/rmcpbridge/command/rakp12.cpp
new file mode 100644
index 0000000..5c674ac
--- /dev/null
+++ b/transport/rmcpbridge/command/rakp12.cpp
@@ -0,0 +1,331 @@
+#include "config.h"
+
+#include "rakp12.hpp"
+
+#include "comm_module.hpp"
+#include "endian.hpp"
+#include "guid.hpp"
+#include "sessions_manager.hpp"
+
+#include <openssl/rand.h>
+
+#include <ipmid/types.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <algorithm>
+#include <cstring>
+#include <iomanip>
+
+namespace command
+{
+
+bool isChannelAccessModeEnabled(const uint8_t accessMode)
+{
+    return accessMode !=
+           static_cast<uint8_t>(ipmi::EChannelAccessMode::disabled);
+}
+
+void logInvalidLoginRedfishEvent(const std::string& journalMsg,
+                                 const std::optional<std::string>& messageArgs)
+{
+    static constexpr std::string_view openBMCMessageRegistryVersion = "0.1.";
+    std::string messageID =
+        "OpenBMC." + std::string(openBMCMessageRegistryVersion) +
+        "InvalidLoginAttempted";
+    lg2::error(
+        "message: {MSG}, id: {REDFISH_MESSAGE_ID}, args: {REDFISH_MESSAGE_ARGS}",
+        "MSG", journalMsg, "REDFISH_MESSAGE_ID", messageID,
+        "REDFISH_MESSAGE_ARGS", messageArgs.value_or(std::string{}));
+}
+std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload,
+                            std::shared_ptr<message::Handler>& /* handler */)
+{
+    auto request = reinterpret_cast<const RAKP1request*>(inPayload.data());
+    // verify inPayload minimum size
+    if (inPayload.size() < (sizeof(*request) - userNameMaxLen))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(RAKP2response));
+    auto response = reinterpret_cast<RAKP2response*>(outPayload.data());
+
+    // Session ID zero is reserved for Session Setup
+    if (endian::from_ipmi(request->managedSystemSessionID) ==
+        session::sessionZero)
+    {
+        lg2::info("RAKP12: BMC invalid Session ID");
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
+        return outPayload;
+    }
+
+    std::shared_ptr<session::Session> session;
+    try
+    {
+        session = session::Manager::get().getSession(
+            endian::from_ipmi(request->managedSystemSessionID));
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("RAKP12 : session not found: {ERROR}", "ERROR", e);
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
+        return outPayload;
+    }
+
+    auto rakp1Size =
+        sizeof(RAKP1request) - (userNameMaxLen - request->user_name_len);
+
+    std::string message = "Invalid login attempted via RCMPP interface ";
+    // Validate user name length in the message
+    if (request->user_name_len > userNameMaxLen ||
+        inPayload.size() != rakp1Size)
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_NAME_LENGTH);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+
+    session->userName.assign(request->user_name, request->user_name_len);
+
+    // Update transaction time
+    session->updateLastTransactionTime();
+
+    auto rcSessionID = endian::to_ipmi(session->getRCSessionID());
+    auto bmcSessionID = endian::to_ipmi(session->getBMCSessionID());
+    auto authAlgo = session->getAuthAlgo();
+
+    /*
+     * Generate Key Authentication Code - RAKP 2
+     *
+     * 1) Remote Console Session ID - 4 bytes
+     * 2) Managed System Session ID - 4 bytes
+     * 3) Remote Console Random Number - 16 bytes
+     * 4) Managed System Random Number - 16 bytes
+     * 5) Managed System GUID - 16 bytes
+     * 6) Requested Privilege Level - 1 byte
+     * 7) User Name Length Byte - 1 byte (0 for 'null' username)
+     * 8) User Name - variable (absent for 'null' username)
+     */
+
+    std::vector<uint8_t> input;
+    input.resize(sizeof(rcSessionID) + sizeof(bmcSessionID) +
+                 cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN +
+                 cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN + BMC_GUID_LEN +
+                 sizeof(request->req_max_privilege_level) +
+                 sizeof(request->user_name_len) + session->userName.size());
+
+    auto iter = input.begin();
+
+    // Remote Console Session ID
+    std::copy_n(reinterpret_cast<uint8_t*>(&rcSessionID), sizeof(rcSessionID),
+                iter);
+    std::advance(iter, sizeof(rcSessionID));
+
+    // Managed System Session ID
+    std::copy_n(reinterpret_cast<uint8_t*>(&bmcSessionID), sizeof(bmcSessionID),
+                iter);
+    std::advance(iter, sizeof(bmcSessionID));
+
+    // Copy the Remote Console Random Number from the RAKP1 request to the
+    // Authentication Algorithm
+    std::copy_n(
+        reinterpret_cast<const uint8_t*>(request->remote_console_random_number),
+        cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN,
+        authAlgo->rcRandomNum.begin());
+
+    std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter);
+    std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN);
+
+    // Generate the Managed System Random Number
+    if (!RAND_bytes(input.data() + sizeof(rcSessionID) + sizeof(bmcSessionID) +
+                        cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN,
+                    cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN))
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
+        return outPayload;
+    }
+    // As stated in Set Session Privilege Level command in IPMI Spec, when
+    // creating a session through Activate command / RAKP 1 message, it must
+    // be established with USER privilege as well as all other sessions are
+    // initially set to USER privilege, regardless of the requested maximum
+    // privilege.
+    if (!(static_cast<session::Privilege>(
+              request->req_max_privilege_level & session::reqMaxPrivMask) >
+          session::Privilege::CALLBACK))
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_ROLE_PRIV);
+        return outPayload;
+    }
+    session->currentPrivilege(static_cast<uint8_t>(session::Privilege::USER));
+
+    session->reqMaxPrivLevel =
+        static_cast<session::Privilege>(request->req_max_privilege_level);
+    if (request->user_name_len == 0)
+    {
+        // Bail out, if user name is not specified.
+        // Yes, NULL user name is not supported for security reasons.
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+
+    // Perform user name based lookup
+    std::string userName(request->user_name, request->user_name_len);
+    ipmi::SecureString passwd;
+    uint8_t userId = ipmi::ipmiUserGetUserId(userName);
+    if (userId == ipmi::invalidUserId)
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+    // check user is enabled before proceeding.
+    bool userEnabled = false;
+    ipmi::ipmiUserCheckEnabled(userId, userEnabled);
+    if (!userEnabled)
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+    // Get the user password for RAKP message authenticate
+    passwd = ipmi::ipmiUserGetPassword(userName);
+    if (passwd.empty())
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+#ifdef PAM_AUTHENTICATE
+    // Check whether user is already locked for failed attempts
+    if (!ipmi::ipmiUserPamAuthenticate(userName, passwd))
+    {
+        lg2::error(
+            "Authentication failed - user already locked out, user id: {ID}",
+            "ID", userId);
+
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+#endif
+
+    uint8_t chNum = static_cast<uint8_t>(getInterfaceIndex());
+    // Get channel based access information
+    if ((ipmi::ipmiUserGetPrivilegeAccess(
+             userId, chNum, session->sessionUserPrivAccess) != IPMI_CC_OK) ||
+        (ipmi::getChannelAccessData(chNum, session->sessionChannelAccess) !=
+         IPMI_CC_OK))
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+    if (!isChannelAccessModeEnabled(session->sessionChannelAccess.accessMode))
+    {
+        lg2::error("Channel access mode disabled.");
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+    if (session->sessionUserPrivAccess.privilege >
+        static_cast<uint8_t>(session::Privilege::OEM))
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+    session->channelNum(chNum);
+    session->userID(userId);
+    // minimum privilege of Channel / User / session::privilege::USER
+    // has to be used as session current privilege level
+    uint8_t minPriv = 0;
+    if (session->sessionChannelAccess.privLimit <
+        session->sessionUserPrivAccess.privilege)
+    {
+        minPriv = session->sessionChannelAccess.privLimit;
+    }
+    else
+    {
+        minPriv = session->sessionUserPrivAccess.privilege;
+    }
+    if (session->currentPrivilege() > minPriv)
+    {
+        session->currentPrivilege(static_cast<uint8_t>(minPriv));
+    }
+    // For username / privilege lookup, fail with UNAUTH_NAME, if requested
+    // max privilege does not match user privilege
+    if (((request->req_max_privilege_level & userNameOnlyLookupMask) ==
+         userNamePrivLookup) &&
+        ((request->req_max_privilege_level & session::reqMaxPrivMask) !=
+         session->sessionUserPrivAccess.privilege))
+    {
+        lg2::info("Username/Privilege lookup failed for requested privilege");
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
+
+        logInvalidLoginRedfishEvent(message);
+        return outPayload;
+    }
+
+    std::fill(authAlgo->userKey.data(),
+              authAlgo->userKey.data() + authAlgo->userKey.size(), 0);
+    std::copy_n(passwd.c_str(), passwd.size(), authAlgo->userKey.data());
+
+    // Copy the Managed System Random Number to the Authentication Algorithm
+    std::copy_n(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN,
+                authAlgo->bmcRandomNum.begin());
+    std::advance(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN);
+
+    // Managed System GUID
+    const Guid& guid = command::getSystemGUID();
+    std::copy_n(guid.data(), guid.size(), iter);
+    std::advance(iter, BMC_GUID_LEN);
+
+    // Requested Privilege Level
+    std::copy_n(&(request->req_max_privilege_level),
+                sizeof(request->req_max_privilege_level), iter);
+    std::advance(iter, sizeof(request->req_max_privilege_level));
+
+    // User Name Length Byte
+    std::copy_n(&(request->user_name_len), sizeof(request->user_name_len),
+                iter);
+    std::advance(iter, sizeof(request->user_name_len));
+
+    std::copy_n(session->userName.data(), session->userName.size(), iter);
+
+    // Generate Key Exchange Authentication Code - RAKP2
+    auto output = authAlgo->generateHMAC(input);
+
+    response->messageTag = request->messageTag;
+    response->rmcpStatusCode = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
+    response->reserved = 0;
+    response->remoteConsoleSessionID = rcSessionID;
+
+    // Copy Managed System Random Number to the Response
+    std::copy(authAlgo->bmcRandomNum.begin(), authAlgo->bmcRandomNum.end(),
+              response->managed_system_random_number);
+
+    // Copy System GUID to the Response
+    std::copy_n(guid.data(), guid.size(), response->managed_system_guid);
+
+    // Insert the HMAC output into the payload
+    outPayload.insert(outPayload.end(), output.begin(), output.end());
+    return outPayload;
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/rakp12.hpp b/transport/rmcpbridge/command/rakp12.hpp
new file mode 100644
index 0000000..e2eebc2
--- /dev/null
+++ b/transport/rmcpbridge/command/rakp12.hpp
@@ -0,0 +1,87 @@
+#pragma once
+
+#include "comm_module.hpp"
+#include "message_handler.hpp"
+
+#include <cstddef>
+#include <vector>
+
+namespace command
+{
+
+constexpr size_t userNameMaxLen = 16;
+
+constexpr uint8_t userNameOnlyLookupMask = 0x10;
+constexpr uint8_t userNameOnlyLookup = 0x10;
+constexpr uint8_t userNamePrivLookup = 0x0;
+
+/**
+ * @struct RAKP1request
+ *
+ * IPMI Payload for RAKP Message 1
+ */
+struct RAKP1request
+{
+    uint8_t messageTag;
+    uint8_t reserved1;
+    uint16_t reserved2;
+    uint32_t managedSystemSessionID;
+    uint8_t remote_console_random_number[16];
+    uint8_t req_max_privilege_level;
+    uint16_t reserved3;
+    uint8_t user_name_len;
+    char user_name[userNameMaxLen];
+} __attribute__((packed));
+
+/**
+ * @struct RAKP2response
+ *
+ * IPMI Payload for RAKP Message 2
+ */
+struct RAKP2response
+{
+    uint8_t messageTag;
+    uint8_t rmcpStatusCode;
+    uint16_t reserved;
+    uint32_t remoteConsoleSessionID;
+    uint8_t managed_system_random_number[16];
+    uint8_t managed_system_guid[16];
+} __attribute__((packed));
+
+/**
+ * @brief RAKP Message 1, RAKP Message 2
+ *
+ * These messages are used to exchange random number and identification
+ * information between the BMC and the remote console that are, in effect,
+ * mutual challenges for a challenge/response. (Unlike IPMI v1.5, the v2.0/RMCP+
+ * challenge/response is symmetric. I.e. the remote console and BMC both issues
+ * challenges,and both need to provide valid responses for the session to be
+ * activated.)
+ *
+ * The remote console request (RAKP Message 1) passes a random number and
+ * username/privilege information that the BMC will later use to ‘sign’ a
+ * response message based on key information associated with the user and the
+ * Authentication Algorithm negotiated in the Open Session Request/Response
+ * exchange. The BMC responds with RAKP Message 2 and passes a random number and
+ * GUID (globally unique ID) for the managed system that the remote console
+ * uses according the Authentication Algorithm to sign a response back to the
+ * BMC.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload,
+                            std::shared_ptr<message::Handler>& handler);
+/**
+ *@brief Log Redfish event for invalid login attempted on RMCPP interface
+ *
+ * @param[in] journalMsg - Show journal Debug Message in journal logs
+ * @param[in] redfishMsg - Log Redfish Event Message
+ *
+ */
+void logInvalidLoginRedfishEvent(
+    const std::string& journalMsg,
+    const std::optional<std::string>& messageArgs = "RMCPP");
+} // namespace command
diff --git a/transport/rmcpbridge/command/rakp34.cpp b/transport/rmcpbridge/command/rakp34.cpp
new file mode 100644
index 0000000..7735d8d
--- /dev/null
+++ b/transport/rmcpbridge/command/rakp34.cpp
@@ -0,0 +1,273 @@
+#include "rakp34.hpp"
+
+#include "comm_module.hpp"
+#include "endian.hpp"
+#include "guid.hpp"
+#include "rmcp.hpp"
+#include "sessions_manager.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <algorithm>
+#include <cstring>
+
+namespace command
+{
+
+void applyIntegrityAlgo(const uint32_t bmcSessionID)
+{
+    auto session = session::Manager::get().getSession(bmcSessionID);
+
+    auto authAlgo = session->getAuthAlgo();
+
+    switch (authAlgo->intAlgo)
+    {
+        case cipher::integrity::Algorithms::HMAC_SHA1_96:
+        {
+            session->setIntegrityAlgo(
+                std::make_unique<cipher::integrity::AlgoSHA1>(
+                    authAlgo->sessionIntegrityKey));
+            break;
+        }
+        case cipher::integrity::Algorithms::HMAC_SHA256_128:
+        {
+            session->setIntegrityAlgo(
+                std::make_unique<cipher::integrity::AlgoSHA256>(
+                    authAlgo->sessionIntegrityKey));
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+void applyCryptAlgo(const uint32_t bmcSessionID)
+{
+    auto session = session::Manager::get().getSession(bmcSessionID);
+
+    auto authAlgo = session->getAuthAlgo();
+
+    switch (authAlgo->cryptAlgo)
+    {
+        case cipher::crypt::Algorithms::AES_CBC_128:
+        {
+            auto intAlgo = session->getIntegrityAlgo();
+            auto k2 = intAlgo->generateKn(authAlgo->sessionIntegrityKey,
+                                          rmcp::const_2);
+            session->setCryptAlgo(
+                std::make_unique<cipher::crypt::AlgoAES128>(k2));
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload,
+                            std::shared_ptr<message::Handler>& /* handler */)
+{
+    std::vector<uint8_t> outPayload(sizeof(RAKP4response));
+    auto request = reinterpret_cast<const RAKP3request*>(inPayload.data());
+    auto response = reinterpret_cast<RAKP4response*>(outPayload.data());
+
+    // Check if the RAKP3 Payload Length is as expected
+    if (inPayload.size() < sizeof(RAKP3request))
+    {
+        lg2::info("RAKP34: Invalid RAKP3 request");
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_VALUE);
+        return outPayload;
+    }
+
+    // Session ID zero is reserved for Session Setup
+    if (endian::from_ipmi(request->managedSystemSessionID) ==
+        session::sessionZero)
+    {
+        lg2::info("RAKP34: BMC invalid Session ID");
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
+        return outPayload;
+    }
+
+    std::shared_ptr<session::Session> session;
+    try
+    {
+        session =
+            session::Manager::get().getSession(request->managedSystemSessionID);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("RAKP12 : session not found: {ERROR}", "ERROR", e);
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
+        return outPayload;
+    }
+
+    session->updateLastTransactionTime();
+
+    auto authAlgo = session->getAuthAlgo();
+    /*
+     * Key Authentication Code - RAKP 3
+     *
+     * 1) Managed System Random Number - 16 bytes
+     * 2) Remote Console Session ID - 4 bytes
+     * 3) Session Privilege Level - 1 byte
+     * 4) User Name Length Byte - 1 byte (0 for 'null' username)
+     * 5) User Name - variable (absent for 'null' username)
+     */
+
+    // Remote Console Session ID
+    auto rcSessionID = endian::to_ipmi(session->getRCSessionID());
+
+    // Session Privilege Level
+    auto sessPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel);
+
+    // User Name Length Byte
+    auto userLength = static_cast<uint8_t>(session->userName.size());
+
+    std::vector<uint8_t> input;
+    input.resize(cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN +
+                 sizeof(rcSessionID) + sizeof(sessPrivLevel) +
+                 sizeof(userLength) + userLength);
+
+    auto iter = input.begin();
+
+    // Managed System Random Number
+    std::copy(authAlgo->bmcRandomNum.begin(), authAlgo->bmcRandomNum.end(),
+              iter);
+    std::advance(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN);
+
+    // Remote Console Session ID
+    std::copy_n(reinterpret_cast<uint8_t*>(&rcSessionID), sizeof(rcSessionID),
+                iter);
+    std::advance(iter, sizeof(rcSessionID));
+
+    // Session Privilege Level
+    std::copy_n(reinterpret_cast<uint8_t*>(&sessPrivLevel),
+                sizeof(sessPrivLevel), iter);
+    std::advance(iter, sizeof(sessPrivLevel));
+
+    // User Name Length Byte
+    std::copy_n(&userLength, sizeof(userLength), iter);
+    std::advance(iter, sizeof(userLength));
+
+    std::copy_n(session->userName.data(), userLength, iter);
+
+    // Generate Key Exchange Authentication Code - RAKP2
+    auto output = authAlgo->generateHMAC(input);
+
+    if (inPayload.size() != (sizeof(RAKP3request) + output.size()) ||
+        std::memcmp(output.data(), request + 1, output.size()))
+    {
+        lg2::info("Mismatch in HMAC sent by remote console");
+
+        response->messageTag = request->messageTag;
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_VALUE);
+        response->reserved = 0;
+        response->remoteConsoleSessionID = rcSessionID;
+
+        // close the session
+        session::Manager::get().stopSession(session->getBMCSessionID());
+
+        return outPayload;
+    }
+
+    /*
+     * Session Integrity Key
+     *
+     * 1) Remote Console Random Number - 16 bytes
+     * 2) Managed System Random Number - 16 bytes
+     * 3) Session Privilege Level - 1 byte
+     * 4) User Name Length Byte - 1 byte (0 for 'null' username)
+     * 5) User Name - variable (absent for 'null' username)
+     */
+
+    input.clear();
+
+    input.resize(cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN +
+                 cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN +
+                 sizeof(sessPrivLevel) + sizeof(userLength) + userLength);
+    iter = input.begin();
+
+    // Remote Console Random Number
+    std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter);
+    std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN);
+
+    // Managed Console Random Number
+    std::copy(authAlgo->bmcRandomNum.begin(), authAlgo->bmcRandomNum.end(),
+              iter);
+    std::advance(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN);
+
+    // Session Privilege Level
+    std::copy_n(reinterpret_cast<uint8_t*>(&sessPrivLevel),
+                sizeof(sessPrivLevel), iter);
+    std::advance(iter, sizeof(sessPrivLevel));
+
+    // User Name Length Byte
+    std::copy_n(&userLength, sizeof(userLength), iter);
+    std::advance(iter, sizeof(userLength));
+
+    std::copy_n(session->userName.data(), userLength, iter);
+
+    // Generate Session Integrity Key
+    auto sikOutput = authAlgo->generateHMAC(input);
+
+    // Update the SIK in the Authentication Algo Interface
+    authAlgo->sessionIntegrityKey.insert(authAlgo->sessionIntegrityKey.begin(),
+                                         sikOutput.begin(), sikOutput.end());
+
+    /*
+     * Integrity Check Value
+     *
+     * 1) Remote Console Random Number - 16 bytes
+     * 2) Managed System Session ID - 4 bytes
+     * 3) Managed System GUID - 16 bytes
+     */
+
+    // Get Managed System Session ID
+    auto bmcSessionID = endian::to_ipmi(session->getBMCSessionID());
+
+    input.clear();
+
+    input.resize(cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN +
+                 sizeof(bmcSessionID) + BMC_GUID_LEN);
+    iter = input.begin();
+
+    // Remote Console Random Number
+    std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter);
+    std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN);
+
+    // Managed System Session ID
+    std::copy_n(reinterpret_cast<uint8_t*>(&bmcSessionID), sizeof(bmcSessionID),
+                iter);
+    std::advance(iter, sizeof(bmcSessionID));
+
+    // Managed System GUID
+    const Guid& guid = command::getSystemGUID();
+    std::copy_n(guid.data(), guid.size(), iter);
+
+    // Integrity Check Value
+    auto icv = authAlgo->generateICV(input);
+
+    outPayload.resize(sizeof(RAKP4response));
+
+    response->messageTag = request->messageTag;
+    response->rmcpStatusCode = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
+    response->reserved = 0;
+    response->remoteConsoleSessionID = rcSessionID;
+
+    // Insert the HMAC output into the payload
+    outPayload.insert(outPayload.end(), icv.begin(), icv.end());
+
+    // Set the Integrity Algorithm
+    applyIntegrityAlgo(session->getBMCSessionID());
+
+    // Set the Confidentiality Algorithm
+    applyCryptAlgo(session->getBMCSessionID());
+
+    session->state(static_cast<uint8_t>(session::State::active));
+    return outPayload;
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/rakp34.hpp b/transport/rmcpbridge/command/rakp34.hpp
new file mode 100644
index 0000000..7b29d70
--- /dev/null
+++ b/transport/rmcpbridge/command/rakp34.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "comm_module.hpp"
+#include "message_handler.hpp"
+
+#include <vector>
+
+namespace command
+{
+
+/**
+ * @struct RAKP3request
+ *
+ * IPMI Payload for RAKP Message 3
+ */
+struct RAKP3request
+{
+    uint8_t messageTag;
+    uint8_t rmcpStatusCode;
+    uint16_t reserved;
+    uint32_t managedSystemSessionID;
+} __attribute__((packed));
+
+/**
+ * @struct RAKP4response
+ *
+ * IPMI Payload for RAKP Message 4
+ */
+struct RAKP4response
+{
+    uint8_t messageTag;
+    uint8_t rmcpStatusCode;
+    uint16_t reserved;
+    uint32_t remoteConsoleSessionID;
+} __attribute__((packed));
+
+/**
+ * @brief RAKP Message 3, RAKP Message 4
+ *
+ * The session activation process is completed by the remote console and BMC
+ * exchanging messages that are signed according to the Authentication Algorithm
+ * that was negotiated, and the parameters that were passed in the earlier
+ * messages. RAKP Message 3 is the signed message from the remote console to the
+ * BMC. After receiving RAKP Message 3, the BMC returns RAKP Message 4 - a
+ * signed message from BMC to the remote console.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload,
+                            std::shared_ptr<message::Handler>& handler);
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/session_cmds.cpp b/transport/rmcpbridge/command/session_cmds.cpp
new file mode 100644
index 0000000..5ee7f8f
--- /dev/null
+++ b/transport/rmcpbridge/command/session_cmds.cpp
@@ -0,0 +1,328 @@
+#include "session_cmds.hpp"
+
+#include "endian.hpp"
+#include "sessions_manager.hpp"
+
+#include <ipmid/api.h>
+
+#include <ipmid/sessionhelper.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <chrono>
+
+using namespace std::chrono_literals;
+
+namespace command
+{
+
+std::vector<uint8_t> setSessionPrivilegeLevel(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler)
+{
+    auto request =
+        reinterpret_cast<const SetSessionPrivLevelReq*>(inPayload.data());
+    if (inPayload.size() != sizeof(*request))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+    if (request->reserved != 0)
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_INVALID_FIELD_REQUEST};
+        return errorPayload;
+    }
+
+    std::vector<uint8_t> outPayload(sizeof(SetSessionPrivLevelResp));
+    auto response =
+        reinterpret_cast<SetSessionPrivLevelResp*>(outPayload.data());
+    response->completionCode = IPMI_CC_OK;
+    uint8_t reqPrivilegeLevel = request->reqPrivLevel;
+
+    auto session = session::Manager::get().getSession(handler->sessionID);
+
+    if (reqPrivilegeLevel == 0) // Just return present privilege level
+    {
+        response->newPrivLevel = session->currentPrivilege();
+        return outPayload;
+    }
+    if (reqPrivilegeLevel ==
+            static_cast<uint8_t>(session::Privilege::CALLBACK) ||
+        reqPrivilegeLevel > static_cast<uint8_t>(session::Privilege::OEM))
+    {
+        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        return outPayload;
+    }
+
+    if (reqPrivilegeLevel > (static_cast<uint8_t>(session->reqMaxPrivLevel) &
+                             session::reqMaxPrivMask))
+    {
+        // Requested level exceeds Channel and/or User Privilege Limit
+        response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV;
+        return outPayload;
+    }
+    // Use the minimum privilege of user or channel
+    uint8_t minPriv = 0;
+    if (session->sessionChannelAccess.privLimit <
+        session->sessionUserPrivAccess.privilege)
+    {
+        minPriv = session->sessionChannelAccess.privLimit;
+    }
+    else
+    {
+        minPriv = session->sessionUserPrivAccess.privilege;
+    }
+    if (reqPrivilegeLevel > minPriv)
+    {
+        // Requested level exceeds Channel and/or User Privilege Limit
+        response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV;
+    }
+    else
+    {
+        // update current privilege of the session.
+        session->currentPrivilege(static_cast<uint8_t>(reqPrivilegeLevel));
+        response->newPrivLevel = reqPrivilegeLevel;
+    }
+
+    return outPayload;
+}
+
+/**
+ * @brief set the session state as teardown
+ *
+ * This function is to set the session state to tear down in progress if the
+ * state is active.
+ *
+ * @param[in] busp - Dbus obj
+ * @param[in] service - service name
+ * @param[in] obj - object path
+ *
+ * @return success completion code if it sets the session state to
+ * tearDownInProgress else return the corresponding error completion code.
+ **/
+uint8_t setSessionState(std::shared_ptr<sdbusplus::asio::connection>& busp,
+                        const std::string& service, const std::string& obj)
+{
+    try
+    {
+        uint8_t sessionState = std::get<uint8_t>(ipmi::getDbusProperty(
+            *busp, service, obj, session::sessionIntf, "State"));
+
+        if (sessionState == static_cast<uint8_t>(session::State::active))
+        {
+            ipmi::setDbusProperty(
+                *busp, service, obj, session::sessionIntf, "State",
+                static_cast<uint8_t>(session::State::tearDownInProgress));
+            return ipmi::ccSuccess;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "Failed in getting session state property: {SERVICE}, {PATH}, {INTERFACE}",
+            "SERVICE", service, "PATH", obj, "INTERFACE", session::sessionIntf);
+        return ipmi::ccUnspecifiedError;
+    }
+
+    return ipmi::ccInvalidFieldRequest;
+}
+
+uint8_t closeOtherNetInstanceSession(const uint32_t reqSessionId,
+                                     const uint8_t reqSessionHandle,
+                                     const uint8_t currentSessionPriv)
+{
+    auto busp = getSdBus();
+
+    try
+    {
+        ipmi::ObjectTree objectTree = ipmi::getAllDbusObjects(
+            *busp, session::sessionManagerRootPath, session::sessionIntf);
+
+        for (auto& objectTreeItr : objectTree)
+        {
+            const std::string obj = objectTreeItr.first;
+
+            if (isSessionObjectMatched(obj, reqSessionId, reqSessionHandle))
+            {
+                auto& serviceMap = objectTreeItr.second;
+
+                if (serviceMap.size() != 1)
+                {
+                    return ipmi::ccUnspecifiedError;
+                }
+
+                auto itr = serviceMap.begin();
+                const std::string service = itr->first;
+                uint8_t closeSessionPriv = std::get<uint8_t>(
+                    ipmi::getDbusProperty(*busp, service, obj,
+                                          session::sessionIntf,
+                                          "CurrentPrivilege"));
+
+                if (currentSessionPriv < closeSessionPriv)
+                {
+                    return ipmi::ccInsufficientPrivilege;
+                }
+                return setSessionState(busp, service, obj);
+            }
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error(
+            "Failed to fetch object from dbus, interface: {INTERFACE}, error: {ERROR}",
+            "INTERFACE", session::sessionIntf, "ERROR", e);
+        return ipmi::ccUnspecifiedError;
+    }
+
+    return ipmi::ccInvalidFieldRequest;
+}
+
+uint8_t closeMyNetInstanceSession(uint32_t reqSessionId,
+                                  uint8_t reqSessionHandle,
+                                  const uint8_t currentSessionPriv)
+{
+    bool status = false;
+
+    try
+    {
+        if (reqSessionId == session::sessionZero)
+        {
+            reqSessionId = session::Manager::get().getSessionIDbyHandle(
+                reqSessionHandle & session::multiIntfaceSessionHandleMask);
+            if (!reqSessionId)
+            {
+                return session::ccInvalidSessionHandle;
+            }
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "Failed to get session manager instance or sessionID by sessionHandle: {ERROR}",
+            "ERROR", e);
+        return session::ccInvalidSessionHandle;
+    }
+
+    try
+    {
+        auto closeSessionInstance =
+            session::Manager::get().getSession(reqSessionId);
+        uint8_t closeSessionPriv = closeSessionInstance->currentPrivilege();
+
+        if (currentSessionPriv < closeSessionPriv)
+        {
+            return ipmi::ccInsufficientPrivilege;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "Failed to get session manager instance or sessionID: {ERROR}",
+            "ERROR", e);
+        return session::ccInvalidSessionId;
+    }
+
+    try
+    {
+        status = session::Manager::get().stopSession(reqSessionId);
+
+        if (!status)
+        {
+            return session::ccInvalidSessionId;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "Failed to get session manager instance or stop session: {ERROR}",
+            "ERROR", e);
+        return ipmi::ccUnspecifiedError;
+    }
+
+    return ipmi::ccSuccess;
+}
+
+std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload,
+                                  std::shared_ptr<message::Handler>& handler)
+{
+    // minimum inPayload size is reqSessionId (uint32_t)
+    // maximum inPayload size is struct CloseSessionRequest
+    if (inPayload.size() != sizeof(uint32_t) &&
+        inPayload.size() != sizeof(CloseSessionRequest))
+    {
+        std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
+        return errorPayload;
+    }
+
+    auto request =
+        reinterpret_cast<const CloseSessionRequest*>(inPayload.data());
+
+    std::vector<uint8_t> outPayload(sizeof(CloseSessionResponse));
+    auto response = reinterpret_cast<CloseSessionResponse*>(outPayload.data());
+    uint32_t reqSessionId = request->sessionID;
+    uint8_t ipmiNetworkInstance = 0;
+    uint8_t currentSessionPriv = 0;
+    uint8_t reqSessionHandle = session::invalidSessionHandle;
+
+    if (inPayload.size() == sizeof(CloseSessionRequest))
+    {
+        reqSessionHandle = request->sessionHandle;
+    }
+
+    if (reqSessionId == session::sessionZero &&
+        reqSessionHandle == session::invalidSessionHandle)
+    {
+        response->completionCode = session::ccInvalidSessionHandle;
+        return outPayload;
+    }
+
+    if (inPayload.size() == sizeof(reqSessionId) &&
+        reqSessionId == session::sessionZero)
+    {
+        response->completionCode = session::ccInvalidSessionId;
+        return outPayload;
+    }
+
+    if (reqSessionId != session::sessionZero &&
+        inPayload.size() != sizeof(reqSessionId))
+    {
+        response->completionCode = ipmi::ccInvalidFieldRequest;
+        return outPayload;
+    }
+
+    try
+    {
+        ipmiNetworkInstance = session::Manager::get().getNetworkInstance();
+        auto currentSession =
+            session::Manager::get().getSession(handler->sessionID);
+        currentSessionPriv = currentSession->currentPrivilege();
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error(
+            "Failed to fetch object from dbus, interface: {INTERFACE}, error: {ERROR}",
+            "INTERFACE", session::sessionIntf, "ERROR", e);
+        response->completionCode = ipmi::ccUnspecifiedError;
+        return outPayload;
+    }
+
+    if (reqSessionId >> myNetInstanceSessionIdShiftMask ==
+            ipmiNetworkInstance ||
+        (reqSessionId == session::sessionZero &&
+         (reqSessionHandle >> myNetInstanceSessionHandleShiftMask ==
+          ipmiNetworkInstance)))
+    {
+        response->completionCode = closeMyNetInstanceSession(
+            reqSessionId, reqSessionHandle, currentSessionPriv);
+        session::Manager::get().scheduleSessionCleaner(100us);
+    }
+    else
+    {
+        response->completionCode = closeOtherNetInstanceSession(
+            reqSessionId, reqSessionHandle, currentSessionPriv);
+    }
+
+    return outPayload;
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/session_cmds.hpp b/transport/rmcpbridge/command/session_cmds.hpp
new file mode 100644
index 0000000..b94143e
--- /dev/null
+++ b/transport/rmcpbridge/command/session_cmds.hpp
@@ -0,0 +1,119 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <vector>
+
+namespace command
+{
+
+constexpr uint8_t IPMI_CC_INVALID_PRIV_LEVEL = 0x80;
+constexpr uint8_t IPMI_CC_EXCEEDS_USER_PRIV = 0x81;
+// bits 30 & 31 (MSB) hold the instanceID, hence shifting by 30 bits
+constexpr uint8_t myNetInstanceSessionIdShiftMask = 30;
+// bits 6 & 7 (MSB) hold the instanceID, hence shifting by 6 bits
+constexpr uint8_t myNetInstanceSessionHandleShiftMask = 6;
+
+/**
+ * @struct SetSessionPrivLevelReq
+ *
+ * IPMI Request data for Set Session Privilege Level command
+ */
+struct SetSessionPrivLevelReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t reqPrivLevel:4;
+    uint8_t reserved:4;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved:4;
+    uint8_t reqPrivLevel:4;
+#endif
+
+} __attribute__((packed));
+
+/**
+ * @struct SetSessionPrivLevelResp
+ *
+ * IPMI Response data for Set Session Privilege Level command
+ */
+struct SetSessionPrivLevelResp
+{
+    uint8_t completionCode;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t newPrivLevel:4;
+    uint8_t reserved:4;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved:4;
+    uint8_t newPrivLevel:4;
+#endif
+
+} __attribute__((packed));
+
+/**
+ * @brief Set Session Privilege Command
+ *
+ * This command is sent in authenticated format. When a session is activated,
+ * the session is set to an initial privilege level. A session that is
+ * activated at a maximum privilege level of Callback is set to an initial
+ * privilege level of Callback and cannot be changed. All other sessions are
+ * initially set to USER level, regardless of the maximum privilege level
+ * requested in the RAKP Message 1.
+ *
+ * This command cannot be used to set a privilege level higher than the lowest
+ * of the privilege level set for the user(via the Set User Access command) and
+ * the privilege limit for the channel that was set via the Set Channel Access
+ * command.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> setSessionPrivilegeLevel(
+    const std::vector<uint8_t>& inPayload,
+    std::shared_ptr<message::Handler>& handler);
+/**
+ * @struct CloseSessionRequest
+ *
+ * IPMI Request data for Close Session command
+ */
+struct CloseSessionRequest
+{
+    uint32_t sessionID;
+    uint8_t sessionHandle;
+} __attribute__((packed));
+
+/**
+ * @struct CloseSessionResponse
+ *
+ * IPMI Response data for Close Session command
+ */
+struct CloseSessionResponse
+{
+    uint8_t completionCode;
+} __attribute__((packed));
+
+/**
+ * @brief Close Session Command
+ *
+ * This command is used to immediately terminate a session in progress. It is
+ * typically used to close the session that the user is communicating over,
+ * though it can be used to other terminate sessions in progress (provided that
+ * the user is operating at the appropriate privilege level, or the command is
+ * executed over a local channel - e.g. the system interface). Closing
+ * sessionless session ( session zero) is restricted in this command
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload,
+                                  std::shared_ptr<message::Handler>& handler);
+
+} // namespace command
diff --git a/transport/rmcpbridge/command/sol_cmds.cpp b/transport/rmcpbridge/command/sol_cmds.cpp
new file mode 100644
index 0000000..9bb92ce
--- /dev/null
+++ b/transport/rmcpbridge/command/sol_cmds.cpp
@@ -0,0 +1,74 @@
+#include "sol_cmds.hpp"
+
+#include "sessions_manager.hpp"
+#include "sol/sol_context.hpp"
+#include "sol/sol_manager.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace sol
+{
+
+namespace command
+{
+
+using namespace phosphor::logging;
+
+std::vector<uint8_t> payloadHandler(const std::vector<uint8_t>& inPayload,
+                                    std::shared_ptr<message::Handler>& handler)
+{
+    // Check inPayload size is at least Payload
+    if (inPayload.size() < sizeof(Payload))
+    {
+        return std::vector<uint8_t>();
+    }
+
+    auto request = reinterpret_cast<const Payload*>(inPayload.data());
+    auto solDataSize = inPayload.size() - sizeof(Payload);
+
+    std::vector<uint8_t> charData(solDataSize);
+    if (solDataSize > 0)
+    {
+        std::copy_n(inPayload.data() + sizeof(Payload), solDataSize,
+                    charData.begin());
+    }
+
+    try
+    {
+        auto& context = sol::Manager::get().getContext(handler->sessionID);
+
+        context.processInboundPayload(
+            request->packetSeqNum, request->packetAckSeqNum,
+            request->acceptedCharCount, request->inOperation.ack,
+            request->inOperation.generateBreak, charData);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to call the getContext method: {ERROR}", "ERROR", e);
+        return std::vector<uint8_t>();
+    }
+
+    return std::vector<uint8_t>();
+}
+
+void activating(uint8_t payloadInstance, uint32_t sessionID)
+{
+    std::vector<uint8_t> outPayload(sizeof(ActivatingRequest));
+
+    auto request = reinterpret_cast<ActivatingRequest*>(outPayload.data());
+
+    request->sessionState = 0;
+    request->payloadInstance = payloadInstance;
+    request->majorVersion = MAJOR_VERSION;
+    request->minorVersion = MINOR_VERSION;
+
+    auto session = session::Manager::get().getSession(sessionID);
+
+    message::Handler msgHandler(session->channelPtr, sessionID);
+
+    msgHandler.sendUnsolicitedIPMIPayload(netfnTransport, solActivatingCmd,
+                                          outPayload);
+}
+} // namespace command
+
+} // namespace sol
diff --git a/transport/rmcpbridge/command/sol_cmds.hpp b/transport/rmcpbridge/command/sol_cmds.hpp
new file mode 100644
index 0000000..b18b292
--- /dev/null
+++ b/transport/rmcpbridge/command/sol_cmds.hpp
@@ -0,0 +1,67 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <vector>
+
+namespace sol
+{
+
+namespace command
+{
+
+/** @brief SOL Payload Handler
+ *
+ *  This command is used for activating and deactivating a payload type under a
+ *  given IPMI session. The UDP Port number for SOL is the same as the port that
+ *  was used to establish the IPMI session.
+ *
+ *  @param[in] inPayload - Request data for the command.
+ *  @param[in] handler - Reference to the message handler.
+ *
+ *  @return Response data for the command.
+ */
+std::vector<uint8_t> payloadHandler(const std::vector<uint8_t>& inPayload,
+                                    std::shared_ptr<message::Handler>& handler);
+
+constexpr uint8_t netfnTransport = 0x0C;
+constexpr uint8_t solActivatingCmd = 0x20;
+
+/** @struct ActivatingRequest
+ *
+ *  IPMI payload for SOL Activating command.
+ */
+struct ActivatingRequest
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t sessionState:4; //!< SOL session state.
+    uint8_t reserved:4;     //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved:4;     //!< Reserved.
+    uint8_t sessionState:4; //!< SOL session state.
+#endif
+
+    uint8_t payloadInstance; //!< Payload instance.
+    uint8_t majorVersion;    //!< SOL format major version
+    uint8_t minorVersion;    //!< SOL format minor version
+} __attribute__((packed));
+
+/** @brief SOL Activating Command.
+ *
+ *  This command provides a mechanism for the BMC to notify a remote application
+ *  that a SOL payload is activating on another channel.The request message is a
+ *  message that is asynchronously generated by the BMC. The BMC will not wait
+ *  for a response from the remote console before dropping the serial connection
+ *  to proceed with SOL, therefore the remote console does not need to respond
+ *  to this command.
+ *
+ *  @param[in] payloadInstance - SOL payload instance.
+ *  @param[in] sessionID - IPMI session ID.
+ */
+void activating(uint8_t payloadInstance, uint32_t sessionID);
+
+} // namespace command
+
+} // namespace sol
diff --git a/transport/rmcpbridge/command_table.cpp b/transport/rmcpbridge/command_table.cpp
new file mode 100644
index 0000000..9880bc0
--- /dev/null
+++ b/transport/rmcpbridge/command_table.cpp
@@ -0,0 +1,161 @@
+#include "command_table.hpp"
+
+#include "main.hpp"
+#include "message_handler.hpp"
+#include "message_parsers.hpp"
+#include "sessions_manager.hpp"
+
+#include <ipmid/types.hpp>
+#include <main.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <user_channel/user_layer.hpp>
+
+#include <iomanip>
+
+namespace command
+{
+
+void Table::registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry)
+{
+    auto& command = commandTable[inCommand.command];
+
+    if (command)
+    {
+        lg2::debug("Already Registered: {COMMAND}", "COMMAND",
+                   inCommand.command);
+        return;
+    }
+
+    command = std::move(entry);
+}
+
+void Table::executeCommand(uint32_t inCommand,
+                           std::vector<uint8_t>& commandData,
+                           std::shared_ptr<message::Handler> handler)
+{
+    using namespace std::chrono_literals;
+
+    auto iterator = commandTable.find(inCommand);
+
+    if (iterator == commandTable.end())
+    {
+        CommandID command(inCommand);
+
+        // Do not forward any session zero commands to ipmid
+        if (handler->sessionID == session::sessionZero)
+        {
+            lg2::info(
+                "Table: refuse to forward session-zero command: lun: {LUN}, netFn: {NETFN}, command: {COMMAND}",
+                "LUN", command.lun(), "NETFN", command.netFn(), "COMMAND",
+                command.cmd());
+            return;
+        }
+        std::shared_ptr<session::Session> session =
+            session::Manager::get().getSession(handler->sessionID);
+
+        // Ignore messages that are not part of an active session
+        auto state = static_cast<session::State>(session->state());
+        if (state != session::State::active)
+        {
+            return;
+        }
+
+        auto bus = getSdBus();
+        // forward the request onto the main ipmi queue
+        using IpmiDbusRspType = std::tuple<uint8_t, uint8_t, uint8_t, uint8_t,
+                                           std::vector<uint8_t>>;
+        uint8_t lun = command.lun();
+        uint8_t netFn = command.netFn();
+        uint8_t cmd = command.cmd();
+
+        std::map<std::string, ipmi::Value> options = {
+            {"userId", ipmi::Value(static_cast<int>(
+                           ipmi::ipmiUserGetUserId(session->userName)))},
+            {"privilege",
+             ipmi::Value(static_cast<int>(session->currentPrivilege()))},
+            {"currentSessionId",
+             ipmi::Value(static_cast<uint32_t>(session->getBMCSessionID()))},
+        };
+        bus->async_method_call(
+            [handler](const boost::system::error_code& ec,
+                      const IpmiDbusRspType& response) {
+                if (!ec)
+                {
+                    const uint8_t& cc = std::get<3>(response);
+                    const std::vector<uint8_t>& responseData =
+                        std::get<4>(response);
+                    std::vector<uint8_t> payload;
+                    payload.reserve(1 + responseData.size());
+                    payload.push_back(cc);
+                    payload.insert(payload.end(), responseData.begin(),
+                                   responseData.end());
+                    handler->outPayload = std::move(payload);
+                }
+                else
+                {
+                    std::vector<uint8_t> payload;
+                    payload.push_back(IPMI_CC_UNSPECIFIED_ERROR);
+                    handler->outPayload = std::move(payload);
+                }
+            },
+            "xyz.openbmc_project.Ipmi.Host", "/xyz/openbmc_project/Ipmi",
+            "xyz.openbmc_project.Ipmi.Server", "execute", netFn, lun, cmd,
+            commandData, options);
+    }
+    else
+    {
+        auto start = std::chrono::steady_clock::now();
+
+        // Ignore messages that are not part of an active/pre-active session
+        if (handler->sessionID != session::sessionZero)
+        {
+            std::shared_ptr<session::Session> session =
+                session::Manager::get().getSession(handler->sessionID);
+            auto state = static_cast<session::State>(session->state());
+            if ((state != session::State::setupInProgress) &&
+                (state != session::State::active))
+            {
+                return;
+            }
+        }
+
+        handler->outPayload =
+            iterator->second->executeCommand(commandData, handler);
+
+        auto end = std::chrono::steady_clock::now();
+
+        std::chrono::duration<size_t> elapsedSeconds =
+            std::chrono::duration_cast<std::chrono::seconds>(end - start);
+
+        // If command time execution time exceeds 2 seconds, log a time
+        // exceeded message
+        if (elapsedSeconds > 2s)
+        {
+            lg2::error("IPMI command timed out: {DELAY}", "DELAY",
+                       elapsedSeconds.count());
+        }
+    }
+}
+
+std::vector<uint8_t> NetIpmidEntry::executeCommand(
+    std::vector<uint8_t>& commandData,
+    std::shared_ptr<message::Handler> handler)
+{
+    std::vector<uint8_t> errResponse;
+
+    // Check if the command qualifies to be run prior to establishing a session
+    if (!sessionless && (handler->sessionID == session::sessionZero))
+    {
+        errResponse.resize(1);
+        errResponse[0] = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+        lg2::info(
+            "Table: Insufficient privilege for command: lun: {LUN}, netFn: {NETFN}, command: {COMMAND}",
+            "LUN", command.lun(), "NETFN", command.netFn(), "COMMAND",
+            command.cmd());
+        return errResponse;
+    }
+
+    return functor(commandData, handler);
+}
+
+} // namespace command
diff --git a/transport/rmcpbridge/command_table.hpp b/transport/rmcpbridge/command_table.hpp
new file mode 100644
index 0000000..3a5e344
--- /dev/null
+++ b/transport/rmcpbridge/command_table.hpp
@@ -0,0 +1,276 @@
+#pragma once
+
+#include "message_handler.hpp"
+
+#include <ipmid/api.h>
+
+#include <cstddef>
+#include <functional>
+#include <map>
+
+namespace command
+{
+
+struct CommandID
+{
+    static constexpr size_t lunBits = 2;
+    CommandID(uint32_t command) : command(command) {}
+
+    uint8_t netFnLun() const
+    {
+        return static_cast<uint8_t>(command >> CHAR_BIT);
+    }
+    uint8_t netFn() const
+    {
+        return netFnLun() >> lunBits;
+    }
+    uint8_t lun() const
+    {
+        return netFnLun() & ((1 << (lunBits + 1)) - 1);
+    }
+    uint8_t cmd() const
+    {
+        return static_cast<uint8_t>(command);
+    }
+    uint32_t command;
+};
+
+/**
+ * CommandFunctor is the functor register for commands defined in
+ * phosphor-net-ipmid. This would take the request part of the command as a
+ * vector and a reference to the message handler. The response part of the
+ * command is returned as a vector.
+ */
+using CommandFunctor = std::function<std::vector<uint8_t>(
+    const std::vector<uint8_t>&, std::shared_ptr<message::Handler>&)>;
+
+/**
+ * @struct CmdDetails
+ *
+ * Command details is used to register commands supported in phosphor-net-ipmid.
+ */
+struct CmdDetails
+{
+    CommandID command;
+    CommandFunctor functor;
+    session::Privilege privilege;
+    bool sessionless;
+};
+
+/**
+ * @enum NetFns
+ *
+ * A field that identifies the functional class of the message. The Network
+ * Function clusters IPMI commands into different sets.
+ */
+enum class NetFns
+{
+    CHASSIS = (0x00 << 10),
+    CHASSIS_RESP = (0x01 << 10),
+
+    BRIDGE = (0x02 << 10),
+    BRIDGE_RESP = (0x03 << 10),
+
+    SENSOR = (0x04 << 10),
+    SENSOR_RESP = (0x05 << 10),
+    EVENT = (0x04 << 10),
+    EVENT_RESP = (0x05 << 10),
+
+    APP = (0x06 << 10),
+    APP_RESP = (0x07 << 10),
+
+    FIRMWARE = (0x08 << 10),
+    FIRMWARE_RESP = (0x09 << 10),
+
+    STORAGE = (0x0A << 10),
+    STORAGE_RESP = (0x0B << 10),
+
+    TRANSPORT = (0x0C << 10),
+    TRANSPORT_RESP = (0x0D << 10),
+
+    //>>
+    RESERVED_START = (0x0E << 10),
+    RESERVED_END = (0x2B << 10),
+    //<<
+
+    GROUP_EXTN = (0x2C << 10),
+    GROUP_EXTN_RESP = (0x2D << 10),
+
+    OEM = (0x2E << 10),
+    OEM_RESP = (0x2F << 10),
+};
+
+/**
+ * @class Entry
+ *
+ * This is the base class for registering IPMI commands. There are two ways of
+ * registering commands to phosphor-net-ipmid, the session related commands and
+ * provider commands
+ *
+ * Every commands has a privilege level which mentions the minimum session
+ * privilege level needed to execute the command
+ */
+
+class Entry
+{
+  public:
+    Entry(CommandID command, session::Privilege privilege) :
+        command(command), privilege(privilege)
+    {}
+
+    /**
+     * @brief Execute the command
+     *
+     * Execute the command
+     *
+     * @param[in] commandData - Request Data for the command
+     * @param[in] handler - Reference to the Message Handler
+     *
+     * @return Response data for the command
+     */
+    virtual std::vector<uint8_t> executeCommand(
+        std::vector<uint8_t>& commandData,
+        std::shared_ptr<message::Handler> handler) = 0;
+
+    auto getCommand() const
+    {
+        return command;
+    }
+
+    auto getPrivilege() const
+    {
+        return privilege;
+    }
+
+    virtual ~Entry() = default;
+    Entry(const Entry&) = default;
+    Entry& operator=(const Entry&) = default;
+    Entry(Entry&&) = default;
+    Entry& operator=(Entry&&) = default;
+
+  protected:
+    CommandID command;
+
+    // Specifies the minimum privilege level required to execute this command
+    session::Privilege privilege;
+};
+
+/**
+ * @class NetIpmidEntry
+ *
+ * NetIpmidEntry is used to register commands that are consumed only in
+ * phosphor-net-ipmid. The RAKP commands, session commands and user management
+ * commands are examples of this.
+ *
+ * There are certain IPMI commands that can be executed before session can be
+ * established like Get System GUID, Get Channel Authentication Capabilities
+ * and RAKP commands.
+ */
+class NetIpmidEntry final : public Entry
+{
+  public:
+    NetIpmidEntry(CommandID command, CommandFunctor functor,
+                  session::Privilege privilege, bool sessionless) :
+        Entry(command, privilege), functor(functor), sessionless(sessionless)
+    {}
+
+    /**
+     * @brief Execute the command
+     *
+     * Execute the command
+     *
+     * @param[in] commandData - Request Data for the command
+     * @param[in] handler - Reference to the Message Handler
+     *
+     * @return Response data for the command
+     */
+    std::vector<uint8_t> executeCommand(
+        std::vector<uint8_t>& commandData,
+        std::shared_ptr<message::Handler> handler) override;
+
+    virtual ~NetIpmidEntry() = default;
+    NetIpmidEntry(const NetIpmidEntry&) = default;
+    NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
+    NetIpmidEntry(NetIpmidEntry&&) = default;
+    NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
+
+  private:
+    CommandFunctor functor;
+
+    bool sessionless;
+};
+
+/**
+ * @class Table
+ *
+ * Table keeps the IPMI command entries as a sorted associative container with
+ * Command ID as the unique key. It has interfaces for registering commands
+ * and executing a command.
+ */
+class Table
+{
+  private:
+    struct Private
+    {};
+
+  public:
+    explicit Table(const Private&) {}
+    Table() = delete;
+    ~Table() = default;
+    // Command Table is a singleton so copy, copy-assignment, move and
+    // move assignment is deleted
+    Table(const Table&) = delete;
+    Table& operator=(const Table&) = delete;
+    Table(Table&&) = default;
+    Table& operator=(Table&&) = default;
+
+    /**
+     * @brief Get a reference to the singleton Table
+     *
+     * @return Table reference
+     */
+    static Table& get()
+    {
+        static std::shared_ptr<Table> ptr = nullptr;
+        if (!ptr)
+        {
+            ptr = std::make_shared<Table>(Private());
+        }
+        return *ptr;
+    }
+
+    using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
+
+    /**
+     * @brief Register a command
+     *
+     * Register a command with the command table
+     *
+     * @param[in] inCommand - Command ID
+     * @param[in] entry - Command Entry
+     *
+     * @return: None
+     *
+     * @note: Duplicate registrations will be rejected.
+     *
+     */
+    void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
+
+    /**
+     * @brief Execute the command
+     *
+     * Execute the command for the corresponding CommandID
+     *
+     * @param[in] inCommand - Command ID to execute.
+     * @param[in] commandData - Request Data for the command
+     * @param[in] handler - Reference to the Message Handler
+     *
+     */
+    void executeCommand(uint32_t inCommand, std::vector<uint8_t>& commandData,
+                        std::shared_ptr<message::Handler> handler);
+
+  private:
+    CommandTable commandTable;
+};
+
+} // namespace command
diff --git a/transport/rmcpbridge/crypt_algo.cpp b/transport/rmcpbridge/crypt_algo.cpp
new file mode 100644
index 0000000..69c333d
--- /dev/null
+++ b/transport/rmcpbridge/crypt_algo.cpp
@@ -0,0 +1,213 @@
+#include "crypt_algo.hpp"
+
+#include "message_parsers.hpp"
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+
+#include <algorithm>
+#include <numeric>
+
+namespace cipher
+{
+
+namespace crypt
+{
+
+constexpr std::array<uint8_t, AlgoAES128::AESCBC128BlockSize - 1>
+    AlgoAES128::confPadBytes;
+
+std::vector<uint8_t> AlgoAES128::decryptPayload(
+    const std::vector<uint8_t>& packet, const size_t sessHeaderLen,
+    const size_t payloadLen) const
+{
+    // verify packet size minimal: sessHeaderLen + payloadLen
+    // and payloadLen is more than AESCBC128ConfHeader
+    if (packet.size() < (sessHeaderLen + payloadLen) ||
+        payloadLen < AESCBC128ConfHeader)
+    {
+        throw std::runtime_error("Invalid data length");
+    }
+
+    auto plainPayload =
+        decryptData(packet.data() + sessHeaderLen,
+                    packet.data() + sessHeaderLen + AESCBC128ConfHeader,
+                    payloadLen - AESCBC128ConfHeader);
+
+    /*
+     * The confidentiality pad length is the last byte in the payload, it would
+     * tell the number of pad bytes in the payload. We added a condition, so
+     * that buffer overrun doesn't happen.
+     */
+    size_t confPadLength = plainPayload.back();
+    auto padLength = std::min(plainPayload.size() - 1, confPadLength);
+
+    auto plainPayloadLen = plainPayload.size() - padLength - 1;
+
+    // Additional check if the confidentiality pad bytes are as expected
+    if (!std::equal(plainPayload.begin() + plainPayloadLen,
+                    plainPayload.begin() + plainPayloadLen + padLength,
+                    confPadBytes.begin()))
+    {
+        throw std::runtime_error("Confidentiality pad bytes check failed");
+    }
+
+    plainPayload.resize(plainPayloadLen);
+
+    return plainPayload;
+}
+
+std::vector<uint8_t> AlgoAES128::encryptPayload(
+    std::vector<uint8_t>& payload) const
+{
+    auto payloadLen = payload.size();
+
+    /*
+     * The following logic calculates the number of padding bytes to be added to
+     * the payload data. This would ensure that the length is a multiple of the
+     * block size of algorithm being used. For the AES algorithm, the block size
+     * is 16 bytes.
+     */
+    auto paddingLen = AESCBC128BlockSize - ((payloadLen + 1) & 0xF);
+
+    /*
+     * The additional field is for the Confidentiality Pad Length field. For the
+     * AES algorithm, this number will range from 0 to 15 bytes. This field is
+     * mandatory.
+     */
+    payload.resize(payloadLen + paddingLen + 1);
+
+    /*
+     * If no Confidentiality Pad bytes are required, the Confidentiality Pad
+     * Length field is set to 00h. If present, the value of the first byte of
+     * Confidentiality Pad shall be one (01h) and all subsequent bytes shall
+     * have a monotonically increasing value (e.g., 02h, 03h, 04h, etc).
+     */
+    if (0 != paddingLen)
+    {
+        std::iota(payload.begin() + payloadLen,
+                  payload.begin() + payloadLen + paddingLen, 1);
+    }
+
+    payload.back() = paddingLen;
+
+    return encryptData(payload.data(), payload.size());
+}
+
+std::vector<uint8_t> AlgoAES128::decryptData(
+    const uint8_t* iv, const uint8_t* input, const int inputLen) const
+{
+    // Initializes Cipher context
+    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+
+    auto cleanupFunc = [](EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_free(ctx); };
+
+    std::unique_ptr<EVP_CIPHER_CTX, decltype(cleanupFunc)> ctxPtr(
+        ctx, cleanupFunc);
+
+    /*
+     * EVP_DecryptInit_ex sets up cipher context ctx for encryption with type
+     * AES-CBC-128. ctx must be initialized before calling this function. K2 is
+     * the symmetric key used and iv is the initialization vector used.
+     */
+    if (!EVP_DecryptInit_ex(ctxPtr.get(), EVP_aes_128_cbc(), NULL, k2.data(),
+                            iv))
+    {
+        throw std::runtime_error("EVP_DecryptInit_ex failed for type "
+                                 "AES-CBC-128");
+    }
+
+    /*
+     * EVP_CIPHER_CTX_set_padding() enables or disables padding. If the pad
+     * parameter is zero then no padding is performed. This function always
+     * returns 1.
+     */
+    EVP_CIPHER_CTX_set_padding(ctxPtr.get(), 0);
+
+    std::vector<uint8_t> output(inputLen + AESCBC128BlockSize);
+
+    int outputLen = 0;
+
+    /*
+     * If padding is disabled then EVP_DecryptFinal_ex() will not encrypt any
+     * more data and it will return an error if any data remains in a partial
+     * block: that is if the total data length is not a multiple of the block
+     * size. Since AES-CBC-128 encrypted payload format adds padding bytes and
+     * ensures that payload is a multiple of block size, we are not making the
+     * call to  EVP_DecryptFinal_ex().
+     */
+    if (!EVP_DecryptUpdate(ctxPtr.get(), output.data(), &outputLen, input,
+                           inputLen))
+    {
+        throw std::runtime_error("EVP_DecryptUpdate failed");
+    }
+
+    output.resize(outputLen);
+
+    return output;
+}
+
+std::vector<uint8_t> AlgoAES128::encryptData(const uint8_t* input,
+                                             const int inputLen) const
+{
+    std::vector<uint8_t> output(inputLen + AESCBC128BlockSize);
+
+    // Generate the initialization vector
+    if (!RAND_bytes(output.data(), AESCBC128ConfHeader))
+    {
+        throw std::runtime_error("RAND_bytes failed");
+    }
+
+    // Initializes Cipher context
+    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+
+    auto cleanupFunc = [](EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_free(ctx); };
+
+    std::unique_ptr<EVP_CIPHER_CTX, decltype(cleanupFunc)> ctxPtr(
+        ctx, cleanupFunc);
+
+    /*
+     * EVP_EncryptInit_ex sets up cipher context ctx for encryption with type
+     * AES-CBC-128. ctx must be initialized before calling this function. K2 is
+     * the symmetric key used and iv is the initialization vector used.
+     */
+    if (!EVP_EncryptInit_ex(ctxPtr.get(), EVP_aes_128_cbc(), NULL, k2.data(),
+                            output.data()))
+    {
+        throw std::runtime_error("EVP_EncryptInit_ex failed for type "
+                                 "AES-CBC-128");
+    }
+
+    /*
+     * EVP_CIPHER_CTX_set_padding() enables or disables padding. If the pad
+     * parameter is zero then no padding is performed. This function always
+     * returns 1.
+     */
+    EVP_CIPHER_CTX_set_padding(ctxPtr.get(), 0);
+
+    int outputLen = 0;
+
+    /*
+     * If padding is disabled then EVP_EncryptFinal_ex() will not encrypt any
+     * more data and it will return an error if any data remains in a partial
+     * block: that is if the total data length is not a multiple of the block
+     * size. Since we are adding padding bytes and ensures that payload is a
+     * multiple of block size, we are not making the call to
+     * EVP_DecryptFinal_ex()
+     */
+    if (!EVP_EncryptUpdate(ctxPtr.get(), output.data() + AESCBC128ConfHeader,
+                           &outputLen, input, inputLen))
+    {
+        throw std::runtime_error("EVP_EncryptUpdate failed for type "
+                                 "AES-CBC-128");
+    }
+
+    output.resize(AESCBC128ConfHeader + outputLen);
+
+    return output;
+}
+
+} // namespace crypt
+
+} // namespace cipher
diff --git a/transport/rmcpbridge/crypt_algo.hpp b/transport/rmcpbridge/crypt_algo.hpp
new file mode 100644
index 0000000..534f1a0
--- /dev/null
+++ b/transport/rmcpbridge/crypt_algo.hpp
@@ -0,0 +1,204 @@
+#pragma once
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace cipher
+{
+
+namespace crypt
+{
+
+/**
+ * @enum Confidentiality Algorithms
+ *
+ * The Confidentiality Algorithm Number specifies the encryption/decryption
+ * algorithm field that is used for encrypted payload data under the session.
+ * The ‘encrypted’ bit in the payload type field being set identifies packets
+ * with payloads that include data that is encrypted per this specification.
+ * When payload data is encrypted, there may be additional “Confidentiality
+ * Header” and/or “Confidentiality Trailer” fields that are included within the
+ * payload. The size and definition of those fields is specific to the
+ * particular confidentiality algorithm. Based on security recommendations
+ * encrypting IPMI traffic is preferred, so NONE is not supported.
+ */
+enum class Algorithms : uint8_t
+{
+    NONE,        /**< No encryption (mandatory , not supported) */
+    AES_CBC_128, /**< AES-CBC-128 Algorithm (mandatory option) */
+    xRC4_128,    /**< xRC4-128 Algorithm (optional option) */
+    xRC4_40,     /**< xRC4-40 Algorithm (optional option) */
+};
+
+/**
+ * @class Interface
+ *
+ * Interface is the base class for the Confidentiality Algorithms.
+ */
+class Interface
+{
+  public:
+    /**
+     * @brief Constructor for Interface
+     */
+    explicit Interface(const std::vector<uint8_t>& k2) : k2(k2) {}
+
+    Interface() = delete;
+    virtual ~Interface() = default;
+    Interface(const Interface&) = default;
+    Interface& operator=(const Interface&) = default;
+    Interface(Interface&&) = default;
+    Interface& operator=(Interface&&) = default;
+
+    /**
+     * @brief Decrypt the incoming payload
+     *
+     * @param[in] packet - Incoming IPMI packet
+     * @param[in] sessHeaderLen - Length of the IPMI Session Header
+     * @param[in] payloadLen - Length of the encrypted IPMI payload
+     *
+     * @return decrypted payload if the operation is successful
+     */
+    virtual std::vector<uint8_t> decryptPayload(
+        const std::vector<uint8_t>& packet, const size_t sessHeaderLen,
+        const size_t payloadLen) const = 0;
+
+    /**
+     * @brief Encrypt the outgoing payload
+     *
+     * @param[in] payload - plain payload for the outgoing IPMI packet
+     *
+     * @return encrypted payload if the operation is successful
+     *
+     */
+    virtual std::vector<uint8_t> encryptPayload(
+        std::vector<uint8_t>& payload) const = 0;
+
+    /**
+     * @brief Check if the Confidentiality algorithm is supported
+     *
+     * @param[in] algo - confidentiality algorithm
+     *
+     * @return true if algorithm is supported else false
+     *
+     */
+    static bool isAlgorithmSupported(Algorithms algo)
+    {
+        if (algo == Algorithms::AES_CBC_128)
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+  protected:
+    /**
+     * @brief The Cipher Key is the first 128-bits of key “K2”, K2 is
+     * generated by processing a pre-defined constant keyed by Session
+     * Integrity Key (SIK) that was created during session activation.
+     */
+    std::vector<uint8_t> k2;
+};
+
+/**
+ * @class AlgoAES128
+ *
+ * @brief Implementation of the AES-CBC-128 Confidentiality algorithm
+ *
+ * AES-128 uses a 128-bit Cipher Key. The Cipher Key is the first 128-bits of
+ * key “K2”.Once the Cipher Key has been generated it is used to encrypt
+ * the payload data. The payload data is padded to make it an integral numbers
+ * of blocks in length (a block is 16 bytes for AES). The payload is then
+ * encrypted one block at a time from the lowest data offset to the highest
+ * using Cipher_Key as specified in AES.
+ */
+class AlgoAES128 final : public Interface
+{
+  public:
+    static constexpr size_t AESCBC128ConfHeader = 16;
+    static constexpr size_t AESCBC128BlockSize = 16;
+
+    /**
+     * If confidentiality bytes are present, the value of the first byte is
+     * one (01h). and all subsequent bytes shall have a monotonically
+     * increasing value (e.g., 02h, 03h, 04h, etc). The receiver, as an
+     * additional check for proper decryption, shall check the value of each
+     * byte of Confidentiality Pad. For AES algorithm, the pad bytes will
+     * range from 0 to 15 bytes. This predefined array would help in
+     * doing the additional check.
+     */
+    static constexpr std::array<uint8_t, AESCBC128BlockSize - 1> confPadBytes =
+        {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+         0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+
+    /**
+     * @brief Constructor for AlgoAES128
+     *
+     * @param[in] - Session Integrity key
+     */
+    explicit AlgoAES128(const std::vector<uint8_t>& k2) : Interface(k2) {}
+
+    AlgoAES128() = delete;
+    ~AlgoAES128() = default;
+    AlgoAES128(const AlgoAES128&) = default;
+    AlgoAES128& operator=(const AlgoAES128&) = default;
+    AlgoAES128(AlgoAES128&&) = default;
+    AlgoAES128& operator=(AlgoAES128&&) = default;
+
+    /**
+     * @brief Decrypt the incoming payload
+     *
+     * @param[in] packet - Incoming IPMI packet
+     * @param[in] sessHeaderLen - Length of the IPMI Session Header
+     * @param[in] payloadLen - Length of the encrypted IPMI payload
+     *
+     * @return decrypted payload if the operation is successful
+     */
+    std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet,
+                                        const size_t sessHeaderLen,
+                                        const size_t payloadLen) const override;
+
+    /**
+     * @brief Encrypt the outgoing payload
+     *
+     * @param[in] payload - plain payload for the outgoing IPMI packet
+     *
+     * @return encrypted payload if the operation is successful
+     *
+     */
+    std::vector<uint8_t> encryptPayload(
+        std::vector<uint8_t>& payload) const override;
+
+  private:
+    /**
+     * @brief Decrypt the passed data
+     *
+     * @param[in] iv - Initialization vector
+     * @param[in] input - Pointer to input data
+     * @param[in] inputLen - Length of input data
+     *
+     * @return decrypted data if the operation is successful
+     */
+    std::vector<uint8_t> decryptData(const uint8_t* iv, const uint8_t* input,
+                                     const int inputLen) const;
+
+    /**
+     * @brief Encrypt the passed data
+     *
+     * @param[in] input - Pointer to input data
+     * @param[in] inputLen - Length of input data
+     *
+     * @return encrypted data if the operation is successful
+     */
+    std::vector<uint8_t> encryptData(const uint8_t* input,
+                                     const int inputLen) const;
+};
+
+} // namespace crypt
+
+} // namespace cipher
diff --git a/transport/rmcpbridge/endian.hpp b/transport/rmcpbridge/endian.hpp
new file mode 100644
index 0000000..446e879
--- /dev/null
+++ b/transport/rmcpbridge/endian.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <endian.h>
+#include <stdint.h>
+
+namespace endian
+{
+namespace details
+{
+template <typename T>
+struct convert
+{
+    static T to_ipmi(T) = delete;
+    static T from_ipmi(T) = delete;
+    static T to_network(T) = delete;
+    static T from_network(T) = delete;
+};
+
+template <>
+struct convert<uint16_t>
+{
+    static uint16_t to_ipmi(uint16_t i)
+    {
+        return htole16(i);
+    };
+    static uint16_t from_ipmi(uint16_t i)
+    {
+        return le16toh(i);
+    };
+    static uint16_t to_network(uint16_t i)
+    {
+        return htobe16(i);
+    };
+    static uint16_t from_network(uint16_t i)
+    {
+        return be16toh(i);
+    };
+};
+
+template <>
+struct convert<uint32_t>
+{
+    static uint32_t to_ipmi(uint32_t i)
+    {
+        return htole32(i);
+    };
+    static uint32_t from_ipmi(uint32_t i)
+    {
+        return le32toh(i);
+    };
+    static uint32_t to_network(uint32_t i)
+    {
+        return htobe32(i);
+    };
+    static uint32_t from_network(uint32_t i)
+    {
+        return be32toh(i);
+    };
+};
+} // namespace details
+
+template <typename T>
+T to_ipmi(T i)
+{
+    return details::convert<T>::to_ipmi(i);
+}
+
+template <typename T>
+T from_ipmi(T i)
+{
+    return details::convert<T>::from_ipmi(i);
+}
+
+template <typename T>
+T to_network(T i)
+{
+    return details::convert<T>::to_network(i);
+}
+template <typename T>
+T from_network(T i)
+{
+    return details::convert<T>::from_network(i);
+}
+} // namespace endian
diff --git a/transport/rmcpbridge/integrity_algo.cpp b/transport/rmcpbridge/integrity_algo.cpp
new file mode 100644
index 0000000..3110fff
--- /dev/null
+++ b/transport/rmcpbridge/integrity_algo.cpp
@@ -0,0 +1,149 @@
+#include "integrity_algo.hpp"
+
+#include "message_parsers.hpp"
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+
+namespace cipher
+{
+
+namespace integrity
+{
+
+AlgoSHA1::AlgoSHA1(const std::vector<uint8_t>& sik) :
+    Interface(SHA1_96_AUTHCODE_LENGTH)
+{
+    k1 = generateKn(sik, rmcp::const_1);
+}
+
+std::vector<uint8_t> AlgoSHA1::generateHMAC(const uint8_t* input,
+                                            const size_t len) const
+{
+    std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+
+    if (HMAC(EVP_sha1(), k1.data(), k1.size(), input, len, output.data(),
+             &mdLen) == NULL)
+    {
+        throw std::runtime_error("Generating integrity data failed");
+    }
+
+    // HMAC generates Message Digest to the size of SHA_DIGEST_LENGTH, the
+    // AuthCode field length is based on the integrity algorithm. So we are
+    // interested only in the AuthCode field length of the generated Message
+    // digest.
+    output.resize(authCodeLength);
+
+    return output;
+}
+
+bool AlgoSHA1::verifyIntegrityData(
+    const std::vector<uint8_t>& packet, const size_t length,
+    std::vector<uint8_t>::const_iterator integrityDataBegin,
+    std::vector<uint8_t>::const_iterator integrityDataEnd) const
+{
+    auto output = generateHMAC(
+        packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length);
+
+    // Verify if the generated integrity data for the packet and the received
+    // integrity data matches.
+    return (std::equal(output.begin(), output.end(), integrityDataBegin,
+                       integrityDataEnd));
+}
+
+std::vector<uint8_t> AlgoSHA1::generateIntegrityData(
+    const std::vector<uint8_t>& packet) const
+{
+    return generateHMAC(
+        packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
+        packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE);
+}
+
+std::vector<uint8_t> AlgoSHA1::generateKn(const std::vector<uint8_t>& sik,
+                                          const rmcp::Const_n& const_n) const
+{
+    unsigned int mdLen = 0;
+    std::vector<uint8_t> Kn(sik.size());
+
+    // Generated Kn for the integrity algorithm with the additional key keyed
+    // with SIK.
+    if (HMAC(EVP_sha1(), sik.data(), sik.size(), const_n.data(), const_n.size(),
+             Kn.data(), &mdLen) == NULL)
+    {
+        throw std::runtime_error("Generating KeyN for integrity "
+                                 "algorithm failed");
+    }
+    return Kn;
+}
+
+AlgoSHA256::AlgoSHA256(const std::vector<uint8_t>& sik) :
+    Interface(SHA256_128_AUTHCODE_LENGTH)
+{
+    k1 = generateKn(sik, rmcp::const_1);
+}
+
+std::vector<uint8_t> AlgoSHA256::generateHMAC(const uint8_t* input,
+                                              const size_t len) const
+{
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+
+    if (HMAC(EVP_sha256(), k1.data(), k1.size(), input, len, output.data(),
+             &mdLen) == NULL)
+    {
+        throw std::runtime_error("Generating HMAC_SHA256_128 failed");
+    }
+
+    // HMAC generates Message Digest to the size of SHA256_DIGEST_LENGTH, the
+    // AuthCode field length is based on the integrity algorithm. So we are
+    // interested only in the AuthCode field length of the generated Message
+    // digest.
+    output.resize(authCodeLength);
+
+    return output;
+}
+
+bool AlgoSHA256::verifyIntegrityData(
+    const std::vector<uint8_t>& packet, const size_t length,
+    std::vector<uint8_t>::const_iterator integrityDataBegin,
+    std::vector<uint8_t>::const_iterator integrityDataEnd) const
+{
+    auto output = generateHMAC(
+        packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length);
+
+    // Verify if the generated integrity data for the packet and the received
+    // integrity data matches.
+    return (std::equal(output.begin(), output.end(), integrityDataBegin,
+                       integrityDataEnd));
+}
+
+std::vector<uint8_t> AlgoSHA256::generateIntegrityData(
+    const std::vector<uint8_t>& packet) const
+{
+    return generateHMAC(
+        packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
+        packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE);
+}
+
+std::vector<uint8_t> AlgoSHA256::generateKn(const std::vector<uint8_t>& sik,
+                                            const rmcp::Const_n& const_n) const
+{
+    unsigned int mdLen = 0;
+    std::vector<uint8_t> Kn(sik.size());
+
+    // Generated Kn for the integrity algorithm with the additional key keyed
+    // with SIK.
+    if (HMAC(EVP_sha256(), sik.data(), sik.size(), const_n.data(),
+             const_n.size(), Kn.data(), &mdLen) == NULL)
+    {
+        throw std::runtime_error("Generating KeyN for integrity "
+                                 "algorithm HMAC_SHA256 failed");
+    }
+    return Kn;
+}
+
+} // namespace integrity
+
+} // namespace cipher
diff --git a/transport/rmcpbridge/integrity_algo.hpp b/transport/rmcpbridge/integrity_algo.hpp
new file mode 100644
index 0000000..4d6674f
--- /dev/null
+++ b/transport/rmcpbridge/integrity_algo.hpp
@@ -0,0 +1,321 @@
+#pragma once
+
+#include "rmcp.hpp"
+
+#include <array>
+#include <cstddef>
+#include <vector>
+
+namespace cipher
+{
+
+namespace integrity
+{
+
+/**
+ * @enum Integrity Algorithms
+ *
+ * The Integrity Algorithm Number specifies the algorithm used to generate the
+ * contents for the AuthCode “signature” field that accompanies authenticated
+ * IPMI v2.0/RMCP+ messages once the session has been established. If the
+ * Integrity Algorithm is none the AuthCode value is not calculated and the
+ * AuthCode field in the message is not present. Based on security
+ * recommendations NONE will not be supported.
+ */
+enum class Algorithms : uint8_t
+{
+    NONE,            // Mandatory (implemented, not supported)
+    HMAC_SHA1_96,    // Mandatory (implemented, default choice in ipmitool)
+    HMAC_MD5_128,    // Optional (not implemented)
+    MD5_128,         // Optional (not implemented)
+    HMAC_SHA256_128, // Optional (implemented, best available)
+};
+
+/**
+ * @class Interface
+ *
+ * Interface is the base class for the Integrity Algorithms.
+ * Unless otherwise specified, the integrity algorithm is applied to the packet
+ * data starting with the AuthType/Format field up to and including the field
+ * that immediately precedes the AuthCode field itself.
+ */
+class Interface
+{
+  public:
+    /**
+     * @brief Constructor for Interface
+     *
+     * @param[in] - AuthCode length
+     */
+    explicit Interface(size_t authLength) : authCodeLength(authLength) {}
+
+    Interface() = delete;
+    virtual ~Interface() = default;
+    Interface(const Interface&) = default;
+    Interface& operator=(const Interface&) = default;
+    Interface(Interface&&) = default;
+    Interface& operator=(Interface&&) = default;
+
+    /**
+     * @brief Verify the integrity data of the packet
+     *
+     * @param[in] packet - Incoming IPMI packet
+     * @param[in] packetLen - Packet length excluding authCode
+     * @param[in] integrityDataBegin - Begin iterator to the authCode in the
+     *                                 packet
+     * @param[in] integrityDataEnd   - End to the authCode in the packet
+     *
+     * @return true if authcode in the packet is equal to one generated
+     *         using integrity algorithm on the packet data, false otherwise
+     */
+    bool virtual verifyIntegrityData(
+        const std::vector<uint8_t>& packet, const size_t packetLen,
+        std::vector<uint8_t>::const_iterator integrityDataBegin,
+        std::vector<uint8_t>::const_iterator integrityDataEnd) const = 0;
+
+    /**
+     * @brief Generate integrity data for the outgoing IPMI packet
+     *
+     * @param[in] input - Outgoing IPMI packet
+     *
+     * @return authcode for the outgoing IPMI packet
+     *
+     */
+    std::vector<uint8_t> virtual generateIntegrityData(
+        const std::vector<uint8_t>& input) const = 0;
+
+    /**
+     * @brief Check if the Integrity algorithm is supported
+     *
+     * @param[in] algo - integrity algorithm
+     *
+     * @return true if algorithm is supported else false
+     *
+     */
+    static bool isAlgorithmSupported(Algorithms algo)
+    {
+        if (algo == Algorithms::HMAC_SHA256_128)
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * @brief Generate additional keying material based on SIK
+     *
+     * @note
+     * The IPMI 2.0 spec only states that the additional keying material is
+     * generated by running HMAC(constN) using SIK as the key. It does not
+     * state whether this is the integrity algorithm or the authentication
+     * algorithm. Other implementations of the RMCP+ algorithm (ipmitool
+     * and ipmiutil) are not consistent on this matter. But it does not
+     * really matter because based on any of the defined cipher suites, the
+     * integrity and authentication algorithms are both based on the same
+     * digest method (integrity::Algorithms::HMAC_SHA1_96 uses SHA1 and
+     * rakp_auth::Algorithms::RAKP_HMAC_SHA1 uses SHA1). None of the
+     * defined cipher suites mix and match digests for integrity and
+     * authentication. Generating Kn belongs in either the integrity or
+     * authentication classes, so in this implementation, integrity has
+     * been chosen.
+     *
+     * @param[in] sik - session integrity key
+     * @param[in] data - 20-byte Const_n
+     *
+     * @return on success returns the Kn based on this integrity class
+     *
+     */
+    std::vector<uint8_t> virtual generateKn(
+        const std::vector<uint8_t>& sik, const rmcp::Const_n& data) const = 0;
+
+    /** @brief Authcode field
+     *
+     *  AuthCode field length varies based on the integrity algorithm, for
+     *  HMAC-SHA1-96 the authcode field is 12 bytes. For HMAC-SHA256-128 and
+     *  HMAC-MD5-128 the authcode field is 16 bytes.
+     */
+    size_t authCodeLength;
+
+  protected:
+    /** @brief K1 key used to generated the integrity data. */
+    std::vector<uint8_t> k1;
+};
+
+/**
+ * @class AlgoSHA1
+ *
+ * @brief Implementation of the HMAC-SHA1-96 Integrity algorithm
+ *
+ * HMAC-SHA1-96 take the Session Integrity Key and use it to generate K1. K1 is
+ * then used as the key for use in HMAC to produce the AuthCode field.
+ * For “one-key” logins, the user’s key (password) is used in the creation of
+ * the Session Integrity Key. When the HMAC-SHA1-96 Integrity Algorithm is used
+ * the resulting AuthCode field is 12 bytes (96 bits).
+ */
+class AlgoSHA1 final : public Interface
+{
+  public:
+    static constexpr size_t SHA1_96_AUTHCODE_LENGTH = 12;
+
+    /**
+     * @brief Constructor for AlgoSHA1
+     *
+     * @param[in] - Session Integrity Key
+     */
+    explicit AlgoSHA1(const std::vector<uint8_t>& sik);
+
+    AlgoSHA1() = delete;
+    ~AlgoSHA1() = default;
+    AlgoSHA1(const AlgoSHA1&) = default;
+    AlgoSHA1& operator=(const AlgoSHA1&) = default;
+    AlgoSHA1(AlgoSHA1&&) = default;
+    AlgoSHA1& operator=(AlgoSHA1&&) = default;
+
+    /**
+     * @brief Verify the integrity data of the packet
+     *
+     * @param[in] packet - Incoming IPMI packet
+     * @param[in] length - Length of the data in the packet to calculate
+     *                     the integrity data
+     * @param[in] integrityDataBegin - Begin iterator to the authCode in the
+     *                                 packet
+     * @param[in] integrityDataEnd   - End to the authCode in the packet
+     *
+     * @return true if authcode in the packet is equal to one generated
+     *         using integrity algorithm on the packet data, false otherwise
+     */
+    bool verifyIntegrityData(
+        const std::vector<uint8_t>& packet, const size_t length,
+        std::vector<uint8_t>::const_iterator integrityDataBegin,
+        std::vector<uint8_t>::const_iterator integrityDataEnd) const override;
+
+    /**
+     * @brief Generate integrity data for the outgoing IPMI packet
+     *
+     * @param[in] input - Outgoing IPMI packet
+     *
+     * @return on success return the integrity data for the outgoing IPMI
+     *         packet
+     */
+    std::vector<uint8_t> generateIntegrityData(
+        const std::vector<uint8_t>& packet) const override;
+
+    /**
+     * @brief Generate additional keying material based on SIK
+     *
+     * @param[in] sik - session integrity key
+     * @param[in] data - 20-byte Const_n
+     *
+     * @return on success returns the Kn based on HMAC-SHA1
+     *
+     */
+    std::vector<uint8_t> generateKn(
+        const std::vector<uint8_t>& sik,
+        const rmcp::Const_n& const_n) const override;
+
+  private:
+    /**
+     * @brief Generate HMAC based on HMAC-SHA1-96 algorithm
+     *
+     * @param[in] input - pointer to the message
+     * @param[in] length - length of the message
+     *
+     * @return on success returns the message authentication code
+     *
+     */
+    std::vector<uint8_t> generateHMAC(const uint8_t* input,
+                                      const size_t len) const;
+};
+
+/**
+ * @class AlgoSHA256
+ *
+ * @brief Implementation of the HMAC-SHA256-128 Integrity algorithm
+ *
+ * HMAC-SHA256-128 take the Session Integrity Key and use it to generate K1. K1
+ * is then used as the key for use in HMAC to produce the AuthCode field.  For
+ * “one-key” logins, the user’s key (password) is used in the creation of the
+ * Session Integrity Key. When the HMAC-SHA256-128 Integrity Algorithm is used
+ * the resulting AuthCode field is 16 bytes (128 bits).
+ */
+class AlgoSHA256 final : public Interface
+{
+  public:
+    static constexpr size_t SHA256_128_AUTHCODE_LENGTH = 16;
+
+    /**
+     * @brief Constructor for AlgoSHA256
+     *
+     * @param[in] - Session Integrity Key
+     */
+    explicit AlgoSHA256(const std::vector<uint8_t>& sik);
+
+    AlgoSHA256() = delete;
+    ~AlgoSHA256() = default;
+    AlgoSHA256(const AlgoSHA256&) = default;
+    AlgoSHA256& operator=(const AlgoSHA256&) = default;
+    AlgoSHA256(AlgoSHA256&&) = default;
+    AlgoSHA256& operator=(AlgoSHA256&&) = default;
+
+    /**
+     * @brief Verify the integrity data of the packet
+     *
+     * @param[in] packet - Incoming IPMI packet
+     * @param[in] length - Length of the data in the packet to calculate
+     *                     the integrity data
+     * @param[in] integrityDataBegin - Begin iterator to the authCode in the
+     *                                 packet
+     * @param[in] integrityDataEnd   - End to the authCode in the packet
+     *
+     * @return true if authcode in the packet is equal to one generated
+     *         using integrity algorithm on the packet data, false otherwise
+     */
+    bool verifyIntegrityData(
+        const std::vector<uint8_t>& packet, const size_t length,
+        std::vector<uint8_t>::const_iterator integrityDataBegin,
+        std::vector<uint8_t>::const_iterator integrityDataEnd) const override;
+
+    /**
+     * @brief Generate integrity data for the outgoing IPMI packet
+     *
+     * @param[in] packet - Outgoing IPMI packet
+     *
+     * @return on success return the integrity data for the outgoing IPMI
+     *         packet
+     */
+    std::vector<uint8_t> generateIntegrityData(
+        const std::vector<uint8_t>& packet) const override;
+
+    /**
+     * @brief Generate additional keying material based on SIK
+     *
+     * @param[in] sik - session integrity key
+     * @param[in] data - 20-byte Const_n
+     *
+     * @return on success returns the Kn based on HMAC-SHA256
+     *
+     */
+    std::vector<uint8_t> generateKn(
+        const std::vector<uint8_t>& sik,
+        const rmcp::Const_n& const_n) const override;
+
+  private:
+    /**
+     * @brief Generate HMAC based on HMAC-SHA256-128 algorithm
+     *
+     * @param[in] input - pointer to the message
+     * @param[in] len - length of the message
+     *
+     * @return on success returns the message authentication code
+     *
+     */
+    std::vector<uint8_t> generateHMAC(const uint8_t* input,
+                                      const size_t len) const;
+};
+
+} // namespace integrity
+
+} // namespace cipher
diff --git a/transport/rmcpbridge/main.cpp b/transport/rmcpbridge/main.cpp
new file mode 100644
index 0000000..a1427ca
--- /dev/null
+++ b/transport/rmcpbridge/main.cpp
@@ -0,0 +1,123 @@
+#include "main.hpp"
+
+#include "comm_module.hpp"
+#include "command/guid.hpp"
+#include "command_table.hpp"
+#include "message.hpp"
+#include "message_handler.hpp"
+#include "sd_event_loop.hpp"
+#include "sessions_manager.hpp"
+#include "socket_channel.hpp"
+#include "sol_module.hpp"
+
+#include <assert.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <ipmid/api.h>
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-event.h>
+#include <unistd.h>
+
+#include <CLI/CLI.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <user_channel/channel_layer.hpp>
+
+#include <tuple>
+
+static auto io = std::make_shared<boost::asio::io_context>();
+std::shared_ptr<boost::asio::io_context> getIo()
+{
+    return io;
+}
+
+sd_bus* bus = nullptr;
+
+std::shared_ptr<sdbusplus::asio::connection> sdbusp;
+
+/*
+ * @brief Required by apphandler IPMI Provider Library
+ */
+sd_bus* ipmid_get_sd_bus_connection()
+{
+    return bus;
+}
+
+/*
+ * @brief mechanism to get at sdbusplus object
+ */
+std::shared_ptr<sdbusplus::asio::connection> getSdBus()
+{
+    return sdbusp;
+}
+
+static EInterfaceIndex currentInterfaceIndex = interfaceUnknown;
+static void setInterfaceIndex(const std::string& channel)
+{
+    try
+    {
+        currentInterfaceIndex =
+            static_cast<EInterfaceIndex>(ipmi::getChannelByName(channel));
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Requested {NAME} is not a valid channel name: {ERROR}",
+                   "NAME", channel, "ERROR", e);
+    }
+}
+EInterfaceIndex getInterfaceIndex(void)
+{
+    return currentInterfaceIndex;
+}
+
+int main(int argc, char* argv[])
+{
+    CLI::App app("KCS RMCP+ bridge");
+    std::string channel;
+    app.add_option("-c,--channel", channel, "channel name. e.g., eth0");
+    uint16_t port = ipmi::rmcpp::defaultPort;
+    app.add_option("-p,--port", port, "port number");
+    bool verbose = false;
+    app.add_option("-v,--verbose", verbose, "print more verbose output");
+    CLI11_PARSE(app, argc, argv);
+
+    // Connect to system bus
+    auto rc = sd_bus_default_system(&bus);
+    if (rc < 0)
+    {
+        lg2::error("Failed to connect to system bus: {ERROR}", "ERROR",
+                   strerror(-rc));
+        return rc;
+    }
+    sdbusp = std::make_shared<sdbusplus::asio::connection>(*io, bus);
+
+    auto& loop = eventloop::EventLoop::get();
+    loop.setupSignal();
+
+    ipmi::ipmiChannelInit();
+    if (channel.size())
+    {
+        setInterfaceIndex(channel);
+    }
+
+    session::Manager::get().managerInit(channel);
+    // Register callback to update cache for a GUID change and cache the GUID
+    command::registerGUIDChangeCallback();
+
+    // Register callback to update cache for sol conf change
+    sol::registerSolConfChangeCallbackHandler(channel);
+
+    // Register the phosphor-net-ipmid session setup commands
+    command::sessionSetupCommands();
+
+    // Register the phosphor-net-ipmid SOL commands
+    sol::command::registerCommands();
+
+    if (loop.setupSocket(sdbusp, channel))
+    {
+        return EXIT_FAILURE;
+    }
+
+    // Start Event Loop
+    return loop.startEventLoop();
+}
diff --git a/transport/rmcpbridge/main.hpp b/transport/rmcpbridge/main.hpp
new file mode 100644
index 0000000..a5be04c
--- /dev/null
+++ b/transport/rmcpbridge/main.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <boost/asio/io_context.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <cstddef>
+#include <memory>
+
+// Select call timeout is set arbitrarily set to 30 sec
+static constexpr size_t SELECT_CALL_TIMEOUT = 30;
+static const auto IPMI_STD_PORT = 623;
+
+extern sd_bus* bus;
+
+std::shared_ptr<sdbusplus::asio::connection> getSdBus();
+std::shared_ptr<boost::asio::io_context> getIo();
diff --git a/transport/rmcpbridge/meson.build b/transport/rmcpbridge/meson.build
new file mode 100644
index 0000000..0e449d4
--- /dev/null
+++ b/transport/rmcpbridge/meson.build
@@ -0,0 +1,120 @@
+project(
+    'phosphor-net-ipmid',
+    'cpp',
+    version: '1.0.0',
+    meson_version: '>=1.1.1',
+    default_options: [
+        'warning_level=3',
+        'werror=true',
+        'cpp_std=c++23',
+        'buildtype=debugoptimized',
+        'b_lto=true',
+    ],
+)
+
+conf_data = configuration_data()
+conf_data.set('RMCP_PING', get_option('rmcp_ping').allowed())
+conf_data.set('PAM_AUTHENTICATE', get_option('pam_authenticate').allowed())
+
+configure_file(output: 'config.h', configuration: conf_data)
+
+sdbusplus_dep = dependency('sdbusplus')
+phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
+phosphor_logging_dep = dependency('phosphor-logging')
+libsystemd_dep = dependency('libsystemd')
+libcrypto_dep = dependency('libcrypto')
+ipmid_dep = dependency('libipmid')
+userlayer_dep = dependency('libuserlayer')
+channellayer_dep = dependency('libchannellayer')
+
+# Project Arguments
+cpp = meson.get_compiler('cpp')
+if cpp.has_header('CLI/CLI.hpp')
+    cli11_dep = declare_dependency()
+else
+    cli11_dep = dependency('CLI11')
+endif
+
+add_project_arguments(
+    cpp.get_supported_arguments(
+        [
+            '-DBOOST_ERROR_CODE_HEADER_ONLY',
+            '-DBOOST_SYSTEM_NO_DEPRECATED',
+            '-DBOOST_COROUTINES_NO_DEPRECATION_WARNING',
+            '-DBOOST_ASIO_DISABLE_THREADS',
+            '-DBOOST_ALL_NO_LIB',
+        ],
+    ),
+    language: 'cpp',
+)
+
+deps = [
+    cli11_dep,
+    ipmid_dep,
+    userlayer_dep,
+    channellayer_dep,
+    libcrypto_dep,
+    libsystemd_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+]
+
+sources = [
+    'auth_algo.cpp',
+    'sessions_manager.cpp',
+    'message_parsers.cpp',
+    'message_handler.cpp',
+    'command_table.cpp',
+    'command/channel_auth.cpp',
+    'command/guid.cpp',
+    'command/open_session.cpp',
+    'command/rakp12.cpp',
+    'command/rakp34.cpp',
+    'command/session_cmds.cpp',
+    'comm_module.cpp',
+    'main.cpp',
+    'integrity_algo.cpp',
+    'crypt_algo.cpp',
+    'sd_event_loop.cpp',
+    'sol/sol_manager.cpp',
+    'sol/sol_context.cpp',
+    'command/sol_cmds.cpp',
+    'command/payload_cmds.cpp',
+    'sol_module.cpp',
+]
+
+executable(
+    'netipmid',
+    sources,
+    implicit_include_directories: true,
+    include_directories: ['command', 'sol'],
+    dependencies: deps,
+    install: true,
+    install_dir: get_option('bindir'),
+)
+
+systemd = dependency('systemd')
+systemd_system_unit_dir = systemd.get_variable(
+    'systemdsystemunitdir',
+    pkgconfig_define: ['prefix', get_option('prefix')],
+)
+
+configure_file(
+    input: 'phosphor-ipmi-net@.service',
+    output: 'phosphor-ipmi-net@.service',
+    copy: true,
+    install_dir: systemd_system_unit_dir,
+)
+
+configure_file(
+    input: 'phosphor-ipmi-net@.socket',
+    output: 'phosphor-ipmi-net@.socket',
+    copy: true,
+    install_dir: systemd_system_unit_dir,
+)
+
+build_tests = get_option('tests')
+if build_tests.allowed()
+    subdir('test')
+endif
diff --git a/transport/rmcpbridge/meson.options b/transport/rmcpbridge/meson.options
new file mode 100644
index 0000000..6f9cbaa
--- /dev/null
+++ b/transport/rmcpbridge/meson.options
@@ -0,0 +1,15 @@
+option('tests', type: 'feature', value: 'enabled', description: 'Build tests')
+
+option(
+    'rmcp_ping',
+    type: 'feature',
+    value: 'enabled',
+    description: 'Enable RMCP Ping support',
+)
+
+option(
+    'pam_authenticate',
+    type: 'feature',
+    value: 'enabled',
+    description: 'Enable Pam Authenticate',
+)
diff --git a/transport/rmcpbridge/message.hpp b/transport/rmcpbridge/message.hpp
new file mode 100644
index 0000000..04dac27
--- /dev/null
+++ b/transport/rmcpbridge/message.hpp
@@ -0,0 +1,266 @@
+#pragma once
+
+#include "config.h"
+
+#include <cstddef>
+#include <memory>
+#include <numeric>
+#include <vector>
+
+namespace message
+{
+
+enum class PayloadType : uint8_t
+{
+    IPMI = 0x00,
+    SOL = 0x01,
+    OPEN_SESSION_REQUEST = 0x10,
+    OPEN_SESSION_RESPONSE = 0x11,
+    RAKP1 = 0x12,
+    RAKP2 = 0x13,
+    RAKP3 = 0x14,
+    RAKP4 = 0x15,
+    INVALID = 0xFF,
+};
+
+// RMCP Classes of Message as per section 13.1.3.
+enum class ClassOfMsg : uint8_t
+{
+    RESERVED = 0x05,
+    ASF = 0x06,
+    IPMI = 0x07,
+    OEM = 0x08,
+};
+
+#ifdef RMCP_PING
+// RMCP Message Type as per section 13.1.3.
+enum class RmcpMsgType : uint8_t
+{
+    PING = 0x80,
+    PONG = 0x40,
+};
+#endif // RMCP_PING
+
+namespace LAN
+{
+
+constexpr uint8_t requesterBMCAddress = 0x20;
+constexpr uint8_t responderBMCAddress = 0x81;
+
+namespace header
+{
+
+/**
+ * @struct IPMI LAN Message Request Header
+ */
+struct Request
+{
+    uint8_t rsaddr;
+    uint8_t netfn;
+    uint8_t cs;
+    uint8_t rqaddr;
+    uint8_t rqseq;
+    uint8_t cmd;
+} __attribute__((packed));
+
+/**
+ * @struct IPMI LAN Message Response Header
+ */
+struct Response
+{
+    uint8_t rqaddr;
+    uint8_t netfn;
+    uint8_t cs;
+    uint8_t rsaddr;
+    uint8_t rqseq;
+    uint8_t cmd;
+} __attribute__((packed));
+
+} // namespace header
+
+namespace trailer
+{
+
+/**
+ * @struct IPMI LAN Message Trailer
+ */
+struct Request
+{
+    uint8_t checksum;
+} __attribute__((packed));
+
+using Response = Request;
+
+} // namespace trailer
+
+} // namespace LAN
+
+/**
+ * @brief Calculate 8 bit 2's complement checksum
+ *
+ * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
+ * modulo 256. Then checksum = - checksum. When the checksum and the
+ * bytes are added together, modulo 256, the result should be 0.
+ */
+static inline uint8_t crc8bit(const uint8_t* ptr, const size_t len)
+{
+    return (0x100 - std::accumulate(ptr, ptr + len, 0));
+}
+
+/**
+ * @struct Message
+ *
+ * IPMI message is data encapsulated in an IPMI Session packet. The IPMI
+ * Session packets are encapsulated in RMCP packets, which are encapsulated in
+ * UDP datagrams. Refer Section 13.5 of IPMI specification(IPMI Messages
+ * Encapsulation Under RMCP). IPMI payload is a special class of data
+ * encapsulated in an IPMI session packet.
+ */
+struct Message
+{
+    static constexpr uint32_t MESSAGE_INVALID_SESSION_ID = 0xBADBADFF;
+
+    Message() :
+        payloadType(PayloadType::INVALID),
+        rcSessionID(Message::MESSAGE_INVALID_SESSION_ID),
+        bmcSessionID(Message::MESSAGE_INVALID_SESSION_ID),
+        rmcpMsgClass(ClassOfMsg::RESERVED)
+    {}
+
+    /**
+     * @brief Special behavior for copy constructor
+     *
+     * Based on incoming message state, the resulting message will have a
+     * pre-baked state. This is used to simplify the flows for creating a
+     * response message. For each pre-session state, the response message is
+     * actually a different type of message. Once the session has been
+     * established, the response type is the same as the request type.
+     */
+    Message(const Message& other) :
+        isPacketEncrypted(other.isPacketEncrypted),
+        isPacketAuthenticated(other.isPacketAuthenticated),
+        payloadType(other.payloadType), rcSessionID(other.rcSessionID),
+        bmcSessionID(other.bmcSessionID), rmcpMsgClass(other.rmcpMsgClass)
+    {
+        // special behavior for rmcp+ session creation
+        if (PayloadType::OPEN_SESSION_REQUEST == other.payloadType)
+        {
+            payloadType = PayloadType::OPEN_SESSION_RESPONSE;
+        }
+        else if (PayloadType::RAKP1 == other.payloadType)
+        {
+            payloadType = PayloadType::RAKP2;
+        }
+        else if (PayloadType::RAKP3 == other.payloadType)
+        {
+            payloadType = PayloadType::RAKP4;
+        }
+    }
+    Message& operator=(const Message&) = default;
+    Message(Message&&) = default;
+    Message& operator=(Message&&) = default;
+    ~Message() = default;
+
+    /**
+     * @brief Extract the command from the IPMI payload
+     *
+     * @return Command ID in the incoming message
+     */
+    uint32_t getCommand()
+    {
+        uint32_t command = 0;
+
+        command |= (static_cast<uint32_t>(payloadType) << 16);
+        if (payloadType == PayloadType::IPMI)
+        {
+            auto request =
+                reinterpret_cast<LAN::header::Request*>(payload.data());
+            command |= request->netfn << 8;
+            command |= static_cast<uint32_t>(request->cmd);
+        }
+        return command;
+    }
+
+    /**
+     * @brief Create the response IPMI message
+     *
+     * The IPMI outgoing message is constructed out of payload and the
+     * corresponding fields are populated. For the payload type IPMI, the
+     * LAN message header and trailer are added.
+     *
+     * @param[in] output - Payload for outgoing message
+     *
+     * @return Outgoing message on success and nullptr on failure
+     */
+    std::shared_ptr<Message> createResponse(std::vector<uint8_t>& output)
+    {
+        // SOL packets don't reply; return NULL
+        if (payloadType == PayloadType::SOL)
+        {
+            return nullptr;
+        }
+        auto outMessage = std::make_shared<Message>(*this);
+
+        if (payloadType == PayloadType::IPMI)
+        {
+            outMessage->payloadType = PayloadType::IPMI;
+
+            outMessage->payload.resize(
+                sizeof(LAN::header::Response) + output.size() +
+                sizeof(LAN::trailer::Response));
+
+            auto reqHeader =
+                reinterpret_cast<LAN::header::Request*>(payload.data());
+            auto respHeader = reinterpret_cast<LAN::header::Response*>(
+                outMessage->payload.data());
+
+            // Add IPMI LAN Message Response Header
+            respHeader->rqaddr = reqHeader->rqaddr;
+            respHeader->netfn = reqHeader->netfn | 0x04;
+            respHeader->cs = crc8bit(&(respHeader->rqaddr), 2);
+            respHeader->rsaddr = reqHeader->rsaddr;
+            respHeader->rqseq = reqHeader->rqseq;
+            respHeader->cmd = reqHeader->cmd;
+
+            auto assembledSize = sizeof(LAN::header::Response);
+
+            // Copy the output by the execution of the command
+            std::copy(output.begin(), output.end(),
+                      outMessage->payload.begin() + assembledSize);
+            assembledSize += output.size();
+
+            // Add the IPMI LAN Message Trailer
+            auto trailer = reinterpret_cast<LAN::trailer::Response*>(
+                outMessage->payload.data() + assembledSize);
+            trailer->checksum = crc8bit(&respHeader->rsaddr, assembledSize - 3);
+        }
+        else
+        {
+            outMessage->payload = output;
+        }
+        return outMessage;
+    }
+
+    bool isPacketEncrypted;     // Message's Encryption Status
+    bool isPacketAuthenticated; // Message's Authentication Status
+    PayloadType payloadType;    // Type of message payload (IPMI,SOL ..etc)
+    uint32_t rcSessionID;       // Remote Client's Session ID
+    uint32_t bmcSessionID;      // BMC's session ID
+    uint32_t sessionSeqNum;     // Session Sequence Number
+    ClassOfMsg rmcpMsgClass;    // Class of Message
+#ifdef RMCP_PING
+    uint8_t asfMsgTag;          // ASF Message Tag
+#endif                          // RMCP_PING
+
+    /** @brief Message payload
+     *
+     *  “Payloads” are a capability specified for RMCP+ that enable an IPMI
+     *  session to carry types of traffic that are in addition to IPMI Messages.
+     *  Payloads can be ‘standard’ or ‘OEM’.Standard payload types include IPMI
+     *  Messages, messages for session setup under RMCP+, and the payload for
+     *  the “Serial Over LAN” capability introduced in IPMI v2.0.
+     */
+    std::vector<uint8_t> payload;
+};
+
+} // namespace message
diff --git a/transport/rmcpbridge/message_handler.cpp b/transport/rmcpbridge/message_handler.cpp
new file mode 100644
index 0000000..b7365bb
--- /dev/null
+++ b/transport/rmcpbridge/message_handler.cpp
@@ -0,0 +1,233 @@
+#include "message_handler.hpp"
+
+#include "command_table.hpp"
+#include "main.hpp"
+#include "message.hpp"
+#include "message_parsers.hpp"
+#include "sessions_manager.hpp"
+
+#include <sys/socket.h>
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace message
+{
+
+bool Handler::receive()
+{
+    std::vector<uint8_t> packet;
+    auto readStatus = 0;
+
+    // Read the packet
+    std::tie(readStatus, packet) = channel->read();
+
+    // Read of the packet failed
+    if (readStatus < 0)
+    {
+        lg2::error("Error in Read status: {STATUS}", "STATUS", readStatus);
+        return false;
+    }
+
+    // Unflatten the packet
+    std::tie(inMessage, sessionHeader) = parser::unflatten(packet);
+
+    return true;
+}
+
+void Handler::updSessionData(std::shared_ptr<Message>& inMessage)
+{
+    session = session::Manager::get().getSession(inMessage->bmcSessionID);
+
+    sessionID = inMessage->bmcSessionID;
+    inMessage->rcSessionID = session->getRCSessionID();
+    session->updateLastTransactionTime();
+    session->channelPtr = channel;
+    session->remotePort(channel->getPort());
+    uint32_t ipAddr = 0;
+    channel->getRemoteAddress(ipAddr);
+    session->remoteIPAddr(ipAddr);
+}
+
+Handler::~Handler()
+{
+    try
+    {
+#ifdef RMCP_PING
+        if (inMessage && (ClassOfMsg::ASF == inMessage->rmcpMsgClass))
+        {
+            sendASF();
+        }
+        else
+#endif // RMCP_PING
+        {
+            if (outPayload)
+            {
+                std::shared_ptr<Message> outMessage =
+                    inMessage->createResponse(*outPayload);
+                if (!outMessage)
+                {
+                    return;
+                }
+                send(outMessage);
+            }
+        }
+    }
+    catch (const std::exception& e)
+    {
+        // send failed, most likely due to a session closure
+        lg2::info("Async RMCP+ reply failed: {ERROR}", "ERROR", e);
+    }
+}
+
+void Handler::processIncoming()
+{
+    // Read the incoming IPMI packet
+    if (!receive())
+    {
+        return;
+    }
+
+#ifdef RMCP_PING
+    // Execute the Command, possibly asynchronously
+    if (inMessage && (ClassOfMsg::ASF != inMessage->rmcpMsgClass))
+#endif // RMCP_PING
+    {
+        updSessionData(inMessage);
+        executeCommand();
+    }
+
+    // send happens during the destructor if a payload was set
+}
+
+void Handler::executeCommand()
+{
+    // Get the CommandID to map into the command table
+    auto command = inMessage->getCommand();
+    if (inMessage->payloadType == PayloadType::IPMI)
+    {
+        // Process PayloadType::IPMI only if ipmi is enabled or for sessionless
+        // or for session establisbment command
+        if (this->sessionID == session::sessionZero ||
+            session->sessionUserPrivAccess.ipmiEnabled)
+        {
+            if (inMessage->payload.size() <
+                (sizeof(LAN::header::Request) + sizeof(LAN::trailer::Request)))
+            {
+                return;
+            }
+
+            auto start = inMessage->payload.begin() +
+                         sizeof(LAN::header::Request);
+            auto end = inMessage->payload.end() - sizeof(LAN::trailer::Request);
+            std::vector<uint8_t> inPayload(start, end);
+            command::Table::get().executeCommand(command, inPayload,
+                                                 shared_from_this());
+        }
+        else
+        {
+            std::vector<uint8_t> payload{IPMI_CC_INSUFFICIENT_PRIVILEGE};
+            outPayload = std::move(payload);
+        }
+    }
+    else
+    {
+        command::Table::get().executeCommand(command, inMessage->payload,
+                                             shared_from_this());
+    }
+}
+
+void Handler::writeData(const std::vector<uint8_t>& packet)
+{
+    auto writeStatus = channel->write(packet);
+    if (writeStatus < 0)
+    {
+        throw std::runtime_error("Error in writing to socket");
+    }
+}
+
+#ifdef RMCP_PING
+void Handler::sendASF()
+{
+    // Flatten the packet
+    auto packet = asfparser::flatten(inMessage->asfMsgTag);
+
+    // Write the packet
+    writeData(packet);
+}
+#endif // RMCP_PING
+
+void Handler::send(std::shared_ptr<Message> outMessage)
+{
+    // Flatten the packet
+    auto packet = parser::flatten(outMessage, sessionHeader, session);
+
+    // Write the packet
+    writeData(packet);
+}
+
+void Handler::setChannelInSession() const
+{
+    session->channelPtr = channel;
+}
+
+void Handler::sendSOLPayload(const std::vector<uint8_t>& input)
+{
+    auto outMessage = std::make_shared<Message>();
+    outMessage->payloadType = PayloadType::SOL;
+    outMessage->payload = input;
+    outMessage->isPacketEncrypted = session->isCryptAlgoEnabled();
+    outMessage->isPacketAuthenticated = session->isIntegrityAlgoEnabled();
+    outMessage->rcSessionID = session->getRCSessionID();
+    outMessage->bmcSessionID = sessionID;
+
+    send(outMessage);
+}
+
+void Handler::sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd,
+                                         const std::vector<uint8_t>& output)
+{
+    auto outMessage = std::make_shared<Message>();
+    outMessage->payloadType = PayloadType::IPMI;
+    outMessage->isPacketEncrypted = session->isCryptAlgoEnabled();
+    outMessage->isPacketAuthenticated = session->isIntegrityAlgoEnabled();
+    outMessage->rcSessionID = session->getRCSessionID();
+    outMessage->bmcSessionID = sessionID;
+
+    outMessage->payload.resize(sizeof(LAN::header::Request) + output.size() +
+                               sizeof(LAN::trailer::Request));
+
+    auto respHeader =
+        reinterpret_cast<LAN::header::Request*>(outMessage->payload.data());
+
+    // Add IPMI LAN Message Request Header
+    respHeader->rsaddr = LAN::requesterBMCAddress;
+    respHeader->netfn = (netfn << 0x02);
+    respHeader->cs = crc8bit(&(respHeader->rsaddr), 2);
+    respHeader->rqaddr = LAN::responderBMCAddress;
+    respHeader->rqseq = 0;
+    respHeader->cmd = cmd;
+
+    auto assembledSize = sizeof(LAN::header::Request);
+
+    // Copy the output by the execution of the command
+    std::copy(output.begin(), output.end(),
+              outMessage->payload.begin() + assembledSize);
+    assembledSize += output.size();
+
+    // Add the IPMI LAN Message Trailer
+    auto trailer = reinterpret_cast<LAN::trailer::Request*>(
+        outMessage->payload.data() + assembledSize);
+
+    // Calculate the checksum for the field rqaddr in the header to the
+    // command data, 3 corresponds to size of the fields before rqaddr( rsaddr,
+    // netfn, cs).
+    trailer->checksum = crc8bit(&respHeader->rqaddr, assembledSize - 3);
+
+    send(outMessage);
+}
+
+} // namespace message
diff --git a/transport/rmcpbridge/message_handler.hpp b/transport/rmcpbridge/message_handler.hpp
new file mode 100644
index 0000000..c1a7032
--- /dev/null
+++ b/transport/rmcpbridge/message_handler.hpp
@@ -0,0 +1,155 @@
+#pragma once
+
+#include "message.hpp"
+#include "message_parsers.hpp"
+#include "session.hpp"
+#include "sessions_manager.hpp"
+#include "sol/console_buffer.hpp"
+
+#include <memory>
+
+namespace message
+{
+
+class Handler : public std::enable_shared_from_this<Handler>
+{
+  public:
+    /**
+     * @brief Create a Handler intended for a full transaction
+     *        that may or may not use asynchronous responses
+     */
+    Handler(std::shared_ptr<udpsocket::Channel> channel,
+            std::shared_ptr<boost::asio::io_context> io,
+            uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) :
+        sessionID(sessionID), channel(channel), io(io)
+    {
+        if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID)
+        {
+            session = session::Manager::get().getSession(sessionID);
+        }
+    }
+
+    /**
+     * @brief Create a Handler intended for a send only (SOL)
+     */
+    Handler(std::shared_ptr<udpsocket::Channel> channel,
+            uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) :
+        sessionID(sessionID), channel(channel), io(nullptr)
+    {
+        if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID)
+        {
+            session = session::Manager::get().getSession(sessionID);
+        }
+    }
+
+    ~Handler();
+    Handler() = delete;
+    Handler(const Handler&) = delete;
+    Handler& operator=(const Handler&) = delete;
+    Handler(Handler&&) = delete;
+    Handler& operator=(Handler&&) = delete;
+
+    /**
+     * @brief Process the incoming IPMI message
+     *
+     * The incoming payload is read from the channel. If a message is read, it
+     * is passed onto executeCommand, which may or may not execute the command
+     * asynchrounously. If the command is executed asynchrounously, a shared_ptr
+     * of self via shared_from_this will keep this object alive until the
+     * response is ready. Then on the destructor, the response will be sent.
+     */
+    void processIncoming();
+
+    /** @brief Set socket channel in session object */
+    void setChannelInSession() const;
+
+    /** @brief Send the SOL payload
+     *
+     *  The SOL payload is flattened and sent out on the socket
+     *
+     *  @param[in] input - SOL Payload
+     */
+    void sendSOLPayload(const std::vector<uint8_t>& input);
+
+    /** @brief Send the unsolicited IPMI payload to the remote console.
+     *
+     *  This is used by commands like SOL activating, in which case the BMC
+     *  has to notify the remote console that a SOL payload is activating
+     *  on another channel.
+     *
+     *  @param[in] netfn - Net function.
+     *  @param[in] cmd - Command.
+     *  @param[in] input - Command request data.
+     */
+    void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd,
+                                    const std::vector<uint8_t>& input);
+
+    // BMC Session ID for the Channel
+    session::SessionID sessionID;
+
+    /** @brief response to send back */
+    std::optional<std::vector<uint8_t>> outPayload;
+
+  private:
+    /**
+     * @brief Receive the IPMI packet
+     *
+     * Read the data on the socket, get the parser based on the Session
+     * header type and flatten the payload and generate the IPMI message
+     */
+    bool receive();
+
+    /**
+     * @brief Get Session data from the IPMI packet
+     *
+     */
+    void updSessionData(std::shared_ptr<Message>& inMessage);
+
+    /**
+     * @brief Process the incoming IPMI message
+     *
+     * The incoming message payload is handled and the command handler for
+     * the Network function and Command is executed and the response message
+     * is returned
+     */
+    void executeCommand();
+
+    /** @brief Send the outgoing message
+     *
+     *  The payload in the outgoing message is flattened and sent out on the
+     *  socket
+     *
+     *  @param[in] outMessage - Outgoing Message
+     */
+    void send(std::shared_ptr<Message> outMessage);
+
+#ifdef RMCP_PING
+    /** @brief Send the outgoing ASF message
+     *
+     *  The outgoing ASF message contains only ASF message header
+     *  which is flattened and sent out on the socket
+     */
+    void sendASF();
+#endif // RMCP_PING
+
+    /** @brief Write the packet to the socket
+     *
+     *  @param[in] packet - Outgoing packet
+     */
+    void writeData(const std::vector<uint8_t>& packet);
+
+    /** @brief Socket channel for communicating with the remote client.*/
+    std::shared_ptr<udpsocket::Channel> channel;
+
+    /** @brief asio io context to run asynchrounously */
+    std::shared_ptr<boost::asio::io_context> io;
+
+    parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20;
+
+    std::shared_ptr<message::Message> inMessage{};
+
+    /** @brief The IPMI session of the handler */
+    std::shared_ptr<session::Session> session{};
+};
+
+} // namespace message
diff --git a/transport/rmcpbridge/message_parsers.cpp b/transport/rmcpbridge/message_parsers.cpp
new file mode 100644
index 0000000..c4e4bd4
--- /dev/null
+++ b/transport/rmcpbridge/message_parsers.cpp
@@ -0,0 +1,466 @@
+#include "message_parsers.hpp"
+
+#include "endian.hpp"
+#include "main.hpp"
+#include "message.hpp"
+#include "sessions_manager.hpp"
+
+#include <memory>
+
+namespace message
+{
+
+namespace parser
+{
+
+std::tuple<std::shared_ptr<Message>, SessionHeader> unflatten(
+    std::vector<uint8_t>& inPacket)
+{
+    // Check if the packet has atleast the size of the RMCP Header
+    if (inPacket.size() < sizeof(RmcpHeader_t))
+    {
+        throw std::runtime_error("RMCP Header missing");
+    }
+
+    auto rmcpHeaderPtr = reinterpret_cast<RmcpHeader_t*>(inPacket.data());
+
+    // Verify if the fields in the RMCP header conforms to the specification
+    if ((rmcpHeaderPtr->version != RMCP_VERSION) ||
+        (rmcpHeaderPtr->rmcpSeqNum != RMCP_SEQ) ||
+        (rmcpHeaderPtr->classOfMsg < static_cast<uint8_t>(ClassOfMsg::ASF) &&
+         rmcpHeaderPtr->classOfMsg > static_cast<uint8_t>(ClassOfMsg::OEM)))
+    {
+        throw std::runtime_error("RMCP Header is invalid");
+    }
+
+    if (rmcpHeaderPtr->classOfMsg == static_cast<uint8_t>(ClassOfMsg::ASF))
+    {
+#ifndef RMCP_PING
+        throw std::runtime_error("RMCP Ping is not supported");
+#else
+        return std::make_tuple(asfparser::unflatten(inPacket),
+                               SessionHeader::IPMI15);
+#endif // RMCP_PING
+    }
+
+    auto sessionHeaderPtr = reinterpret_cast<BasicHeader_t*>(inPacket.data());
+
+    // Read the Session Header and invoke the parser corresponding to the
+    // header type
+    switch (static_cast<SessionHeader>(sessionHeaderPtr->format.formatType))
+    {
+        case SessionHeader::IPMI15:
+        {
+            return std::make_tuple(ipmi15parser::unflatten(inPacket),
+                                   SessionHeader::IPMI15);
+        }
+        case SessionHeader::IPMI20:
+        {
+            return std::make_tuple(ipmi20parser::unflatten(inPacket),
+                                   SessionHeader::IPMI20);
+        }
+        default:
+        {
+            throw std::runtime_error("Invalid Session Header");
+        }
+    }
+}
+
+std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
+                             SessionHeader authType,
+                             const std::shared_ptr<session::Session>& session)
+{
+    // Call the flatten routine based on the header type
+    switch (authType)
+    {
+        case SessionHeader::IPMI15:
+        {
+            return ipmi15parser::flatten(outMessage, session);
+        }
+        case SessionHeader::IPMI20:
+        {
+            return ipmi20parser::flatten(outMessage, session);
+        }
+        default:
+        {
+            return {};
+        }
+    }
+}
+
+} // namespace parser
+
+namespace ipmi15parser
+{
+
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
+{
+    if (inPacket.size() < sizeof(SessionHeader_t))
+    {
+        throw std::runtime_error("IPMI1.5 Session Header Missing");
+    }
+
+    auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data());
+
+    uint32_t sessionID = endian::from_ipmi(header->sessId);
+    if (sessionID != session::sessionZero)
+    {
+        throw std::runtime_error("IPMI1.5 session packets are unsupported");
+    }
+
+    auto message = std::make_shared<Message>();
+
+    message->payloadType = PayloadType::IPMI;
+    message->bmcSessionID = session::sessionZero;
+    message->sessionSeqNum = endian::from_ipmi(header->sessSeqNum);
+    message->isPacketEncrypted = false;
+    message->isPacketAuthenticated = false;
+    message->rmcpMsgClass =
+        static_cast<ClassOfMsg>(header->base.rmcp.classOfMsg);
+
+    // Confirm the number of data bytes received correlates to
+    // the packet length in the header
+    size_t payloadLen = header->payloadLength;
+    if ((payloadLen == 0) || (inPacket.size() < (sizeof(*header) + payloadLen)))
+    {
+        throw std::runtime_error("Invalid data length");
+    }
+
+    (message->payload)
+        .assign(inPacket.data() + sizeof(SessionHeader_t),
+                inPacket.data() + sizeof(SessionHeader_t) + payloadLen);
+
+    return message;
+}
+
+std::vector<uint8_t> flatten(
+    const std::shared_ptr<Message>& outMessage,
+    const std::shared_ptr<session::Session>& /* session */)
+{
+    std::vector<uint8_t> packet(sizeof(SessionHeader_t));
+
+    // Insert Session Header into the Packet
+    auto header = reinterpret_cast<SessionHeader_t*>(packet.data());
+    header->base.rmcp.version = parser::RMCP_VERSION;
+    header->base.rmcp.reserved = 0x00;
+    header->base.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
+    header->base.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::IPMI);
+    header->base.format.formatType =
+        static_cast<uint8_t>(parser::SessionHeader::IPMI15);
+    header->sessSeqNum = 0;
+    header->sessId = endian::to_ipmi(outMessage->rcSessionID);
+
+    header->payloadLength = static_cast<uint8_t>(outMessage->payload.size());
+
+    // Insert the Payload into the Packet
+    packet.insert(packet.end(), outMessage->payload.begin(),
+                  outMessage->payload.end());
+
+    // Insert the Session Trailer
+    packet.resize(packet.size() + sizeof(SessionTrailer_t));
+    auto trailer =
+        reinterpret_cast<SessionTrailer_t*>(packet.data() + packet.size());
+    trailer->legacyPad = 0x00;
+
+    return packet;
+}
+
+} // namespace ipmi15parser
+
+namespace ipmi20parser
+{
+
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
+{
+    // Check if the packet has atleast the Session Header
+    if (inPacket.size() < sizeof(SessionHeader_t))
+    {
+        throw std::runtime_error("IPMI2.0 Session Header Missing");
+    }
+
+    auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data());
+
+    uint32_t sessionID = endian::from_ipmi(header->sessId);
+
+    auto session = session::Manager::get().getSession(sessionID);
+    if (!session)
+    {
+        throw std::runtime_error("RMCP+ message from unknown session");
+    }
+
+    auto message = std::make_shared<Message>();
+
+    message->payloadType = static_cast<PayloadType>(header->payloadType & 0x3F);
+    message->bmcSessionID = sessionID;
+    message->sessionSeqNum = endian::from_ipmi(header->sessSeqNum);
+    message->isPacketEncrypted =
+        ((header->payloadType & PAYLOAD_ENCRYPT_MASK) ? true : false);
+    message->isPacketAuthenticated =
+        ((header->payloadType & PAYLOAD_AUTH_MASK) ? true : false);
+    message->rmcpMsgClass =
+        static_cast<ClassOfMsg>(header->base.rmcp.classOfMsg);
+
+    // Confirm the number of data bytes received correlates to
+    // the packet length in the header
+    size_t payloadLen = endian::from_ipmi(header->payloadLength);
+    if ((payloadLen == 0) || (inPacket.size() < (sizeof(*header) + payloadLen)))
+    {
+        throw std::runtime_error("Invalid data length");
+    }
+
+    bool integrityMismatch =
+        session->isIntegrityAlgoEnabled() && !message->isPacketAuthenticated;
+    bool encryptMismatch = session->isCryptAlgoEnabled() &&
+                           !message->isPacketEncrypted;
+
+    if (sessionID != session::sessionZero &&
+        (integrityMismatch || encryptMismatch))
+    {
+        throw std::runtime_error("unencrypted or unauthenticated message");
+    }
+
+    if (message->isPacketAuthenticated)
+    {
+        if (!(internal::verifyPacketIntegrity(inPacket, message, payloadLen,
+                                              session)))
+        {
+            throw std::runtime_error("Packet Integrity check failed");
+        }
+    }
+
+    // Decrypt the payload if the payload is encrypted
+    if (message->isPacketEncrypted)
+    {
+        // Assign the decrypted payload to the IPMI Message
+        message->payload =
+            internal::decryptPayload(inPacket, message, payloadLen, session);
+    }
+    else
+    {
+        message->payload.assign(
+            inPacket.begin() + sizeof(SessionHeader_t),
+            inPacket.begin() + sizeof(SessionHeader_t) + payloadLen);
+    }
+
+    return message;
+}
+
+std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
+                             const std::shared_ptr<session::Session>& session)
+{
+    std::vector<uint8_t> packet(sizeof(SessionHeader_t));
+
+    SessionHeader_t* header = reinterpret_cast<SessionHeader_t*>(packet.data());
+    header->base.rmcp.version = parser::RMCP_VERSION;
+    header->base.rmcp.reserved = 0x00;
+    header->base.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
+    header->base.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::IPMI);
+    header->base.format.formatType =
+        static_cast<uint8_t>(parser::SessionHeader::IPMI20);
+    header->payloadType = static_cast<uint8_t>(outMessage->payloadType);
+    header->sessId = endian::to_ipmi(outMessage->rcSessionID);
+
+    // Add session sequence number
+    internal::addSequenceNumber(packet, session);
+
+    size_t payloadLen = 0;
+
+    // Encrypt the payload if needed
+    if (outMessage->isPacketEncrypted)
+    {
+        header->payloadType |= PAYLOAD_ENCRYPT_MASK;
+        auto cipherPayload = internal::encryptPayload(outMessage, session);
+        payloadLen = cipherPayload.size();
+        header->payloadLength = endian::to_ipmi<uint16_t>(cipherPayload.size());
+
+        // Insert the encrypted payload into the outgoing IPMI packet
+        packet.insert(packet.end(), cipherPayload.begin(), cipherPayload.end());
+    }
+    else
+    {
+        header->payloadLength =
+            endian::to_ipmi<uint16_t>(outMessage->payload.size());
+        payloadLen = outMessage->payload.size();
+
+        // Insert the Payload into the Packet
+        packet.insert(packet.end(), outMessage->payload.begin(),
+                      outMessage->payload.end());
+    }
+
+    if (outMessage->isPacketAuthenticated)
+    {
+        header = reinterpret_cast<SessionHeader_t*>(packet.data());
+        header->payloadType |= PAYLOAD_AUTH_MASK;
+        internal::addIntegrityData(packet, outMessage, payloadLen, session);
+    }
+
+    return packet;
+}
+
+namespace internal
+{
+
+void addSequenceNumber(std::vector<uint8_t>& packet,
+                       const std::shared_ptr<session::Session>& session)
+{
+    SessionHeader_t* header = reinterpret_cast<SessionHeader_t*>(packet.data());
+
+    if (header->sessId == session::sessionZero)
+    {
+        header->sessSeqNum = 0x00;
+    }
+    else
+    {
+        auto seqNum = session->sequenceNums.increment();
+        header->sessSeqNum = endian::to_ipmi(seqNum);
+    }
+}
+
+bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
+                           const std::shared_ptr<Message>& /* message */,
+                           size_t payloadLen,
+                           const std::shared_ptr<session::Session>& session)
+{
+    /*
+     * Padding bytes are added to cause the number of bytes in the data range
+     * covered by the AuthCode(Integrity Data) field to be a multiple of 4 bytes
+     * .If present each integrity Pad byte is set to FFh. The following logic
+     * calculates the number of padding bytes added in the IPMI packet.
+     */
+    auto paddingLen = 4 - ((payloadLen + 2) & 3);
+
+    auto sessTrailerPos = sizeof(SessionHeader_t) + payloadLen + paddingLen;
+
+    // verify packet size includes trailer struct starts at sessTrailerPos
+    if (packet.size() < (sessTrailerPos + sizeof(SessionTrailer_t)))
+    {
+        return false;
+    }
+
+    auto trailer = reinterpret_cast<const SessionTrailer_t*>(
+        packet.data() + sessTrailerPos);
+
+    // Check trailer->padLength against paddingLen, both should match up,
+    // return false if the lengths don't match
+    if (trailer->padLength != paddingLen)
+    {
+        return false;
+    }
+
+    auto integrityAlgo = session->getIntegrityAlgo();
+
+    // Check if Integrity data length is as expected, check integrity data
+    // length is same as the length expected for the Integrity Algorithm that
+    // was negotiated during the session open process.
+    if ((packet.size() - sessTrailerPos - sizeof(SessionTrailer_t)) !=
+        integrityAlgo->authCodeLength)
+    {
+        return false;
+    }
+
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, sessTrailerPos + sizeof(SessionTrailer_t));
+
+    // The integrity data is calculated from the AuthType/Format field up to and
+    // including the field that immediately precedes the AuthCode field itself.
+    size_t length = packet.size() - integrityAlgo->authCodeLength -
+                    message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    return integrityAlgo->verifyIntegrityData(packet, length, integrityIter,
+                                              packet.cend());
+}
+
+void addIntegrityData(std::vector<uint8_t>& packet,
+                      const std::shared_ptr<Message>& /* message */,
+                      size_t payloadLen,
+                      const std::shared_ptr<session::Session>& session)
+{
+    // The following logic calculates the number of padding bytes to be added to
+    // IPMI packet. If needed each integrity Pad byte is set to FFh.
+    auto paddingLen = 4 - ((payloadLen + 2) & 3);
+    packet.insert(packet.end(), paddingLen, 0xFF);
+
+    packet.resize(packet.size() + sizeof(SessionTrailer_t));
+
+    auto trailer = reinterpret_cast<SessionTrailer_t*>(
+        packet.data() + packet.size() - sizeof(SessionTrailer_t));
+
+    trailer->padLength = paddingLen;
+    trailer->nextHeader = parser::RMCP_MESSAGE_CLASS_IPMI;
+
+    auto integrityData =
+        session->getIntegrityAlgo()->generateIntegrityData(packet);
+
+    packet.insert(packet.end(), integrityData.begin(), integrityData.end());
+}
+
+std::vector<uint8_t> decryptPayload(
+    const std::vector<uint8_t>& packet,
+    const std::shared_ptr<Message>& /* message */, size_t payloadLen,
+    const std::shared_ptr<session::Session>& session)
+{
+    return session->getCryptAlgo()->decryptPayload(
+        packet, sizeof(SessionHeader_t), payloadLen);
+}
+
+std::vector<uint8_t> encryptPayload(
+    const std::shared_ptr<Message>& message,
+    const std::shared_ptr<session::Session>& session)
+{
+    return session->getCryptAlgo()->encryptPayload(message->payload);
+}
+
+} // namespace internal
+
+} // namespace ipmi20parser
+
+#ifdef RMCP_PING
+namespace asfparser
+{
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
+{
+    auto message = std::make_shared<Message>();
+
+    auto header = reinterpret_cast<AsfMessagePing_t*>(inPacket.data());
+
+    message->payloadType = PayloadType::IPMI;
+    message->rmcpMsgClass = ClassOfMsg::ASF;
+    message->asfMsgTag = header->msgTag;
+
+    return message;
+}
+
+std::vector<uint8_t> flatten(uint8_t asfMsgTag)
+{
+    std::vector<uint8_t> packet(sizeof(AsfMessagePong_t));
+
+    // Insert RMCP header into the Packet
+    auto header = reinterpret_cast<AsfMessagePong_t*>(packet.data());
+    header->ping.rmcp.version = parser::RMCP_VERSION;
+    header->ping.rmcp.reserved = 0x00;
+    header->ping.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
+    header->ping.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::ASF);
+
+    // No OEM-specific capabilities exist, therefore the second
+    // IANA Enterprise Number contains the same IANA(4542)
+    header->ping.iana = header->iana = endian::to_ipmi(parser::ASF_IANA);
+    header->ping.msgType = static_cast<uint8_t>(RmcpMsgType::PONG);
+    header->ping.msgTag = asfMsgTag;
+    header->ping.reserved = 0x00;
+    header->ping.dataLen =
+        parser::RMCP_ASF_PONG_DATA_LEN; // as per spec 13.2.4,
+
+    header->iana = parser::ASF_IANA;
+    header->oemDefined = 0x00;
+    header->suppEntities = parser::ASF_SUPP_ENT;
+    header->suppInteract = parser::ASF_SUPP_INT;
+    header->reserved1 = 0x00;
+    header->reserved2 = 0x00;
+
+    return packet;
+}
+
+} // namespace asfparser
+#endif // RMCP_PING
+
+} // namespace message
diff --git a/transport/rmcpbridge/message_parsers.hpp b/transport/rmcpbridge/message_parsers.hpp
new file mode 100644
index 0000000..ed75ce2
--- /dev/null
+++ b/transport/rmcpbridge/message_parsers.hpp
@@ -0,0 +1,307 @@
+#pragma once
+
+#include "message.hpp"
+#include "session.hpp"
+
+#include <cstddef>
+
+namespace message
+{
+
+namespace parser
+{
+
+constexpr size_t RMCP_VERSION = 6;
+
+// RMCP Messages with class=IPMI should be sent with an RMCP Sequence
+// Number of FFh to indicate that an RMCP ACK message should not be
+// generated by the message receiver.
+constexpr size_t RMCP_SEQ = 0xFF;
+
+// RMCP Message Class 7h is for IPMI
+constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7;
+
+// RMCP Session Header Size
+constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;
+
+// RMCP/ASF Pong Message ASF Header Data Length
+// as per IPMI spec 13.2.4
+constexpr size_t RMCP_ASF_PONG_DATA_LEN = 16;
+
+// ASF IANA
+constexpr uint32_t ASF_IANA = 4542;
+
+// ASF Supported Entities
+constexpr uint32_t ASF_SUPP_ENT = 0x81;
+
+// ASF Supported Entities
+constexpr uint32_t ASF_SUPP_INT = 0x00;
+
+// Maximum payload size
+constexpr size_t MAX_PAYLOAD_SIZE = 255;
+
+enum class SessionHeader
+{
+    IPMI15 = 0x00,
+    IPMI20 = 0x06,
+    INVALID = 0xFF,
+};
+
+// RMCP Header
+struct RmcpHeader_t
+{
+    // RMCP Header
+    uint8_t version;
+    uint8_t reserved;
+    uint8_t rmcpSeqNum;
+    uint8_t classOfMsg;
+} __attribute__((packed));
+
+struct BasicHeader_t
+{
+    // RMCP Header
+    struct RmcpHeader_t rmcp;
+
+    // IPMI partial session header
+    union
+    {
+        uint8_t reserved1:4;
+        uint8_t authType:4;
+        uint8_t formatType;
+    } format;
+} __attribute__((packed));
+
+/**
+ * @brief Unflatten an incoming packet and prepare the IPMI message
+ *
+ * @param[in] inPacket - Incoming IPMI packet
+ *
+ * @return A tuple with IPMI message and the session header type to sent the
+ *         response packet. In case of success incoming message and session
+ *         header type. In case of failure nullptr and session header type
+ *         would be invalid.
+ */
+std::tuple<std::shared_ptr<Message>, SessionHeader> unflatten(
+    std::vector<uint8_t>& inPacket);
+
+/**
+ * @brief Flatten an IPMI message and generate the IPMI packet with the
+ *        session header
+ *
+ * @param[in] outMessage - IPMI message to be flattened
+ * @param[in] authType - Session header type to be added to the IPMI
+ *                       packet
+ *
+ * @return IPMI packet on success
+ */
+std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
+                             SessionHeader authType,
+                             const std::shared_ptr<session::Session>& session);
+
+} // namespace parser
+
+namespace ipmi15parser
+{
+
+struct SessionHeader_t
+{
+    struct parser::BasicHeader_t base;
+    uint32_t sessSeqNum;
+    uint32_t sessId;
+    // <Optional Field: AuthCode>
+    uint8_t payloadLength;
+} __attribute__((packed));
+
+struct SessionTrailer_t
+{
+    uint8_t legacyPad;
+} __attribute__((packed));
+
+/**
+ * @brief Unflatten an incoming packet and prepare the IPMI message
+ *
+ * @param[in] inPacket - Incoming IPMI packet
+ *
+ * @return IPMI message in the packet on success
+ */
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
+
+/**
+ * @brief Flatten an IPMI message and generate the IPMI packet with the
+ *        session header
+ *
+ * @param[in] outMessage - IPMI message to be flattened
+ *
+ * @return IPMI packet on success
+ */
+std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
+                             const std::shared_ptr<session::Session>& session);
+
+} // namespace ipmi15parser
+
+namespace ipmi20parser
+{
+
+constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
+constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
+constexpr size_t PAYLOAD_AUTH_MASK = 0x40;
+
+struct SessionHeader_t
+{
+    struct parser::BasicHeader_t base;
+
+    uint8_t payloadType;
+
+    uint32_t sessId;
+    uint32_t sessSeqNum;
+    uint16_t payloadLength;
+} __attribute__((packed));
+
+struct SessionTrailer_t
+{
+    // Integrity Pad
+    uint8_t padLength;
+    uint8_t nextHeader;
+} __attribute__((packed));
+
+/**
+ * @brief Unflatten an incoming packet and prepare the IPMI message
+ *
+ * @param[in] inPacket - Incoming IPMI packet
+ *
+ * @return IPMI message in the packet on success
+ */
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
+
+/**
+ * @brief Flatten an IPMI message and generate the IPMI packet with the
+ *        session header
+ *
+ * @param[in] outMessage - IPMI message to be flattened
+ * @param[in] session - session handle
+ *
+ * @return IPMI packet on success
+ */
+std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
+                             const std::shared_ptr<session::Session>& session);
+
+namespace internal
+{
+
+/**
+ * @brief Add sequence number to the message
+ *
+ * @param[in] packet - outgoing packet to which to add sequence number
+ * @param[in] session - session handle
+ *
+ */
+void addSequenceNumber(std::vector<uint8_t>& packet,
+                       const std::shared_ptr<session::Session>& session);
+
+/**
+ * @brief Verify the integrity data of the incoming IPMI packet
+ *
+ * @param[in] packet - Incoming IPMI packet
+ * @param[in] message - IPMI Message populated from the incoming packet
+ * @param[in] payloadLen - Length of the IPMI payload
+ * @param[in] session - session handle
+ *
+ */
+bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
+                           const std::shared_ptr<Message>& message,
+                           size_t payloadLen,
+                           const std::shared_ptr<session::Session>& session);
+
+/**
+ * @brief Add Integrity data to the outgoing IPMI packet
+ *
+ * @param[in] packet - Outgoing IPMI packet
+ * @param[in] message - IPMI Message populated for the outgoing packet
+ * @param[in] payloadLen - Length of the IPMI payload
+ */
+void addIntegrityData(std::vector<uint8_t>& packet,
+                      const std::shared_ptr<Message>& message,
+                      size_t payloadLen,
+                      const std::shared_ptr<session::Session>& session);
+
+/**
+ * @brief Decrypt the encrypted payload in the incoming IPMI packet
+ *
+ * @param[in] packet - Incoming IPMI packet
+ * @param[in] message - IPMI Message populated from the incoming packet
+ * @param[in] payloadLen - Length of encrypted IPMI payload
+ * @param[in] session - session handle
+ *
+ * @return on successful completion, return the plain text payload
+ */
+std::vector<uint8_t> decryptPayload(
+    const std::vector<uint8_t>& packet, const std::shared_ptr<Message>& message,
+    size_t payloadLen, const std::shared_ptr<session::Session>& session);
+
+/**
+ * @brief Encrypt the plain text payload for the outgoing IPMI packet
+ *
+ * @param[in] message - IPMI Message populated for the outgoing packet
+ * @param[in] session - session handle
+ *
+ * @return on successful completion, return the encrypted payload
+ */
+std::vector<uint8_t> encryptPayload(
+    const std::shared_ptr<Message>& message,
+    const std::shared_ptr<session::Session>& session);
+
+} // namespace internal
+
+} // namespace ipmi20parser
+
+#ifdef RMCP_PING
+namespace asfparser
+{
+
+// ASF message fields for RMCP Ping message
+struct AsfMessagePing_t
+{
+    struct parser::RmcpHeader_t rmcp;
+
+    uint32_t iana;
+    uint8_t msgType;
+    uint8_t msgTag;
+    uint8_t reserved;
+    uint8_t dataLen;
+} __attribute__((packed));
+
+// ASF message fields for RMCP Pong message
+struct AsfMessagePong_t
+{
+    struct AsfMessagePing_t ping;
+
+    uint32_t iana;
+    uint32_t oemDefined;
+    uint8_t suppEntities;
+    uint8_t suppInteract;
+    uint32_t reserved1;
+    uint16_t reserved2;
+} __attribute__((packed));
+
+/**
+ * @brief Unflatten an incoming packet and prepare the ASF message
+ *
+ * @param[in] inPacket - Incoming ASF packet
+ *
+ * @return ASF message in the packet on success
+ */
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
+
+/**
+ * @brief Generate the ASF packet with the RMCP header
+ *
+ * @param[in] asfMsgTag - ASF Message Tag from Ping request
+ *
+ * @return ASF packet on success
+ */
+std::vector<uint8_t> flatten(uint8_t asfMsgTag);
+
+} // namespace asfparser
+#endif // RMCP_PING
+
+} // namespace message
diff --git a/transport/rmcpbridge/phosphor-ipmi-net@.service b/transport/rmcpbridge/phosphor-ipmi-net@.service
new file mode 100644
index 0000000..beb3785
--- /dev/null
+++ b/transport/rmcpbridge/phosphor-ipmi-net@.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=Network IPMI daemon
+After=phosphor-ipmi-host.service
+Requires=sys-subsystem-net-devices-%i.device
+After=sys-subsystem-net-devices-%i.device
+ConditionPathExists=/sys/class/net/%i
+
+[Service]
+ExecStart=/usr/bin/netipmid -c %i
+SyslogIdentifier=netipmid-%i
+Restart=always
+RuntimeDirectory = ipmi
+RuntimeDirectoryPreserve = yes
+StateDirectory = ipmi
+
+[Install]
+DefaultInstance=eth0
+WantedBy=multi-user.target
+RequiredBy=
diff --git a/transport/rmcpbridge/phosphor-ipmi-net@.socket b/transport/rmcpbridge/phosphor-ipmi-net@.socket
new file mode 100644
index 0000000..7dddfb6
--- /dev/null
+++ b/transport/rmcpbridge/phosphor-ipmi-net@.socket
@@ -0,0 +1,10 @@
+[Unit]
+ConditionPathExists=/sys/class/net/%i
+
+[Socket]
+ListenDatagram=623
+BindToDevice=sys-subsystem-net-devices-%i.device
+
+[Install]
+WantedBy=sockets.target
+
diff --git a/transport/rmcpbridge/prng.hpp b/transport/rmcpbridge/prng.hpp
new file mode 100644
index 0000000..95946f7
--- /dev/null
+++ b/transport/rmcpbridge/prng.hpp
@@ -0,0 +1,16 @@
+#include <openssl/rand.h>
+
+namespace crypto
+{
+
+struct prng
+{
+    static unsigned int rand()
+    {
+        unsigned int v;
+        RAND_bytes(reinterpret_cast<unsigned char*>(&v), sizeof(v));
+        return v;
+    }
+};
+
+} // namespace crypto
diff --git a/transport/rmcpbridge/rmcp.hpp b/transport/rmcpbridge/rmcp.hpp
new file mode 100644
index 0000000..b18809a
--- /dev/null
+++ b/transport/rmcpbridge/rmcp.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+
+namespace rmcp
+{
+
+/*
+ * RSP needs more keying material than can be provided by session
+ * integrity key alone. As a result all keying material for the RSP
+ * confidentiality algorithms will be generated by processing a
+ * pre-defined set of constants using HMAC per [RFC2104], keyed by SIK.
+ * These constants are constructed using a hexadecimal octet value
+ * repeated up to the HMAC block size in length starting with the
+ * constant 01h. This mechanism can be used to derive up to 255
+ * HMAC-block-length pieces of keying material from a single SIK.For the
+ * mandatory confidentiality algorithm AES-CBC-128, processing the
+ * following constant will generate the required amount of keying
+ * material.
+ */
+constexpr size_t CONST_N_SIZE = 20;
+using Const_n = std::array<uint8_t, CONST_N_SIZE>;
+
+static constexpr Const_n const_1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+static constexpr Const_n const_2 = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+                                    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+                                    0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
+
+} // namespace rmcp
diff --git a/transport/rmcpbridge/sd_event_loop.cpp b/transport/rmcpbridge/sd_event_loop.cpp
new file mode 100644
index 0000000..4d55977
--- /dev/null
+++ b/transport/rmcpbridge/sd_event_loop.cpp
@@ -0,0 +1,262 @@
+#include "sd_event_loop.hpp"
+
+#include "main.hpp"
+#include "message_handler.hpp"
+
+#include <error.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <systemd/sd-daemon.h>
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/signal_set.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <user_channel/channel_layer.hpp>
+
+namespace eventloop
+{
+
+void EventLoop::handleRmcpPacket()
+{
+    try
+    {
+        auto channelPtr = std::make_shared<udpsocket::Channel>(udpSocket);
+
+        // Initialize the Message Handler with the socket channel
+        auto msgHandler = std::make_shared<message::Handler>(channelPtr, io);
+
+        msgHandler->processIncoming();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Executing the IPMI message failed: {ERROR}", "ERROR", e);
+    }
+}
+
+void EventLoop::startRmcpReceive()
+{
+    udpSocket->async_wait(
+        boost::asio::socket_base::wait_read,
+        [this](const boost::system::error_code& ec) {
+            if (!ec)
+            {
+                boost::asio::post(*io, [this]() { startRmcpReceive(); });
+                handleRmcpPacket();
+            }
+        });
+}
+
+int EventLoop::getVLANID(const std::string channel)
+{
+    int vlanid = 0;
+    if (channel.empty())
+    {
+        return 0;
+    }
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    // Enumerate all VLAN + ETHERNET interfaces
+    auto req = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
+                                   "GetSubTree");
+    req.append(PATH_ROOT, 0,
+               std::vector<std::string>{INTF_VLAN, INTF_ETHERNET});
+    ObjectTree objs;
+    try
+    {
+        auto reply = bus.call(req);
+        reply.read(objs);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("getVLANID: failed to execute/read GetSubTree: {ERROR}",
+                   "ERROR", e);
+        return 0;
+    }
+
+    std::string ifService, logicalPath;
+    for (const auto& [path, impls] : objs)
+    {
+        if (path.find(channel) == path.npos)
+        {
+            continue;
+        }
+        for (const auto& [service, intfs] : impls)
+        {
+            bool vlan = false;
+            bool ethernet = false;
+            for (const auto& intf : intfs)
+            {
+                if (intf == INTF_VLAN)
+                {
+                    vlan = true;
+                }
+                else if (intf == INTF_ETHERNET)
+                {
+                    ethernet = true;
+                }
+            }
+            if (ifService.empty() && (vlan || ethernet))
+            {
+                ifService = service;
+            }
+            if (logicalPath.empty() && vlan)
+            {
+                logicalPath = path;
+            }
+        }
+    }
+
+    // VLAN devices will always have a separate logical object
+    if (logicalPath.empty())
+    {
+        return 0;
+    }
+
+    Value value;
+    auto method = bus.new_method_call(ifService.c_str(), logicalPath.c_str(),
+                                      PROP_INTF, METHOD_GET);
+    method.append(INTF_VLAN, "Id");
+    try
+    {
+        auto method_reply = bus.call(method);
+        method_reply.read(value);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("getVLANID: failed to execute/read VLAN Id: {ERROR}",
+                   "ERROR", e);
+        return 0;
+    }
+
+    vlanid = std::get<uint32_t>(value);
+    if ((vlanid & VLAN_VALUE_MASK) != vlanid)
+    {
+        lg2::error("networkd returned an invalid vlan: {VLAN}", "VLAN", vlanid);
+        return 0;
+    }
+
+    return vlanid;
+}
+
+int EventLoop::setupSocket(std::shared_ptr<sdbusplus::asio::connection>& bus,
+                           std::string channel, uint16_t reqPort)
+{
+    std::string iface = channel;
+    static constexpr const char* unboundIface = "rmcpp";
+    if (channel == "")
+    {
+        iface = channel = unboundIface;
+    }
+    else
+    {
+        // If VLANID of this channel is set, bind the socket to this
+        // VLAN logic device
+        auto vlanid = getVLANID(channel);
+        if (vlanid)
+        {
+            iface = iface + "." + std::to_string(vlanid);
+            lg2::debug("This channel has VLAN id: {VLAN}", "VLAN", vlanid);
+        }
+    }
+    // Create our own socket if SysD did not supply one.
+    int listensFdCount = sd_listen_fds(0);
+    if (listensFdCount > 1)
+    {
+        lg2::error("Too many file descriptors received, listensFdCount: {FD}",
+                   "FD", listensFdCount);
+        return EXIT_FAILURE;
+    }
+    if (listensFdCount == 1)
+    {
+        int openFd = SD_LISTEN_FDS_START;
+        if (!sd_is_socket(openFd, AF_UNSPEC, SOCK_DGRAM, -1))
+        {
+            lg2::error("Failed to set up systemd-passed socket: {ERROR}",
+                       "ERROR", strerror(errno));
+            return EXIT_FAILURE;
+        }
+        udpSocket = std::make_shared<boost::asio::ip::udp::socket>(
+            *io, boost::asio::ip::udp::v6(), openFd);
+    }
+    else
+    {
+        // asio does not natively offer a way to bind to an interface
+        // so it must be done in steps
+        boost::asio::ip::udp::endpoint ep(boost::asio::ip::udp::v6(), reqPort);
+        udpSocket = std::make_shared<boost::asio::ip::udp::socket>(*io);
+        udpSocket->open(ep.protocol());
+        // bind
+        udpSocket->set_option(
+            boost::asio::ip::udp::socket::reuse_address(true));
+        udpSocket->bind(ep);
+    }
+    // SO_BINDTODEVICE
+    char nameout[IFNAMSIZ];
+    unsigned int lenout = sizeof(nameout);
+    if ((::getsockopt(udpSocket->native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
+                      nameout, &lenout) == -1))
+    {
+        lg2::error("Failed to read bound device: {ERROR}", "ERROR",
+                   strerror(errno));
+    }
+    if (iface != nameout && iface != unboundIface)
+    {
+        // SO_BINDTODEVICE
+        if ((::setsockopt(udpSocket->native_handle(), SOL_SOCKET,
+                          SO_BINDTODEVICE, iface.c_str(), iface.size() + 1) ==
+             -1))
+        {
+            lg2::error("Failed to bind to requested interface: {ERROR}",
+                       "ERROR", strerror(errno));
+            return EXIT_FAILURE;
+        }
+        lg2::info("Bind to interface: {INTERFACE}", "INTERFACE", iface);
+    }
+    // cannot be constexpr because it gets passed by address
+    const int option_enabled = 1;
+    // common socket stuff; set options to get packet info (DST addr)
+    ::setsockopt(udpSocket->native_handle(), IPPROTO_IP, IP_PKTINFO,
+                 &option_enabled, sizeof(option_enabled));
+    ::setsockopt(udpSocket->native_handle(), IPPROTO_IPV6, IPV6_RECVPKTINFO,
+                 &option_enabled, sizeof(option_enabled));
+
+    // set the dbus name
+    std::string busName = "xyz.openbmc_project.Ipmi.Channel." + channel;
+    try
+    {
+        bus->request_name(busName.c_str());
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to acquire D-Bus name: {NAME}: {ERROR}", "NAME",
+                   busName, "ERROR", e);
+        return EXIT_FAILURE;
+    }
+    return 0;
+}
+
+int EventLoop::startEventLoop()
+{
+    startRmcpReceive();
+
+    io->run();
+
+    return EXIT_SUCCESS;
+}
+
+void EventLoop::setupSignal()
+{
+    static boost::asio::signal_set signals(*io, SIGINT, SIGTERM);
+    signals.async_wait([this](const boost::system::error_code& /* error */,
+                              int /* signalNumber */) {
+        if (udpSocket)
+        {
+            udpSocket->cancel();
+            udpSocket->close();
+        }
+        io->stop();
+    });
+}
+
+} // namespace eventloop
diff --git a/transport/rmcpbridge/sd_event_loop.hpp b/transport/rmcpbridge/sd_event_loop.hpp
new file mode 100644
index 0000000..b40782c
--- /dev/null
+++ b/transport/rmcpbridge/sd_event_loop.hpp
@@ -0,0 +1,112 @@
+#pragma once
+
+#include "main.hpp"
+#include "sol/sol_manager.hpp"
+
+#include <systemd/sd-event.h>
+
+#include <boost/asio/io_context.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <chrono>
+#include <map>
+#include <string>
+
+namespace ipmi
+{
+namespace rmcpp
+{
+constexpr uint16_t defaultPort = 623;
+} // namespace rmcpp
+} // namespace ipmi
+
+namespace eventloop
+{
+using DbusObjectPath = std::string;
+using DbusService = std::string;
+using DbusInterface = std::string;
+using ObjectTree =
+    std::map<DbusObjectPath, std::map<DbusService, std::vector<DbusInterface>>>;
+using Value = std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
+                           int64_t, uint64_t, double, std::string>;
+// VLANs are a 12-bit value
+constexpr uint16_t VLAN_VALUE_MASK = 0x0fff;
+constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper";
+constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper";
+constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";
+constexpr auto PATH_ROOT = "/xyz/openbmc_project/network";
+constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN";
+constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface";
+constexpr auto METHOD_GET = "Get";
+constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
+
+class EventLoop
+{
+  private:
+    struct Private
+    {};
+
+  public:
+    EventLoop(std::shared_ptr<boost::asio::io_context>& io, const Private&) :
+        io(io)
+    {}
+    EventLoop() = delete;
+    ~EventLoop() = default;
+    EventLoop(const EventLoop&) = delete;
+    EventLoop& operator=(const EventLoop&) = delete;
+    EventLoop(EventLoop&&) = delete;
+    EventLoop& operator=(EventLoop&&) = delete;
+
+    /**
+     * @brief Get a reference to the singleton EventLoop
+     *
+     * @return EventLoop reference
+     */
+    static EventLoop& get()
+    {
+        static std::shared_ptr<EventLoop> ptr = nullptr;
+        if (!ptr)
+        {
+            std::shared_ptr<boost::asio::io_context> io = getIo();
+            ptr = std::make_shared<EventLoop>(io, Private());
+        }
+        return *ptr;
+    }
+
+    /** @brief Initialise the event loop and add the handler for incoming
+     *         IPMI packets.
+     *
+     *  @return EXIT_SUCCESS on success and EXIT_FAILURE on failure.
+     */
+    int startEventLoop();
+
+    /** @brief Set up the socket (if systemd has not already) and
+     *         make sure that the bus name matches the specified channel
+     */
+    int setupSocket(std::shared_ptr<sdbusplus::asio::connection>& bus,
+                    std::string iface,
+                    uint16_t reqPort = ipmi::rmcpp::defaultPort);
+
+    /** @brief set up boost::asio signal handling */
+    void setupSignal();
+
+  private:
+    /** @brief async handler for incoming udp packets */
+    void handleRmcpPacket();
+
+    /** @brief register the async handler for incoming udp packets */
+    void startRmcpReceive();
+
+    /** @brief get vlanid  */
+    int getVLANID(const std::string channel);
+
+    /** @brief boost::asio io context to run with
+     */
+    std::shared_ptr<boost::asio::io_context> io;
+
+    /** @brief boost::asio udp socket
+     */
+    std::shared_ptr<boost::asio::ip::udp::socket> udpSocket = nullptr;
+};
+
+} // namespace eventloop
diff --git a/transport/rmcpbridge/session.hpp b/transport/rmcpbridge/session.hpp
new file mode 100644
index 0000000..c12ec2c
--- /dev/null
+++ b/transport/rmcpbridge/session.hpp
@@ -0,0 +1,312 @@
+#pragma once
+
+#include "auth_algo.hpp"
+#include "crypt_algo.hpp"
+#include "endian.hpp"
+#include "integrity_algo.hpp"
+#include "prng.hpp"
+#include "socket_channel.hpp"
+
+#include <ipmid/api.hpp>
+#include <ipmid/sessiondef.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <user_channel/channel_layer.hpp>
+#include <user_channel/user_layer.hpp>
+#include <xyz/openbmc_project/Ipmi/SessionInfo/server.hpp>
+
+#include <chrono>
+#include <exception>
+#include <list>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace session
+{
+
+using namespace std::chrono_literals;
+using SessionID = uint32_t;
+
+enum class Privilege : uint8_t
+{
+    HIGHEST_MATCHING,
+    CALLBACK,
+    USER,
+    OPERATOR,
+    ADMIN,
+    OEM,
+};
+
+// Mask to get only the privilege from requested maximum privlege (RAKP message
+// 1)
+constexpr uint8_t reqMaxPrivMask = 0xF;
+
+/**
+ * @struct SequenceNumbers Session Sequence Numbers
+ *
+ * IPMI v2.0 RMCP+ Session Sequence Numbers are used for rejecting packets that
+ * may have been duplicated by the network or intentionally replayed. There are
+ * two sets of Session SequenceNumbers for a given session.One set of inbound
+ * and outbound sequence numbers is used for authenticated (signed) packets,
+ * and the other set is used for unauthenticated packets.
+ *
+ * The individual Session Sequence Numbers is are initialized to zero whenever
+ * a session is created and incremented by one at the start of outbound
+ * processing for a given packet (i.e. the first transmitted packet has a ‘1’
+ * as the sequence number, not 0). Session Sequence numbers are incremented for
+ * every packet that is transmitted by a given sender, regardless of whether
+ * the payload for the packet is a ‘retry’ or not.
+ */
+struct SequenceNumbers
+{
+    auto get(bool inbound = true) const
+    {
+        return inbound ? in : out;
+    }
+
+    void set(uint32_t seqNumber, bool inbound = true)
+    {
+        inbound ? (in = seqNumber) : (out = seqNumber);
+    }
+
+    auto increment()
+    {
+        return ++out;
+    }
+
+  private:
+    uint32_t in = 0;
+    uint32_t out = 0;
+};
+/**
+ * @class Session
+ *
+ * Encapsulates the data related to an IPMI Session
+ *
+ * Authenticated IPMI communication to the BMC is accomplished by establishing
+ * a session. Once established, a session is identified by a Session ID. The
+ * Session ID may be thought of as a handle that identifies a connection between
+ * a given remote user and the BMC. The specification supports having multiple
+ * active sessions established with the BMC. It is recommended that a BMC
+ * implementation support at least four simultaneous sessions
+ */
+
+using SessionIface = sdbusplus::server::object_t<
+    sdbusplus::xyz::openbmc_project::Ipmi::server::SessionInfo>;
+
+class Session : public SessionIface
+{
+  public:
+    Session() = delete;
+    ~Session() = default;
+    Session(const Session&) = delete;
+    Session& operator=(const Session&) = delete;
+    Session(Session&&) = delete;
+    Session& operator=(Session&&) = delete;
+
+    /**
+     * @brief Session Constructor
+     *
+     * This is issued by the Session Manager when a session is started for
+     * the Open SessionRequest command
+     *
+     * @param[in] inRemoteConsoleSessID - Remote Console Session ID
+     * @param[in] priv - Privilege Level requested in the Command
+     */
+    Session(sdbusplus::bus_t& bus, const char* path,
+            SessionID inRemoteConsoleSessID, SessionID BMCSessionID,
+            char priv) : SessionIface(bus, path)
+    {
+        reqMaxPrivLevel = static_cast<session::Privilege>(priv);
+        bmcSessionID = BMCSessionID;
+        remoteConsoleSessionID = inRemoteConsoleSessID;
+    }
+
+    auto getBMCSessionID() const
+    {
+        return bmcSessionID;
+    }
+
+    auto getRCSessionID() const
+    {
+        return remoteConsoleSessionID;
+    }
+
+    auto getAuthAlgo() const
+    {
+        if (authAlgoInterface)
+        {
+            return authAlgoInterface.get();
+        }
+        else
+        {
+            throw std::runtime_error("Authentication Algorithm Empty");
+        }
+    }
+
+    void setAuthAlgo(std::unique_ptr<cipher::rakp_auth::Interface>&& inAuthAlgo)
+    {
+        authAlgoInterface = std::move(inAuthAlgo);
+    }
+
+    /**
+     * @brief Get Session's Integrity Algorithm
+     *
+     * @return pointer to the integrity algorithm
+     */
+    auto getIntegrityAlgo() const
+    {
+        if (integrityAlgoInterface)
+        {
+            return integrityAlgoInterface.get();
+        }
+        else
+        {
+            throw std::runtime_error("Integrity Algorithm Empty");
+        }
+    }
+
+    /**
+     * @brief Set Session's Integrity Algorithm
+     *
+     * @param[in] integrityAlgo - unique pointer to integrity algorithm
+     *                              instance
+     */
+    void setIntegrityAlgo(
+        std::unique_ptr<cipher::integrity::Interface>&& integrityAlgo)
+    {
+        integrityAlgoInterface = std::move(integrityAlgo);
+    }
+
+    /** @brief Check if integrity algorithm is enabled for this session.
+     *
+     *  @return true if integrity algorithm is enabled else false.
+     */
+    auto isIntegrityAlgoEnabled()
+    {
+        return integrityAlgoInterface ? true : false;
+    }
+
+    /**
+     * @brief Get Session's Confidentiality Algorithm
+     *
+     * @return pointer to the confidentiality algorithm
+     */
+    auto getCryptAlgo() const
+    {
+        if (cryptAlgoInterface)
+        {
+            return cryptAlgoInterface.get();
+        }
+        else
+        {
+            throw std::runtime_error("Confidentiality Algorithm Empty");
+        }
+    }
+
+    /**
+     * @brief Set Session's Confidentiality Algorithm
+     *
+     * @param[in] confAlgo - unique pointer to confidentiality algorithm
+     *                       instance
+     */
+    void setCryptAlgo(std::unique_ptr<cipher::crypt::Interface>&& cryptAlgo)
+    {
+        cryptAlgoInterface = std::move(cryptAlgo);
+    }
+
+    /** @brief Check if confidentiality algorithm is enabled for this
+     *         session.
+     *
+     *  @return true if confidentiality algorithm is enabled else false.
+     */
+    auto isCryptAlgoEnabled()
+    {
+        return cryptAlgoInterface ? true : false;
+    }
+
+    void updateLastTransactionTime()
+    {
+        lastTime = std::chrono::steady_clock::now();
+    }
+
+    /**
+     * @brief Session Active Status
+     *
+     * Session Active status is decided upon the Session State and the last
+     * transaction time is compared against the session inactivity timeout.
+     *
+     * @param[in] activeGrace - microseconds of idle time for active sessions
+     * @param[in] setupGrace - microseconds of idle time for sessions in setup
+     *
+     */
+    bool isSessionActive(const std::chrono::microseconds& activeGrace,
+                         const std::chrono::microseconds& setupGrace)
+    {
+        auto currentTime = std::chrono::steady_clock::now();
+        auto elapsedMicros =
+            std::chrono::duration_cast<std::chrono::microseconds>(
+                currentTime - lastTime);
+
+        State state = static_cast<session::State>(this->state());
+
+        switch (state)
+        {
+            case State::active:
+                if (elapsedMicros < activeGrace)
+                {
+                    return true;
+                }
+                break;
+            case State::setupInProgress:
+                if (elapsedMicros < setupGrace)
+                {
+                    return true;
+                }
+                break;
+            case State::tearDownInProgress:
+                break;
+            default:
+                break;
+        }
+        return false;
+    }
+
+    /**
+     * @brief Session's Requested Maximum Privilege Level
+     */
+    Privilege reqMaxPrivLevel;
+
+    /**
+     * @brief session's user & channel access details
+     */
+    ipmi::PrivAccess sessionUserPrivAccess{};
+    ipmi::ChannelAccess sessionChannelAccess{};
+
+    SequenceNumbers sequenceNums; // Session Sequence Numbers
+    std::string userName{};       // User Name
+
+    /** @brief Socket channel for communicating with the remote client.*/
+    std::shared_ptr<udpsocket::Channel> channelPtr;
+
+  private:
+    SessionID bmcSessionID = 0;           // BMC Session ID
+    SessionID remoteConsoleSessionID = 0; // Remote Console Session ID
+
+    // Authentication Algorithm Interface for the Session
+    std::unique_ptr<cipher::rakp_auth::Interface> authAlgoInterface;
+
+    // Integrity Algorithm Interface for the Session
+    std::unique_ptr<cipher::integrity::Interface> integrityAlgoInterface =
+        nullptr;
+
+    // Confidentiality Algorithm Interface for the Session
+    std::unique_ptr<cipher::crypt::Interface> cryptAlgoInterface = nullptr;
+
+    // Last Transaction Time
+    decltype(std::chrono::steady_clock::now()) lastTime;
+};
+
+} // namespace session
diff --git a/transport/rmcpbridge/sessions_manager.cpp b/transport/rmcpbridge/sessions_manager.cpp
new file mode 100644
index 0000000..8c18cba
--- /dev/null
+++ b/transport/rmcpbridge/sessions_manager.cpp
@@ -0,0 +1,353 @@
+#include "sessions_manager.hpp"
+
+#include "main.hpp"
+#include "session.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <user_channel/channel_layer.hpp>
+
+#include <algorithm>
+#include <cstdlib>
+#include <iomanip>
+#include <memory>
+
+namespace session
+{
+
+static std::array<uint8_t, session::maxNetworkInstanceSupported>
+    ipmiNetworkChannelNumList = {0};
+
+void Manager::setNetworkInstance(void)
+{
+    uint8_t index = 0, ch = 1;
+    // Constructing net-ipmid instances list based on channel info
+    // valid channel start from 1 to 15  and assuming max 4 LAN channel
+    // supported
+
+    while (ch < ipmi::maxIpmiChannels &&
+           index < session::maxNetworkInstanceSupported)
+    {
+        ipmi::ChannelInfo chInfo;
+        ipmi::getChannelInfo(ch, chInfo);
+        if (static_cast<ipmi::EChannelMediumType>(chInfo.mediumType) ==
+            ipmi::EChannelMediumType::lan8032)
+        {
+            if (getInterfaceIndex() == ch)
+            {
+                ipmiNetworkInstance = index;
+            }
+
+            ipmiNetworkChannelNumList[index] = ch;
+            index++;
+        }
+        ch++;
+    }
+}
+
+uint8_t Manager::getNetworkInstance(void)
+{
+    return ipmiNetworkInstance;
+}
+
+void Manager::managerInit(const std::string& channel)
+{
+    /*
+     * Session ID is 0000_0000h for messages that are sent outside the session.
+     * The session setup commands are sent on this session, so when the session
+     * manager comes up, is creates the Session ID  0000_0000h. It is active
+     * through the lifetime of the Session Manager.
+     */
+
+    objManager = std::make_unique<sdbusplus::server::manager_t>(
+        *getSdBus(), session::sessionManagerRootPath);
+
+    auto objPath = std::string(session::sessionManagerRootPath) + "/" +
+                   channel + "/0";
+
+    chName = channel;
+    setNetworkInstance();
+    sessionsMap.emplace(
+        0, std::make_shared<Session>(*getSdBus(), objPath.c_str(), 0, 0, 0));
+
+    // set up the timer for clearing out stale sessions
+    scheduleSessionCleaner(std::chrono::microseconds(3 * 1000 * 1000));
+}
+
+std::shared_ptr<Session> Manager::startSession(
+    SessionID remoteConsoleSessID, Privilege priv,
+    cipher::rakp_auth::Algorithms authAlgo,
+    cipher::integrity::Algorithms intAlgo, cipher::crypt::Algorithms cryptAlgo)
+{
+    std::shared_ptr<Session> session = nullptr;
+    SessionID bmcSessionID = 0;
+    cleanStaleEntries();
+    // set up the timer for monitoring this session
+    scheduleSessionCleaner(std::chrono::microseconds(1 * 1000 * 1000));
+
+    uint8_t sessionHandle = 0;
+
+    auto activeSessions = sessionsMap.size() - session::maxSessionlessCount;
+
+    if (activeSessions < maxSessionHandles)
+    {
+        do
+        {
+            bmcSessionID = (crypto::prng::rand());
+            bmcSessionID &= session::multiIntfaceSessionIDMask;
+            // In sessionID , BIT 31 BIT30 are used for netipmid instance
+            bmcSessionID |= static_cast<uint32_t>(ipmiNetworkInstance) << 30;
+            /*
+             * Every IPMI Session has two ID's attached to it Remote Console
+             * Session ID and BMC Session ID. The remote console ID is passed
+             * along with the Open Session request command. The BMC session ID
+             * is the key for the session map and is generated using std::rand.
+             * There is a rare chance for collision of BMC session ID, so the
+             * following check validates that. In the case of collision the
+             * created session is reset and a new session is created for
+             * validating collision.
+             */
+            auto iterator = sessionsMap.find(bmcSessionID);
+            if (iterator != sessionsMap.end())
+            {
+                // Detected BMC Session ID collisions
+                continue;
+            }
+            else
+            {
+                break;
+            }
+        } while (1);
+
+        sessionHandle = storeSessionHandle(bmcSessionID);
+
+        if (!sessionHandle)
+        {
+            throw std::runtime_error(
+                "Invalid sessionHandle - No sessionID slot ");
+        }
+        sessionHandle &= session::multiIntfaceSessionHandleMask;
+        // In sessionID , BIT 31 BIT30 are used for netipmid instance
+        sessionHandle |= static_cast<uint8_t>(ipmiNetworkInstance) << 6;
+        std::stringstream sstream;
+        sstream << std::hex << bmcSessionID;
+        std::stringstream shstream;
+        shstream << std::hex << (int)sessionHandle;
+        auto objPath = std::string(session::sessionManagerRootPath) + "/" +
+                       chName + "/" + sstream.str() + "_" + shstream.str();
+        session = std::make_shared<Session>(*getSdBus(), objPath.c_str(),
+                                            remoteConsoleSessID, bmcSessionID,
+                                            static_cast<uint8_t>(priv));
+
+        // Set the Authentication Algorithm
+        switch (authAlgo)
+        {
+            case cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA1:
+            {
+                session->setAuthAlgo(
+                    std::make_unique<cipher::rakp_auth::AlgoSHA1>(intAlgo,
+                                                                  cryptAlgo));
+                break;
+            }
+            case cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA256:
+            {
+                session->setAuthAlgo(
+                    std::make_unique<cipher::rakp_auth::AlgoSHA256>(intAlgo,
+                                                                    cryptAlgo));
+                break;
+            }
+            default:
+            {
+                throw std::runtime_error("Invalid Authentication Algorithm");
+            }
+        }
+
+        sessionsMap.emplace(bmcSessionID, session);
+        session->sessionHandle(sessionHandle);
+
+        return session;
+    }
+
+    lg2::info("No free RMCP+ sessions left");
+
+    throw std::runtime_error("No free sessions left");
+}
+
+bool Manager::stopSession(SessionID bmcSessionID)
+{
+    auto iter = sessionsMap.find(bmcSessionID);
+    if (iter != sessionsMap.end())
+    {
+        iter->second->state(
+            static_cast<uint8_t>(session::State::tearDownInProgress));
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+std::shared_ptr<Session> Manager::getSession(SessionID sessionID,
+                                             RetrieveOption option)
+{
+    switch (option)
+    {
+        case RetrieveOption::BMC_SESSION_ID:
+        {
+            auto iter = sessionsMap.find(sessionID);
+            if (iter != sessionsMap.end())
+            {
+                return iter->second;
+            }
+            break;
+        }
+        case RetrieveOption::RC_SESSION_ID:
+        {
+            auto iter = std::find_if(
+                sessionsMap.begin(), sessionsMap.end(),
+                [sessionID](
+                    const std::pair<const uint32_t, std::shared_ptr<Session>>&
+                        in) -> bool {
+                    return sessionID == in.second->getRCSessionID();
+                });
+
+            if (iter != sessionsMap.end())
+            {
+                return iter->second;
+            }
+            break;
+        }
+        default:
+            throw std::runtime_error("Invalid retrieval option");
+    }
+
+    throw std::runtime_error("Session ID not found");
+}
+
+void Manager::cleanStaleEntries()
+{
+    // with overflow = min(1, max - active sessions)
+    // active idle time in seconds = 60 / overflow^3
+    constexpr int baseIdleMicros = 60 * 1000 * 1000;
+    // no +1 for the zero session here because this is just active sessions
+    int sessionDivisor =
+        getActiveSessionCount() - session::maxSessionCountPerChannel;
+    sessionDivisor = std::max(0, sessionDivisor) + 1;
+    sessionDivisor = sessionDivisor * sessionDivisor * sessionDivisor;
+    int activeMicros = baseIdleMicros / sessionDivisor;
+
+    // with overflow = min(1, max - total sessions)
+    // setup idle time in seconds = max(3, 60 / overflow^3)
+
+    // +1 for the zero session here because size() counts that too
+    int setupDivisor =
+        sessionsMap.size() - (session::maxSessionCountPerChannel + 1);
+    setupDivisor = std::max(0, setupDivisor) + 1;
+    setupDivisor = setupDivisor * setupDivisor * setupDivisor;
+    constexpr int maxSetupMicros = 3 * 1000 * 1000;
+    int setupMicros = std::min(maxSetupMicros, baseIdleMicros / setupDivisor);
+
+    std::chrono::microseconds activeGrace(activeMicros);
+    std::chrono::microseconds setupGrace(setupMicros);
+
+    for (auto iter = sessionsMap.begin(); iter != sessionsMap.end();)
+    {
+        auto session = iter->second;
+        // special handling for sessionZero
+        if (session->getBMCSessionID() == session::sessionZero)
+        {
+            iter++;
+            continue;
+        }
+        if (!(session->isSessionActive(activeGrace, setupGrace)))
+        {
+            lg2::info(
+                "Removing idle IPMI LAN session, id: {ID}, handler: {HANDLE}",
+                "ID", session->getBMCSessionID(), "HANDLE",
+                getSessionHandle(session->getBMCSessionID()));
+            sessionHandleMap[getSessionHandle(session->getBMCSessionID())] = 0;
+            iter = sessionsMap.erase(iter);
+        }
+        else
+        {
+            iter++;
+        }
+    }
+    if (sessionsMap.size() > 1)
+    {
+        constexpr int maxCleanupDelay = 1 * 1000 * 1000;
+        std::chrono::microseconds cleanupDelay(
+            std::min(setupMicros, maxCleanupDelay));
+        scheduleSessionCleaner(cleanupDelay);
+    }
+}
+
+uint8_t Manager::storeSessionHandle(SessionID bmcSessionID)
+{
+    // Handler index 0 is  reserved for invalid session.
+    // index starts with 1, for direct usage. Index 0 reserved
+    for (size_t i = 1; i < session::maxSessionHandles; i++)
+    {
+        if (sessionHandleMap[i] == 0)
+        {
+            sessionHandleMap[i] = bmcSessionID;
+            return i;
+        }
+    }
+    return 0;
+}
+
+uint32_t Manager::getSessionIDbyHandle(uint8_t sessionHandle) const
+{
+    if (sessionHandle < session::maxSessionHandles)
+    {
+        return sessionHandleMap[sessionHandle];
+    }
+    return 0;
+}
+
+uint8_t Manager::getSessionHandle(SessionID bmcSessionID) const
+{
+    // Handler index 0 is reserved for invalid session.
+    // index starts with 1, for direct usage. Index 0 reserved
+    for (size_t i = 1; i < session::maxSessionHandles; i++)
+    {
+        if (sessionHandleMap[i] == bmcSessionID)
+        {
+            return (i);
+        }
+    }
+    return 0;
+}
+uint8_t Manager::getActiveSessionCount() const
+{
+    return (std::count_if(
+        sessionsMap.begin(), sessionsMap.end(),
+        [](const std::pair<const uint32_t, std::shared_ptr<Session>>& in)
+            -> bool {
+            return in.second->state() ==
+                   static_cast<uint8_t>(session::State::active);
+        }));
+}
+
+void Manager::scheduleSessionCleaner(const std::chrono::microseconds& when)
+{
+    std::chrono::duration expTime =
+        timer.expiry() - boost::asio::steady_timer::clock_type::now();
+    if (expTime > std::chrono::microseconds(0) && expTime < when)
+    {
+        // if timer has not already expired AND requested timeout is greater
+        // than current timeout then ignore this new requested timeout
+        return;
+    }
+    timer.expires_after(when);
+    timer.async_wait([this](const boost::system::error_code& ec) {
+        if (!ec)
+        {
+            cleanStaleEntries();
+        }
+    });
+}
+
+} // namespace session
diff --git a/transport/rmcpbridge/sessions_manager.hpp b/transport/rmcpbridge/sessions_manager.hpp
new file mode 100644
index 0000000..d6f847b
--- /dev/null
+++ b/transport/rmcpbridge/sessions_manager.hpp
@@ -0,0 +1,167 @@
+#pragma once
+
+#include "main.hpp"
+#include "session.hpp"
+
+#include <boost/asio/steady_timer.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/sessiondef.hpp>
+
+#include <chrono>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string>
+
+namespace session
+{
+
+enum class RetrieveOption
+{
+    BMC_SESSION_ID,
+    RC_SESSION_ID,
+};
+
+static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask;
+
+/**
+ * @class Manager
+ *
+ * Manager class acts a manager for the IPMI sessions and provides interfaces
+ * to start a session, stop a session and get reference to the session objects.
+ *
+ */
+
+class Manager
+{
+  private:
+    struct Private
+    {};
+
+  public:
+    // BMC Session ID is the key for the map
+    using SessionMap = std::map<SessionID, std::shared_ptr<Session>>;
+
+    Manager() = delete;
+    Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) :
+        io(io), timer(*io) {};
+    ~Manager() = default;
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = default;
+    Manager& operator=(Manager&&) = default;
+
+    /**
+     * @brief Get a reference to the singleton Manager
+     *
+     * @return Manager reference
+     */
+    static Manager& get()
+    {
+        static std::shared_ptr<Manager> ptr = nullptr;
+        if (!ptr)
+        {
+            std::shared_ptr<boost::asio::io_context> io = getIo();
+            ptr = std::make_shared<Manager>(io, Private());
+            if (!ptr)
+            {
+                throw std::runtime_error("failed to create session manager");
+            }
+        }
+        return *ptr;
+    }
+
+    /**
+     * @brief Start an IPMI session
+     *
+     * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned
+     *            in the Open SessionRequest Command
+     * @param[in] priv - Privilege level requested
+     * @param[in] authAlgo - Authentication Algorithm
+     * @param[in] intAlgo - Integrity Algorithm
+     * @param[in] cryptAlgo - Confidentiality Algorithm
+     *
+     * @return session handle on success and nullptr on failure
+     *
+     */
+    std::shared_ptr<Session> startSession(
+        SessionID remoteConsoleSessID, Privilege priv,
+        cipher::rakp_auth::Algorithms authAlgo,
+        cipher::integrity::Algorithms intAlgo,
+        cipher::crypt::Algorithms cryptAlgo);
+
+    /**
+     * @brief Stop IPMI Session
+     *
+     * @param[in] bmcSessionID - BMC Session ID
+     *
+     * @return true on success and failure if session ID is invalid
+     *
+     */
+    bool stopSession(SessionID bmcSessionID);
+
+    /**
+     * @brief Get Session Handle
+     *
+     * @param[in] sessionID - Session ID
+     * @param[in] option - Select between BMC Session ID and Remote Console
+     *            Session ID, Default option is BMC Session ID
+     *
+     * @return session handle on success and nullptr on failure
+     *
+     */
+    std::shared_ptr<Session> getSession(
+        SessionID sessionID,
+        RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
+    uint8_t getActiveSessionCount() const;
+    uint8_t getSessionHandle(SessionID bmcSessionID) const;
+    uint8_t storeSessionHandle(SessionID bmcSessionID);
+    uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const;
+
+    void managerInit(const std::string& channel);
+
+    uint8_t getNetworkInstance(void);
+
+    /**
+     * @brief Clean Session Stale Entries
+     *
+     *  Schedules cleaning the inactive sessions entries from the Session Map
+     */
+    void scheduleSessionCleaner(const std::chrono::microseconds& grace);
+
+  private:
+    /**
+     * @brief reclaim system resources by limiting idle sessions
+     *
+     * Limits on active, authenticated sessions are calculated independently
+     * from in-setup sessions, which are not required to be authenticated. This
+     * will prevent would-be DoS attacks by calling a bunch of Open Session
+     * requests to fill up all available sessions. Too many active sessions will
+     * trigger a shorter timeout, but is unaffected by setup session counts.
+     *
+     * For active sessions, grace time is inversely proportional to (the number
+     * of active sessions beyond max sessions per channel)^3
+     *
+     * For sessions in setup, grace time is inversely proportional to (the
+     * number of total sessions beyond max sessions per channel)^3, with a max
+     * of 3 seconds
+     */
+    void cleanStaleEntries();
+
+    std::shared_ptr<boost::asio::io_context> io;
+    boost::asio::steady_timer timer;
+
+    std::array<uint32_t, session::maxSessionHandles> sessionHandleMap = {0};
+
+    /**
+     * @brief Session Manager keeps the session objects as a sorted
+     *        associative container with Session ID as the unique key
+     */
+    SessionMap sessionsMap;
+    std::unique_ptr<sdbusplus::server::manager_t> objManager = nullptr;
+    std::string chName{}; // Channel Name
+    uint8_t ipmiNetworkInstance = 0;
+    void setNetworkInstance(void);
+};
+
+} // namespace session
diff --git a/transport/rmcpbridge/socket_channel.hpp b/transport/rmcpbridge/socket_channel.hpp
new file mode 100644
index 0000000..0edfcd5
--- /dev/null
+++ b/transport/rmcpbridge/socket_channel.hpp
@@ -0,0 +1,245 @@
+#pragma once
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <boost/asio/ip/udp.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <variant>
+#include <vector>
+
+namespace udpsocket
+{
+static constexpr uint8_t v4v6Index = 12;
+
+/** @class Channel
+ *
+ *  @brief Provides encapsulation for UDP socket operations like Read, Peek,
+ *         Write, Remote peer's IP Address and Port.
+ */
+class Channel
+{
+  public:
+    Channel() = delete;
+    ~Channel() = default;
+    Channel(const Channel& right) = delete;
+    Channel& operator=(const Channel& right) = delete;
+    Channel(Channel&&) = delete;
+    Channel& operator=(Channel&&) = delete;
+
+    /**
+     * @brief Constructor
+     *
+     * Initialize the IPMI socket object with the socket descriptor
+     *
+     * @param [in] pointer to a boost::asio udp socket object
+     *
+     * @return None
+     */
+    explicit Channel(std::shared_ptr<boost::asio::ip::udp::socket> socket) :
+        socket(socket)
+    {}
+    /**
+     * @brief Check if ip address is ipv4 mapped ipv6
+     *
+     *  @param v6Addr : in6_addr obj
+     *
+     * @return true if ipv4 mapped ipv6 else return false
+     */
+    bool isIpv4InIpv6(const struct in6_addr& v6Addr) const
+    {
+        constexpr uint8_t prefix[v4v6Index] = {0, 0, 0, 0, 0,    0,
+                                               0, 0, 0, 0, 0xff, 0xff};
+        return 0 == std::memcmp(&v6Addr.s6_addr[0], &prefix[0], sizeof(prefix));
+    }
+    /**
+     * @brief Fetch the IP address of the remote peer
+     *
+     *  @param remoteIpv4Addr : ipv4 address is assigned to it.
+     *
+     * Returns the IP address of the remote peer which is connected to this
+     * socket
+     *
+     * @return IP address of the remote peer
+     */
+    std::string getRemoteAddress(uint32_t& remoteIpv4Addr) const
+    {
+        const char* retval = nullptr;
+        if (sockAddrSize == sizeof(sockaddr_in))
+        {
+            char ipv4addr[INET_ADDRSTRLEN];
+            const sockaddr_in* sa =
+                reinterpret_cast<const sockaddr_in*>(&remoteSockAddr);
+            remoteIpv4Addr = sa->sin_addr.s_addr;
+            retval =
+                inet_ntop(AF_INET, &(sa->sin_addr), ipv4addr, sizeof(ipv4addr));
+        }
+        else if (sockAddrSize == sizeof(sockaddr_in6))
+        {
+            char ipv6addr[INET6_ADDRSTRLEN];
+            const sockaddr_in6* sa =
+                reinterpret_cast<const sockaddr_in6*>(&remoteSockAddr);
+
+            if (isIpv4InIpv6(sa->sin6_addr))
+            {
+                std::copy_n(&sa->sin6_addr.s6_addr[v4v6Index],
+                            sizeof(remoteIpv4Addr),
+                            reinterpret_cast<uint8_t*>(&remoteIpv4Addr));
+            }
+            retval = inet_ntop(AF_INET6, &(sa->sin6_addr), ipv6addr,
+                               sizeof(ipv6addr));
+        }
+
+        if (retval)
+        {
+            return retval;
+        }
+        lg2::error("Error in inet_ntop: {ERROR}", "ERROR", strerror(errno));
+        return std::string();
+    }
+
+    /**
+     * @brief Fetch the port number of the remote peer
+     *
+     * Returns the port number of the remote peer
+     *
+     * @return Port number
+     *
+     */
+    uint16_t getPort() const
+    {
+        if (sockAddrSize == sizeof(sockaddr_in))
+        {
+            return ntohs(reinterpret_cast<const sockaddr_in*>(&remoteSockAddr)
+                             ->sin_port);
+        }
+        if (sockAddrSize == sizeof(sockaddr_in6))
+        {
+            return ntohs(reinterpret_cast<const sockaddr_in6*>(&remoteSockAddr)
+                             ->sin6_port);
+        }
+        return 0;
+    }
+
+    /**
+     * @brief Read the incoming packet
+     *
+     * Reads the data available on the socket
+     *
+     * @return A tuple with return code and vector with the buffer
+     *         In case of success, the vector is populated with the data
+     *         available on the socket and return code is 0.
+     *         In case of error, the return code is < 0 and vector is set
+     *         to size 0.
+     */
+    std::tuple<int, std::vector<uint8_t>> read()
+    {
+        // cannot use the standard asio reading mechanism because it does not
+        // provide a mechanism to reach down into the depths and use a msghdr
+        std::vector<uint8_t> packet(socket->available());
+        iovec iov = {packet.data(), packet.size()};
+        char msgCtrl[1024];
+        msghdr msg = {&remoteSockAddr, sizeof(remoteSockAddr), &iov, 1,
+                      msgCtrl,         sizeof(msgCtrl),        0};
+
+        ssize_t bytesReceived = recvmsg(socket->native_handle(), &msg, 0);
+        // Read of the packet failed
+        if (bytesReceived < 0)
+        {
+            // something bad happened; bail
+            lg2::error("Error in recvmsg: {ERROR}", "ERROR",
+                       strerror(-bytesReceived));
+            return std::make_tuple(-errno, std::vector<uint8_t>());
+        }
+        // save the size of either ipv4 or i4v6 sockaddr
+        sockAddrSize = msg.msg_namelen;
+
+        // extract the destination address from the message
+        cmsghdr* cmsg;
+        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != 0;
+             cmsg = CMSG_NXTHDR(&msg, cmsg))
+        {
+            if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
+            {
+                // save local address from the pktinfo4
+                pktinfo4 = *reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+            }
+            if (cmsg->cmsg_level == IPPROTO_IPV6 &&
+                cmsg->cmsg_type == IPV6_PKTINFO)
+            {
+                // save local address from the pktinfo6
+                pktinfo6 = *reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+            }
+        }
+        return std::make_tuple(0, packet);
+    }
+
+    /**
+     *  @brief Write the outgoing packet
+     *
+     *  Writes the data in the vector to the socket
+     *
+     *  @param [in] inBuffer
+     *      The vector would be the buffer of data to write to the socket.
+     *
+     *  @return In case of success the return code is the number of bytes
+     *          written and return code is < 0 in case of failure.
+     */
+    int write(const std::vector<uint8_t>& inBuffer)
+    {
+        // in order to make sure packets go back out from the same
+        // IP address they came in on, sendmsg must be used instead
+        // of the boost::asio::ip::send or sendto
+        iovec iov = {const_cast<uint8_t*>(inBuffer.data()), inBuffer.size()};
+        char msgCtrl[1024];
+        msghdr msg = {&remoteSockAddr, sockAddrSize,    &iov, 1,
+                      msgCtrl,         sizeof(msgCtrl), 0};
+        int cmsg_space = 0;
+        cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+        if (pktinfo6)
+        {
+            cmsg->cmsg_level = IPPROTO_IPV6;
+            cmsg->cmsg_type = IPV6_PKTINFO;
+            cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
+            *reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg)) = *pktinfo6;
+            cmsg_space += CMSG_SPACE(sizeof(in6_pktinfo));
+        }
+        else if (pktinfo4)
+        {
+            cmsg->cmsg_level = IPPROTO_IP;
+            cmsg->cmsg_type = IP_PKTINFO;
+            cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
+            *reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg)) = *pktinfo4;
+            cmsg_space += CMSG_SPACE(sizeof(in_pktinfo));
+        }
+        msg.msg_controllen = cmsg_space;
+        int ret = sendmsg(socket->native_handle(), &msg, 0);
+        if (ret < 0)
+        {
+            lg2::error("Error in sendmsg: {ERROR}", "ERROR", strerror(-ret));
+        }
+        return ret;
+    }
+
+    /**
+     * @brief Returns file descriptor for the socket
+     */
+    auto getHandle(void) const
+    {
+        return socket->native_handle();
+    }
+
+  private:
+    std::shared_ptr<boost::asio::ip::udp::socket> socket;
+    sockaddr_storage remoteSockAddr;
+    socklen_t sockAddrSize;
+    std::optional<in_pktinfo> pktinfo4;
+    std::optional<in6_pktinfo> pktinfo6;
+};
+
+} // namespace udpsocket
diff --git a/transport/rmcpbridge/sol/console_buffer.hpp b/transport/rmcpbridge/sol/console_buffer.hpp
new file mode 100644
index 0000000..dbb75c9
--- /dev/null
+++ b/transport/rmcpbridge/sol/console_buffer.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <deque>
+#include <vector>
+
+namespace sol
+{
+
+using ConsoleBuffer = std::deque<uint8_t>;
+
+/** @class ConsoleData
+ *
+ *  The console data is the buffer that holds the data that comes from the host
+ *  console which is to be sent to the remote console. The buffer is needed due
+ *  to the latency with the IPMI remote client. The current support for the
+ *  buffer is to support one instance of the SOL payload.
+ */
+class ConsoleData
+{
+  public:
+    /** @brief Get the current size of the host console buffer.
+     *
+     *  @return size of the host console buffer.
+     */
+    auto size() const noexcept
+    {
+        return data.size();
+    }
+
+    /** @brief Read host console data.
+     *
+     *  This API would return the iterator to the read data from the
+     *  console data buffer.
+     *
+     *  @return iterator to read data from the buffer
+     */
+    auto read() const
+    {
+        return data.cbegin();
+    }
+
+    /** @brief Write host console data.
+     *
+     *  This API would append the input data to the host console buffer.
+     *
+     *  @param[in] input - data to be written to the console buffer.
+     */
+    void write(const std::vector<uint8_t>& input)
+    {
+        data.insert(data.end(), input.begin(), input.end());
+    }
+
+    /** @brief Erase console buffer.
+     *
+     *  @param[in] size - the number of bytes to be erased from the console
+     *                    buffer.
+     *
+     *  @note If the console buffer has less bytes that that was requested,
+     *        then the available size is erased.
+     */
+    void erase(size_t size) noexcept
+    {
+        data.erase(data.begin(), data.begin() + std::min(data.size(), size));
+    }
+
+  private:
+    /** @brief Storage for host console data. */
+    ConsoleBuffer data;
+};
+
+} // namespace sol
diff --git a/transport/rmcpbridge/sol/sol_context.cpp b/transport/rmcpbridge/sol/sol_context.cpp
new file mode 100644
index 0000000..21632a4
--- /dev/null
+++ b/transport/rmcpbridge/sol/sol_context.cpp
@@ -0,0 +1,348 @@
+#include "sol_context.hpp"
+
+#include "main.hpp"
+#include "message_handler.hpp"
+#include "sd_event_loop.hpp"
+#include "sessions_manager.hpp"
+#include "sol_manager.hpp"
+
+#include <errno.h>
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace sol
+{
+using namespace phosphor::logging;
+
+Context::Context(std::shared_ptr<boost::asio::io_context> io,
+                 uint8_t maxRetryCount, uint8_t sendThreshold, uint8_t instance,
+                 session::SessionID sessionID) :
+    accumulateTimer(*io), retryTimer(*io), maxRetryCount(maxRetryCount),
+    retryCounter(maxRetryCount), sendThreshold(sendThreshold),
+    payloadInstance(instance), sessionID(sessionID)
+{
+    session = session::Manager::get().getSession(sessionID);
+}
+
+std::shared_ptr<Context> Context::makeContext(
+    std::shared_ptr<boost::asio::io_context> io, uint8_t maxRetryCount,
+    uint8_t sendThreshold, uint8_t instance, session::SessionID sessionID)
+{
+    auto ctx = std::make_shared<Context>(io, maxRetryCount, sendThreshold,
+                                         instance, sessionID);
+    ctx->enableAccumulateTimer(true);
+    return ctx;
+}
+
+void Context::enableAccumulateTimer(bool enable)
+{
+    // fetch the timeout from the SOL manager
+    std::chrono::microseconds interval = sol::Manager::get().accumulateInterval;
+
+    if (enable)
+    {
+        auto bufferSize = sol::Manager::get().dataBuffer.size();
+        if (bufferSize > sendThreshold)
+        {
+            try
+            {
+                int rc = sendOutboundPayload();
+                if (rc == 0)
+                {
+                    return;
+                }
+            }
+            catch (const std::exception& e)
+            {
+                lg2::error(
+                    "Failed to call the sendOutboundPayload method: {ERROR}",
+                    "ERROR", e);
+                return;
+            }
+        }
+        accumulateTimer.expires_after(interval);
+        std::weak_ptr<Context> weakRef = weak_from_this();
+        accumulateTimer.async_wait(
+            [weakRef](const boost::system::error_code& ec) {
+                std::shared_ptr<Context> self = weakRef.lock();
+                if (!ec && self)
+                {
+                    self->charAccTimerHandler();
+                }
+            });
+    }
+    else
+    {
+        accumulateTimer.cancel();
+    }
+}
+
+void Context::enableRetryTimer(bool enable)
+{
+    if (enable)
+    {
+        // fetch the timeout from the SOL manager
+        std::chrono::microseconds interval = sol::Manager::get().retryInterval;
+        retryTimer.expires_after(interval);
+        std::weak_ptr<Context> weakRef = weak_from_this();
+        retryTimer.async_wait([weakRef](const boost::system::error_code& ec) {
+            std::shared_ptr<Context> self = weakRef.lock();
+            if (!ec && self)
+            {
+                self->retryTimerHandler();
+            }
+        });
+    }
+    else
+    {
+        retryTimer.cancel();
+    }
+}
+
+void Context::processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum,
+                                    uint8_t count, bool status, bool isBreak,
+                                    const std::vector<uint8_t>& input)
+{
+    uint8_t respAckSeqNum = 0;
+    uint8_t acceptedCount = 0;
+    auto ack = false;
+
+    /*
+     * Check if the Inbound sequence number is same as the expected one.
+     * If the Packet Sequence Number is 0, it is an ACK-Only packet. Multiple
+     * outstanding sequence numbers are not supported in this version of the SOL
+     * specification. Retried packets use the same sequence number as the first
+     * packet.
+     */
+    if (seqNum && (seqNum != seqNums.get(true)))
+    {
+        lg2::info("Out of sequence SOL packet - packet is dropped");
+        return;
+    }
+
+    /*
+     * Check if the expected ACK/NACK sequence number is same as the
+     * ACK/NACK sequence number in the packet. If packet ACK/NACK sequence
+     * number is 0, then it is an informational packet. No request packet being
+     * ACK'd or NACK'd.
+     */
+    if (ackSeqNum && (ackSeqNum != seqNums.get(false)))
+    {
+        lg2::info("Out of sequence ack number - SOL packet is dropped");
+        return;
+    }
+
+    /*
+     * Retry the SOL payload packet in the following conditions:
+     *
+     * a) NACK in Operation/Status
+     * b) Accepted Character Count does not match with the sent out SOL payload
+     * c) Non-zero Packet ACK/NACK Sequence Number
+     */
+    if (status || ((count != expectedCharCount) && ackSeqNum))
+    {
+        resendPayload(noClear);
+        enableRetryTimer(false);
+        enableRetryTimer(true);
+        return;
+    }
+    /*
+     * Clear the sent data once the acknowledgment sequence number matches
+     * and the expected character count matches.
+     */
+    else if ((count == expectedCharCount) && ackSeqNum)
+    {
+        // Clear the Host Console Buffer
+        sol::Manager::get().dataBuffer.erase(count);
+
+        // Once it is acknowledged stop the retry interval timer
+        enableRetryTimer(false);
+
+        retryCounter = maxRetryCount;
+        expectedCharCount = 0;
+        payloadCache.clear();
+    }
+
+    if (isBreak && seqNum)
+    {
+        lg2::info("Writing break to console socket descriptor");
+        constexpr uint8_t sysrqValue = 72; // use this to notify sol server
+        const std::vector<uint8_t> test{sysrqValue};
+        auto ret = sol::Manager::get().writeConsoleSocket(test, isBreak);
+        if (ret)
+        {
+            lg2::error("Writing to console socket descriptor failed: {ERROR}",
+                       "ERROR", strerror(errno));
+        }
+    }
+
+    isBreak = false;
+    // Write character data to the Host Console
+    if (!input.empty() && seqNum)
+    {
+        auto rc = sol::Manager::get().writeConsoleSocket(input, isBreak);
+        if (rc)
+        {
+            lg2::error("Writing to console socket descriptor failed: {ERROR}",
+                       "ERROR", strerror(errno));
+            ack = true;
+        }
+        else
+        {
+            respAckSeqNum = seqNum;
+            ack = false;
+            acceptedCount = input.size();
+        }
+    }
+    /*
+     * SOL payload with no character data and valid sequence number can be used
+     * as method to keep the SOL session active.
+     */
+    else if (input.empty() && seqNum)
+    {
+        respAckSeqNum = seqNum;
+    }
+
+    if (seqNum != 0)
+    {
+        seqNums.incInboundSeqNum();
+        prepareResponse(respAckSeqNum, acceptedCount, ack);
+    }
+    else
+    {
+        enableAccumulateTimer(true);
+    }
+}
+
+void Context::prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack)
+{
+    auto bufferSize = sol::Manager::get().dataBuffer.size();
+
+    /* Sent a ACK only response */
+    if (payloadCache.size() != 0 || (bufferSize < sendThreshold))
+    {
+        enableAccumulateTimer(true);
+
+        std::vector<uint8_t> outPayload(sizeof(Payload));
+        auto response = reinterpret_cast<Payload*>(outPayload.data());
+        response->packetSeqNum = 0;
+        response->packetAckSeqNum = ackSeqNum;
+        response->acceptedCharCount = count;
+        response->outOperation.ack = ack;
+        sendPayload(outPayload);
+        return;
+    }
+
+    auto readSize = std::min(bufferSize, MAX_PAYLOAD_SIZE);
+    payloadCache.resize(sizeof(Payload) + readSize);
+    auto response = reinterpret_cast<Payload*>(payloadCache.data());
+    response->packetAckSeqNum = ackSeqNum;
+    response->acceptedCharCount = count;
+    response->outOperation.ack = ack;
+    response->packetSeqNum = seqNums.incOutboundSeqNum();
+
+    auto handle = sol::Manager::get().dataBuffer.read();
+    std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload));
+    expectedCharCount = readSize;
+
+    enableRetryTimer(true);
+    enableAccumulateTimer(false);
+
+    sendPayload(payloadCache);
+}
+
+int Context::sendOutboundPayload()
+{
+    if (payloadCache.size() != 0)
+    {
+        return -1;
+    }
+
+    auto bufferSize = sol::Manager::get().dataBuffer.size();
+    auto readSize = std::min(bufferSize, MAX_PAYLOAD_SIZE);
+
+    payloadCache.resize(sizeof(Payload) + readSize);
+    auto response = reinterpret_cast<Payload*>(payloadCache.data());
+    response->packetAckSeqNum = 0;
+    response->acceptedCharCount = 0;
+    response->outOperation.ack = false;
+    response->packetSeqNum = seqNums.incOutboundSeqNum();
+
+    auto handle = sol::Manager::get().dataBuffer.read();
+    std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload));
+    expectedCharCount = readSize;
+
+    enableRetryTimer(true);
+    enableAccumulateTimer(false);
+
+    sendPayload(payloadCache);
+
+    return 0;
+}
+
+void Context::resendPayload(bool clear)
+{
+    sendPayload(payloadCache);
+
+    if (clear)
+    {
+        payloadCache.clear();
+        expectedCharCount = 0;
+        sol::Manager::get().dataBuffer.erase(expectedCharCount);
+    }
+}
+
+void Context::sendPayload(const std::vector<uint8_t>& out) const
+{
+    message::Handler msgHandler(session->channelPtr, sessionID);
+
+    msgHandler.sendSOLPayload(out);
+}
+
+void Context::charAccTimerHandler()
+{
+    auto bufferSize = sol::Manager::get().dataBuffer.size();
+
+    try
+    {
+        if (bufferSize > 0)
+        {
+            int rc = sendOutboundPayload();
+            if (rc == 0)
+            {
+                return;
+            }
+        }
+        enableAccumulateTimer(true);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to call the sendOutboundPayload method: {ERROR}",
+                   "ERROR", e);
+    }
+}
+
+void Context::retryTimerHandler()
+{
+    try
+    {
+        if (retryCounter)
+        {
+            --retryCounter;
+            enableRetryTimer(true);
+            resendPayload(sol::Context::noClear);
+        }
+        else
+        {
+            retryCounter = maxRetryCount;
+            resendPayload(sol::Context::clear);
+            enableRetryTimer(false);
+            enableAccumulateTimer(true);
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to retry timer: {ERROR}", "ERROR", e);
+    }
+}
+} // namespace sol
diff --git a/transport/rmcpbridge/sol/sol_context.hpp b/transport/rmcpbridge/sol/sol_context.hpp
new file mode 100644
index 0000000..981360e
--- /dev/null
+++ b/transport/rmcpbridge/sol/sol_context.hpp
@@ -0,0 +1,312 @@
+#pragma once
+
+#include "console_buffer.hpp"
+#include "session.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
+
+#include <cstddef>
+
+namespace sol
+{
+
+/** @struct Outbound
+ *
+ *  Operation/Status in an outbound SOL payload format(BMC to Remote Console).
+ */
+struct Outbound
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t testMode:2;        //!< Not supported.
+    uint8_t breakDetected:1;   //!< Not supported.
+    uint8_t transmitOverrun:1; //!< Not supported.
+    uint8_t SOLDeactivating:1; //!< 0 : SOL is active, 1 : SOL deactivated.
+    uint8_t charUnavailable:1; //!< 0 : Available, 1 : Unavailable.
+    uint8_t ack:1;             //!< 0 : ACK, 1 : NACK.
+    uint8_t reserved:1;        //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved:1;        //!< Reserved.
+    uint8_t ack:1;             //!< 0 : ACK, 1 : NACK.
+    uint8_t charUnavailable:1; //!< 0 : Available, 1 : Unavailable.
+    uint8_t SOLDeactivating:1; //!< 0 : SOL is active, 1 : SOL deactivated.
+    uint8_t transmitOverrun:1; //!< Not supported.
+    uint8_t breakDetected:1;   //!< Not supported.
+    uint8_t testMode:2;        //!< Not supported.
+#endif
+} __attribute__((packed));
+
+/** @struct Inbound
+ *
+ *  Operation/Status in an Inbound SOL Payload format(Remote Console to BMC).
+ */
+struct Inbound
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t flushOut:1;      //!< Not supported.
+    uint8_t flushIn:1;       //!< Not supported.
+    uint8_t dcd:1;           //!< Not supported.
+    uint8_t cts:1;           //!< Not supported.
+    uint8_t generateBreak:1; //!< Not supported.
+    uint8_t ring:1;          //!< Not supported.
+    uint8_t ack:1;           //!< 0 : ACK, 1 : NACK.
+    uint8_t reserved:1;      //!< Reserved.
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved:1;      //!< Reserved.
+    uint8_t ack:1;           //!< 0 : ACK, 1 : NACK.
+    uint8_t ring:1;          //!< Not supported.
+    uint8_t generateBreak:1; //!< Not supported.
+    uint8_t cts:1;           //!< Not supported.
+    uint8_t dcd:1;           //!< Not supported.
+    uint8_t flushIn:1;       //!< Not supported.
+    uint8_t flushOut:1;      //!< Not supported.
+#endif
+} __attribute__((packed));
+
+/** @struct Payload
+ *
+ *  SOL Payload Data Format.The following fields make up the SOL payload in an
+ *  RMCP+ packet, followed by the console character data.
+ */
+struct Payload
+{
+    uint8_t packetSeqNum;      //!< Packet sequence number
+    uint8_t packetAckSeqNum;   //!< Packet ACK/NACK sequence number
+    uint8_t acceptedCharCount; //!< Accepted character count
+    union
+    {
+        uint8_t operation;            //!< Operation/Status
+        struct Outbound outOperation; //!< BMC to Remote Console
+        struct Inbound inOperation;   //!< Remote Console to BMC
+    };
+} __attribute__((packed));
+
+namespace internal
+{
+
+/** @struct SequenceNumbers
+ *
+ *  SOL sequence numbers. At the session level, SOL Payloads share the session
+ *  sequence numbers for authenticated and unauthenticated packets with other
+ *  packets under the IPMI session. At the payload level, SOL packets include
+ *  their own message sequence numbers that are used for tracking missing and
+ *  retried SOL messages. The sequence numbers must be non-zero. Retried
+ *  packets use the same sequence number as the first packet.
+ */
+struct SequenceNumbers
+{
+    static constexpr uint8_t MAX_SOL_SEQUENCE_NUMBER = 0x10;
+
+    /** @brief Get the SOL sequence number.
+     *
+     *  @param[in] inbound - true for inbound sequence number and false for
+     *                       outbound sequence number
+     *
+     *  @return sequence number
+     */
+    auto get(bool inbound = true) const
+    {
+        return inbound ? in : out;
+    }
+
+    /** @brief Increment the inbound SOL sequence number. */
+    void incInboundSeqNum()
+    {
+        if ((++in) == MAX_SOL_SEQUENCE_NUMBER)
+        {
+            in = 1;
+        }
+    }
+
+    /** @brief Increment the outbound SOL sequence number.
+     *
+     *  @return outbound sequence number to populate the SOL payload.
+     */
+    auto incOutboundSeqNum()
+    {
+        if ((++out) == MAX_SOL_SEQUENCE_NUMBER)
+        {
+            out = 1;
+        }
+
+        return out;
+    }
+
+  private:
+    uint8_t in = 1;  //!< Inbound sequence number.
+    uint8_t out = 0; //!< Outbound sequence number, since the first
+                     //!< operation is increment, it is initialised to 0
+};
+
+} // namespace internal
+
+/** @class Context
+ *
+ *  Context keeps the state of the SOL session. The information needed to
+ *  maintain the state of the SOL is part of this class. This class provides
+ *  interfaces to handle incoming SOL payload, send response and send outbound
+ *  SOL payload.
+ */
+class Context : public std::enable_shared_from_this<Context>
+{
+  public:
+    Context() = delete;
+    ~Context() = default;
+    Context(const Context&) = delete;
+    Context& operator=(const Context&) = delete;
+    Context(Context&&) = delete;
+    Context& operator=(Context&&) = delete;
+
+    /** @brief Context Factory
+     *
+     *  This is called by the SOL Manager when a SOL payload instance is
+     *  started for the activate payload command. Its purpose is to be able
+     *  to perform post-creation tasks on the object without changing the
+     *  code flow
+     *
+     *  @param[in] io  - boost::asio io context for event scheduling.
+     *  @param[in] maxRetryCount  - Retry count max value.
+     *  @param[in] sendThreshold - Character send threshold.
+     *  @param[in] instance - SOL payload instance.
+     *  @param[in] sessionID - BMC session ID.
+     */
+    static std::shared_ptr<Context> makeContext(
+        std::shared_ptr<boost::asio::io_context> io, uint8_t maxRetryCount,
+        uint8_t sendThreshold, uint8_t instance, session::SessionID sessionID);
+
+    /** @brief Context Constructor.
+     *
+     *  This should only be used by the Context factory makeContext
+     *  or the accumulate timer will not be initialized properly
+     *
+     *  @param[in] io  - boost::asio io context for event scheduling.
+     *  @param[in] maxRetryCount  - Retry count max value.
+     *  @param[in] sendThreshold - Character send threshold.
+     *  @param[in] instance - SOL payload instance.
+     *  @param[in] sessionID - BMC session ID.
+     */
+    Context(std::shared_ptr<boost::asio::io_context> io, uint8_t maxRetryCount,
+            uint8_t sendThreshold, uint8_t instance,
+            session::SessionID sessionID);
+
+    static constexpr auto clear = true;
+    static constexpr auto noClear = false;
+
+    /** @brief accumulate timer */
+    boost::asio::steady_timer accumulateTimer;
+
+    /** @brief retry timer */
+    boost::asio::steady_timer retryTimer;
+
+    /** @brief Retry count max value. */
+    const uint8_t maxRetryCount = 0;
+
+    /** @brief Retry counter. */
+    uint8_t retryCounter = 0;
+
+    /** @brief Character send threshold. */
+    const uint8_t sendThreshold = 0;
+
+    /** @brief SOL payload instance. */
+    const uint8_t payloadInstance = 0;
+
+    /** @brief Session ID. */
+    const session::SessionID sessionID = 0;
+
+    /** @brief session pointer
+     */
+    std::shared_ptr<session::Session> session;
+
+    /** @brief enable/disable accumulate timer
+     *
+     *  The timeout interval is managed by the SOL Manager;
+     *  this function only enables or disable the timer
+     *
+     *  @param[in] enable - enable(true) or disable(false) accumulation timer
+     */
+    void enableAccumulateTimer(bool enable);
+
+    /** @brief enable/disable retry timer
+     *
+     *  The timeout interval is managed by the SOL Manager;
+     *  this function only enables or disable the timer
+     *
+     *  @param[in] enable - enable(true) or disable(false) retry timer
+     */
+    void enableRetryTimer(bool enable);
+
+    /** @brief Process the Inbound SOL payload.
+     *
+     *  The SOL payload from the remote console is processed and the
+     *  acknowledgment handling is done.
+     *
+     *  @param[in] seqNum - Packet sequence number.
+     *  @param[in] ackSeqNum - Packet ACK/NACK sequence number.
+     *  @param[in] count - Accepted character count.
+     *  @param[in] operation - ACK is false, NACK is true
+     *  @param[in] input - Incoming SOL character data.
+     */
+    void processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum, uint8_t count,
+                               bool status, bool isBreak,
+                               const std::vector<uint8_t>& input);
+
+    /** @brief Send the outbound SOL payload.
+     *
+     *  @return zero on success and negative value if condition for sending
+     *          the payload fails.
+     */
+    int sendOutboundPayload();
+
+    /** @brief Resend the SOL payload.
+     *
+     *  @param[in] clear - if true then send the payload and clear the
+     *                     cached payload, if false only send the payload.
+     */
+    void resendPayload(bool clear);
+
+    /** @brief accumlate timer handler called by timer */
+    void charAccTimerHandler();
+
+    /** @brief retry timer handler called by timer */
+    void retryTimerHandler();
+
+  private:
+    /** @brief Expected character count.
+     *
+     *  Expected Sequence number and expected character count is set before
+     *  sending the SOL payload. The check is done against these values when
+     *  an incoming SOL payload is received.
+     */
+    size_t expectedCharCount = 0;
+
+    /** @brief Inbound and Outbound sequence numbers. */
+    internal::SequenceNumbers seqNums;
+
+    /** @brief Copy of the last sent SOL payload.
+     *
+     *  A copy of the SOL payload is kept here, so that when a retry needs
+     *  to be attempted the payload is sent again.
+     */
+    std::vector<uint8_t> payloadCache;
+
+    /**
+     * @brief Send Response for Incoming SOL payload.
+     *
+     * @param[in] ackSeqNum - Packet ACK/NACK Sequence Number.
+     * @param[in] count - Accepted Character Count.
+     * @param[in] ack - Set ACK/NACK in the Operation.
+     */
+    void prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack);
+
+    /** @brief Send the outgoing SOL payload.
+     *
+     *  @param[in] out - buffer containing the SOL payload.
+     */
+    void sendPayload(const std::vector<uint8_t>& out) const;
+};
+
+} // namespace sol
diff --git a/transport/rmcpbridge/sol/sol_manager.cpp b/transport/rmcpbridge/sol/sol_manager.cpp
new file mode 100644
index 0000000..ccfbc3c
--- /dev/null
+++ b/transport/rmcpbridge/sol/sol_manager.cpp
@@ -0,0 +1,366 @@
+#include "sol_manager.hpp"
+
+#include "main.hpp"
+#include "sol_context.hpp"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <boost/asio/basic_stream_socket.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+#include <boost/asio/write.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/message/types.hpp>
+
+#include <chrono>
+#include <cmath>
+
+constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
+constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol/";
+
+namespace sol
+{
+
+std::unique_ptr<sdbusplus::bus::match_t> matchPtrSOL(nullptr);
+std::unique_ptr<sdbusplus::bus::match_t> solConfPropertiesSignal(nullptr);
+
+void Manager::initConsoleSocket()
+{
+    // explicit length constructor for NUL-prefixed abstract path
+    std::string path(CONSOLE_SOCKET_PATH, CONSOLE_SOCKET_PATH_LEN);
+    boost::asio::local::stream_protocol::endpoint ep(path);
+    consoleSocket =
+        std::make_unique<boost::asio::local::stream_protocol::socket>(*io);
+    consoleSocket->connect(ep);
+}
+
+void Manager::consoleInputHandler()
+{
+    boost::system::error_code ec;
+    boost::asio::socket_base::bytes_readable cmd(true);
+    consoleSocket->io_control(cmd, ec);
+    size_t readSize;
+    if (!ec)
+    {
+        readSize = cmd.get();
+    }
+    else
+    {
+        lg2::error(
+            "Reading ready count from host console socket failed: {ERROR}",
+            "ERROR", ec.value());
+        return;
+    }
+    std::vector<uint8_t> buffer(readSize);
+    ec.clear();
+    size_t readDataLen =
+        consoleSocket->read_some(boost::asio::buffer(buffer), ec);
+    if (ec)
+    {
+        lg2::error("Reading from host console socket failed: {ERROR}", "ERROR",
+                   ec.value());
+        return;
+    }
+
+    // Update the Console buffer with data read from the socket
+    buffer.resize(readDataLen);
+    dataBuffer.write(buffer);
+}
+
+int Manager::writeConsoleSocket(const std::vector<uint8_t>& input,
+                                bool breakFlag) const
+{
+    boost::system::error_code ec;
+    if (breakFlag)
+    {
+        consoleSocket->send(boost::asio::buffer(input), MSG_OOB, ec);
+    }
+    else
+    {
+        consoleSocket->send(boost::asio::buffer(input), 0, ec);
+    }
+
+    return ec.value();
+}
+
+void Manager::startHostConsole()
+{
+    if (!consoleSocket)
+    {
+        initConsoleSocket();
+    }
+
+    // Register callback to close SOL session for disable SSH SOL
+    if (matchPtrSOL == nullptr)
+    {
+        registerSOLServiceChangeCallback();
+    }
+
+    consoleSocket->async_wait(boost::asio::socket_base::wait_read,
+                              [this](const boost::system::error_code& ec) {
+                                  if (!ec)
+                                  {
+                                      consoleInputHandler();
+                                      startHostConsole();
+                                  }
+                              });
+} // namespace sol
+
+void Manager::stopHostConsole()
+{
+    if (consoleSocket)
+    {
+        consoleSocket->cancel();
+        consoleSocket.reset();
+    }
+}
+
+void Manager::updateSOLParameter(uint8_t channelNum)
+{
+    sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection());
+    static std::string solService{};
+    ipmi::PropertyMap properties;
+    std::string ethdevice = ipmi::getChannelName(channelNum);
+    std::string solPathWitheEthName = solPath + ethdevice;
+    if (solService.empty())
+    {
+        try
+        {
+            solService =
+                ipmi::getService(dbus, solInterface, solPathWitheEthName);
+        }
+        catch (const std::runtime_error& e)
+        {
+            solService.clear();
+            lg2::error("Get SOL service failed: {ERROR}", "ERROR", e);
+            return;
+        }
+    }
+    try
+    {
+        properties = ipmi::getAllDbusProperties(
+            dbus, solService, solPathWitheEthName, solInterface);
+    }
+    catch (const std::runtime_error& e)
+    {
+        lg2::error("Setting sol parameter: {ERROR}", "ERROR", e);
+        return;
+    }
+
+    progress = std::get<uint8_t>(properties["Progress"]);
+
+    enable = std::get<bool>(properties["Enable"]);
+
+    forceEncrypt = std::get<bool>(properties["ForceEncryption"]);
+
+    forceAuth = std::get<bool>(properties["ForceAuthentication"]);
+
+    solMinPrivilege = static_cast<session::Privilege>(
+        std::get<uint8_t>(properties["Privilege"]));
+
+    accumulateInterval =
+        std::get<uint8_t>((properties["AccumulateIntervalMS"])) *
+        sol::accIntervalFactor * 1ms;
+
+    sendThreshold = std::get<uint8_t>(properties["Threshold"]);
+
+    retryCount = std::get<uint8_t>(properties["RetryCount"]);
+
+    retryInterval = std::get<uint8_t>(properties["RetryIntervalMS"]) *
+                    sol::retryIntervalFactor * 1ms;
+
+    return;
+}
+
+void Manager::startPayloadInstance(uint8_t payloadInstance,
+                                   session::SessionID sessionID)
+{
+    if (payloadMap.empty())
+    {
+        try
+        {
+            startHostConsole();
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error(
+                "Encountered exception when starting host console. Hence stopping host console: {ERROR}",
+                "ERROR", e);
+            stopHostConsole();
+            throw;
+        }
+    }
+
+    // Create the SOL Context data for payload instance
+    std::shared_ptr<Context> context = Context::makeContext(
+        io, retryCount, sendThreshold, payloadInstance, sessionID);
+
+    payloadMap.emplace(payloadInstance, std::move(context));
+}
+
+void Manager::stopPayloadInstance(uint8_t payloadInstance)
+{
+    auto iter = payloadMap.find(payloadInstance);
+    if (iter == payloadMap.end())
+    {
+        throw std::runtime_error("SOL Payload instance not found ");
+    }
+
+    payloadMap.erase(iter);
+
+    if (payloadMap.empty())
+    {
+        stopHostConsole();
+
+        dataBuffer.erase(dataBuffer.size());
+    }
+}
+
+void Manager::stopAllPayloadInstance()
+{
+    // Erase all payload instance
+    payloadMap.erase(payloadMap.begin(), payloadMap.end());
+
+    stopHostConsole();
+
+    dataBuffer.erase(dataBuffer.size());
+}
+
+void registerSOLServiceChangeCallback()
+{
+    using namespace sdbusplus::bus::match::rules;
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    try
+    {
+        auto servicePath = ipmi::getDbusObject(
+            bus, "xyz.openbmc_project.Control.Service.Attributes",
+            "/xyz/openbmc_project/control/service", "_6fbmc_2dconsole");
+
+        if (!std::empty(servicePath.first))
+        {
+            matchPtrSOL = std::make_unique<sdbusplus::bus::match_t>(
+                bus,
+                path_namespace(servicePath.first) +
+                    "arg0namespace='xyz.openbmc_project.Control.Service."
+                    "Attributes'"
+                    ", " +
+                    type::signal() + member("PropertiesChanged") +
+                    interface("org.freedesktop.DBus.Properties"),
+                [](sdbusplus::message_t& msg) {
+                    std::string intfName;
+                    std::map<std::string, std::variant<bool>> properties;
+                    msg.read(intfName, properties);
+
+                    const auto it = properties.find("Enabled");
+                    if (it != properties.end())
+                    {
+                        const bool* state = std::get_if<bool>(&it->second);
+
+                        if (state != nullptr && *state == false)
+                        {
+                            // Stop all the payload session.
+                            sol::Manager::get().stopAllPayloadInstance();
+                        }
+                    }
+                });
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error(
+            "Failed to get service path in registerSOLServiceChangeCallback: {ERROR}",
+            "ERROR", e);
+    }
+}
+
+void procSolConfChange(sdbusplus::message_t& msg)
+{
+    using SolConfVariant = std::variant<bool, uint8_t>;
+    using SolConfProperties =
+        std::vector<std::pair<std::string, SolConfVariant>>;
+
+    std::string iface;
+    SolConfProperties properties;
+
+    try
+    {
+        msg.read(iface, properties);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("procSolConfChange get properties FAIL: {ERROR}", "ERROR",
+                   e);
+        return;
+    }
+
+    for (const auto& prop : properties)
+    {
+        if (prop.first == "Progress")
+        {
+            sol::Manager::get().progress = std::get<uint8_t>(prop.second);
+        }
+        else if (prop.first == "Enable")
+        {
+            sol::Manager::get().enable = std::get<bool>(prop.second);
+        }
+        else if (prop.first == "ForceEncryption")
+        {
+            sol::Manager::get().forceEncrypt = std::get<bool>(prop.second);
+        }
+        else if (prop.first == "ForceAuthentication")
+        {
+            sol::Manager::get().forceAuth = std::get<bool>(prop.second);
+        }
+        else if (prop.first == "Privilege")
+        {
+            sol::Manager::get().solMinPrivilege =
+                static_cast<session::Privilege>(std::get<uint8_t>(prop.second));
+        }
+        else if (prop.first == "AccumulateIntervalMS")
+        {
+            sol::Manager::get().accumulateInterval =
+                std::get<uint8_t>(prop.second) * sol::accIntervalFactor * 1ms;
+        }
+        else if (prop.first == "Threshold")
+        {
+            sol::Manager::get().sendThreshold = std::get<uint8_t>(prop.second);
+        }
+        else if (prop.first == "RetryCount")
+        {
+            sol::Manager::get().retryCount = std::get<uint8_t>(prop.second);
+        }
+        else if (prop.first == "RetryIntervalMS")
+        {
+            sol::Manager::get().retryInterval =
+                std::get<uint8_t>(prop.second) * sol::retryIntervalFactor * 1ms;
+        }
+    }
+}
+
+void registerSolConfChangeCallbackHandler(std::string channel)
+{
+    if (solConfPropertiesSignal == nullptr)
+    {
+        using namespace sdbusplus::bus::match::rules;
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+        try
+        {
+            auto servicePath = solPath + channel;
+
+            solConfPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
+                bus, propertiesChangedNamespace(servicePath, solInterface),
+                procSolConfChange);
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            lg2::error(
+                "Failed to get service path in registerSolConfChangeCallbackHandler, channel: {CHANNEL}, error: {ERROR}",
+                "CHANNEL", channel, "ERROR", e);
+        }
+    }
+    return;
+}
+
+} // namespace sol
diff --git a/transport/rmcpbridge/sol/sol_manager.hpp b/transport/rmcpbridge/sol/sol_manager.hpp
new file mode 100644
index 0000000..4d7652a
--- /dev/null
+++ b/transport/rmcpbridge/sol/sol_manager.hpp
@@ -0,0 +1,301 @@
+#pragma once
+
+#include "console_buffer.hpp"
+#include "main.hpp"
+#include "session.hpp"
+#include "sol_context.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+
+#include <cstddef>
+#include <map>
+#include <memory>
+#include <string>
+
+namespace sol
+{
+
+constexpr size_t MAX_PAYLOAD_SIZE = 255;
+constexpr uint8_t MAJOR_VERSION = 0x01;
+constexpr uint8_t MINOR_VERSION = 0x00;
+
+constexpr char CONSOLE_SOCKET_PATH[] = "\0obmc-console.default";
+constexpr size_t CONSOLE_SOCKET_PATH_LEN = sizeof(CONSOLE_SOCKET_PATH) - 1;
+
+constexpr uint8_t accIntervalFactor = 5;
+constexpr uint8_t retryIntervalFactor = 10;
+
+using Instance = uint8_t;
+
+using namespace std::chrono_literals;
+
+/** @class Manager
+ *
+ *  Manager class acts a manager for the SOL payload instances and provides
+ *  interfaces to start a payload instance, stop a payload instance and get
+ *  reference to the context object.
+ */
+class Manager
+{
+  private:
+    struct Private
+    {};
+
+  public:
+    /** @brief SOL Payload Instance is the key for the map, the value is the
+     *         SOL context.
+     */
+    using SOLPayloadMap = std::map<Instance, std::shared_ptr<Context>>;
+
+    Manager() = delete;
+    ~Manager() = default;
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = default;
+    Manager& operator=(Manager&&) = default;
+
+    Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) :
+        io(io)
+    {}
+
+    /**
+     * @brief Get a reference to the singleton Manager
+     *
+     * @return Manager reference
+     */
+    static Manager& get()
+    {
+        static std::shared_ptr<Manager> ptr = nullptr;
+        if (!ptr)
+        {
+            std::shared_ptr<boost::asio::io_context> io = getIo();
+            ptr = std::make_shared<Manager>(io, Private());
+        }
+        return *ptr;
+    }
+
+    /** @brief io context to add events to */
+    std::shared_ptr<boost::asio::io_context> io;
+
+    /** @brief Host Console Buffer. */
+    ConsoleData dataBuffer;
+
+    /** @brief Set in Progress.
+     *
+     *  This parameter is used to indicate when any of the SOL parameters
+     *  are being updated, and when the changes are completed. The bit is
+     *  primarily provided to alert software than some other software or
+     *  utility is in the process of making changes to the data. This field
+     *  is initialized to set complete.
+     */
+    uint8_t progress = 0;
+
+    /** @brief SOL enable
+     *
+     *  This controls whether the SOL payload can be activated. By default
+     *  the SOL is enabled.
+     */
+    bool enable = true;
+
+    /** @brief SOL payload encryption.
+     *
+     *  Force encryption: if the cipher suite for the session supports
+     *  encryption, then this setting will force the use of encryption for
+     *  all SOL payload data. Encryption controlled by remote console:
+     *  Whether SOL packets are encrypted or not is selectable by the remote
+     *  console at the time the payload is activated. The default is force
+     *  encryption.
+     */
+    bool forceEncrypt = true;
+
+    /** @brief SOL payload authentication.
+     *
+     *  Force authentication: if the cipher suite for the session supports
+     *  authentication, then this setting will force the use of  for
+     *  authentication for all SOL payload data. Authentication controlled
+     *  by remote console: Note that for the standard Cipher Suites,
+     *  if encryption is used authentication must also be used. Therefore,
+     *  while encryption is being used software will not be able to select
+     *  using unauthenticated payloads.
+     */
+    bool forceAuth = true;
+
+    /** @brief SOL privilege level.
+     *
+     *  Sets the minimum operating privilege level that is required to be
+     *  able to activate SOL using the Activate Payload command.
+     */
+    session::Privilege solMinPrivilege = session::Privilege::USER;
+
+    /** @brief Character Accumulate Interval
+     *
+     *  This sets the typical amount of time that the BMC will wait before
+     *  transmitting a partial SOL character data packet. (Where a partial
+     *  packet is defined as a packet that has fewer characters to transmit
+     *  than the number of characters specified by the character send
+     *  threshold. This parameter can be modified by the set SOL
+     *  configuration parameters command. The SOL configuration parameter,
+     *  Character Accumulate Interval is 5 ms increments, 1-based value. The
+     *  parameter value is accumulateInterval/5. The accumulateInterval
+     *  needs to be a multiple of 5.
+     */
+    std::chrono::milliseconds accumulateInterval = 100ms;
+
+    /** @brief Character Send Threshold
+     *
+     *  The BMC will automatically send an SOL character data packet
+     *  containing this number of characters as soon as this number of
+     *  characters (or greater) has been accepted from the baseboard serial
+     *  controller into the BMC. This provides a mechanism to tune the
+     *  buffer to reduce latency to when the first characters are received
+     *  after an idle interval. In the degenerate case, setting this value
+     *  to a ‘1’ would cause the BMC to send a packet as soon as the first
+     *  character was received. This parameter can be modified by the set
+     *  SOL configuration parameters command.
+     */
+    uint8_t sendThreshold = 1;
+
+    /** @brief Retry Count
+     *
+     *  1-based. 0 = no retries after packet is transmitted. Packet will be
+     *  dropped if no ACK/NACK received by time retries expire. The maximum
+     *  value for retry count is 7. This parameter can be modified by the
+     *  set SOL configuration parameters command.
+     */
+    uint8_t retryCount = 7;
+
+    /** @brief Retry Interval
+     *
+     *  Sets the time that the BMC will wait before the first retry and the
+     *  time between retries when sending SOL packets to the remote console.
+     *  This parameter can be modified by the set SOL configuration
+     *  parameters command. The SOL configuration parameter Retry Interval
+     *  is 10 ms increments, 1-based value. The parameter value is
+     *  retryInterval/10. The retryInterval needs to be a multiple of 10.
+     */
+    std::chrono::milliseconds retryInterval = 100ms;
+
+    /** @brief Channel Number
+     *
+     *  This parameter indicates which IPMI channel is being used for the
+     *  communication parameters (e.g. IP address, MAC address) for the SOL
+     *  Payload. Typically, these parameters will come from the same channel
+     *  that the Activate Payload command for SOL was accepted over. The
+     *  network channel number is defaulted to 1.
+     */
+    uint8_t channel = 1;
+
+    /** @brief Add host console I/O event source to the event loop.  */
+    void startHostConsole();
+
+    /** @brief Remove host console I/O event source. */
+    void stopHostConsole();
+
+    /** @brief Start a SOL payload instance.
+     *
+     *  Starting a payload instance involves creating the context object,
+     *  add the accumulate interval timer and retry interval timer to the
+     *  event loop.
+     *
+     *  @param[in] payloadInstance - SOL payload instance.
+     *  @param[in] sessionID - BMC session ID.
+     */
+    void startPayloadInstance(uint8_t payloadInstance,
+                              session::SessionID sessionID);
+
+    /** @brief Stop SOL payload instance.
+     *
+     *  Stopping a payload instance involves stopping and removing the
+     *  accumulate interval timer and retry interval timer from the event
+     *  loop, delete the context object.
+     *
+     *  @param[in] payloadInstance - SOL payload instance
+     */
+    void stopPayloadInstance(uint8_t payloadInstance);
+
+    /* @brief Stop all the active SOL payload instances */
+    void stopAllPayloadInstance();
+
+    /** @brief Get SOL Context by Payload Instance.
+     *
+     *  @param[in] payloadInstance - SOL payload instance.
+     *
+     *  @return reference to the SOL payload context.
+     */
+    Context& getContext(uint8_t payloadInstance)
+    {
+        auto iter = payloadMap.find(payloadInstance);
+
+        if (iter != payloadMap.end())
+        {
+            return *(iter->second);
+        }
+
+        std::string msg =
+            "Invalid SOL payload instance " + std::to_string(payloadInstance);
+        throw std::runtime_error(msg.c_str());
+    }
+
+    /** @brief Get SOL Context by Session ID.
+     *
+     *  @param[in] sessionID - IPMI Session ID.
+     *
+     *  @return reference to the SOL payload context.
+     */
+    Context& getContext(session::SessionID sessionID)
+    {
+        for (const auto& kv : payloadMap)
+        {
+            if (kv.second->sessionID == sessionID)
+            {
+                return *kv.second;
+            }
+        }
+
+        std::string msg = "Invalid SOL SessionID " + std::to_string(sessionID);
+        throw std::runtime_error(msg.c_str());
+    }
+
+    /** @brief Check if SOL payload is active.
+     *
+     *  @param[in] payloadInstance - SOL payload instance.
+     *
+     *  @return true if the instance is active and false it is not active.
+     */
+    auto isPayloadActive(uint8_t payloadInstance) const
+    {
+        return (0 != payloadMap.count(payloadInstance));
+    }
+
+    /** @brief Write data to the host console unix socket.
+     *
+     *  @param[in] input - Data from the remote console.
+     *
+     *  @return 0 on success and errno on failure.
+     */
+    int writeConsoleSocket(const std::vector<uint8_t>& input,
+                           bool breakFlag) const;
+    void updateSOLParameter(uint8_t channelNum);
+
+  private:
+    SOLPayloadMap payloadMap;
+
+    /** @brief Local stream socket for the host console. */
+    std::unique_ptr<boost::asio::local::stream_protocol::socket> consoleSocket =
+        nullptr;
+
+    /** @brief Initialize the host console file descriptor. */
+    void initConsoleSocket();
+
+    /** @brief Handle incoming console data on the console socket */
+    void consoleInputHandler();
+};
+
+/** @brief Callback method to close SOL sessions for SOL service change  */
+void registerSOLServiceChangeCallback();
+
+/** @brief Callback register method to SOL conf parameters change */
+void registerSolConfChangeCallbackHandler(std::string channel);
+
+} // namespace sol
diff --git a/transport/rmcpbridge/sol_module.cpp b/transport/rmcpbridge/sol_module.cpp
new file mode 100644
index 0000000..21196d8
--- /dev/null
+++ b/transport/rmcpbridge/sol_module.cpp
@@ -0,0 +1,57 @@
+#include "command/payload_cmds.hpp"
+#include "command/sol_cmds.hpp"
+#include "command_table.hpp"
+#include "session.hpp"
+
+namespace sol
+{
+
+namespace command
+{
+
+void registerCommands()
+{
+    static const ::command::CmdDetails commands[] = {
+        // SOL Payload Handler
+        {{(static_cast<uint32_t>(message::PayloadType::SOL) << 16)},
+         &payloadHandler,
+         session::Privilege::HIGHEST_MATCHING,
+         false},
+        // Activate Payload Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(::command::NetFns::APP) | 0x48},
+         &activatePayload,
+         session::Privilege::USER,
+         false},
+        // Deactivate Payload Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(::command::NetFns::APP) | 0x49},
+         &deactivatePayload,
+         session::Privilege::USER,
+         false},
+        // Get Payload Activation Status
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(::command::NetFns::APP) | 0x4A},
+         &getPayloadStatus,
+         session::Privilege::USER,
+         false},
+        // Get Payload Instance Info Command
+        {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+          static_cast<uint16_t>(::command::NetFns::APP) | 0x4B},
+         &getPayloadInfo,
+         session::Privilege::USER,
+         false},
+    };
+
+    for (const auto& iter : commands)
+    {
+        ::command::Table::get().registerCommand(
+            iter.command,
+            std::make_unique<::command::NetIpmidEntry>(
+                iter.command, iter.functor, iter.privilege, iter.sessionless));
+    }
+}
+
+} // namespace command
+
+} // namespace sol
diff --git a/transport/rmcpbridge/sol_module.hpp b/transport/rmcpbridge/sol_module.hpp
new file mode 100644
index 0000000..f1a4beb
--- /dev/null
+++ b/transport/rmcpbridge/sol_module.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+namespace sol
+{
+
+namespace command
+{
+
+/** @brief Register SOL commands to the Command Table */
+void registerCommands();
+
+} // namespace command
+
+} // namespace sol
diff --git a/transport/rmcpbridge/subprojects/CLI11.wrap b/transport/rmcpbridge/subprojects/CLI11.wrap
new file mode 100644
index 0000000..2e5a95b
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/CLI11.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/CLIUtils/CLI11.git
+revision = HEAD
+
+[provide]
+CLI11 = CLI11_dep
diff --git a/transport/rmcpbridge/subprojects/googletest.wrap b/transport/rmcpbridge/subprojects/googletest.wrap
new file mode 100644
index 0000000..766a562
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/googletest.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/google/googletest.git
+revision = HEAD
diff --git a/transport/rmcpbridge/subprojects/phosphor-dbus-interfaces.wrap b/transport/rmcpbridge/subprojects/phosphor-dbus-interfaces.wrap
new file mode 100644
index 0000000..346aa0c
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/phosphor-dbus-interfaces.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-dbus-interfaces.git
+revision = HEAD
+
+[provide]
+phosphor-dbus-interfaces = phosphor_dbus_interfaces_dep
diff --git a/transport/rmcpbridge/subprojects/phosphor-host-ipmid.wrap b/transport/rmcpbridge/subprojects/phosphor-host-ipmid.wrap
new file mode 100644
index 0000000..29bb550
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/phosphor-host-ipmid.wrap
@@ -0,0 +1,8 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-host-ipmid.git
+revision = HEAD
+
+[provide]
+libipmid = ipmid_dep
+libchannellayer = channellayer_dep
+libuserlayer = userlayer_dep
diff --git a/transport/rmcpbridge/subprojects/phosphor-logging.wrap b/transport/rmcpbridge/subprojects/phosphor-logging.wrap
new file mode 100644
index 0000000..71eee8b
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/phosphor-logging.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-logging.git
+revision = HEAD
+
+[provide]
+phosphor-logging = phosphor_logging_dep
diff --git a/transport/rmcpbridge/subprojects/sdbusplus.wrap b/transport/rmcpbridge/subprojects/sdbusplus.wrap
new file mode 100644
index 0000000..7b076d0
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/sdbusplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdbusplus.git
+revision = HEAD
+
+[provide]
+sdbusplus = sdbusplus_dep
diff --git a/transport/rmcpbridge/test/cipher.cpp b/transport/rmcpbridge/test/cipher.cpp
new file mode 100644
index 0000000..d7720d4
--- /dev/null
+++ b/transport/rmcpbridge/test/cipher.cpp
@@ -0,0 +1,486 @@
+#include "crypt_algo.hpp"
+#include "integrity_algo.hpp"
+#include "message_parsers.hpp"
+#include "rmcp.hpp"
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+TEST(IntegrityAlgo, HMAC_SHA1_96_GenerateIntegrityDataCheck)
+{
+    /*
+     * Step-1 Generate Integrity Data for the packet, using the implemented API
+     */
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik);
+
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    // Generate the Integrity Data
+    auto response = algoPtr->generateIntegrityData(packet);
+
+    EXPECT_EQ(true, (response.size() ==
+                     cipher::integrity::AlgoSHA1::SHA1_96_AUTHCODE_LENGTH));
+
+    /*
+     * Step-2 Generate Integrity data using OpenSSL SHA1 algorithm
+     */
+    std::vector<uint8_t> k1(SHA_DIGEST_LENGTH);
+    constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+    // Generated K1 for the integrity algorithm with the additional key keyed
+    // with SIK.
+    unsigned int mdLen = 0;
+    if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(),
+             k1.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating Key1 failed";
+    }
+
+    mdLen = 0;
+    std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
+    size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    if (HMAC(EVP_sha1(), k1.data(), k1.size(),
+             packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length,
+             output.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating integrity data failed";
+    }
+
+    output.resize(cipher::integrity::AlgoSHA1::SHA1_96_AUTHCODE_LENGTH);
+
+    /*
+     * Step-3 Check if the integrity data we generated using the implemented API
+     * matches with one generated by OpenSSL SHA1 algorithm.
+     */
+    auto check = std::equal(output.begin(), output.end(), response.begin());
+    EXPECT_EQ(true, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataPass)
+{
+    /*
+     * Step-1 Generate Integrity data using OpenSSL SHA1 algorithm
+     */
+
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+
+    std::vector<uint8_t> k1(SHA_DIGEST_LENGTH);
+    constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+    // Generated K1 for the integrity algorithm with the additional key keyed
+    // with SIK.
+    unsigned int mdLen = 0;
+    if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(),
+             k1.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating Key1 failed";
+    }
+
+    mdLen = 0;
+    std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
+    size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    if (HMAC(EVP_sha1(), k1.data(), k1.size(),
+             packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length,
+             output.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating integrity data failed";
+    }
+
+    output.resize(cipher::integrity::AlgoSHA1::SHA1_96_AUTHCODE_LENGTH);
+
+    /*
+     * Step-2 Insert the integrity data into the packet
+     */
+    auto packetSize = packet.size();
+    packet.insert(packet.end(), output.begin(), output.end());
+
+    // Point to the integrity data in the packet
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, packetSize);
+
+    /*
+     * Step-3 Invoke the verifyIntegrityData API and validate the response
+     */
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik);
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    auto check = algoPtr->verifyIntegrityData(
+        packet, packetSize - message::parser::RMCP_SESSION_HEADER_SIZE,
+        integrityIter, packet.cend());
+
+    EXPECT_EQ(true, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataFail)
+{
+    /*
+     * Step-1 Add hardcoded Integrity data to the packet
+     */
+
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    std::vector<uint8_t> integrity = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    packet.insert(packet.end(), integrity.begin(), integrity.end());
+
+    // Point to the integrity data in the packet
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, integrity.size());
+
+    /*
+     * Step-2 Invoke the verifyIntegrityData API and validate the response
+     */
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik);
+
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    // Verify the Integrity Data
+    auto check = algoPtr->verifyIntegrityData(
+        packet, packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE,
+        integrityIter, packet.cend());
+
+    EXPECT_EQ(false, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA256_128_GenerateIntegrityDataCheck)
+{
+    /*
+     * Step-1 Generate Integrity Data for the packet, using the implemented API
+     */
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
+                                12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                                23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik);
+
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    // Generate the Integrity Data
+    auto response = algoPtr->generateIntegrityData(packet);
+
+    EXPECT_EQ(true,
+              (response.size() ==
+               cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH));
+
+    /*
+     * Step-2 Generate Integrity data using OpenSSL SHA256 algorithm
+     */
+    std::vector<uint8_t> k1(SHA256_DIGEST_LENGTH);
+    constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+    // Generated K1 for the integrity algorithm with the additional key keyed
+    // with SIK.
+    unsigned int mdLen = 0;
+    if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(), const1.size(),
+             k1.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating Key1 failed";
+    }
+
+    mdLen = 0;
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    if (HMAC(EVP_sha256(), k1.data(), k1.size(),
+             packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length,
+             output.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating integrity data failed";
+    }
+
+    output.resize(cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH);
+
+    /*
+     * Step-3 Check if the integrity data we generated using the implemented API
+     * matches with one generated by OpenSSL SHA256 algorithm.
+     */
+    auto check = std::equal(output.begin(), output.end(), response.begin());
+    EXPECT_EQ(true, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataPass)
+{
+    /*
+     * Step-1 Generate Integrity data using OpenSSL SHA256 algorithm
+     */
+
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
+                                12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                                23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
+
+    std::vector<uint8_t> k1(SHA256_DIGEST_LENGTH);
+    constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                                      0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+    // Generated K1 for the integrity algorithm with the additional key keyed
+    // with SIK.
+    unsigned int mdLen = 0;
+    if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(), const1.size(),
+             k1.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating Key1 failed";
+    }
+
+    mdLen = 0;
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    if (HMAC(EVP_sha256(), k1.data(), k1.size(),
+             packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length,
+             output.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating integrity data failed";
+    }
+
+    output.resize(cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH);
+
+    /*
+     * Step-2 Insert the integrity data into the packet
+     */
+    auto packetSize = packet.size();
+    packet.insert(packet.end(), output.begin(), output.end());
+
+    // Point to the integrity data in the packet
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, packetSize);
+
+    /*
+     * Step-3 Invoke the verifyIntegrityData API and validate the response
+     */
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik);
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    auto check = algoPtr->verifyIntegrityData(
+        packet, packetSize - message::parser::RMCP_SESSION_HEADER_SIZE,
+        integrityIter, packet.cend());
+
+    EXPECT_EQ(true, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataFail)
+{
+    /*
+     * Step-1 Add hardcoded Integrity data to the packet
+     */
+
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    std::vector<uint8_t> integrity = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    packet.insert(packet.end(), integrity.begin(), integrity.end());
+
+    // Point to the integrity data in the packet
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, integrity.size());
+
+    /*
+     * Step-2 Invoke the verifyIntegrityData API and validate the response
+     */
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
+                                12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                                23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik);
+
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    // Verify the Integrity Data
+    auto check = algoPtr->verifyIntegrityData(
+        packet, packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE,
+        integrityIter, packet.cend());
+
+    EXPECT_EQ(false, check);
+}
+
+TEST(CryptAlgo, AES_CBC_128_EncryptPayloadValidate)
+{
+    /*
+     * Step-1 Generate the encrypted data using the implemented API for
+     * AES-CBC-128
+     */
+    std::vector<uint8_t> payload = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+
+    std::vector<uint8_t> k2(SHA_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+    constexpr rmcp::Const_n const1 = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+                                      0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+                                      0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
+
+    // Generated K2 for the confidentiality algorithm with the additional key
+    // keyed with SIK.
+    if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(),
+             k2.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating K2 for confidentiality algorithm failed";
+    }
+
+    auto cryptPtr = std::make_unique<cipher::crypt::AlgoAES128>(k2);
+
+    ASSERT_EQ(true, (cryptPtr != NULL));
+
+    auto cipher = cryptPtr->encryptPayload(payload);
+
+    /*
+     * Step-2 Decrypt the encrypted payload using OpenSSL EVP_aes_128_cbc()
+     * implementation
+     */
+
+    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+    if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, k2.data(),
+                            cipher.data()))
+    {
+        EVP_CIPHER_CTX_free(ctx);
+        FAIL() << "EVP_DecryptInit_ex failed for type AES-CBC-128";
+    }
+
+    EVP_CIPHER_CTX_set_padding(ctx, 0);
+    std::vector<uint8_t> output(
+        cipher.size() + cipher::crypt::AlgoAES128::AESCBC128BlockSize);
+    int outputLen = 0;
+
+    if (!EVP_DecryptUpdate(
+            ctx, output.data(), &outputLen,
+            cipher.data() + cipher::crypt::AlgoAES128::AESCBC128ConfHeader,
+            cipher.size() - cipher::crypt::AlgoAES128::AESCBC128ConfHeader))
+    {
+        EVP_CIPHER_CTX_free(ctx);
+        FAIL() << "EVP_DecryptUpdate failed";
+    }
+
+    output.resize(outputLen);
+    EVP_CIPHER_CTX_free(ctx);
+
+    /*
+     * Step -3 Check if the plain payload matches with the decrypted one
+     */
+    auto check = std::equal(payload.begin(), payload.end(), output.begin());
+    EXPECT_EQ(true, check);
+}
+
+TEST(CryptAlgo, AES_CBC_128_DecryptPayloadValidate)
+{
+    /*
+     * Step-1 Encrypt the payload using OpenSSL EVP_aes_128_cbc()
+     * implementation
+     */
+
+    std::vector<uint8_t> payload = {1, 2,  3,  4,  5,  6,  7,  8,
+                                    9, 10, 11, 12, 13, 14, 15, 16};
+    payload.resize(payload.size() + 1);
+    payload.back() = 0;
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+    EVP_CIPHER_CTX* ctx;
+    ctx = EVP_CIPHER_CTX_new();
+    std::vector<uint8_t> k2(SHA_DIGEST_LENGTH);
+    unsigned int mdLen = 0;
+    constexpr rmcp::Const_n const1 = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+                                      0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+                                      0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
+    std::vector<uint8_t> output(
+        payload.size() + cipher::crypt::AlgoAES128::AESCBC128BlockSize);
+
+    if (!RAND_bytes(output.data(),
+                    cipher::crypt::AlgoAES128::AESCBC128ConfHeader))
+    {
+        FAIL() << "RAND_bytes failed";
+    }
+
+    // Generated K2 for the confidentiality algorithm with the additional key
+    // keyed with SIK.
+    if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(),
+             k2.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating K2 for confidentiality algorithm failed";
+    }
+
+    if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, k2.data(),
+                            output.data()))
+    {
+        EVP_CIPHER_CTX_free(ctx);
+        FAIL() << "EVP_EncryptInit_ex failed for type AES-CBC-128";
+    }
+
+    EVP_CIPHER_CTX_set_padding(ctx, 0);
+    int outputLen = 0;
+
+    if (!EVP_EncryptUpdate(
+            ctx, output.data() + cipher::crypt::AlgoAES128::AESCBC128ConfHeader,
+            &outputLen, payload.data(), payload.size()))
+    {
+        EVP_CIPHER_CTX_free(ctx);
+        FAIL() << "EVP_EncryptUpdate failed";
+    }
+
+    output.resize(cipher::crypt::AlgoAES128::AESCBC128ConfHeader + outputLen);
+    EVP_CIPHER_CTX_free(ctx);
+
+    /*
+     * Step-2 Decrypt the encrypted payload using the implemented API for
+     * AES-CBC-128
+     */
+
+    auto cryptPtr = std::make_unique<cipher::crypt::AlgoAES128>(k2);
+
+    ASSERT_EQ(true, (cryptPtr != NULL));
+
+    auto plain = cryptPtr->decryptPayload(output, 0, output.size());
+
+    /*
+     * Step -3 Check if the plain payload matches with the decrypted one
+     */
+    auto check = std::equal(payload.begin(), payload.end(), plain.begin());
+    EXPECT_EQ(true, check);
+}
diff --git a/transport/rmcpbridge/test/meson.build b/transport/rmcpbridge/test/meson.build
new file mode 100644
index 0000000..6fcfd04
--- /dev/null
+++ b/transport/rmcpbridge/test/meson.build
@@ -0,0 +1,38 @@
+gtest_dep = dependency('gtest', main: true, disabler: true, required: false)
+gmock_dep = dependency('gmock', disabler: true, required: false)
+if not gtest_dep.found() or not gmock_dep.found()
+    gtest_proj = import('cmake').subproject('googletest', required: false)
+    if gtest_proj.found()
+        gtest_dep = declare_dependency(
+            dependencies: [
+                dependency('threads'),
+                gtest_proj.dependency('gtest'),
+                gtest_proj.dependency('gtest_main'),
+            ],
+        )
+        gmock_dep = gtest_proj.dependency('gmock')
+    else
+        assert(
+            not get_option('tests').enabled(),
+            'Googletest is required if tests are enabled',
+        )
+    endif
+endif
+
+test_sources = ['../integrity_algo.cpp', '../crypt_algo.cpp']
+
+tests = ['cipher.cpp']
+
+foreach t : tests
+    test(
+        t,
+        executable(
+            t.underscorify(),
+            t,
+            test_sources,
+            include_directories: ['..'],
+            dependencies: [gtest_dep, gmock_dep, libcrypto_dep],
+        ),
+        workdir: meson.current_source_dir(),
+    )
+endforeach
