diff --git a/user_channel/channel_layer.cpp b/user_channel/channel_layer.cpp
new file mode 100644
index 0000000..32f4ded
--- /dev/null
+++ b/user_channel/channel_layer.cpp
@@ -0,0 +1,131 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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.
+*/
+
+#include "channel_layer.hpp"
+
+#include "channel_mgmt.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace ipmi
+{
+
+bool doesDeviceExist(const uint8_t& chNum)
+{
+    // TODO: This is not the reliable way to find the device
+    // associated with ethernet interface as the channel number to
+    // eth association is not done. Need to revisit later
+    struct stat fileStat;
+    std::string devName("/sys/class/net/eth");
+    devName += std::to_string(chNum - 1);
+
+    if (stat(devName.data(), &fileStat) != 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::DEBUG>(
+            "Ethernet device not found");
+        return false;
+    }
+
+    return true;
+}
+
+bool isValidPrivLimit(const uint8_t& privLimit)
+{
+    return ((privLimit >= PRIVILEGE_CALLBACK) && (privLimit <= PRIVILEGE_OEM));
+}
+
+bool isValidAccessMode(const uint8_t& accessMode)
+{
+    return (
+        (accessMode >= static_cast<uint8_t>(EChannelAccessMode::disabled)) &&
+        (accessMode <= static_cast<uint8_t>(EChannelAccessMode::shared)));
+}
+
+bool isValidChannel(const uint8_t& chNum)
+{
+    return getChannelConfigObject().isValidChannel(chNum);
+}
+
+bool isValidAuthType(const uint8_t& chNum, const EAuthType& authType)
+{
+    return getChannelConfigObject().isValidAuthType(chNum, authType);
+}
+
+EChannelSessSupported getChannelSessionSupport(const uint8_t& chNum)
+{
+    return getChannelConfigObject().getChannelSessionSupport(chNum);
+}
+
+int getChannelActiveSessions(const uint8_t& chNum)
+{
+    return getChannelConfigObject().getChannelActiveSessions(chNum);
+}
+
+ipmi_ret_t ipmiChannelInit()
+{
+    getChannelConfigObject();
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t getChannelInfo(const uint8_t& chNum, ChannelInfo& chInfo)
+{
+    return getChannelConfigObject().getChannelInfo(chNum, chInfo);
+}
+
+ipmi_ret_t getChannelAccessData(const uint8_t& chNum,
+                                ChannelAccess& chAccessData)
+{
+    return getChannelConfigObject().getChannelAccessData(chNum, chAccessData);
+}
+
+ipmi_ret_t setChannelAccessData(const uint8_t& chNum,
+                                const ChannelAccess& chAccessData,
+                                const uint8_t& setFlag)
+{
+    return getChannelConfigObject().setChannelAccessData(chNum, chAccessData,
+                                                         setFlag);
+}
+
+ipmi_ret_t getChannelAccessPersistData(const uint8_t& chNum,
+                                       ChannelAccess& chAccessData)
+{
+    return getChannelConfigObject().getChannelAccessPersistData(chNum,
+                                                                chAccessData);
+}
+
+ipmi_ret_t setChannelAccessPersistData(const uint8_t& chNum,
+                                       const ChannelAccess& chAccessData,
+                                       const uint8_t& setFlag)
+{
+    return getChannelConfigObject().setChannelAccessPersistData(
+        chNum, chAccessData, setFlag);
+}
+
+ipmi_ret_t getChannelAuthTypeSupported(const uint8_t& chNum,
+                                       uint8_t& authTypeSupported)
+{
+    return getChannelConfigObject().getChannelAuthTypeSupported(
+        chNum, authTypeSupported);
+}
+
+ipmi_ret_t getChannelEnabledAuthType(const uint8_t& chNum, const uint8_t& priv,
+                                     EAuthType& authType)
+{
+    return getChannelConfigObject().getChannelEnabledAuthType(chNum, priv,
+                                                              authType);
+}
+
+} // namespace ipmi
diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp
new file mode 100644
index 0000000..4c931df
--- /dev/null
+++ b/user_channel/channel_layer.hpp
@@ -0,0 +1,275 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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.
+*/
+#pragma once
+#include <host-ipmid/ipmid-api.h>
+
+#include <string>
+
+namespace ipmi
+{
+
+static constexpr uint8_t maxIpmiChannels = 16;
+
+// IPMI return codes specific to channel
+enum ipmi_channel_return_codes
+{
+    IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL = 0x82,
+    IPMI_CC_ACCESS_MODE_NOT_SUPPORTED_FOR_CHANEL = 0x83
+};
+
+// IPMI Spec: Channel Protocol Type
+enum class EChannelProtocolType : uint8_t
+{
+    na = 0x00,
+    ipmbV10 = 0x01,
+    icmbV11 = 0x02,
+    reserved = 0x03,
+    ipmiSmbus = 0x04,
+    kcs = 0x05,
+    smic = 0x06,
+    bt10 = 0x07,
+    bt15 = 0x08,
+    tMode = 0x09,
+    oem = 0x1C,
+};
+
+// IPMI Spec: Channel Medium Type
+enum class EChannelMediumType : uint8_t
+{
+    reserved = 0x00,
+    ipmb = 0x01,
+    icmbV10 = 0x02,
+    icmbV09 = 0x03,
+    lan8032 = 0x04,
+    serial = 0x05,
+    otherLan = 0x06,
+    pciSmbus = 0x07,
+    smbusV11 = 0x08,
+    smbusV20 = 0x09,
+    usbV1x = 0x0A,
+    usbV2x = 0x0B,
+    systemInterface = 0x0C,
+    oem = 0x60,
+    unknown = 0x82,
+};
+
+// IPMI Spec: Channel Session Type
+enum class EChannelSessSupported : uint8_t
+{
+    none = 0,
+    single = 1,
+    multi = 2,
+    any = 3,
+};
+
+// IPMI Spec: Channel Access Mode
+enum class EChannelAccessMode : uint8_t
+{
+    disabled = 0,
+    preboot = 1,
+    alwaysAvail = 2,
+    shared = 3,
+};
+
+// IPMI Spec 2.0 : Authentication Types
+enum class EAuthType : uint8_t
+{
+    none = (1 << 0x0),
+    md2 = (1 << 0x1),
+    md5 = (1 << 0x2),
+    reserved = (1 << 0x3),
+    straightPasswd = (1 << 0x4),
+    oem = (1 << 0x5),
+};
+
+// IPMI Spec: Access mode for channel access set/get
+typedef enum
+{
+    doNotSet = 0x00,
+    nvData = 0x01,
+    activeData = 0x02,
+    reserved = 0x03,
+} EChannelActionType;
+
+enum AccessSetFlag
+{
+    setAccessMode = (1 << 0),
+    setUserAuthEnabled = (1 << 1),
+    setMsgAuthEnabled = (1 << 2),
+    setAlertingEnabled = (1 << 3),
+    setPrivLimit = (1 << 4),
+};
+
+// Struct to store channel access data
+struct ChannelAccess
+{
+    uint8_t accessMode;
+    bool userAuthDisabled;
+    bool perMsgAuthDisabled;
+    bool alertingDisabled;
+    uint8_t privLimit;
+};
+
+// Struct store channel info data
+struct ChannelInfo
+{
+    uint8_t mediumType;
+    uint8_t protocolType;
+    uint8_t sessionSupported;
+    bool isIpmi; // Is session IPMI
+    // This is used in Get LAN Configuration parameter.
+    // This holds the supported AuthTypes for a given channel.
+    uint8_t authTypeSupported;
+};
+
+/** @brief determines valid channel
+ *
+ *  @param[in] chNum- channel number
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidChannel(const uint8_t& chNum);
+
+/** @brief determines whether channel device exist
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return true if valid, false otherwise
+ */
+bool doesDeviceExist(const uint8_t& chNum);
+
+/** @brief determines whether privilege limit is valid
+ *
+ *  @param[in] privLimit - Privilege limit
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidPrivLimit(const uint8_t& privLimit);
+
+/** @brief determines whether access mode  is valid
+ *
+ *  @param[in] accessMode - Access mode
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidAccessMode(const uint8_t& accessMode);
+
+/** @brief determines valid authentication type based on channel number
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] authType - authentication type
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidAuthType(const uint8_t& chNum, const EAuthType& authType);
+
+/** @brief determines supported session type of a channel
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return EChannelSessSupported - supported session type
+ */
+EChannelSessSupported getChannelSessionSupport(const uint8_t& chNum);
+
+/** @brief determines number of active sessions on a channel
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return numer of active sessions
+ */
+int getChannelActiveSessions(const uint8_t& chNum);
+
+/** @brief initializes channel management
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiChannelInit();
+
+/** @brief provides channel info details
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] chInfo - channel info details
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t getChannelInfo(const uint8_t& chNum, ChannelInfo& chInfo);
+
+/** @brief provides channel access data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] chAccessData -channel access data
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t getChannelAccessData(const uint8_t& chNum,
+                                ChannelAccess& chAccessData);
+
+/** @brief to set channel access data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] chAccessData - channel access data
+ *  @param[in] setFlag - flag to indicate updatable fields
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t setChannelAccessData(const uint8_t& chNum,
+                                const ChannelAccess& chAccessData,
+                                const uint8_t& setFlag);
+
+/** @brief to get channel access data persistent data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] chAccessData - channel access data
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t getChannelAccessPersistData(const uint8_t& chNum,
+                                       ChannelAccess& chAccessData);
+
+/** @brief to set channel access data persistent data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] chAccessData - channel access data
+ *  @param[in] setFlag - flag to indicate updatable fields
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t setChannelAccessPersistData(const uint8_t& chNum,
+                                       const ChannelAccess& chAccessData,
+                                       const uint8_t& setFlag);
+
+/** @brief provides supported authentication type for the channel
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] authTypeSupported - supported authentication type
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t getChannelAuthTypeSupported(const uint8_t& chNum,
+                                       uint8_t& authTypeSupported);
+
+/** @brief provides enabled authentication type for the channel
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] priv - privilege
+ *  @param[out] authType - enabled authentication type
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t getChannelEnabledAuthType(const uint8_t& chNum, const uint8_t& priv,
+                                     EAuthType& authType);
+
+} // namespace ipmi
diff --git a/user_channel/channel_mgmt.cpp b/user_channel/channel_mgmt.cpp
new file mode 100644
index 0000000..0db54b6
--- /dev/null
+++ b/user_channel/channel_mgmt.cpp
@@ -0,0 +1,1027 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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.
+*/
+
+#include "channel_mgmt.hpp"
+
+#include "apphandler.hpp"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <cerrno>
+#include <experimental/filesystem>
+#include <fstream>
+#include <phosphor-logging/log.hpp>
+#include <unordered_map>
+
+namespace ipmi
+{
+
+using namespace phosphor::logging;
+
+static constexpr const char* channelAccessDefaultFilename =
+    "/usr/share/ipmi-providers/channel_access.json";
+static constexpr const char* channelConfigDefaultFilename =
+    "/usr/share/ipmi-providers/channel_config.json";
+static constexpr const char* channelNvDataFilename =
+    "/var/lib/ipmi/channel_access_nv.json";
+static constexpr const char* channelVolatileDataFilename =
+    "/run/ipmi/channel_access_volatile.json";
+
+// STRING DEFINES: Should sync with key's in JSON
+static constexpr const char* nameString = "name";
+static constexpr const char* isValidString = "is_valid";
+static constexpr const char* activeSessionsString = "active_sessions";
+static constexpr const char* channelInfoString = "channel_info";
+static constexpr const char* mediumTypeString = "medium_type";
+static constexpr const char* protocolTypeString = "protocol_type";
+static constexpr const char* sessionSupportedString = "session_supported";
+static constexpr const char* isIpmiString = "is_ipmi";
+static constexpr const char* authTypeSupportedString = "auth_type_supported";
+static constexpr const char* accessModeString = "access_mode";
+static constexpr const char* userAuthDisabledString = "user_auth_disabled";
+static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
+static constexpr const char* alertingDisabledString = "alerting_disabled";
+static constexpr const char* privLimitString = "priv_limit";
+static constexpr const char* authTypeEnabledString = "auth_type_enabled";
+
+// Default values
+static constexpr const char* defaultChannelName = "RESERVED";
+static constexpr const uint8_t defaultMediumType =
+    static_cast<uint8_t>(EChannelMediumType::reserved);
+static constexpr const uint8_t defaultProtocolType =
+    static_cast<uint8_t>(EChannelProtocolType::reserved);
+static constexpr const uint8_t defaultSessionSupported =
+    static_cast<uint8_t>(EChannelSessSupported::none);
+static constexpr const uint8_t defaultAuthType =
+    static_cast<uint8_t>(EAuthType::none);
+static constexpr const bool defaultIsIpmiState = false;
+
+// String mappings use in JSON config file
+static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
+    {"reserved", EChannelMediumType::reserved},
+    {"ipmb", EChannelMediumType::ipmb},
+    {"icmb-v1.0", EChannelMediumType::icmbV10},
+    {"icmb-v0.9", EChannelMediumType::icmbV09},
+    {"lan-802.3", EChannelMediumType::lan8032},
+    {"serial", EChannelMediumType::serial},
+    {"other-lan", EChannelMediumType::otherLan},
+    {"pci-smbus", EChannelMediumType::pciSmbus},
+    {"smbus-v1.0", EChannelMediumType::smbusV11},
+    {"smbus-v2.0", EChannelMediumType::smbusV20},
+    {"usb-1x", EChannelMediumType::usbV1x},
+    {"usb-2x", EChannelMediumType::usbV2x},
+    {"system-interface", EChannelMediumType::systemInterface},
+    {"oem", EChannelMediumType::oem},
+    {"unknown", EChannelMediumType::unknown}};
+
+static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
+    {"na", EChannelProtocolType::na},
+    {"ipmb-1.0", EChannelProtocolType::ipmbV10},
+    {"icmb-2.0", EChannelProtocolType::icmbV11},
+    {"reserved", EChannelProtocolType::reserved},
+    {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
+    {"kcs", EChannelProtocolType::kcs},
+    {"smic", EChannelProtocolType::smic},
+    {"bt-10", EChannelProtocolType::bt10},
+    {"bt-15", EChannelProtocolType::bt15},
+    {"tmode", EChannelProtocolType::tMode},
+    {"oem", EChannelProtocolType::oem}};
+
+static std::array<std::string, 4> accessModeList = {
+    "disabled", "pre-boot", "always_available", "shared"};
+
+static std::array<std::string, 4> sessionSupportList = {
+    "session-less", "single-session", "multi-session", "session-based"};
+
+static std::array<std::string, PRIVILEGE_OEM + 1> privList = {
+    "priv-reserved", "priv-callback", "priv-user",
+    "priv-operator", "priv-admin",    "priv-oem"};
+
+ChannelConfig& getChannelConfigObject()
+{
+    static ChannelConfig channelConfig;
+    return channelConfig;
+}
+
+ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
+{
+    std::ofstream mutexCleanUpFile;
+    mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
+                          std::ofstream::out | std::ofstream::app);
+    if (!mutexCleanUpFile.good())
+    {
+        log<level::DEBUG>("Unable to open mutex cleanup file");
+        return;
+    }
+    mutexCleanUpFile.close();
+    mutexCleanupLock =
+        boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
+    if (mutexCleanupLock.try_lock())
+    {
+        boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
+        channelMutex =
+            std::make_unique<boost::interprocess::named_recursive_mutex>(
+                boost::interprocess::open_or_create, ipmiChannelMutex);
+        mutexCleanupLock.lock_sharable();
+    }
+    else
+    {
+        mutexCleanupLock.lock_sharable();
+        channelMutex =
+            std::make_unique<boost::interprocess::named_recursive_mutex>(
+                boost::interprocess::open_or_create, ipmiChannelMutex);
+    }
+
+    initChannelPersistData();
+}
+
+bool ChannelConfig::isValidChannel(const uint8_t& chNum)
+{
+    if (chNum > maxIpmiChannels)
+    {
+        log<level::DEBUG>("Invalid channel ID - Out of range");
+        return false;
+    }
+
+    if (channelData[chNum].isChValid == false)
+    {
+        log<level::DEBUG>("Channel is not valid");
+        return false;
+    }
+
+    return true;
+}
+
+EChannelSessSupported
+    ChannelConfig::getChannelSessionSupport(const uint8_t& chNum)
+{
+    EChannelSessSupported chSessSupport =
+        (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
+    return chSessSupport;
+}
+
+bool ChannelConfig::isValidAuthType(const uint8_t& chNum,
+                                    const EAuthType& authType)
+{
+    if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
+    {
+        log<level::DEBUG>("Invalid authentication type");
+        return false;
+    }
+
+    uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
+    if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
+    {
+        log<level::DEBUG>("Authentication type is not supported.");
+        return false;
+    }
+
+    return true;
+}
+
+int ChannelConfig::getChannelActiveSessions(const uint8_t& chNum)
+{
+    // TODO: TEMPORARY FIX
+    // Channels active session count is managed separatly
+    // by monitoring channel session which includes LAN and
+    // RAKP layer changes. This will be updated, once the
+    // authentication part is implemented.
+    return channelData[chNum].activeSessCount;
+}
+
+ipmi_ret_t ChannelConfig::getChannelInfo(const uint8_t& chNum,
+                                         ChannelInfo& chInfo)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
+                sizeof(channelData[chNum].chInfo),
+                reinterpret_cast<uint8_t*>(&chInfo));
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ChannelConfig::getChannelAccessData(const uint8_t& chNum,
+                                               ChannelAccess& chAccessData)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Session-less channel doesn't have access data.");
+        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+    }
+
+    if (checkAndReloadVolatileData() != 0)
+    {
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    std::copy_n(
+        reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
+        sizeof(channelData[chNum].chAccess.chVolatileData),
+        reinterpret_cast<uint8_t*>(&chAccessData));
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t
+    ChannelConfig::setChannelAccessData(const uint8_t& chNum,
+                                        const ChannelAccess& chAccessData,
+                                        const uint8_t& setFlag)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Session-less channel doesn't have access data.");
+        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+    }
+
+    if ((setFlag & setAccessMode) &&
+        (!isValidAccessMode(chAccessData.accessMode)))
+    {
+        log<level::DEBUG>("Invalid access mode specified");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    if (checkAndReloadVolatileData() != 0)
+    {
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    if (setFlag & setAccessMode)
+    {
+        channelData[chNum].chAccess.chVolatileData.accessMode =
+            chAccessData.accessMode;
+    }
+    if (setFlag & setUserAuthEnabled)
+    {
+        channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
+            chAccessData.userAuthDisabled;
+    }
+    if (setFlag & setMsgAuthEnabled)
+    {
+        channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
+            chAccessData.perMsgAuthDisabled;
+    }
+    if (setFlag & setAlertingEnabled)
+    {
+        channelData[chNum].chAccess.chVolatileData.alertingDisabled =
+            chAccessData.alertingDisabled;
+    }
+    if (setFlag & setPrivLimit)
+    {
+        channelData[chNum].chAccess.chVolatileData.privLimit =
+            chAccessData.privLimit;
+    }
+
+    // Write Volatile data to file
+    if (writeChannelVolatileData() != 0)
+    {
+        log<level::DEBUG>("Failed to update the channel volatile data");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t
+    ChannelConfig::getChannelAccessPersistData(const uint8_t& chNum,
+                                               ChannelAccess& chAccessData)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Session-less channel doesn't have access data.");
+        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+    }
+
+    if (checkAndReloadNVData() != 0)
+    {
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    std::copy_n(reinterpret_cast<uint8_t*>(
+                    &channelData[chNum].chAccess.chNonVolatileData),
+                sizeof(channelData[chNum].chAccess.chNonVolatileData),
+                reinterpret_cast<uint8_t*>(&chAccessData));
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ChannelConfig::setChannelAccessPersistData(
+    const uint8_t& chNum, const ChannelAccess& chAccessData,
+    const uint8_t& setFlag)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Session-less channel doesn't have access data.");
+        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+    }
+
+    if ((setFlag & setAccessMode) &&
+        (!isValidAccessMode(chAccessData.accessMode)))
+    {
+        log<level::DEBUG>("Invalid access mode specified");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    if (checkAndReloadNVData() != 0)
+    {
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    if (setFlag & setAccessMode)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.accessMode =
+            chAccessData.accessMode;
+    }
+    if (setFlag & setUserAuthEnabled)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
+            chAccessData.userAuthDisabled;
+    }
+    if (setFlag & setMsgAuthEnabled)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
+            chAccessData.perMsgAuthDisabled;
+    }
+    if (setFlag & setAlertingEnabled)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
+            chAccessData.alertingDisabled;
+    }
+    if (setFlag & setPrivLimit)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.privLimit =
+            chAccessData.privLimit;
+    }
+
+    // Write persistent data to file
+    if (writeChannelPersistData() != 0)
+    {
+        log<level::DEBUG>("Failed to update the presist data file");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t
+    ChannelConfig::getChannelAuthTypeSupported(const uint8_t& chNum,
+                                               uint8_t& authTypeSupported)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ChannelConfig::getChannelEnabledAuthType(const uint8_t& chNum,
+                                                    const uint8_t& priv,
+                                                    EAuthType& authType)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Invalid channel");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Sessionless channel doesn't have access data.");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (!isValidPrivLimit(priv))
+    {
+        log<level::DEBUG>("Invalid privilege specified.");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    // TODO: Hardcoded for now. Need to implement.
+    authType = EAuthType::none;
+
+    return IPMI_CC_OK;
+}
+
+std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
+{
+    struct stat fileStat;
+    if (stat(fileName.c_str(), &fileStat) != 0)
+    {
+        log<level::DEBUG>("Error in getting last updated time stamp");
+        return -EIO;
+    }
+    return fileStat.st_mtime;
+}
+
+EChannelAccessMode
+    ChannelConfig::convertToAccessModeIndex(const std::string& mode)
+{
+    auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
+    if (iter == accessModeList.end())
+    {
+        log<level::ERR>("Invalid access mode.",
+                        entry("MODE_STR=%s", mode.c_str()));
+        throw std::invalid_argument("Invalid access mode.");
+    }
+
+    return static_cast<EChannelAccessMode>(
+        std::distance(accessModeList.begin(), iter));
+}
+
+std::string ChannelConfig::convertToAccessModeString(const uint8_t& value)
+{
+    if (accessModeList.size() <= value)
+    {
+        log<level::ERR>("Invalid access mode.", entry("MODE_IDX=%d", value));
+        throw std::invalid_argument("Invalid access mode.");
+    }
+
+    return accessModeList.at(value);
+}
+
+CommandPrivilege
+    ChannelConfig::convertToPrivLimitIndex(const std::string& value)
+{
+    auto iter = std::find(privList.begin(), privList.end(), value);
+    if (iter == privList.end())
+    {
+        log<level::ERR>("Invalid privilege.",
+                        entry("PRIV_STR=%s", value.c_str()));
+        throw std::invalid_argument("Invalid privilege.");
+    }
+
+    return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
+}
+
+std::string ChannelConfig::convertToPrivLimitString(const uint8_t& value)
+{
+    if (privList.size() <= value)
+    {
+        log<level::ERR>("Invalid privilege.", entry("PRIV_IDX=%d", value));
+        throw std::invalid_argument("Invalid privilege.");
+    }
+
+    return privList.at(value);
+}
+
+EChannelSessSupported
+    ChannelConfig::convertToSessionSupportIndex(const std::string& value)
+{
+    auto iter =
+        std::find(sessionSupportList.begin(), sessionSupportList.end(), value);
+    if (iter == sessionSupportList.end())
+    {
+        log<level::ERR>("Invalid session supported.",
+                        entry("SESS_STR=%s", value.c_str()));
+        throw std::invalid_argument("Invalid session supported.");
+    }
+
+    return static_cast<EChannelSessSupported>(
+        std::distance(sessionSupportList.begin(), iter));
+}
+
+EChannelMediumType
+    ChannelConfig::convertToMediumTypeIndex(const std::string& value)
+{
+    std::unordered_map<std::string, EChannelMediumType>::iterator it =
+        mediumTypeMap.find(value);
+    if (it == mediumTypeMap.end())
+    {
+        log<level::ERR>("Invalid medium type.",
+                        entry("MEDIUM_STR=%s", value.c_str()));
+        throw std::invalid_argument("Invalid medium type.");
+    }
+
+    return static_cast<EChannelMediumType>(it->second);
+}
+
+EChannelProtocolType
+    ChannelConfig::convertToProtocolTypeIndex(const std::string& value)
+{
+    std::unordered_map<std::string, EChannelProtocolType>::iterator it =
+        protocolTypeMap.find(value);
+    if (it == protocolTypeMap.end())
+    {
+        log<level::ERR>("Invalid protocol type.",
+                        entry("PROTO_STR=%s", value.c_str()));
+        throw std::invalid_argument("Invalid protocol type.");
+    }
+
+    return static_cast<EChannelProtocolType>(it->second);
+}
+
+Json ChannelConfig::readJsonFile(const std::string& configFile)
+{
+    std::ifstream jsonFile(configFile);
+    if (!jsonFile.good())
+    {
+        log<level::ERR>("JSON file not found");
+        return nullptr;
+    }
+
+    Json data = nullptr;
+    try
+    {
+        data = Json::parse(jsonFile, nullptr, false);
+    }
+    catch (Json::parse_error& e)
+    {
+        log<level::DEBUG>("Corrupted channel config.",
+                          entry("MSG: %s", e.what()));
+        throw std::runtime_error("Corrupted channel config file");
+    }
+
+    return data;
+}
+
+int ChannelConfig::writeJsonFile(const std::string& configFile,
+                                 const Json& jsonData)
+{
+    std::ofstream jsonFile(configFile);
+    if (!jsonFile.good())
+    {
+        log<level::ERR>("JSON file not found");
+        return -EIO;
+    }
+
+    // Write JSON to file
+    jsonFile << jsonData;
+
+    jsonFile.flush();
+    return 0;
+}
+
+void ChannelConfig::setDefaultChannelConfig(const uint8_t& chNum,
+                                            const std::string& chName)
+{
+    channelData[chNum].chName = chName;
+    channelData[chNum].chID = chNum;
+    channelData[chNum].isChValid = false;
+    channelData[chNum].activeSessCount = 0;
+
+    channelData[chNum].chInfo.mediumType = defaultMediumType;
+    channelData[chNum].chInfo.protocolType = defaultProtocolType;
+    channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
+    channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
+    channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
+}
+
+int ChannelConfig::loadChannelConfig()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    Json data = readJsonFile(channelConfigDefaultFilename);
+    if (data == nullptr)
+    {
+        log<level::DEBUG>("Error in opening IPMI Channel data file");
+        return -EIO;
+    }
+
+    try
+    {
+        // Fill in global structure
+        for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
+        {
+            std::fill(reinterpret_cast<uint8_t*>(&channelData[chNum]),
+                      reinterpret_cast<uint8_t*>(&channelData[chNum]) +
+                          sizeof(ChannelData),
+                      0);
+            std::string chKey = std::to_string(chNum);
+            Json jsonChData = data[chKey].get<Json>();
+            if (jsonChData.is_null())
+            {
+                log<level::WARNING>(
+                    "Channel not configured so loading default.",
+                    entry("CHANNEL_NUM:%d", chNum));
+                // If user didn't want to configure specific channel (say
+                // reserved channel), then load that index with default values.
+                std::string chName(defaultChannelName);
+                setDefaultChannelConfig(chNum, chName);
+            }
+            else
+            {
+                std::string chName = jsonChData[nameString].get<std::string>();
+                channelData[chNum].chName = chName;
+                channelData[chNum].chID = chNum;
+                channelData[chNum].isChValid =
+                    jsonChData[isValidString].get<bool>();
+                channelData[chNum].activeSessCount =
+                    jsonChData.value(activeSessionsString, 0);
+                Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
+                if (jsonChInfo.is_null())
+                {
+                    log<level::ERR>("Invalid/corrupted channel config file");
+                    return -EBADMSG;
+                }
+                else
+                {
+                    std::string medTypeStr =
+                        jsonChInfo[mediumTypeString].get<std::string>();
+                    channelData[chNum].chInfo.mediumType = static_cast<uint8_t>(
+                        convertToMediumTypeIndex(medTypeStr));
+                    std::string protoTypeStr =
+                        jsonChInfo[protocolTypeString].get<std::string>();
+                    channelData[chNum].chInfo.protocolType =
+                        static_cast<uint8_t>(
+                            convertToProtocolTypeIndex(protoTypeStr));
+                    std::string sessStr =
+                        jsonChInfo[sessionSupportedString].get<std::string>();
+                    channelData[chNum].chInfo.sessionSupported =
+                        static_cast<uint8_t>(
+                            convertToSessionSupportIndex(sessStr));
+                    channelData[chNum].chInfo.isIpmi =
+                        jsonChInfo[isIpmiString].get<bool>();
+                    channelData[chNum].chInfo.authTypeSupported =
+                        defaultAuthType;
+                }
+            }
+        }
+    }
+    catch (const Json::exception& e)
+    {
+        log<level::DEBUG>("Json Exception caught.", entry("MSG:%s", e.what()));
+        return -EBADMSG;
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>("Corrupted config.", entry("MSG:%s", e.what()));
+        return -EBADMSG;
+    }
+
+    return 0;
+}
+
+int ChannelConfig::readChannelVolatileData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    Json data = readJsonFile(channelVolatileDataFilename);
+    if (data == nullptr)
+    {
+        log<level::DEBUG>("Error in opening IPMI Channel data file");
+        return -EIO;
+    }
+
+    try
+    {
+        // Fill in global structure
+        for (auto it = data.begin(); it != data.end(); ++it)
+        {
+            std::string chKey = it.key();
+            uint8_t chNum = std::stoi(chKey, nullptr, 10);
+            if ((chNum < 0) || (chNum > maxIpmiChannels))
+            {
+                log<level::DEBUG>(
+                    "Invalid channel access entry in config file");
+                throw std::out_of_range("Out of range - channel number");
+            }
+            Json jsonChData = it.value();
+            if (!jsonChData.is_null())
+            {
+                std::string accModeStr =
+                    jsonChData[accessModeString].get<std::string>();
+                channelData[chNum].chAccess.chVolatileData.accessMode =
+                    static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
+                channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
+                    jsonChData[userAuthDisabledString].get<bool>();
+                channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
+                    jsonChData[perMsgAuthDisabledString].get<bool>();
+                channelData[chNum].chAccess.chVolatileData.alertingDisabled =
+                    jsonChData[alertingDisabledString].get<bool>();
+                std::string privStr =
+                    jsonChData[privLimitString].get<std::string>();
+                channelData[chNum].chAccess.chVolatileData.privLimit =
+                    static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
+            }
+            else
+            {
+                log<level::ERR>(
+                    "Invalid/corrupted volatile channel access file",
+                    entry("FILE: %s", channelVolatileDataFilename));
+                throw std::runtime_error(
+                    "Corrupted volatile channel access file");
+            }
+        }
+    }
+    catch (const Json::exception& e)
+    {
+        log<level::DEBUG>("Json Exception caught.", entry("MSG:%s", e.what()));
+        throw std::runtime_error("Corrupted volatile channel access file");
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>("Corrupted config.", entry("MSG:%s", e.what()));
+        throw std::runtime_error("Corrupted volatile channel access file");
+    }
+
+    // Update the timestamp
+    voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
+    return 0;
+}
+
+int ChannelConfig::readChannelPersistData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    Json data = readJsonFile(channelNvDataFilename);
+    if (data == nullptr)
+    {
+        log<level::DEBUG>("Error in opening IPMI Channel data file");
+        return -EIO;
+    }
+
+    try
+    {
+        // Fill in global structure
+        for (auto it = data.begin(); it != data.end(); ++it)
+        {
+            std::string chKey = it.key();
+            uint8_t chNum = std::stoi(chKey, nullptr, 10);
+            if ((chNum < 0) || (chNum > maxIpmiChannels))
+            {
+                log<level::DEBUG>(
+                    "Invalid channel access entry in config file");
+                throw std::out_of_range("Out of range - channel number");
+            }
+            Json jsonChData = it.value();
+            if (!jsonChData.is_null())
+            {
+                std::string accModeStr =
+                    jsonChData[accessModeString].get<std::string>();
+                channelData[chNum].chAccess.chNonVolatileData.accessMode =
+                    static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
+                channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
+                    jsonChData[userAuthDisabledString].get<bool>();
+                channelData[chNum]
+                    .chAccess.chNonVolatileData.perMsgAuthDisabled =
+                    jsonChData[perMsgAuthDisabledString].get<bool>();
+                channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
+                    jsonChData[alertingDisabledString].get<bool>();
+                std::string privStr =
+                    jsonChData[privLimitString].get<std::string>();
+                channelData[chNum].chAccess.chNonVolatileData.privLimit =
+                    static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
+            }
+            else
+            {
+                log<level::ERR>("Invalid/corrupted nv channel access file",
+                                entry("FILE:%s", channelNvDataFilename));
+                throw std::runtime_error("Corrupted nv channel access file");
+            }
+        }
+    }
+    catch (const Json::exception& e)
+    {
+        log<level::DEBUG>("Json Exception caught.", entry("MSG:%s", e.what()));
+        throw std::runtime_error("Corrupted nv channel access file");
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>("Corrupted config.", entry("MSG: %s", e.what()));
+        throw std::runtime_error("Corrupted nv channel access file");
+    }
+
+    // Update the timestamp
+    nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
+    return 0;
+}
+
+int ChannelConfig::writeChannelVolatileData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+    Json outData;
+
+    try
+    {
+        for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
+        {
+            if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
+            {
+                Json jsonObj;
+                std::string chKey = std::to_string(chNum);
+                std::string accModeStr = convertToAccessModeString(
+                    channelData[chNum].chAccess.chVolatileData.accessMode);
+                jsonObj[accessModeString] = accModeStr;
+                jsonObj[userAuthDisabledString] =
+                    channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
+                jsonObj[perMsgAuthDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chVolatileData.perMsgAuthDisabled;
+                jsonObj[alertingDisabledString] =
+                    channelData[chNum].chAccess.chVolatileData.alertingDisabled;
+                std::string privStr = convertToPrivLimitString(
+                    channelData[chNum].chAccess.chVolatileData.privLimit);
+                jsonObj[privLimitString] = privStr;
+
+                outData[chKey] = jsonObj;
+            }
+        }
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>("Corrupted config.", entry("MSG: %s", e.what()));
+        return -EINVAL;
+    }
+
+    if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
+    {
+        log<level::DEBUG>("Error in write JSON data to file");
+        return -EIO;
+    }
+
+    // Update the timestamp
+    voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
+    return 0;
+}
+
+int ChannelConfig::writeChannelPersistData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+    Json outData;
+
+    try
+    {
+        for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
+        {
+            if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
+            {
+                Json jsonObj;
+                std::string chKey = std::to_string(chNum);
+                std::string accModeStr = convertToAccessModeString(
+                    channelData[chNum].chAccess.chNonVolatileData.accessMode);
+                jsonObj[accessModeString] = accModeStr;
+                jsonObj[userAuthDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chNonVolatileData.userAuthDisabled;
+                jsonObj[perMsgAuthDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chNonVolatileData.perMsgAuthDisabled;
+                jsonObj[alertingDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chNonVolatileData.alertingDisabled;
+                std::string privStr = convertToPrivLimitString(
+                    channelData[chNum].chAccess.chNonVolatileData.privLimit);
+                jsonObj[privLimitString] = privStr;
+
+                outData[chKey] = jsonObj;
+            }
+        }
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>("Corrupted config.", entry("MSG: %s", e.what()));
+        return -EINVAL;
+    }
+
+    if (writeJsonFile(channelNvDataFilename, outData) != 0)
+    {
+        log<level::DEBUG>("Error in write JSON data to file");
+        return -EIO;
+    }
+
+    // Update the timestamp
+    nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
+    return 0;
+}
+
+int ChannelConfig::checkAndReloadNVData()
+{
+    std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
+    int ret = 0;
+    if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
+    {
+        try
+        {
+            ret = readChannelPersistData();
+        }
+        catch (const std::exception& e)
+        {
+            log<level::ERR>("Exception caught in readChannelPersistData.",
+                            entry("MSG=%s", e.what()));
+            ret = -EIO;
+        }
+    }
+    return ret;
+}
+
+int ChannelConfig::checkAndReloadVolatileData()
+{
+    std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
+    int ret = 0;
+    if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
+    {
+        try
+        {
+            ret = readChannelVolatileData();
+        }
+        catch (const std::exception& e)
+        {
+            log<level::ERR>("Exception caught in readChannelVolatileData.",
+                            entry("MSG=%s", e.what()));
+            ret = -EIO;
+        }
+    }
+    return ret;
+}
+
+void ChannelConfig::initChannelPersistData()
+{
+    /* Always read the channel config */
+    if (loadChannelConfig() != 0)
+    {
+        log<level::ERR>("Failed to read channel config file");
+        throw std::ios_base::failure("Failed to load channel configuration");
+    }
+
+    /* Populate the channel persist data */
+    if (readChannelPersistData() != 0)
+    {
+        // Copy default NV data to RW location
+        std::experimental::filesystem::copy_file(channelAccessDefaultFilename,
+                                                 channelNvDataFilename);
+
+        // Load the channel access NV data
+        if (readChannelPersistData() != 0)
+        {
+            log<level::ERR>("Failed to read channel access NV data");
+            throw std::ios_base::failure(
+                "Failed to read channel access NV configuration");
+        }
+    }
+
+    // First check the volatile data file
+    // If not present, load the default values
+    if (readChannelVolatileData() != 0)
+    {
+        // Copy default volatile data to temporary location
+        // NV file(channelNvDataFilename) must have created by now.
+        std::experimental::filesystem::copy_file(channelNvDataFilename,
+                                                 channelVolatileDataFilename);
+
+        // Load the channel access volatile data
+        if (readChannelVolatileData() != 0)
+        {
+            log<level::ERR>("Failed to read channel access volatile data");
+            throw std::ios_base::failure(
+                "Failed to read channel access volatile configuration");
+        }
+    }
+    return;
+}
+
+} // namespace ipmi
diff --git a/user_channel/channel_mgmt.hpp b/user_channel/channel_mgmt.hpp
new file mode 100644
index 0000000..053fa39
--- /dev/null
+++ b/user_channel/channel_mgmt.hpp
@@ -0,0 +1,334 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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.
+*/
+
+#pragma once
+#include "channel_layer.hpp"
+
+#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/interprocess/sync/named_recursive_mutex.hpp>
+#include <cstdint>
+#include <ctime>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace ipmi
+{
+
+using Json = nlohmann::json;
+
+static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex";
+static constexpr const char* ipmiChMutexCleanupLockFile =
+    "/var/lib/ipmi/ipmi_channel_mutex_cleanup";
+
+struct ChannelAccessData
+{
+    ChannelAccess chNonVolatileData;
+    ChannelAccess chVolatileData;
+};
+
+struct ChannelData
+{
+    std::string chName;
+    uint8_t chID;
+    bool isChValid;
+    uint8_t activeSessCount;
+    ChannelInfo chInfo;
+    ChannelAccessData chAccess;
+};
+
+class ChannelConfig;
+
+ChannelConfig& getChannelConfigObject();
+
+class ChannelConfig
+{
+  public:
+    ChannelConfig(const ChannelConfig&) = delete;
+    ChannelConfig& operator=(const ChannelConfig&) = delete;
+    ChannelConfig(ChannelConfig&&) = delete;
+    ChannelConfig& operator=(ChannelConfig&&) = delete;
+
+    ~ChannelConfig() = default;
+    ChannelConfig();
+
+    /** @brief determines valid channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return true if valid, false otherwise
+     */
+    bool isValidChannel(const uint8_t& chNum);
+
+    /** @brief determines valid authentication type
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] authType - authentication type
+     *
+     *  @return true if valid, false otherwise
+     */
+    bool isValidAuthType(const uint8_t& chNum, const EAuthType& authType);
+
+    /** @brief determines supported session type of a channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return EChannelSessSupported - supported session type
+     */
+    EChannelSessSupported getChannelSessionSupport(const uint8_t& chNum);
+
+    /** @brief determines number of active sessions on a channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return numer of active sessions
+     */
+    int getChannelActiveSessions(const uint8_t& chNum);
+
+    /** @brief provides channel info details
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] chInfo - channel info details
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t getChannelInfo(const uint8_t& chNum, ChannelInfo& chInfo);
+
+    /** @brief provides channel access data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] chAccessData - channel access data
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t getChannelAccessData(const uint8_t& chNum,
+                                    ChannelAccess& chAccessData);
+
+    /** @brief to set channel access data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] chAccessData - channel access data
+     *  @param[in] setFlag - flag to indicate updatable fields
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t setChannelAccessData(const uint8_t& chNum,
+                                    const ChannelAccess& chAccessData,
+                                    const uint8_t& setFlag);
+
+    /** @brief to get channel access data persistent data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] chAccessData - channel access data
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t getChannelAccessPersistData(const uint8_t& chNum,
+                                           ChannelAccess& chAccessData);
+
+    /** @brief to set channel access data persistent data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] chAccessData - channel access data
+     *  @param[in] setFlag - flag to indicate updatable fields
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t setChannelAccessPersistData(const uint8_t& chNum,
+                                           const ChannelAccess& chAccessData,
+                                           const uint8_t& setFlag);
+
+    /** @brief provides supported authentication type for the channel
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] authTypeSupported - supported authentication type
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t getChannelAuthTypeSupported(const uint8_t& chNum,
+                                           uint8_t& authTypeSupported);
+
+    /** @brief provides enabled authentication type for the channel
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] priv - privilege
+     *  @param[out] authType - enabled authentication type
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t getChannelEnabledAuthType(const uint8_t& chNum,
+                                         const uint8_t& priv,
+                                         EAuthType& authType);
+
+    std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
+        nullptr};
+
+  private:
+    ChannelData channelData[maxIpmiChannels];
+    std::time_t nvFileLastUpdatedTime;
+    std::time_t voltFileLastUpdatedTime;
+    std::time_t getUpdatedFileTime(const std::string& fileName);
+    boost::interprocess::file_lock mutexCleanupLock;
+    sdbusplus::bus::bus bus;
+
+    /** @brief function to initialize persistent channel configuration
+     *
+     */
+    void initChannelPersistData();
+
+    /** @brief function to set default channel configuration based on channel
+     * number
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] chName - channel name
+     */
+    void setDefaultChannelConfig(const uint8_t& chNum,
+                                 const std::string& chName);
+
+    /** @brief function to load all channel configuration
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int loadChannelConfig();
+
+    /** @brief function to read persistent channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int readChannelPersistData();
+
+    /** @brief function to write persistent channel configuration to config file
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeChannelPersistData();
+
+    /** @brief function to read volatile channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int readChannelVolatileData();
+
+    /** @brief function to write volatile channel configuration to config file
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeChannelVolatileData();
+
+    /** @brief function to check and reload persistent channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int checkAndReloadNVData();
+
+    /** @brief function to check and reload volatile channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int checkAndReloadVolatileData();
+
+    /** @brief function to read json config file
+     *
+     *  @param[in] configFile - configuration file name
+     *
+     *  @return Json object
+     */
+    Json readJsonFile(const std::string& configFile);
+
+    /** @brief function to write json config file
+     *
+     *  @param[in] configFile - configuration file name
+     *  @param[in] jsonData - json object
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeJsonFile(const std::string& configFile, const Json& jsonData);
+
+    /** @brief function to convert system access mode to Channel access mode
+     * type
+     *
+     *  @param[in] mode - access mode in string
+     *
+     *  @return Channel access mode.
+     */
+    EChannelAccessMode convertToAccessModeIndex(const std::string& mode);
+
+    /** @brief function to convert access mode value to string
+     *
+     *  @param[in] value - acess mode value
+     *
+     *  @return access mode in string
+     */
+    std::string convertToAccessModeString(const uint8_t& value);
+
+    /** @brief conver to channel privilege from system privilege
+     *
+     *  @param[in] value - privilege value
+     *
+     *  @return Channel privilege
+     */
+    CommandPrivilege convertToPrivLimitIndex(const std::string& value);
+
+    /** @brief function to convert privilege value to string
+     *
+     *  @param[in] value - privilege value
+     *
+     *  @return privilege in string
+     */
+    std::string convertToPrivLimitString(const uint8_t& value);
+
+    /** @brief function to convert session support string to value type
+     *
+     *  @param[in] value - session support type in string
+     *
+     *  @return support session type
+     */
+    EChannelSessSupported
+        convertToSessionSupportIndex(const std::string& value);
+
+    /** @brief function to convert medium type string to value type
+     *
+     *  @param[in] value - medium type in string
+     *
+     *  @return channel medium type
+     */
+    EChannelMediumType convertToMediumTypeIndex(const std::string& value);
+
+    /** @brief function to convert protocol type string to value type
+     *
+     *  @param[in] value - protocol type in string
+     *
+     *  @return channel protocol  type
+     */
+    EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
+
+    /** @brief function to convert channel number to channel index
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return channel index
+     */
+    uint8_t convertToChannelIndexNumber(const uint8_t& chNum);
+
+    /** @brief function to convert channel name to network interface name
+     *
+     *  @param[in] value - channel interface name - ipmi centric
+     *
+     *  @return network channel interface name
+     */
+    std::string convertToNetInterface(const std::string& value);
+};
+
+} // namespace ipmi
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp
new file mode 100644
index 0000000..c5ef8b7
--- /dev/null
+++ b/user_channel/channelcommands.cpp
@@ -0,0 +1,391 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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.
+*/
+
+#include "channelcommands.hpp"
+
+#include "apphandler.hpp"
+#include "channel_layer.hpp"
+
+#include <phosphor-logging/log.hpp>
+#include <regex>
+
+using namespace phosphor::logging;
+
+namespace ipmi
+{
+
+struct setChannelAccessReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t chNum : 4;
+    uint8_t reserved_1 : 4;
+    uint8_t accessMode : 3;
+    uint8_t usrAuthDisabled : 1;
+    uint8_t msgAuthDisabled : 1;
+    uint8_t alertDisabled : 1;
+    uint8_t accessSetMode : 2;
+    uint8_t privLimit : 4;
+    uint8_t reserved_2 : 2;
+    uint8_t privSetMode : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved_1 : 4;
+    uint8_t chNum : 4;
+    uint8_t accessSetMode : 2;
+    uint8_t alertDisabled : 1;
+    uint8_t msgAuthDisabled : 1;
+    uint8_t usrAuthDisabled : 1;
+    uint8_t accessMode : 3;
+    uint8_t privSetMode : 2;
+    uint8_t reserved_2 : 2;
+    uint8_t privLimit : 4;
+#endif
+
+} __attribute__((packed));
+
+struct getChannelAccessReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t chNum : 4;
+    uint8_t reserved_1 : 4;
+    uint8_t reserved_2 : 6;
+    uint8_t accessSetMode : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved_1 : 4;
+    uint8_t chNum : 4;
+    uint8_t accessSetMode : 2;
+    uint8_t reserved_2 : 6;
+#endif
+} __attribute__((packed));
+
+struct getChannelAccessResp
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t accessMode : 3;
+    uint8_t usrAuthDisabled : 1;
+    uint8_t msgAuthDisabled : 1;
+    uint8_t alertDisabled : 1;
+    uint8_t reserved_1 : 2;
+    uint8_t privLimit : 4;
+    uint8_t reserved_2 : 4;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved_1 : 2;
+    uint8_t alertDisabled : 1;
+    uint8_t msgAuthDisabled : 1;
+    uint8_t usrAuthDisabled : 1;
+    uint8_t accessMode : 3;
+    uint8_t reserved_2 : 4;
+    uint8_t privLimit : 4;
+#endif
+} __attribute__((packed));
+
+struct getChannelInfoReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t chNum : 4;
+    uint8_t reserved_1 : 4;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved_1 : 4;
+    uint8_t chNum : 4;
+#endif
+} __attribute__((packed));
+
+struct getChannelInfoResp
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t chNum : 4;
+    uint8_t reserved_1 : 4;
+    uint8_t mediumType : 7;
+    uint8_t reserved_2 : 1;
+    uint8_t msgProtType : 5;
+    uint8_t reserved_3 : 3;
+    uint8_t actSessCount : 6;
+    uint8_t sessType : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved_1 : 4;
+    uint8_t chNum : 4;
+    uint8_t reserved_2 : 1;
+    uint8_t mediumType : 7;
+    uint8_t reserved_3 : 3;
+    uint8_t msgProtType : 5;
+    uint8_t sessType : 2;
+    uint8_t actSessCount : 6;
+#endif
+    uint8_t vendorId[3];
+    uint8_t auxChInfo[2];
+} __attribute__((packed));
+
+ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                ipmi_request_t request,
+                                ipmi_response_t response,
+                                ipmi_data_len_t data_len,
+                                ipmi_context_t context)
+{
+    const setChannelAccessReq* req = static_cast<setChannelAccessReq*>(request);
+    size_t reqLength = *data_len;
+
+    *data_len = 0;
+
+    if (reqLength != sizeof(*req))
+    {
+        log<level::DEBUG>("Set channel access - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    // TODO: Self channel number (0xE) has to be determined.
+    uint8_t chNum = req->chNum;
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Set channel access - Parameter out of range");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (EChannelSessSupported::none == getChannelSessionSupport(chNum))
+    {
+        log<level::DEBUG>("Set channel access - No support on channel");
+        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+    }
+
+    ChannelAccess chActData;
+    ChannelAccess chNVData;
+    uint8_t setActFlag = 0;
+    uint8_t setNVFlag = 0;
+    ipmi_ret_t compCode = IPMI_CC_OK;
+
+    switch (req->accessSetMode)
+    {
+        case doNotSet:
+            // Do nothing
+            break;
+        case nvData:
+            chNVData.accessMode = req->accessMode;
+            chNVData.userAuthDisabled = req->usrAuthDisabled;
+            chNVData.perMsgAuthDisabled = req->msgAuthDisabled;
+            chNVData.alertingDisabled = req->alertDisabled;
+            setNVFlag |= (setAccessMode | setUserAuthEnabled |
+                          setMsgAuthEnabled | setAlertingEnabled);
+            break;
+        case activeData:
+            chActData.accessMode = req->accessMode;
+            chActData.userAuthDisabled = req->usrAuthDisabled;
+            chActData.perMsgAuthDisabled = req->msgAuthDisabled;
+            chActData.alertingDisabled = req->alertDisabled;
+            setActFlag |= (setAccessMode | setUserAuthEnabled |
+                           setMsgAuthEnabled | setAlertingEnabled);
+            break;
+        case reserved:
+        default:
+            log<level::DEBUG>("Set channel access - Invalid access set mode");
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    switch (req->privSetMode)
+    {
+        case doNotSet:
+            // Do nothing
+            break;
+        case nvData:
+            chNVData.privLimit = req->privLimit;
+            setNVFlag |= setPrivLimit;
+            break;
+        case activeData:
+            chActData.privLimit = req->privLimit;
+            setActFlag |= setPrivLimit;
+            break;
+        case reserved:
+        default:
+            log<level::DEBUG>("Set channel access - Invalid access priv mode");
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (setNVFlag != 0)
+    {
+        compCode = setChannelAccessPersistData(chNum, chNVData, setNVFlag);
+        if (compCode != IPMI_CC_OK)
+        {
+            log<level::DEBUG>("Set channel access - Failed to set access data");
+            return compCode;
+        }
+    }
+
+    if (setActFlag != 0)
+    {
+        compCode = setChannelAccessData(chNum, chActData, setActFlag);
+        if (compCode != IPMI_CC_OK)
+        {
+            log<level::DEBUG>("Set channel access - Failed to set access data");
+            return compCode;
+        }
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiGetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                ipmi_request_t request,
+                                ipmi_response_t response,
+                                ipmi_data_len_t data_len,
+                                ipmi_context_t context)
+{
+    const getChannelAccessReq* req = static_cast<getChannelAccessReq*>(request);
+    size_t reqLength = *data_len;
+
+    *data_len = 0;
+
+    if (reqLength != sizeof(*req))
+    {
+        log<level::DEBUG>("Get channel access - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    // TODO: Self channel number (0xE) has to be determined.
+    uint8_t chNum = req->chNum;
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Get channel access - Parameter out of range");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if ((req->accessSetMode == doNotSet) || (req->accessSetMode == reserved))
+    {
+        log<level::DEBUG>("Get channel access - Invalid Access mode");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    if (EChannelSessSupported::none == getChannelSessionSupport(chNum))
+    {
+        log<level::DEBUG>("Get channel access - No support on channel");
+        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+    }
+
+    getChannelAccessResp* resp = static_cast<getChannelAccessResp*>(response);
+
+    std::fill(reinterpret_cast<uint8_t*>(resp),
+              reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+
+    ChannelAccess chAccess;
+    ipmi_ret_t compCode = IPMI_CC_OK;
+
+    if (req->accessSetMode == nvData)
+    {
+        compCode = getChannelAccessPersistData(chNum, chAccess);
+    }
+    else if (req->accessSetMode == activeData)
+    {
+        compCode = getChannelAccessData(chNum, chAccess);
+    }
+
+    if (compCode != IPMI_CC_OK)
+    {
+        return compCode;
+    }
+
+    resp->accessMode = chAccess.accessMode;
+    resp->usrAuthDisabled = chAccess.userAuthDisabled;
+    resp->msgAuthDisabled = chAccess.perMsgAuthDisabled;
+    resp->alertDisabled = chAccess.alertingDisabled;
+    resp->privLimit = chAccess.privLimit;
+
+    *data_len = sizeof(*resp);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiGetChannelInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                              ipmi_request_t request, ipmi_response_t response,
+                              ipmi_data_len_t data_len, ipmi_context_t context)
+{
+    const getChannelInfoReq* req = static_cast<getChannelInfoReq*>(request);
+    size_t reqLength = *data_len;
+
+    *data_len = 0;
+
+    if (reqLength != sizeof(*req))
+    {
+        log<level::DEBUG>("Get channel info - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    // TODO: Self channel number (0xE) has to be determined.
+    uint8_t chNum = req->chNum;
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Get channel info - Parameter out of range");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    // Check the existance of device for session-less channels.
+    if ((EChannelSessSupported::none != getChannelSessionSupport(chNum)) &&
+        (!(doesDeviceExist(chNum))))
+    {
+        log<level::DEBUG>("Get channel info - Device not exist");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    getChannelInfoResp* resp = static_cast<getChannelInfoResp*>(response);
+
+    std::fill(reinterpret_cast<uint8_t*>(resp),
+              reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+
+    ChannelInfo chInfo;
+    ipmi_ret_t compCode = getChannelInfo(chNum, chInfo);
+    if (compCode != IPMI_CC_OK)
+    {
+        return compCode;
+    }
+
+    resp->chNum = chNum;
+    resp->mediumType = chInfo.mediumType;
+    resp->msgProtType = chInfo.protocolType;
+    resp->actSessCount = getChannelActiveSessions(chNum);
+    resp->sessType = chInfo.sessionSupported;
+
+    // IPMI Spec: The IPMI Enterprise Number is: 7154 (decimal)
+    resp->vendorId[0] = 0xF2;
+    resp->vendorId[1] = 0x1B;
+    resp->vendorId[2] = 0x00;
+
+    // Auxiliary Channel info  - byte 1:2
+    // TODO: For System Interface(0xF) and OEM channel types, this needs
+    // to be changed acoordingly.
+    // All other channel types, its reverved
+    resp->auxChInfo[0] = 0x00;
+    resp->auxChInfo[1] = 0x00;
+
+    *data_len = sizeof(*resp);
+
+    return IPMI_CC_OK;
+}
+
+void registerChannelFunctions()
+{
+    ipmiChannelInit();
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_CHANNEL_ACCESS, NULL,
+                           ipmiSetChannelAccess, PRIVILEGE_ADMIN);
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL,
+                           ipmiGetChannelAccess, PRIVILEGE_USER);
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_INFO, NULL,
+                           ipmiGetChannelInfo, PRIVILEGE_USER);
+    return;
+}
+
+} // namespace ipmi
diff --git a/user_channel/channelcommands.hpp b/user_channel/channelcommands.hpp
new file mode 100644
index 0000000..84d2dcb
--- /dev/null
+++ b/user_channel/channelcommands.hpp
@@ -0,0 +1,32 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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.
+*/
+
+#pragma once
+#include <cstdint>
+
+namespace ipmi
+{
+
+// IPMI commands for channel command NETFN:APP.
+enum ipmi_netfn_channel_cmds
+{
+    IPMI_CMD_SET_CHANNEL_ACCESS = 0x40,
+    IPMI_CMD_GET_CHANNEL_ACCESS = 0x41,
+    IPMI_CMD_GET_CHANNEL_INFO = 0x42,
+};
+
+void registerChannelFunctions();
+} // namespace ipmi
