diff --git a/CMakeLists.txt b/CMakeLists.txt
index e733fad..d1c2d6d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,7 @@
     link_directories (${CMAKE_BINARY_DIR}/sdbusplus-src/.libs)
     include_directories (${CMAKE_BINARY_DIR}/phosphor-logging-src)
     link_directories (${CMAKE_BINARY_DIR}/phosphor-logging-src/.libs)
-
+    include_directories (${CMAKE_BINARY_DIR}/phosphor-ipmi-host/include)
     include_directories (${CMAKE_BINARY_DIR}) # link_directories
                                               # (${CMAKE_BINARY_DIR}/sdbusplus-
                                               # src/.libs)
@@ -44,6 +44,7 @@
 if (YOCTO)
     find_package (PkgConfig REQUIRED)
     pkg_check_modules (LOGGING phosphor-logging REQUIRED)
+    pkg_check_modules (LIBIPMID libipmid REQUIRED)
     include_directories (${LOGGING_INCLUDE_DIRS})
     link_directories (${LOGGING_LIBRARY_DIRS})
 
@@ -61,17 +62,20 @@
     add_executable (runSensorTests ${SENSOR_TEST_SRC})
     add_test (NAME test_sensorcommands COMMAND runSensorTests)
     target_link_libraries (runSensorTests ${GTEST_BOTH_LIBRARIES}
-                           ${CMAKE_THREAD_LIBS_INIT}
-                           phosphor_logging sdbusplus -lsystemd)
+                           ${CMAKE_THREAD_LIBS_INIT} phosphor_logging sdbusplus
+                           -lsystemd)
 endif ()
 
 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
 
 add_library (zinteloemcmds
-             SHARED src/oemcommands.cpp src/utils.cpp src/sensorcommands.cpp
+             SHARED src/oemcommands.cpp src/sensorcommands.cpp
              src/storagecommands.cpp)
 set_target_properties (zinteloemcmds PROPERTIES VERSION "0.1.0")
 set_target_properties (zinteloemcmds PROPERTIES SOVERSION "0")
+if (YOCTO)
+    target_link_libraries (zinteloemcmds ipmid)
+endif ()
 target_link_libraries (zinteloemcmds sdbusplus)
 target_link_libraries (zinteloemcmds phosphor_logging)
 
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index cc4a437..455c61c 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -25,8 +25,8 @@
 #include <boost/process/io.hpp>
 #include <commandutils.hpp>
 #include <iostream>
+#include <ipmid/utils.hpp>
 #include <oemcommands.hpp>
-#include <phosphor-ipmi-host/utils.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <string>
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
index 1666d0b..45cd30b 100644
--- a/src/sensorcommands.cpp
+++ b/src/sensorcommands.cpp
@@ -22,7 +22,7 @@
 #include <cmath>
 #include <commandutils.hpp>
 #include <iostream>
-#include <phosphor-ipmi-host/utils.hpp>
+#include <ipmid/utils.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sdrutils.hpp>
diff --git a/src/utils.cpp b/src/utils.cpp
deleted file mode 100644
index 7619186..0000000
--- a/src/utils.cpp
+++ /dev/null
@@ -1,566 +0,0 @@
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <net/if.h>
-
-#include <phosphor-ipmi-host/utils.hpp>
-#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;
-
-namespace network
-{
-
-/** @brief checks if the given ip is Link Local Ip or not.
- *  @param[in] ipaddress - IPAddress.
- */
-bool isLinkLocalIP(const std::string& ipaddress);
-
-} // 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()));
-    }
-}
-
-ObjectTree getAllAncestors(sdbusplus::bus::bus& bus, const std::string& path,
-                           InterfaceList&& interfaces)
-{
-    auto convertToString = [](InterfaceList& interfaces) -> std::string {
-        std::string intfStr;
-        for (const auto& intf : interfaces)
-        {
-            intfStr += "," + intf;
-        }
-        return intfStr;
-    };
-
-    auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
-                                          MAPPER_INTF, "GetAncestors");
-    mapperCall.append(path, interfaces);
-
-    ObjectTree objectTree;
-    try
-    {
-        auto mapperReply = bus.call(mapperCall);
-        mapperReply.read(objectTree);
-    }
-    catch (sdbusplus::exception_t&)
-    {
-        log<level::ERR>(
-            "Error in mapper call", entry("PATH=%s", path.c_str()),
-            entry("INTERFACES=%s", convertToString(interfaces).c_str()));
-
-        elog<InternalFailure>();
-    }
-
-    if (objectTree.empty())
-    {
-        log<level::ERR>(
-            "No Object has implemented the interface",
-            entry("PATH=%s", path.c_str()),
-            entry("INTERFACES=%s", convertToString(interfaces).c_str()));
-        elog<InternalFailure>();
-    }
-
-    return objectTree;
-}
-
-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 network
-{
-
-bool isLinkLocalIP(const std::string& address)
-{
-    return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
-}
-
-void createIP(sdbusplus::bus::bus& bus, const std::string& service,
-              const std::string& objPath, const std::string& protocolType,
-              const std::string& ipaddress, uint8_t prefix)
-{
-    std::string gateway = "";
-
-    auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                         IP_CREATE_INTERFACE, "IP");
-
-    busMethod.append(protocolType, ipaddress, prefix, gateway);
-
-    try
-    {
-        bus.call(busMethod);
-    }
-    catch (sdbusplus::exception_t&)
-    {
-        log<level::ERR>("Failed to execute method", entry("METHOD=%s", "IP"),
-                        entry("PATH=%s", objPath.c_str()));
-        elog<InternalFailure>();
-    }
-}
-
-void createVLAN(sdbusplus::bus::bus& bus, const std::string& service,
-                const std::string& objPath, const std::string& interfaceName,
-                uint32_t vlanID)
-{
-    auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                         VLAN_CREATE_INTERFACE, "VLAN");
-
-    busMethod.append(interfaceName, vlanID);
-
-    try
-    {
-        bus.call(busMethod);
-    }
-    catch (sdbusplus::exception_t&)
-    {
-        log<level::ERR>("Failed to execute method", entry("METHOD=%s", "VLAN"),
-                        entry("PATH=%s", objPath.c_str()));
-        elog<InternalFailure>();
-    }
-}
-
-uint8_t toPrefix(int addressFamily, const std::string& subnetMask)
-{
-    if (addressFamily == AF_INET6)
-    {
-        return 0;
-    }
-
-    uint32_t buff{};
-
-    auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
-    if (rc <= 0)
-    {
-        log<level::ERR>("inet_pton failed:",
-                        entry("SUBNETMASK=%s", subnetMask.c_str()));
-        return 0;
-    }
-
-    buff = be32toh(buff);
-    // total no of bits - total no of leading zero == total no of ones
-    if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) ==
-        __builtin_popcount(buff))
-    {
-        return __builtin_popcount(buff);
-    }
-    else
-    {
-        log<level::ERR>("Invalid Mask",
-                        entry("SUBNETMASK=%s", subnetMask.c_str()));
-        return 0;
-    }
-}
-
-uint32_t getVLAN(const std::string& path)
-{
-    // Path would be look like
-    // /xyz/openbmc_project/network/eth0_443/ipv4
-
-    uint32_t vlanID = 0;
-    try
-    {
-        auto intfObjectPath = path.substr(0, path.find(IP_TYPE) - 1);
-
-        auto intfName = intfObjectPath.substr(intfObjectPath.rfind("/") + 1);
-
-        auto index = intfName.find("_");
-        if (index != std::string::npos)
-        {
-            auto str = intfName.substr(index + 1);
-            vlanID = std::stoul(str);
-        }
-    }
-    catch (std::exception& e)
-    {
-        log<level::ERR>("Exception occurred during getVLAN",
-                        entry("PATH=%s", path.c_str()),
-                        entry("EXCEPTION=%s", e.what()));
-    }
-    return vlanID;
-}
-
-} // namespace network
-} // namespace ipmi
