diff --git a/Makefile.am b/Makefile.am
index 9eef999..d4f43db 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@
 libapphandlerdir = ${libdir}/ipmid-providers
 libapphandler_LTLIBRARIES = libapphandler.la
 libapphandler_la_SOURCES = \
+	app/channel.cpp \
 	app/watchdog.cpp \
 	apphandler.cpp \
 	sensorhandler.cpp \
diff --git a/app/channel.cpp b/app/channel.cpp
new file mode 100644
index 0000000..72f1571
--- /dev/null
+++ b/app/channel.cpp
@@ -0,0 +1,428 @@
+#include "channel.hpp"
+#include "types.hpp"
+#include "transporthandler.hpp"
+#include "utils.hpp"
+
+#include <string>
+#include <arpa/inet.h>
+
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
+
+extern struct ChannelConfig_t channelConfig;
+
+constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+/** @struct GetChannelAccessRequest
+ *
+ *  IPMI payload for Get Channel access command request.
+ */
+struct GetChannelAccessRequest
+{
+    uint8_t channelNumber;      //!< Channel number.
+    uint8_t volatileSetting;    //!< Get non-volatile or the volatile setting.
+} __attribute__((packed));
+
+/** @struct GetChannelAccessResponse
+ *
+ *  IPMI payload for Get Channel access command response.
+ */
+struct GetChannelAccessResponse
+{
+    uint8_t settings;          //!< Channel settings.
+    uint8_t privilegeLimit;    //!< Channel privilege level limit.
+} __attribute__((packed));
+
+ipmi_ret_t ipmi_set_channel_access(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)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    std::string ipaddress;
+    std::string gateway;
+    uint8_t prefix {};
+    uint32_t vlanID {};
+    std::string networkInterfacePath;
+    ipmi::DbusObjectInfo ipObject;
+    ipmi::DbusObjectInfo systemObject;
+
+    // Todo: parse the request data if needed.
+    // Using Set Channel cmd to apply changes of Set Lan Cmd.
+    try
+    {
+        sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+        log<level::INFO>("Network data from Cache",
+                         entry("PREFIX=%s", channelConfig.netmask.c_str()),
+                         entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
+                         entry("GATEWAY=%s", channelConfig.gateway.c_str()),
+                         entry("VLAN=%d", channelConfig.vlanID),
+                         entry("IPSRC=%d", channelConfig.ipsrc));
+
+        if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
+        {
+            //get the first twelve bits which is vlan id
+            //not interested in rest of the bits.
+            channelConfig.vlanID = le32toh(channelConfig.vlanID);
+            vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
+        }
+
+        // if the asked ip src is DHCP then not interested in
+        // any given data except vlan.
+        if (channelConfig.ipsrc != ipmi::network::IPOrigin::DHCP)
+        {
+            // always get the system object
+            systemObject = ipmi::getDbusObject(
+                    bus,
+                    ipmi::network::SYSTEMCONFIG_INTERFACE,
+                    ipmi::network::ROOT);
+
+            // the below code is to determine the mode of the interface
+            // as the handling is same, if the system is configured with
+            // DHCP or user has given all the data.
+            try
+            {
+                ipmi::ObjectTree ancestorMap;
+
+                ipmi::InterfaceList interfaces {
+                    ipmi::network::ETHERNET_INTERFACE };
+
+                // if the system is having ip object,then
+                // get the IP object.
+                ipObject = ipmi::getDbusObject(bus,
+                                               ipmi::network::IP_INTERFACE,
+                                               ipmi::network::ROOT,
+                                               ipmi::network::IP_TYPE);
+
+                // Get the parent interface of the IP object.
+                try
+                {
+                    ancestorMap = ipmi::getAllAncestors(bus,
+                                                        ipObject.first,
+                                                        std::move(interfaces));
+                }
+                catch (InternalFailure& e)
+                {
+                    // if unable to get the parent interface
+                    // then commit the error and return.
+                    log<level::ERR>("Unable to get the parent interface",
+                                    entry("PATH=%s", ipObject.first.c_str()),
+                                    entry("INTERFACE=%s",
+                                          ipmi::network::ETHERNET_INTERFACE));
+                    commit<InternalFailure>();
+                    rc = IPMI_CC_UNSPECIFIED_ERROR;
+                    channelConfig.clear();
+                    return rc;
+                }
+
+                networkInterfacePath = ancestorMap.begin()->first;
+            }
+            catch (InternalFailure& e)
+            {
+                // TODO Currently IPMI supports single interface,need to handle
+                // Multiple interface through
+                // https://github.com/openbmc/openbmc/issues/2138
+
+                // if there is no ip configured on the system,then
+                // get the network interface object.
+                auto networkInterfaceObject = ipmi::getDbusObject(
+                        bus,
+                        ipmi::network::ETHERNET_INTERFACE,
+                        ipmi::network::ROOT,
+                        ipmi::network::INTERFACE);
+
+                networkInterfacePath = std::move(networkInterfaceObject.first);
+            }
+
+            // get the configured mode on the system.
+            auto enableDHCP = ipmi::getDbusProperty(
+                    bus,
+                    ipmi::network::SERVICE,
+                    networkInterfacePath,
+                    ipmi::network::ETHERNET_INTERFACE,
+                    "DHCPEnabled").get<bool>();
+
+            // check whether user has given all the data
+            // or the configured system interface is dhcp enabled,
+            // in both of the cases get the values from the cache.
+            if ((!channelConfig.ipaddr.empty() &&
+                 !channelConfig.netmask.empty() &&
+                 !channelConfig.gateway.empty()) ||
+                (enableDHCP)) // configured system interface mode = DHCP
+            {
+                //convert mask into prefix
+                ipaddress = channelConfig.ipaddr;
+                prefix = ipmi::network::toPrefix(AF_INET, channelConfig.netmask);
+                gateway = channelConfig.gateway;
+                if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
+                {
+                    //get the first twelve bits which is vlan id
+                    //not interested in rest of the bits.
+                    channelConfig.vlanID = le32toh(channelConfig.vlanID);
+                    vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
+                }
+                else
+                {
+                    vlanID = ipmi::network::getVLAN(networkInterfacePath);
+                }
+
+            }
+            else // asked ip src = static and configured system src = static
+                // or partially given data.
+            {
+                // We have partial filled cache so get the remaining
+                // info from the system.
+
+                // Get the network data from the system as user has
+                // not given all the data then use the data fetched from the
+                // system but it is implementation dependent,IPMI spec doesn't
+                // force it.
+
+                // if system is not having any ip object don't throw error,
+                try
+                {
+                    auto properties = ipmi::getAllDbusProperties(
+                            bus,
+                            ipObject.second,
+                            ipObject.first,
+                            ipmi::network::IP_INTERFACE);
+
+                    ipaddress = channelConfig.ipaddr.empty() ?
+                                ipmi::getIPAddress(bus,
+                                                   ipmi::network::IP_INTERFACE,
+                                                   ipmi::network::ROOT,
+                                                   ipmi::network::IP_TYPE) :
+                                channelConfig.ipaddr;
+
+                    prefix = channelConfig.netmask.empty() ?
+                        properties["PrefixLength"].get<uint8_t>() :
+                        ipmi::network::toPrefix(AF_INET,
+                                channelConfig.netmask);
+
+                }
+                catch (InternalFailure& e)
+                {
+                    log<level::INFO>("Failed to get IP object which matches",
+                            entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
+                            entry("MATCH=%s", ipmi::network::IP_TYPE));
+                }
+
+                auto systemProperties = ipmi::getAllDbusProperties(
+                        bus,
+                        systemObject.second,
+                        systemObject.first,
+                        ipmi::network::SYSTEMCONFIG_INTERFACE);
+
+                gateway = channelConfig.gateway.empty() ?
+                        systemProperties["DefaultGateway"].get<std::string>() :
+                        channelConfig.gateway;
+
+            }
+        }
+
+        // Currently network manager doesn't support purging of all the
+        // ip addresses and the vlan interfaces from the parent interface,
+        // TODO once the support is there, will make the change here.
+        // https://github.com/openbmc/openbmc/issues/2141.
+
+        // TODO Currently IPMI supports single interface,need to handle
+        // Multiple interface through
+        // https://github.com/openbmc/openbmc/issues/2138
+
+        // instead of deleting all the vlan interfaces and
+        // all the ipv4 address,we will call reset method.
+        //delete all the vlan interfaces
+
+        ipmi::deleteAllDbusObjects(bus,
+                                   ipmi::network::ROOT,
+                                   ipmi::network::VLAN_INTERFACE);
+
+        // set the interface mode  to static
+        auto networkInterfaceObject = ipmi::getDbusObject(
+                bus,
+                ipmi::network::ETHERNET_INTERFACE,
+                ipmi::network::ROOT,
+                ipmi::network::INTERFACE);
+
+        // setting the physical interface mode to static.
+        ipmi::setDbusProperty(bus,
+                              ipmi::network::SERVICE,
+                              networkInterfaceObject.first,
+                              ipmi::network::ETHERNET_INTERFACE,
+                              "DHCPEnabled",
+                              false);
+
+        networkInterfacePath = networkInterfaceObject.first;
+
+        //delete all the ipv4 addresses
+        ipmi::deleteAllDbusObjects(bus,
+                                   ipmi::network::ROOT,
+                                   ipmi::network::IP_INTERFACE,
+                                   ipmi::network::IP_TYPE);
+
+        if (vlanID)
+        {
+            ipmi::network::createVLAN(bus,
+                                      ipmi::network::SERVICE,
+                                      ipmi::network::ROOT,
+                                      ipmi::network::INTERFACE,
+                                      vlanID);
+
+            auto networkInterfaceObject = ipmi::getDbusObject(
+                    bus,
+                    ipmi::network::VLAN_INTERFACE,
+                    ipmi::network::ROOT);
+
+           networkInterfacePath = networkInterfaceObject.first;
+        }
+
+        if (channelConfig.ipsrc == ipmi::network::IPOrigin::DHCP)
+        {
+            ipmi::setDbusProperty(bus,
+                                  ipmi::network::SERVICE,
+                                  networkInterfacePath,
+                                  ipmi::network::ETHERNET_INTERFACE,
+                                  "DHCPEnabled",
+                                  true);
+        }
+        else
+        {
+            //change the mode to static
+            ipmi::setDbusProperty(bus,
+                                  ipmi::network::SERVICE,
+                                  networkInterfacePath,
+                                  ipmi::network::ETHERNET_INTERFACE,
+                                  "DHCPEnabled",
+                                  false);
+
+            if (!ipaddress.empty())
+            {
+                ipmi::network::createIP(bus,
+                                        ipmi::network::SERVICE,
+                                        networkInterfacePath,
+                                        ipv4Protocol,
+                                        ipaddress,
+                                        prefix);
+            }
+
+            if (!gateway.empty())
+            {
+                ipmi::setDbusProperty(bus,
+                                      systemObject.second,
+                                      systemObject.first,
+                                      ipmi::network::SYSTEMCONFIG_INTERFACE,
+                                      "DefaultGateway",
+                                      std::string(gateway));
+            }
+        }
+
+    }
+    catch (InternalFailure& e)
+    {
+        log<level::ERR>("Failed to set network data",
+                        entry("PREFIX=%d", prefix),
+                        entry("ADDRESS=%s", ipaddress.c_str()),
+                        entry("GATEWAY=%s", gateway.c_str()),
+                        entry("VLANID=%d", vlanID),
+                        entry("IPSRC=%d", channelConfig.ipsrc));
+
+        commit<InternalFailure>();
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    channelConfig.clear();
+    return rc;
+}
+
+ipmi_ret_t ipmi_get_channel_access(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)
+{
+    auto requestData = reinterpret_cast<const GetChannelAccessRequest*>
+                   (request);
+    std::vector<uint8_t> outPayload(sizeof(GetChannelAccessResponse));
+    auto responseData = reinterpret_cast<GetChannelAccessResponse*>
+            (outPayload.data());
+
+    // Channel 1 is arbitrarily assigned to ETH0 channel
+    constexpr auto channelOne = 0x01;
+
+    /*
+     * The value Eh is used as a way to identify the current channel that
+     * the command is being received from.
+     */
+    constexpr auto channelE = 0x0E;
+
+    if (requestData->channelNumber != channelOne &&
+        requestData->channelNumber != channelE)
+    {
+        *data_len = 0;
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    /*
+     * [7:6] - reserved
+     * [5]   - 1b = Alerting disabled
+     * [4]   - 1b = per message authentication disabled
+     * [3]   - 0b = User level authentication enabled
+     * [2:0] - 2h = always available
+     */
+    constexpr auto channelSetting = 0x32;
+
+    responseData->settings = channelSetting;
+    //Defaulting the channel privilege to administrator level.
+    responseData->privilegeLimit = PRIVILEGE_ADMIN;
+
+    *data_len = outPayload.size();
+    memcpy(response, outPayload.data(), *data_len);
+
+    return IPMI_CC_OK;
+}
+
+// ATTENTION: This ipmi function is very hardcoded on purpose
+// OpenBMC does not fully support IPMI.  This command is useful
+// to have around because it enables testing of interfaces with
+// the IPMI tool.
+#define GET_CHANNEL_INFO_CHANNEL_OFFSET 0
+// IPMI Table 6-2
+#define IPMI_CHANNEL_TYPE_IPMB 1
+// IPMI Table 6-3
+#define IPMI_CHANNEL_MEDIUM_TYPE_OTHER 6
+
+ipmi_ret_t ipmi_app_channel_info(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)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+    uint8_t resp[] = {
+        1,
+        IPMI_CHANNEL_MEDIUM_TYPE_OTHER,
+        IPMI_CHANNEL_TYPE_IPMB,
+        1,0x41,0xA7,0x00,0,0};
+    uint8_t *p = (uint8_t*) request;
+
+    printf("IPMI APP GET CHANNEL INFO\n");
+
+    // The supported channels numbers are 1 and 8.
+    // Channel Number E is used as way to identify the current channel
+    // that the command is being is received from.
+    if (*p == 0xe || *p == 1 || *p == 8) {
+
+        *data_len = sizeof(resp);
+        memcpy(response, resp, *data_len);
+
+    } else {
+        rc = IPMI_CC_PARM_OUT_OF_RANGE;
+        *data_len = 0;
+    }
+
+    return rc;
+}
diff --git a/app/channel.hpp b/app/channel.hpp
new file mode 100644
index 0000000..1391d62
--- /dev/null
+++ b/app/channel.hpp
@@ -0,0 +1,59 @@
+#include "ipmid.hpp"
+
+/** @brief The set channel access IPMI command.
+ *
+ *  @param[in] netfn
+ *  @param[in] cmd
+ *  @param[in] request
+ *  @param[in,out] response
+ *  @param[out] data_len
+ *  @param[in] context
+ *
+ *  @return IPMI_CC_OK on success, non-zero otherwise.
+ */
+ipmi_ret_t ipmi_set_channel_access(
+        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);
+
+/** @brief The get channel access IPMI command.
+ *
+ *  @param[in] netfn
+ *  @param[in] cmd
+ *  @param[in] request
+ *  @param[in,out] response
+ *  @param[out] data_len
+ *  @param[in] context
+ *
+ *  @return IPMI_CC_OK on success, non-zero otherwise.
+ */
+ipmi_ret_t ipmi_get_channel_access(
+        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);
+
+/** @brief The get channel info IPMI command.
+ *
+ *  @param[in] netfn
+ *  @param[in] cmd
+ *  @param[in] request
+ *  @param[in,out] response
+ *  @param[out] data_len
+ *  @param[in] context
+ *
+ *  @return IPMI_CC_OK on success, non-zero otherwise.
+ */
+ipmi_ret_t ipmi_app_channel_info(
+        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);
+
diff --git a/apphandler.cpp b/apphandler.cpp
index f1cd2dd..1655144 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -1,4 +1,5 @@
 #include "apphandler.h"
+#include "app/channel.hpp"
 #include "app/watchdog.hpp"
 #include "host-ipmid/ipmid-api.h"
 #include "ipmid.hpp"
@@ -27,8 +28,6 @@
 constexpr auto app_ifc = "org.openbmc.NetworkManager";
 constexpr auto app_nwinterface = "eth0";
 
-constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
-
 void register_netfn_app_functions() __attribute__((constructor));
 
 using namespace phosphor::logging;
@@ -366,398 +365,6 @@
     return rc;
 }
 
-extern struct ChannelConfig_t channelConfig;
-
-ipmi_ret_t ipmi_set_channel_access(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)
-{
-    ipmi_ret_t rc = IPMI_CC_OK;
-
-    std::string ipaddress;
-    std::string gateway;
-    uint8_t prefix {};
-    uint32_t vlanID {};
-    std::string networkInterfacePath;
-    ipmi::DbusObjectInfo ipObject;
-    ipmi::DbusObjectInfo systemObject;
-
-    // Todo: parse the request data if needed.
-    // Using Set Channel cmd to apply changes of Set Lan Cmd.
-    try
-    {
-        sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
-
-        log<level::INFO>("Network data from Cache",
-                         entry("PREFIX=%s", channelConfig.netmask.c_str()),
-                         entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
-                         entry("GATEWAY=%s", channelConfig.gateway.c_str()),
-                         entry("VLAN=%d", channelConfig.vlanID),
-                         entry("IPSRC=%d", channelConfig.ipsrc));
-
-        if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
-        {
-            //get the first twelve bits which is vlan id
-            //not interested in rest of the bits.
-            channelConfig.vlanID = le32toh(channelConfig.vlanID);
-            vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
-        }
-
-        // if the asked ip src is DHCP then not interested in
-        // any given data except vlan.
-        if (channelConfig.ipsrc != ipmi::network::IPOrigin::DHCP)
-        {
-            // always get the system object
-            systemObject = ipmi::getDbusObject(
-                    bus,
-                    ipmi::network::SYSTEMCONFIG_INTERFACE,
-                    ipmi::network::ROOT);
-
-            // the below code is to determine the mode of the interface
-            // as the handling is same, if the system is configured with
-            // DHCP or user has given all the data.
-            try
-            {
-                ipmi::ObjectTree ancestorMap;
-
-                ipmi::InterfaceList interfaces {
-                    ipmi::network::ETHERNET_INTERFACE };
-
-                // if the system is having ip object,then
-                // get the IP object.
-                ipObject = ipmi::getDbusObject(bus,
-                                               ipmi::network::IP_INTERFACE,
-                                               ipmi::network::ROOT,
-                                               ipmi::network::IP_TYPE);
-
-                // Get the parent interface of the IP object.
-                try
-                {
-                    ancestorMap = ipmi::getAllAncestors(bus,
-                                                        ipObject.first,
-                                                        std::move(interfaces));
-                }
-                catch (InternalFailure& e)
-                {
-                    // if unable to get the parent interface
-                    // then commit the error and return.
-                    log<level::ERR>("Unable to get the parent interface",
-                                    entry("PATH=%s", ipObject.first.c_str()),
-                                    entry("INTERFACE=%s",
-                                          ipmi::network::ETHERNET_INTERFACE));
-                    commit<InternalFailure>();
-                    rc = IPMI_CC_UNSPECIFIED_ERROR;
-                    channelConfig.clear();
-                    return rc;
-                }
-
-                networkInterfacePath = ancestorMap.begin()->first;
-            }
-            catch (InternalFailure& e)
-            {
-                // TODO Currently IPMI supports single interface,need to handle
-                // Multiple interface through
-                // https://github.com/openbmc/openbmc/issues/2138
-
-                // if there is no ip configured on the system,then
-                // get the network interface object.
-                auto networkInterfaceObject = ipmi::getDbusObject(
-                        bus,
-                        ipmi::network::ETHERNET_INTERFACE,
-                        ipmi::network::ROOT,
-                        ipmi::network::INTERFACE);
-
-                networkInterfacePath = std::move(networkInterfaceObject.first);
-            }
-
-            // get the configured mode on the system.
-            auto enableDHCP = ipmi::getDbusProperty(
-                    bus,
-                    ipmi::network::SERVICE,
-                    networkInterfacePath,
-                    ipmi::network::ETHERNET_INTERFACE,
-                    "DHCPEnabled").get<bool>();
-
-            // check whether user has given all the data
-            // or the configured system interface is dhcp enabled,
-            // in both of the cases get the values from the cache.
-            if ((!channelConfig.ipaddr.empty() &&
-                 !channelConfig.netmask.empty() &&
-                 !channelConfig.gateway.empty()) ||
-                (enableDHCP)) // configured system interface mode = DHCP
-            {
-                //convert mask into prefix
-                ipaddress = channelConfig.ipaddr;
-                prefix = ipmi::network::toPrefix(AF_INET, channelConfig.netmask);
-                gateway = channelConfig.gateway;
-                if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
-                {
-                    //get the first twelve bits which is vlan id
-                    //not interested in rest of the bits.
-                    channelConfig.vlanID = le32toh(channelConfig.vlanID);
-                    vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
-                }
-                else
-                {
-                    vlanID = ipmi::network::getVLAN(networkInterfacePath);
-                }
-
-            }
-            else // asked ip src = static and configured system src = static
-                // or partially given data.
-            {
-                // We have partial filled cache so get the remaining
-                // info from the system.
-
-                // Get the network data from the system as user has
-                // not given all the data then use the data fetched from the
-                // system but it is implementation dependent,IPMI spec doesn't
-                // force it.
-
-                // if system is not having any ip object don't throw error,
-                try
-                {
-                    auto properties = ipmi::getAllDbusProperties(
-                            bus,
-                            ipObject.second,
-                            ipObject.first,
-                            ipmi::network::IP_INTERFACE);
-
-                    ipaddress = channelConfig.ipaddr.empty() ?
-                                ipmi::getIPAddress(bus,
-                                                   ipmi::network::IP_INTERFACE,
-                                                   ipmi::network::ROOT,
-                                                   ipmi::network::IP_TYPE) :
-                                channelConfig.ipaddr;
-
-                    prefix = channelConfig.netmask.empty() ?
-                        properties["PrefixLength"].get<uint8_t>() :
-                        ipmi::network::toPrefix(AF_INET,
-                                channelConfig.netmask);
-
-                }
-                catch (InternalFailure& e)
-                {
-                    log<level::INFO>("Failed to get IP object which matches",
-                            entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
-                            entry("MATCH=%s", ipmi::network::IP_TYPE));
-                }
-
-                auto systemProperties = ipmi::getAllDbusProperties(
-                        bus,
-                        systemObject.second,
-                        systemObject.first,
-                        ipmi::network::SYSTEMCONFIG_INTERFACE);
-
-                gateway = channelConfig.gateway.empty() ?
-                        systemProperties["DefaultGateway"].get<std::string>() :
-                        channelConfig.gateway;
-
-            }
-        }
-
-        // Currently network manager doesn't support purging of all the
-        // ip addresses and the vlan interfaces from the parent interface,
-        // TODO once the support is there, will make the change here.
-        // https://github.com/openbmc/openbmc/issues/2141.
-
-        // TODO Currently IPMI supports single interface,need to handle
-        // Multiple interface through
-        // https://github.com/openbmc/openbmc/issues/2138
-
-        // instead of deleting all the vlan interfaces and
-        // all the ipv4 address,we will call reset method.
-        //delete all the vlan interfaces
-
-        ipmi::deleteAllDbusObjects(bus,
-                                   ipmi::network::ROOT,
-                                   ipmi::network::VLAN_INTERFACE);
-
-        // set the interface mode  to static
-        auto networkInterfaceObject = ipmi::getDbusObject(
-                bus,
-                ipmi::network::ETHERNET_INTERFACE,
-                ipmi::network::ROOT,
-                ipmi::network::INTERFACE);
-
-        // setting the physical interface mode to static.
-        ipmi::setDbusProperty(bus,
-                              ipmi::network::SERVICE,
-                              networkInterfaceObject.first,
-                              ipmi::network::ETHERNET_INTERFACE,
-                              "DHCPEnabled",
-                              false);
-
-        networkInterfacePath = networkInterfaceObject.first;
-
-        //delete all the ipv4 addresses
-        ipmi::deleteAllDbusObjects(bus,
-                                   ipmi::network::ROOT,
-                                   ipmi::network::IP_INTERFACE,
-                                   ipmi::network::IP_TYPE);
-
-        if (vlanID)
-        {
-            ipmi::network::createVLAN(bus,
-                                      ipmi::network::SERVICE,
-                                      ipmi::network::ROOT,
-                                      ipmi::network::INTERFACE,
-                                      vlanID);
-
-            auto networkInterfaceObject = ipmi::getDbusObject(
-                    bus,
-                    ipmi::network::VLAN_INTERFACE,
-                    ipmi::network::ROOT);
-
-           networkInterfacePath = networkInterfaceObject.first;
-        }
-
-        if (channelConfig.ipsrc == ipmi::network::IPOrigin::DHCP)
-        {
-            ipmi::setDbusProperty(bus,
-                                  ipmi::network::SERVICE,
-                                  networkInterfacePath,
-                                  ipmi::network::ETHERNET_INTERFACE,
-                                  "DHCPEnabled",
-                                  true);
-        }
-        else
-        {
-            //change the mode to static
-            ipmi::setDbusProperty(bus,
-                                  ipmi::network::SERVICE,
-                                  networkInterfacePath,
-                                  ipmi::network::ETHERNET_INTERFACE,
-                                  "DHCPEnabled",
-                                  false);
-
-            if (!ipaddress.empty())
-            {
-                ipmi::network::createIP(bus,
-                                        ipmi::network::SERVICE,
-                                        networkInterfacePath,
-                                        ipv4Protocol,
-                                        ipaddress,
-                                        prefix);
-            }
-
-            if (!gateway.empty())
-            {
-                ipmi::setDbusProperty(bus,
-                                      systemObject.second,
-                                      systemObject.first,
-                                      ipmi::network::SYSTEMCONFIG_INTERFACE,
-                                      "DefaultGateway",
-                                      std::string(gateway));
-            }
-        }
-
-    }
-    catch (InternalFailure& e)
-    {
-        log<level::ERR>("Failed to set network data",
-                        entry("PREFIX=%d", prefix),
-                        entry("ADDRESS=%s", ipaddress.c_str()),
-                        entry("GATEWAY=%s", gateway.c_str()),
-                        entry("VLANID=%d", vlanID),
-                        entry("IPSRC=%d", channelConfig.ipsrc));
-
-        commit<InternalFailure>();
-        rc = IPMI_CC_UNSPECIFIED_ERROR;
-    }
-
-    channelConfig.clear();
-    return rc;
-}
-
-ipmi_ret_t getChannelAccess(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)
-{
-    auto requestData = reinterpret_cast<const GetChannelAccessRequest*>
-                   (request);
-    std::vector<uint8_t> outPayload(sizeof(GetChannelAccessResponse));
-    auto responseData = reinterpret_cast<GetChannelAccessResponse*>
-            (outPayload.data());
-
-    // Channel 1 is arbitrarily assigned to ETH0 channel
-    constexpr auto channelOne = 0x01;
-
-    /*
-     * The value Eh is used as a way to identify the current channel that
-     * the command is being received from.
-     */
-    constexpr auto channelE = 0x0E;
-
-    if (requestData->channelNumber != channelOne &&
-        requestData->channelNumber != channelE)
-    {
-        *data_len = 0;
-        return IPMI_CC_INVALID_FIELD_REQUEST;
-    }
-
-    /*
-     * [7:6] - reserved
-     * [5]   - 1b = Alerting disabled
-     * [4]   - 1b = per message authentication disabled
-     * [3]   - 0b = User level authentication enabled
-     * [2:0] - 2h = always available
-     */
-    constexpr auto channelSetting = 0x32;
-
-    responseData->settings = channelSetting;
-    //Defaulting the channel privilege to administrator level.
-    responseData->privilegeLimit = PRIVILEGE_ADMIN;
-
-    *data_len = outPayload.size();
-    memcpy(response, outPayload.data(), *data_len);
-
-    return IPMI_CC_OK;
-}
-
-// ATTENTION: This ipmi function is very hardcoded on purpose
-// OpenBMC does not fully support IPMI.  This command is useful
-// to have around because it enables testing of interfaces with
-// the IPMI tool.
-#define GET_CHANNEL_INFO_CHANNEL_OFFSET 0
-// IPMI Table 6-2
-#define IPMI_CHANNEL_TYPE_IPMB 1
-// IPMI Table 6-3
-#define IPMI_CHANNEL_MEDIUM_TYPE_OTHER 6
-
-ipmi_ret_t ipmi_app_channel_info(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)
-{
-    ipmi_ret_t rc = IPMI_CC_OK;
-    uint8_t resp[] = {
-        1,
-        IPMI_CHANNEL_MEDIUM_TYPE_OTHER,
-        IPMI_CHANNEL_TYPE_IPMB,
-        1,0x41,0xA7,0x00,0,0};
-    uint8_t *p = (uint8_t*) request;
-
-    printf("IPMI APP GET CHANNEL INFO\n");
-
-    // The supported channels numbers are 1 and 8.
-    // Channel Number E is used as way to identify the current channel
-    // that the command is being is received from.
-    if (*p == 0xe || *p == 1 || *p == 8) {
-
-        *data_len = sizeof(resp);
-        memcpy(response, resp, *data_len);
-
-    } else {
-        rc = IPMI_CC_PARM_OUT_OF_RANGE;
-        *data_len = 0;
-    }
-
-    return rc;
-}
-
 ipmi_ret_t ipmi_app_wildcard_handler(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)
@@ -826,7 +433,7 @@
     // <Get Channel Access>
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS);
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL,
-                           getChannelAccess, PRIVILEGE_USER);
+                           ipmi_get_channel_access, PRIVILEGE_USER);
 
     // <Get Channel Info Command>
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CHAN_INFO);
diff --git a/apphandler.h b/apphandler.h
index 497b24b..72997d9 100644
--- a/apphandler.h
+++ b/apphandler.h
@@ -19,24 +19,4 @@
     IPMI_CMD_GET_CHAN_INFO          = 0x42,
 };
 
-/** @struct GetChannelAccessRequest
- *
- *  IPMI payload for Get Channel access command request.
- */
-struct GetChannelAccessRequest
-{
-    uint8_t channelNumber;      //!< Channel number.
-    uint8_t volatileSetting;    //!< Get non-volatile or the volatile setting.
-} __attribute__((packed));
-
-/** @struct GetChannelAccessResponse
- *
- *  IPMI payload for Get Channel access command response.
- */
-struct GetChannelAccessResponse
-{
-    uint8_t settings;          //!< Channel settings.
-    uint8_t privilegeLimit;    //!< Channel privilege level limit.
-} __attribute__((packed));
-
 #endif
