diff --git a/CMakeLists.txt b/CMakeLists.txt
index 95c4a7b..6fadd46 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,7 +67,7 @@
 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
 
 add_library (zfboemcmds
-             SHARED src/oemcommands.cpp src/utils.cpp
+             SHARED src/oemcommands.cpp
              src/storagecommands.cpp src/usb-dbg.cpp)
 set_target_properties (zfboemcmds PROPERTIES VERSION "0.1.0")
 set_target_properties (zfboemcmds PROPERTIES SOVERSION "0")
diff --git a/include/sdrutils.hpp b/include/sdrutils.hpp
new file mode 100644
index 0000000..317ec06
--- /dev/null
+++ b/include/sdrutils.hpp
@@ -0,0 +1,139 @@
+#pragma once
+
+#include <ipmid/types.hpp>
+
+#include <ipmid/api.h>
+#include <stdint.h>
+
+/**
+ * Get SDR
+ */
+namespace get_sdr
+{
+
+// Response
+struct GetSdrResp
+{
+    uint8_t next_record_id_lsb;
+    uint8_t next_record_id_msb;
+    uint8_t record_data[64];
+} __attribute__((packed));
+
+// Record header
+struct SensorDataRecordHeader
+{
+    uint8_t record_id_lsb;
+    uint8_t record_id_msb;
+    uint8_t sdr_version;
+    uint8_t record_type;
+    uint8_t record_length; // Length not counting the header
+} __attribute__((packed));
+
+enum SensorDataRecordType
+{
+    SENSOR_DATA_FULL_RECORD = 0x1,
+    SENSOR_DATA_FRU_RECORD = 0x11,
+    SENSOR_DATA_ENTITY_RECORD = 0x8,
+};
+
+// Record key
+struct SensorDataRecordKey
+{
+    uint8_t owner_id;
+    uint8_t owner_lun;
+    uint8_t sensor_number;
+} __attribute__((packed));
+
+/** @struct SensorDataFruRecordKey
+ *
+ *  FRU Device Locator Record(key) - SDR Type 11
+ */
+struct SensorDataFruRecordKey
+{
+    uint8_t deviceAddress;
+    uint8_t fruID;
+    uint8_t accessLun;
+    uint8_t channelNumber;
+} __attribute__((packed));
+
+// Body - full record
+#define FULL_RECORD_ID_STR_MAX_LENGTH 16
+
+static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
+
+struct SensorDataFullRecordBody
+{
+    uint8_t entity_id;
+    uint8_t entity_instance;
+    uint8_t sensor_initialization;
+    uint8_t sensor_capabilities; // no macro support
+    uint8_t sensor_type;
+    uint8_t event_reading_type;
+    uint8_t supported_assertions[2];          // no macro support
+    uint8_t supported_deassertions[2];        // no macro support
+    uint8_t discrete_reading_setting_mask[2]; // no macro support
+    uint8_t sensor_units_1;
+    uint8_t sensor_units_2_base;
+    uint8_t sensor_units_3_modifier;
+    uint8_t linearization;
+    uint8_t m_lsb;
+    uint8_t m_msb_and_tolerance;
+    uint8_t b_lsb;
+    uint8_t b_msb_and_accuracy_lsb;
+    uint8_t accuracy_and_sensor_direction;
+    uint8_t r_b_exponents;
+    uint8_t analog_characteristic_flags; // no macro support
+    uint8_t nominal_reading;
+    uint8_t normal_max;
+    uint8_t normal_min;
+    uint8_t sensor_max;
+    uint8_t sensor_min;
+    uint8_t upper_nonrecoverable_threshold;
+    uint8_t upper_critical_threshold;
+    uint8_t upper_noncritical_threshold;
+    uint8_t lower_nonrecoverable_threshold;
+    uint8_t lower_critical_threshold;
+    uint8_t lower_noncritical_threshold;
+    uint8_t positive_threshold_hysteresis;
+    uint8_t negative_threshold_hysteresis;
+    uint16_t reserved;
+    uint8_t oem_reserved;
+    uint8_t id_string_info;
+    char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
+} __attribute__((packed));
+
+/** @struct SensorDataFruRecordBody
+ *
+ *  FRU Device Locator Record(body) - SDR Type 11
+ */
+struct SensorDataFruRecordBody
+{
+    uint8_t reserved;
+    uint8_t deviceType;
+    uint8_t deviceTypeModifier;
+    uint8_t entityID;
+    uint8_t entityInstance;
+    uint8_t oem;
+    uint8_t deviceIDLen;
+    char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
+} __attribute__((packed));
+
+struct SensorDataFullRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataRecordKey key;
+    SensorDataFullRecordBody body;
+} __attribute__((packed));
+
+/** @struct SensorDataFruRecord
+ *
+ *  FRU Device Locator Record - SDR Type 11
+ */
+struct SensorDataFruRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataFruRecordKey key;
+    SensorDataFruRecordBody body;
+} __attribute__((packed));
+
+} // namespace get_sdr
diff --git a/include/storagecommands.hpp b/include/storagecommands.hpp
index f9b1ed5..9e2d79b 100644
--- a/include/storagecommands.hpp
+++ b/include/storagecommands.hpp
@@ -15,7 +15,7 @@
  */
 
 #pragma once
-#include <phosphor-ipmi-host/sensorhandler.hpp>
+#include "sdrutils.hpp"
 
 static constexpr uint8_t ipmiSdrVersion = 0x51;
 
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index f30481a..af21713 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -23,7 +23,7 @@
 #include <cstring>
 #include <iostream>
 #include <oemcommands.hpp>
-#include <phosphor-ipmi-host/utils.hpp>
+#include <ipmid/utils.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <string>
@@ -43,6 +43,92 @@
                                     uint8_t *);
 ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t *,
                                    uint8_t *);
+namespace variant_ns = sdbusplus::message::variant_ns;
+
+enum class LanParam : uint8_t
+{
+    INPROGRESS = 0,
+    AUTHSUPPORT = 1,
+    AUTHENABLES = 2,
+    IP = 3,
+    IPSRC = 4,
+    MAC = 5,
+    SUBNET = 6,
+    GATEWAY = 12,
+    VLAN = 20,
+    CIPHER_SUITE_COUNT = 22,
+    CIPHER_SUITE_ENTRIES = 23,
+    IPV6 = 59,
+};
+
+ipmi_ret_t getNetworkData(uint8_t lan_param, char *data)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+    const std::string ethdevice = "eth0";
+
+    switch (static_cast<LanParam>(lan_param))
+    {
+        case LanParam::IP:
+        {
+            auto ethIP = ethdevice + "/" + ipmi::network::IP_TYPE;
+            std::string ipaddress;
+            auto ipObjectInfo = ipmi::getIPObject(
+                bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
+
+            auto properties = ipmi::getAllDbusProperties(
+                bus, ipObjectInfo.second, ipObjectInfo.first,
+                ipmi::network::IP_INTERFACE);
+
+            ipaddress = variant_ns::get<std::string>(properties["Address"]);
+
+            std::strcpy(data, ipaddress.c_str());
+        }
+        break;
+
+        case LanParam::IPV6:
+        {
+            auto ethIP = ethdevice + "/ipv6";
+            std::string ipaddress;
+            auto ipObjectInfo = ipmi::getIPObject(
+                bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
+
+            auto properties = ipmi::getAllDbusProperties(
+                bus, ipObjectInfo.second, ipObjectInfo.first,
+                ipmi::network::IP_INTERFACE);
+
+            ipaddress = variant_ns::get<std::string>(properties["Address"]);
+
+            std::strcpy(data, ipaddress.c_str());
+        }
+        break;
+
+        case LanParam::MAC:
+        {
+            std::string macAddress;
+            auto macObjectInfo =
+                ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
+                                    ipmi::network::ROOT, ethdevice);
+
+            auto variant = ipmi::getDbusProperty(
+                bus, macObjectInfo.second, macObjectInfo.first,
+                ipmi::network::MAC_INTERFACE, "MACAddress");
+
+            macAddress = variant_ns::get<std::string>(variant);
+
+            sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
+                   (data), (data + 1), (data + 2), (data + 3), (data + 4),
+                   (data + 5));
+            std::strcpy(data, macAddress.c_str());
+        }
+        break;
+
+        default:
+            rc = IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    return rc;
+}
 
 // return code: 0 successful
 int8_t getFruData(std::string &data, std::string &name)
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
index acb7fee..d64ebf4 100644
--- a/src/storagecommands.cpp
+++ b/src/storagecommands.cpp
@@ -20,7 +20,7 @@
 #include <boost/container/flat_map.hpp>
 #include <commandutils.hpp>
 #include <iostream>
-#include <phosphor-ipmi-host/utils.hpp>
+#include <ipmid/utils.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/message/types.hpp>
 #include <sdbusplus/timer.hpp>
diff --git a/src/utils.cpp b/src/utils.cpp
deleted file mode 100644
index 49c37ab..0000000
--- a/src/utils.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-#include "phosphor-ipmi-host/utils.hpp"
-
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <net/if.h>
-
-#include <cstring>
-#include <iostream>
-#include <ipmid/api.h>
-#include <phosphor-logging/elog-errors.hpp>
-#include <phosphor-logging/log.hpp>
-#include <xyz/openbmc_project/Common/error.hpp>
-
-namespace ipmi
-{
-
-using namespace phosphor::logging;
-using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-
-// Parameters
-enum class LanParam : uint8_t
-{
-    INPROGRESS = 0,
-    AUTHSUPPORT = 1,
-    AUTHENABLES = 2,
-    IP = 3,
-    IPSRC = 4,
-    MAC = 5,
-    SUBNET = 6,
-    GATEWAY = 12,
-    VLAN = 20,
-    CIPHER_SUITE_COUNT = 22,
-    CIPHER_SUITE_ENTRIES = 23,
-    IPV6 = 59,
-};
-
-namespace network
-{
-
-/** @brief checks if the given ip is Link Local Ip or not.
- *  @param[in] ipaddress - IPAddress.
- */
-bool isLinkLocalIP(const std::string &address)
-{
-    return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
-}
-
-} // namespace network
-
-// TODO There may be cases where an interface is implemented by multiple
-//  objects,to handle such cases we are interested on that object
-//  which are on interested busname.
-//  Currently mapper doesn't give the readable busname(gives busid) so we can't
-//  use busname to find the object,will do later once the support is there.
-
-DbusObjectInfo getDbusObject(sdbusplus::bus::bus &bus,
-                             const std::string &interface,
-                             const std::string &serviceRoot,
-                             const std::string &match)
-{
-    std::vector<DbusInterface> interfaces;
-    interfaces.emplace_back(interface);
-
-    auto depth = 0;
-
-    auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
-                                          MAPPER_INTF, "GetSubTree");
-
-    mapperCall.append(serviceRoot, depth, interfaces);
-
-    ObjectTree objectTree;
-    try
-    {
-        auto mapperReply = bus.call(mapperCall);
-        mapperReply.read(objectTree);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Error in mapper call");
-        elog<InternalFailure>();
-    }
-
-    if (objectTree.empty())
-    {
-        log<level::ERR>("No Object has implemented the interface",
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-
-    DbusObjectInfo objectInfo;
-
-    // if match is empty then return the first object
-    if (match == "")
-    {
-        objectInfo = std::make_pair(
-            objectTree.begin()->first,
-            std::move(objectTree.begin()->second.begin()->first));
-        return objectInfo;
-    }
-
-    // else search the match string in the object path
-    auto objectFound = false;
-    for (auto &object : objectTree)
-    {
-        if (object.first.find(match) != std::string::npos)
-        {
-            objectFound = true;
-            objectInfo = make_pair(object.first,
-                                   std::move(object.second.begin()->first));
-            break;
-        }
-    }
-
-    if (!objectFound)
-    {
-        log<level::ERR>("Failed to find object which matches",
-                        entry("MATCH=%s", match.c_str()));
-        elog<InternalFailure>();
-    }
-    return objectInfo;
-}
-
-DbusObjectInfo getIPObject(sdbusplus::bus::bus &bus,
-                           const std::string &interface,
-                           const std::string &serviceRoot,
-                           const std::string &match)
-{
-    auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
-
-    if (objectTree.empty())
-    {
-        log<level::ERR>("No Object has implemented the IP interface",
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-
-    DbusObjectInfo objectInfo;
-
-    for (auto &object : objectTree)
-    {
-        auto variant = ipmi::getDbusProperty(
-            bus, object.second.begin()->first, object.first,
-            ipmi::network::IP_INTERFACE, "Address");
-
-        objectInfo = std::make_pair(object.first, object.second.begin()->first);
-
-        // if LinkLocalIP found look for Non-LinkLocalIP
-        if (ipmi::network::isLinkLocalIP(
-                sdbusplus::message::variant_ns::get<std::string>(variant)))
-        {
-            continue;
-        }
-        else
-        {
-            break;
-        }
-    }
-    return objectInfo;
-}
-
-Value getDbusProperty(sdbusplus::bus::bus &bus, const std::string &service,
-                      const std::string &objPath, const std::string &interface,
-                      const std::string &property)
-{
-
-    Value value;
-
-    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                      PROP_INTF, METHOD_GET);
-
-    method.append(interface, property);
-
-    try
-    {
-        auto reply = bus.call(method);
-        reply.read(value);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Failed to get property",
-                        entry("PROPERTY=%s", property.c_str()),
-                        entry("PATH=%s", objPath.c_str()),
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-
-    return value;
-}
-
-PropertyMap getAllDbusProperties(sdbusplus::bus::bus &bus,
-                                 const std::string &service,
-                                 const std::string &objPath,
-                                 const std::string &interface)
-{
-    PropertyMap properties;
-
-    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                      PROP_INTF, METHOD_GET_ALL);
-
-    method.append(interface);
-
-    try
-    {
-        auto reply = bus.call(method);
-        reply.read(properties);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Failed to get all properties",
-                        entry("PATH=%s", objPath.c_str()),
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-
-    return properties;
-}
-
-ObjectValueTree getManagedObjects(sdbusplus::bus::bus &bus,
-                                  const std::string &service,
-                                  const std::string &objPath)
-{
-    ipmi::ObjectValueTree interfaces;
-
-    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                      "org.freedesktop.DBus.ObjectManager",
-                                      "GetManagedObjects");
-
-    try
-    {
-        auto reply = bus.call(method);
-        reply.read(interfaces);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Failed to get managed objects",
-                        entry("PATH=%s", objPath.c_str()));
-        elog<InternalFailure>();
-    }
-
-    return interfaces;
-}
-
-void setDbusProperty(sdbusplus::bus::bus &bus, const std::string &service,
-                     const std::string &objPath, const std::string &interface,
-                     const std::string &property, const Value &value)
-{
-    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                      PROP_INTF, METHOD_SET);
-
-    method.append(interface, property, value);
-
-    try
-    {
-        bus.call(method);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Failed to set property",
-                        entry("PROPERTY=%s", property.c_str()),
-                        entry("PATH=%s", objPath.c_str()),
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-}
-
-ServiceCache::ServiceCache(const std::string &intf, const std::string &path) :
-    intf(intf), path(path), cachedService(std::nullopt),
-    cachedBusName(std::nullopt)
-{
-}
-
-ServiceCache::ServiceCache(std::string &&intf, std::string &&path) :
-    intf(std::move(intf)), path(std::move(path)), cachedService(std::nullopt),
-    cachedBusName(std::nullopt)
-{
-}
-
-const std::string &ServiceCache::getService(sdbusplus::bus::bus &bus)
-{
-    if (!isValid(bus))
-    {
-        cachedBusName = bus.get_unique_name();
-        cachedService = ::ipmi::getService(bus, intf, path);
-    }
-    return cachedService.value();
-}
-
-void ServiceCache::invalidate()
-{
-    cachedBusName = std::nullopt;
-    cachedService = std::nullopt;
-}
-
-sdbusplus::message::message
-    ServiceCache::newMethodCall(sdbusplus::bus::bus &bus, const char *intf,
-                                const char *method)
-{
-    return bus.new_method_call(getService(bus).c_str(), path.c_str(), intf,
-                               method);
-}
-
-bool ServiceCache::isValid(sdbusplus::bus::bus &bus) const
-{
-    return cachedService && cachedBusName == bus.get_unique_name();
-}
-
-std::string getService(sdbusplus::bus::bus &bus, const std::string &intf,
-                       const std::string &path)
-{
-    auto mapperCall =
-        bus.new_method_call("xyz.openbmc_project.ObjectMapper",
-                            "/xyz/openbmc_project/object_mapper",
-                            "xyz.openbmc_project.ObjectMapper", "GetObject");
-
-    mapperCall.append(path);
-    mapperCall.append(std::vector<std::string>({intf}));
-
-    std::map<std::string, std::vector<std::string>> mapperResponse;
-    try
-    {
-        auto mapperResponseMsg = bus.call(mapperCall);
-        mapperResponseMsg.read(mapperResponse);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        throw std::runtime_error("ERROR in mapper call");
-    }
-
-    if (mapperResponse.begin() == mapperResponse.end())
-    {
-        throw std::runtime_error("ERROR in reading the mapper response");
-    }
-
-    return mapperResponse.begin()->first;
-}
-
-ipmi::ObjectTree getAllDbusObjects(sdbusplus::bus::bus &bus,
-                                   const std::string &serviceRoot,
-                                   const std::string &interface,
-                                   const std::string &match)
-{
-    std::vector<std::string> interfaces;
-    interfaces.emplace_back(interface);
-
-    auto depth = 0;
-
-    auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
-                                          MAPPER_INTF, "GetSubTree");
-
-    mapperCall.append(serviceRoot, depth, interfaces);
-
-    ObjectTree objectTree;
-    try
-    {
-        auto mapperReply = bus.call(mapperCall);
-        mapperReply.read(objectTree);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Error in mapper call",
-                        entry("SERVICEROOT=%s", serviceRoot.c_str()),
-                        entry("INTERFACE=%s", interface.c_str()));
-
-        elog<InternalFailure>();
-    }
-
-    for (auto it = objectTree.begin(); it != objectTree.end();)
-    {
-        if (it->first.find(match) == std::string::npos)
-        {
-            it = objectTree.erase(it);
-        }
-        else
-        {
-            ++it;
-        }
-    }
-
-    return objectTree;
-}
-
-void deleteAllDbusObjects(sdbusplus::bus::bus &bus,
-                          const std::string &serviceRoot,
-                          const std::string &interface,
-                          const std::string &match)
-{
-    try
-    {
-        auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
-
-        for (auto &object : objectTree)
-        {
-            method_no_args::callDbusMethod(bus, object.second.begin()->first,
-                                           object.first, DELETE_INTERFACE,
-                                           "Delete");
-        }
-    }
-    catch (sdbusplus::exception::exception &e)
-    {
-        log<level::INFO>("sdbusplus exception - Unable to delete the objects",
-                         entry("ERROR=%s", e.what()),
-                         entry("INTERFACE=%s", interface.c_str()),
-                         entry("SERVICE=%s", serviceRoot.c_str()));
-    }
-}
-
-namespace variant_ns = sdbusplus::message::variant_ns;
-ipmi_ret_t getNetworkData(uint8_t lan_param, char *data)
-{
-    ipmi_ret_t rc = IPMI_CC_OK;
-    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
-
-    const std::string ethdevice = "eth0";
-
-    switch (static_cast<LanParam>(lan_param))
-    {
-        case LanParam::IP:
-        {
-            auto ethIP = ethdevice + "/" + ipmi::network::IP_TYPE;
-            std::string ipaddress;
-            auto ipObjectInfo = ipmi::getIPObject(
-                bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
-
-            auto properties = ipmi::getAllDbusProperties(
-                bus, ipObjectInfo.second, ipObjectInfo.first,
-                ipmi::network::IP_INTERFACE);
-
-            ipaddress = variant_ns::get<std::string>(properties["Address"]);
-
-            std::strcpy(data, ipaddress.c_str());
-        }
-        break;
-
-        case LanParam::IPV6:
-        {
-            auto ethIP = ethdevice + "/ipv6";
-            std::string ipaddress;
-            auto ipObjectInfo = ipmi::getIPObject(
-                bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
-
-            auto properties = ipmi::getAllDbusProperties(
-                bus, ipObjectInfo.second, ipObjectInfo.first,
-                ipmi::network::IP_INTERFACE);
-
-            ipaddress = variant_ns::get<std::string>(properties["Address"]);
-
-            std::strcpy(data, ipaddress.c_str());
-        }
-        break;
-
-        case LanParam::MAC:
-        {
-            std::string macAddress;
-            auto macObjectInfo =
-                ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
-                                    ipmi::network::ROOT, ethdevice);
-
-            auto variant = ipmi::getDbusProperty(
-                bus, macObjectInfo.second, macObjectInfo.first,
-                ipmi::network::MAC_INTERFACE, "MACAddress");
-
-            macAddress = variant_ns::get<std::string>(variant);
-
-            sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
-                   (data), (data + 1), (data + 2), (data + 3), (data + 4),
-                   (data + 5));
-            std::strcpy(data, macAddress.c_str());
-        }
-        break;
-
-        default:
-            rc = IPMI_CC_PARM_OUT_OF_RANGE;
-    }
-    return rc;
-}
-
-namespace method_no_args
-{
-
-void callDbusMethod(sdbusplus::bus::bus &bus, const std::string &service,
-                    const std::string &objPath, const std::string &interface,
-                    const std::string &method)
-
-{
-    auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                         interface.c_str(), method.c_str());
-
-    try
-    {
-        bus.call(busMethod);
-    }
-    catch (sdbusplus::exception_t &)
-    {
-        log<level::ERR>("Failed to execute method",
-                        entry("METHOD=%s", method.c_str()),
-                        entry("PATH=%s", objPath.c_str()),
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-}
-
-} // namespace method_no_args
-
-} // namespace ipmi
