diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index e6eddcc..6b38579 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -17,9 +17,9 @@
 #include <host-ipmid/ipmid-api.h>
 
 #include <array>
-#include <host-ipmid/utils.hpp>
 #include <iostream>
 #include <oemcommands.hpp>
+#include <phosphor-ipmi-host/utils.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sstream>
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
new file mode 100644
index 0000000..3c1f050
--- /dev/null
+++ b/src/sensorcommands.cpp
@@ -0,0 +1,1228 @@
+/*
+// Copyright (c) 2017 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 <host-ipmid/ipmid-api.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/container/flat_map.hpp>
+#include <chrono>
+#include <cmath>
+#include <commandutils.hpp>
+#include <iostream>
+#include <phosphor-ipmi-host/utils.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdrutils.hpp>
+#include <sensorcommands.hpp>
+#include <sensorutils.hpp>
+#include <storagecommands.hpp>
+#include <string>
+
+namespace ipmi
+{
+using ManagedObjectType =
+    std::map<sdbusplus::message::object_path,
+             std::map<std::string, std::map<std::string, DbusVariant>>>;
+
+using SensorMap = std::map<std::string, std::map<std::string, DbusVariant>>;
+
+static constexpr int sensorListUpdatePeriod = 10;
+static constexpr int sensorMapUpdatePeriod = 2;
+
+constexpr size_t maxSDRTotalSize =
+    76; // Largest SDR Record Size (type 01) + SDR Overheader Size
+constexpr static const uint32_t noTimestamp = 0xFFFFFFFF;
+
+static uint16_t sdrReservationID;
+static uint32_t sdrLastAdd = noTimestamp;
+static uint32_t sdrLastRemove = noTimestamp;
+
+static SensorSubTree sensorTree;
+static boost::container::flat_map<std::string, ManagedObjectType> SensorCache;
+
+const static boost::container::flat_map<const char *, SensorUnits> sensorUnits{
+    {{"temperature", SensorUnits::degreesC},
+     {"voltage", SensorUnits::volts},
+     {"current", SensorUnits::amps},
+     {"fan_tach", SensorUnits::rpm},
+     {"power", SensorUnits::watts}}};
+
+void registerSensorFunctions() __attribute__((constructor));
+static sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
+
+static sdbusplus::bus::match::match sensorAdded(
+    dbus,
+    "type='signal',member='InterfacesAdded',arg0path='/xyz/openbmc_project/"
+    "sensors/'",
+    [](sdbusplus::message::message &m) {
+        sensorTree.clear();
+        sdrLastAdd = std::chrono::duration_cast<std::chrono::seconds>(
+                         std::chrono::system_clock::now().time_since_epoch())
+                         .count();
+    });
+
+static sdbusplus::bus::match::match sensorRemoved(
+    dbus,
+    "type='signal',member='InterfacesRemoved',arg0path='/xyz/openbmc_project/"
+    "sensors/'",
+    [](sdbusplus::message::message &m) {
+        sensorTree.clear();
+        sdrLastRemove = std::chrono::duration_cast<std::chrono::seconds>(
+                            std::chrono::system_clock::now().time_since_epoch())
+                            .count();
+    });
+
+static void
+    getSensorMaxMin(const std::map<std::string, DbusVariant> &sensorPropertyMap,
+                    double &max, double &min)
+{
+    auto maxMap = sensorPropertyMap.find("MaxValue");
+    auto minMap = sensorPropertyMap.find("MinValue");
+    max = 127;
+    min = -128;
+
+    if (maxMap != sensorPropertyMap.end())
+    {
+        max = apply_visitor(VariantToDoubleVisitor(), maxMap->second);
+    }
+    if (minMap != sensorPropertyMap.end())
+    {
+        min = apply_visitor(VariantToDoubleVisitor(), minMap->second);
+    }
+}
+
+static ipmi_ret_t getSensorConnection(uint8_t sensnum, std::string &connection,
+                                      std::string &path)
+{
+    if (sensorTree.empty() && !getSensorSubtree(sensorTree))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    if (sensorTree.size() < (sensnum + 1))
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    uint8_t sensorIndex = sensnum;
+    for (const auto &sensor : sensorTree)
+    {
+        if (sensorIndex-- == 0)
+        {
+            if (!sensor.second.size())
+            {
+                return IPMI_CC_RESPONSE_ERROR;
+            }
+            connection = sensor.second.begin()->first;
+            path = sensor.first;
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static bool getSensorMap(std::string sensorConnection, std::string sensorPath,
+                         SensorMap &sensorMap)
+{
+    static boost::container::flat_map<
+        std::string, std::chrono::time_point<std::chrono::steady_clock>>
+        updateTimeMap;
+
+    auto updateFind = updateTimeMap.find(sensorConnection);
+    auto lastUpdate = std::chrono::time_point<std::chrono::steady_clock>();
+    if (updateFind != updateTimeMap.end())
+    {
+        lastUpdate = updateFind->second;
+    }
+
+    auto now = std::chrono::steady_clock::now();
+
+    if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate)
+            .count() > sensorMapUpdatePeriod)
+    {
+        updateTimeMap[sensorConnection] = now;
+
+        auto managedObj = dbus.new_method_call(
+            sensorConnection.c_str(), "/", "org.freedesktop.DBus.ObjectManager",
+            "GetManagedObjects");
+
+        ManagedObjectType managedObjects;
+        try
+        {
+            auto reply = dbus.call(managedObj);
+            reply.read(managedObjects);
+        }
+        catch (sdbusplus::exception_t &)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Error getting managed objects from connection",
+                phosphor::logging::entry("CONNECTION=%s",
+                                         sensorConnection.c_str()));
+            return false;
+        }
+
+        SensorCache[sensorConnection] = managedObjects;
+    }
+    auto connection = SensorCache.find(sensorConnection);
+    if (connection == SensorCache.end())
+    {
+        return false;
+    }
+    auto path = connection->second.find(sensorPath);
+    if (path == connection->second.end())
+    {
+        return false;
+    }
+    sensorMap = path->second;
+
+    return true;
+}
+
+/* sensor commands */
+ipmi_ret_t ipmiSensorWildcardHandler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                     ipmi_request_t request,
+                                     ipmi_response_t response,
+                                     ipmi_data_len_t dataLen,
+                                     ipmi_context_t context)
+{
+    *dataLen = 0;
+    printCommand(+netfn, +cmd);
+    return IPMI_CC_INVALID;
+}
+
+ipmi_ret_t ipmiSenGetSensorReading(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                   ipmi_request_t request,
+                                   ipmi_response_t response,
+                                   ipmi_data_len_t dataLen,
+                                   ipmi_context_t context)
+{
+    if (*dataLen != 1)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+
+    uint8_t sensnum = *(static_cast<uint8_t *>(request));
+
+    std::string connection;
+    std::string path;
+
+    auto status = getSensorConnection(sensnum, connection, path);
+    if (status)
+    {
+        return status;
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value");
+
+    if (sensorObject == sensorMap.end() ||
+        sensorObject->second.find("Value") == sensorObject->second.end())
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    auto &value = sensorObject->second["Value"];
+    double reading = apply_visitor(VariantToDoubleVisitor(), value);
+
+    double max;
+    double min;
+    getSensorMaxMin(sensorObject->second, max, min);
+
+    int16_t mValue = 0;
+    int16_t bValue = 0;
+    int8_t rExp = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    SensorReadingResp *msgReply = static_cast<SensorReadingResp *>(response);
+    *dataLen = sizeof(SensorReadingResp);
+
+    msgReply->value =
+        scaleIPMIValueFromDouble(reading, mValue, rExp, bValue, bExp, bSigned);
+    msgReply->operation =
+        static_cast<uint8_t>(IPMISensorReadingByte2::sensorScanningEnable);
+    msgReply->indication[0] = 0; // ignore for non-threshold sensors
+    msgReply->indication[1] = 0;
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiSenSetSensorThresholds(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                      ipmi_request_t request,
+                                      ipmi_response_t response,
+                                      ipmi_data_len_t dataLen,
+                                      ipmi_context_t context)
+{
+    if (*dataLen != 8)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0;
+
+    SensorThresholdReq *req = static_cast<SensorThresholdReq *>(request);
+
+    // upper two bits reserved
+    if (req->mask & 0xC0)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    // lower nc and upper nc not suppported on any sensor
+    if ((req->mask & static_cast<uint8_t>(
+                         SensorThresholdReqEnable::setLowerNonRecoverable)) ||
+        (req->mask & static_cast<uint8_t>(
+                         SensorThresholdReqEnable::setUpperNonRecoverable)))
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    // if no bits are set in the mask, nothing to do
+    if (!(req->mask))
+    {
+        return IPMI_CC_OK;
+    }
+
+    std::string connection;
+    std::string path;
+
+    ipmi_ret_t status = getSensorConnection(req->sensorNum, connection, path);
+    if (status)
+    {
+        return status;
+    }
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value");
+
+    if (sensorObject == sensorMap.end())
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    double max = 0;
+    double min = 0;
+    getSensorMaxMin(sensorObject->second, max, min);
+
+    int16_t mValue = 0;
+    int16_t bValue = 0;
+    int8_t rExp = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    bool setLowerCritical =
+        req->mask &
+        static_cast<uint8_t>(SensorThresholdReqEnable::setLowerCritical);
+    bool setUpperCritical =
+        req->mask &
+        static_cast<uint8_t>(SensorThresholdReqEnable::setUpperCritical);
+
+    bool setLowerWarning =
+        req->mask &
+        static_cast<uint8_t>(SensorThresholdReqEnable::setLowerNonCritical);
+    bool setUpperWarning =
+        req->mask &
+        static_cast<uint8_t>(SensorThresholdReqEnable::setUpperNonCritical);
+
+    // store a vector of property name, value to set, and interface
+    std::vector<std::tuple<std::string, uint8_t, std::string>> thresholdsToSet;
+
+    // define the indexes of the tuple
+    constexpr uint8_t propertyName = 0;
+    constexpr uint8_t thresholdValue = 1;
+    constexpr uint8_t interface = 2;
+    // verifiy all needed fields are present
+    if (setLowerCritical || setUpperCritical)
+    {
+        auto findThreshold =
+            sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+        if (findThreshold == sensorMap.end())
+        {
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+        if (setLowerCritical)
+        {
+            auto findLower = findThreshold->second.find("CriticalLow");
+            if (findLower == findThreshold->second.end())
+            {
+                return IPMI_CC_INVALID_FIELD_REQUEST;
+            }
+            thresholdsToSet.emplace_back("CriticalLow", req->lowerCritical,
+                                         findThreshold->first);
+        }
+        if (setUpperCritical)
+        {
+            auto findUpper = findThreshold->second.find("CriticalHigh");
+            if (findUpper == findThreshold->second.end())
+            {
+                return IPMI_CC_INVALID_FIELD_REQUEST;
+            }
+            thresholdsToSet.emplace_back("CriticalHigh", req->upperCritical,
+                                         findThreshold->first);
+        }
+    }
+    if (setLowerWarning || setUpperWarning)
+    {
+        auto findThreshold =
+            sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+        if (findThreshold == sensorMap.end())
+        {
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+        if (setLowerWarning)
+        {
+            auto findLower = findThreshold->second.find("WarningLow");
+            if (findLower == findThreshold->second.end())
+            {
+                return IPMI_CC_INVALID_FIELD_REQUEST;
+            }
+            thresholdsToSet.emplace_back("WarningLow", req->lowerNonCritical,
+                                         findThreshold->first);
+        }
+        if (setUpperWarning)
+        {
+            auto findUpper = findThreshold->second.find("WarningHigh");
+            if (findUpper == findThreshold->second.end())
+            {
+                return IPMI_CC_INVALID_FIELD_REQUEST;
+            }
+            thresholdsToSet.emplace_back("WarningHigh", req->upperNonCritical,
+                                         findThreshold->first);
+        }
+    }
+
+    for (const auto &property : thresholdsToSet)
+    {
+        // from section 36.3 in the IPMI Spec, assume all linear
+        double valueToSet = ((mValue * std::get<thresholdValue>(property)) +
+                             (bValue * std::pow(10, bExp))) *
+                            std::pow(10, rExp);
+        setDbusProperty(dbus, connection, path, std::get<interface>(property),
+                        std::get<propertyName>(property),
+                        ipmi::Value(valueToSet));
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiSenGetSensorThresholds(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                      ipmi_request_t request,
+                                      ipmi_response_t response,
+                                      ipmi_data_len_t dataLen,
+                                      ipmi_context_t context)
+{
+    if (*dataLen != 1)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+
+    uint8_t sensnum = *(static_cast<uint8_t *>(request));
+
+    std::string connection;
+    std::string path;
+
+    auto status = getSensorConnection(sensnum, connection, path);
+    if (status)
+    {
+        return status;
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    // zero out response buff
+    auto responseClear = static_cast<uint8_t *>(response);
+    std::fill(responseClear, responseClear + sizeof(SensorThresholdResp), 0);
+
+    auto warningInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    auto criticalInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+
+    if ((warningInterface != sensorMap.end()) ||
+        (criticalInterface != sensorMap.end()))
+    {
+        auto sensorPair = sensorMap.find("xyz.openbmc_project.Sensor.Value");
+
+        if (sensorPair == sensorMap.end())
+        {
+            // should not have been able to find a sensor not implementing
+            // the sensor object
+            return IPMI_CC_RESPONSE_ERROR;
+        }
+
+        double max;
+        double min;
+        getSensorMaxMin(sensorPair->second, max, min);
+
+        int16_t mValue = 0;
+        int16_t bValue = 0;
+        int8_t rExp = 0;
+        int8_t bExp = 0;
+        bool bSigned = false;
+
+        if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+        {
+            return IPMI_CC_RESPONSE_ERROR;
+        }
+
+        auto msgReply = static_cast<SensorThresholdResp *>(response);
+
+        if (warningInterface != sensorMap.end())
+        {
+            auto &warningMap = warningInterface->second;
+
+            auto warningHigh = warningMap.find("WarningHigh");
+            auto warningLow = warningMap.find("WarningLow");
+
+            if (warningHigh != warningMap.end())
+            {
+                msgReply->readable |=
+                    1 << static_cast<int>(
+                        IPMIhresholdRespBits::upperNonCritical);
+                double value = apply_visitor(VariantToDoubleVisitor(),
+                                             warningHigh->second);
+                msgReply->uppernc = scaleIPMIValueFromDouble(
+                    value, mValue, rExp, bValue, bExp, bSigned);
+            }
+            if (warningLow != warningMap.end())
+            {
+                msgReply->readable |=
+                    1 << static_cast<int>(
+                        IPMIhresholdRespBits::lowerNonCritical);
+                double value =
+                    apply_visitor(VariantToDoubleVisitor(), warningLow->second);
+                msgReply->lowernc = scaleIPMIValueFromDouble(
+                    value, mValue, rExp, bValue, bExp, bSigned);
+            }
+        }
+        if (criticalInterface != sensorMap.end())
+        {
+            auto &criticalMap = criticalInterface->second;
+
+            auto criticalHigh = criticalMap.find("CriticalHigh");
+            auto criticalLow = criticalMap.find("CriticalLow");
+
+            if (criticalHigh != criticalMap.end())
+            {
+                msgReply->readable |=
+                    1 << static_cast<int>(IPMIhresholdRespBits::upperCritical);
+                double value = apply_visitor(VariantToDoubleVisitor(),
+                                             criticalHigh->second);
+                msgReply->uppercritical = scaleIPMIValueFromDouble(
+                    value, mValue, rExp, bValue, bExp, bSigned);
+            }
+            if (criticalLow != criticalMap.end())
+            {
+                msgReply->readable |=
+                    1 << static_cast<int>(IPMIhresholdRespBits::lowerCritical);
+                double value = apply_visitor(VariantToDoubleVisitor(),
+                                             criticalLow->second);
+                msgReply->lowercritical = scaleIPMIValueFromDouble(
+                    value, mValue, rExp, bValue, bExp, bSigned);
+            }
+        }
+    }
+
+    *dataLen = sizeof(SensorThresholdResp);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiSenGetSensorEventEnable(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                       ipmi_request_t request,
+                                       ipmi_response_t response,
+                                       ipmi_data_len_t dataLen,
+                                       ipmi_context_t context)
+{
+    if (*dataLen != 1)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+
+    uint8_t sensnum = *(static_cast<uint8_t *>(request));
+
+    std::string connection;
+    std::string path;
+
+    auto status = getSensorConnection(sensnum, connection, path);
+    if (status)
+    {
+        return status;
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    auto warningInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    auto criticalInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+
+    if ((warningInterface != sensorMap.end()) ||
+        (criticalInterface != sensorMap.end()))
+    {
+        // zero out response buff
+        auto responseClear = static_cast<uint8_t *>(response);
+        std::fill(responseClear, responseClear + sizeof(SensorEventEnableResp),
+                  0);
+
+        // assume all threshold sensors
+        auto resp = static_cast<SensorEventEnableResp *>(response);
+
+        resp->enabled = static_cast<uint8_t>(
+            IPMISensorEventEnableByte2::sensorScanningEnable);
+        if (warningInterface != sensorMap.end())
+        {
+            auto &warningMap = warningInterface->second;
+
+            auto warningHigh = warningMap.find("WarningHigh");
+            auto warningLow = warningMap.find("WarningLow");
+            if (warningHigh != warningMap.end())
+            {
+                resp->assertionEnabledLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh);
+                resp->deassertionEnabledLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::upperNonCriticalGoingLow);
+            }
+            if (warningLow != warningMap.end())
+            {
+                resp->assertionEnabledLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::lowerNonCriticalGoingLow);
+                resp->deassertionEnabledLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::lowerNonCriticalGoingHigh);
+            }
+        }
+        if (criticalInterface != sensorMap.end())
+        {
+            auto &criticalMap = criticalInterface->second;
+
+            auto criticalHigh = criticalMap.find("CriticalHigh");
+            auto criticalLow = criticalMap.find("CriticalLow");
+
+            if (criticalHigh != criticalMap.end())
+            {
+                resp->assertionEnabledMSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::upperCriticalGoingHigh);
+                resp->deassertionEnabledMSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::upperCriticalGoingLow);
+            }
+            if (criticalLow != criticalMap.end())
+            {
+                resp->assertionEnabledLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::lowerCriticalGoingLow);
+                resp->deassertionEnabledLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::lowerCriticalGoingHigh);
+            }
+        }
+        *dataLen =
+            sizeof(SensorEventEnableResp); // todo only return needed bytes
+    }
+    // no thresholds enabled
+    else
+    {
+        *dataLen = 1;
+        auto resp = static_cast<uint8_t *>(response);
+        *resp = static_cast<uint8_t>(
+            IPMISensorEventEnableByte2::eventMessagesEnable);
+        *resp |= static_cast<uint8_t>(
+            IPMISensorEventEnableByte2::sensorScanningEnable);
+    }
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiSenGetSensorEventStatus(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                       ipmi_request_t request,
+                                       ipmi_response_t response,
+                                       ipmi_data_len_t dataLen,
+                                       ipmi_context_t context)
+{
+    if (*dataLen != 1)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+
+    uint8_t sensnum = *(static_cast<uint8_t *>(request));
+
+    std::string connection;
+    std::string path;
+
+    auto status = getSensorConnection(sensnum, connection, path);
+    if (status)
+    {
+        return status;
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    auto warningInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    auto criticalInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+
+    // zero out response buff
+    auto responseClear = static_cast<uint8_t *>(response);
+    std::fill(responseClear, responseClear + sizeof(SensorEventStatusResp), 0);
+    auto resp = static_cast<SensorEventStatusResp *>(response);
+    resp->enabled =
+        static_cast<uint8_t>(IPMISensorEventEnableByte2::sensorScanningEnable);
+
+    if ((warningInterface != sensorMap.end()) ||
+        (criticalInterface != sensorMap.end()))
+    {
+        resp->enabled = static_cast<uint8_t>(
+            IPMISensorEventEnableByte2::eventMessagesEnable);
+        if (warningInterface != sensorMap.end())
+        {
+            auto &warningMap = warningInterface->second;
+
+            auto warningHigh = warningMap.find("WarningAlarmHigh");
+            auto warningLow = warningMap.find("WarningAlarmLow");
+            auto warningHighAlarm = false;
+            auto warningLowAlarm = false;
+
+            if (warningHigh != warningMap.end())
+            {
+                warningHighAlarm = warningHigh->second.get<bool>();
+            }
+            if (warningLow != warningMap.end())
+            {
+                warningLowAlarm = warningLow->second.get<bool>();
+            }
+            if (warningHighAlarm)
+            {
+                resp->assertionsLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh);
+            }
+            if (warningLowAlarm)
+            {
+                resp->assertionsLSB |= 1; // lower nc going low
+            }
+        }
+        if (criticalInterface != sensorMap.end())
+        {
+            auto &criticalMap = criticalInterface->second;
+
+            auto criticalHigh = criticalMap.find("CriticalAlarmHigh");
+            auto criticalLow = criticalMap.find("CriticalAlarmLow");
+            auto criticalHighAlarm = false;
+            auto criticalLowAlarm = false;
+
+            if (criticalHigh != criticalMap.end())
+            {
+                criticalHighAlarm = criticalHigh->second.get<bool>();
+            }
+            if (criticalLow != criticalMap.end())
+            {
+                criticalLowAlarm = criticalLow->second.get<bool>();
+            }
+            if (criticalHighAlarm)
+            {
+                resp->assertionsMSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::upperCriticalGoingHigh);
+            }
+            if (criticalLowAlarm)
+            {
+                resp->assertionsLSB |= static_cast<uint8_t>(
+                    IPMISensorEventEnableThresholds::lowerCriticalGoingLow);
+            }
+        }
+        *dataLen = sizeof(SensorEventStatusResp);
+    }
+
+    // no thresholds enabled, don't need assertionMSB
+    else
+    {
+        *dataLen = sizeof(SensorEventStatusResp) - 1;
+    }
+
+    return IPMI_CC_OK;
+}
+
+/* end sensor commands */
+
+/* storage commands */
+
+ipmi_ret_t ipmiStorageGetSDRRepositoryInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                           ipmi_request_t request,
+                                           ipmi_response_t response,
+                                           ipmi_data_len_t dataLen,
+                                           ipmi_context_t context)
+{
+    printCommand(+netfn, +cmd);
+
+    if (*dataLen)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+
+    if (sensorTree.empty() && !getSensorSubtree(sensorTree))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    // zero out response buff
+    auto responseClear = static_cast<uint8_t *>(response);
+    std::fill(responseClear, responseClear + sizeof(GetSDRInfoResp), 0);
+
+    auto resp = static_cast<GetSDRInfoResp *>(response);
+    resp->sdrVersion = ipmiSdrVersion;
+    uint16_t recordCount = sensorTree.size();
+
+    // todo: for now, sdr count is number of sensors
+    resp->recordCountLS = recordCount & 0xFF;
+    resp->recordCountMS = recordCount >> 8;
+
+    // free space unspcified
+    resp->freeSpace[0] = 0xFF;
+    resp->freeSpace[1] = 0xFF;
+
+    resp->mostRecentAddition = sdrLastAdd;
+    resp->mostRecentErase = sdrLastRemove;
+    resp->operationSupport = static_cast<uint8_t>(
+        SdrRepositoryInfoOps::overflow); // write not supported
+    resp->operationSupport |=
+        static_cast<uint8_t>(SdrRepositoryInfoOps::allocCommandSupported);
+    resp->operationSupport |= static_cast<uint8_t>(
+        SdrRepositoryInfoOps::reserveSDRRepositoryCommandSupported);
+    *dataLen = sizeof(GetSDRInfoResp);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiStorageGetSDRAllocationInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                           ipmi_request_t request,
+                                           ipmi_response_t response,
+                                           ipmi_data_len_t dataLen,
+                                           ipmi_context_t context)
+{
+    if (*dataLen)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+    GetAllocInfoResp *resp = static_cast<GetAllocInfoResp *>(response);
+
+    // 0000h unspecified number of alloc units
+    resp->allocUnitsLSB = 0;
+    resp->allocUnitsMSB = 0;
+
+    // max unit size is size of max record
+    resp->allocUnitSizeLSB = maxSDRTotalSize & 0xFF;
+    resp->allocUnitSizeMSB = maxSDRTotalSize >> 8;
+    // read only sdr, no free alloc blocks
+    resp->allocUnitFreeLSB = 0;
+    resp->allocUnitFreeMSB = 0;
+    resp->allocUnitLargestFreeLSB = 0;
+    resp->allocUnitLargestFreeMSB = 0;
+    // only allow one block at a time
+    resp->maxRecordSize = 1;
+
+    *dataLen = sizeof(GetAllocInfoResp);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiStorageReserveSDR(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                                 ipmi_request_t request,
+                                 ipmi_response_t response,
+                                 ipmi_data_len_t dataLen,
+                                 ipmi_context_t context)
+{
+    printCommand(+netfn, +cmd);
+
+    if (*dataLen)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    *dataLen = 0; // default to 0 in case of an error
+    sdrReservationID++;
+    *dataLen = 2;
+    auto resp = static_cast<uint8_t *>(response);
+    resp[0] = sdrReservationID & 0xFF;
+    resp[1] = sdrReservationID >> 8;
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiStorageGetSDR(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    printCommand(+netfn, +cmd);
+
+    if (*dataLen != 6)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    auto requestedSize = *dataLen;
+    *dataLen = 0; // default to 0 in case of an error
+
+    constexpr uint16_t lastRecordIndex = 0xFFFF;
+    auto req = static_cast<GetSDRReq *>(request);
+
+    // reservation required for partial reads with non zero offset into
+    // record
+    if (req->reservationID != sdrReservationID && req->offset)
+    {
+        return IPMI_CC_INVALID_RESERVATION_ID;
+    }
+
+    if (sensorTree.empty() && !getSensorSubtree(sensorTree))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    size_t fruCount = 0;
+    ipmi_ret_t ret = ipmi::storage::getFruSdrCount(fruCount);
+    if (ret != IPMI_CC_OK)
+    {
+        return ret;
+    }
+
+    size_t lastRecord = sensorTree.size() + fruCount - 1;
+    if (req->recordID == lastRecordIndex)
+    {
+        req->recordID = lastRecord;
+    }
+    if (req->recordID > lastRecord)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    uint16_t nextRecord =
+        lastRecord > (req->recordID + 1) ? req->recordID + 1 : 0XFFFF;
+
+    auto responseClear = static_cast<uint8_t *>(response);
+    std::fill(responseClear, responseClear + requestedSize, 0);
+
+    auto resp = static_cast<get_sdr::GetSdrResp *>(response);
+    resp->next_record_id_lsb = nextRecord & 0xFF;
+    resp->next_record_id_msb = nextRecord >> 8;
+
+    if (req->recordID >= sensorTree.size())
+    {
+        size_t fruIndex = req->recordID - sensorTree.size();
+        if (fruIndex >= fruCount)
+        {
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+        get_sdr::SensorDataFruRecord data;
+        if (req->offset > sizeof(data))
+        {
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+        ret = ipmi::storage::getFruSdrs(fruIndex, data);
+        if (ret != IPMI_CC_OK)
+        {
+            return ret;
+        }
+        data.header.record_id_msb = req->recordID << 8;
+        data.header.record_id_lsb = req->recordID & 0xFF;
+        if (sizeof(data) < (req->offset + req->bytesToRead))
+        {
+            req->bytesToRead = sizeof(data) - req->offset;
+        }
+        *dataLen = req->bytesToRead + 2; // next record
+        std::memcpy(&resp->record_data, (char *)&data + req->offset,
+                    req->bytesToRead);
+        return IPMI_CC_OK;
+    }
+
+    std::string connection;
+    std::string path;
+    uint16_t sensorIndex = req->recordID;
+    for (const auto &sensor : sensorTree)
+    {
+        if (sensorIndex-- == 0)
+        {
+            if (!sensor.second.size())
+            {
+                return IPMI_CC_RESPONSE_ERROR;
+            }
+            connection = sensor.second.begin()->first;
+            path = sensor.first;
+            break;
+        }
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    uint8_t sensornumber = (req->recordID & 0xFF);
+    get_sdr::SensorDataFullRecord record = {0};
+
+    record.header.record_id_msb = req->recordID << 8;
+    record.header.record_id_lsb = req->recordID & 0xFF;
+    record.header.sdr_version = ipmiSdrVersion;
+    record.header.record_type = get_sdr::SENSOR_DATA_FULL_RECORD;
+    record.header.record_length = sizeof(get_sdr::SensorDataFullRecord) -
+                                  sizeof(get_sdr::SensorDataRecordHeader);
+    record.key.owner_id = 0x20;
+    record.key.owner_lun = 0x0;
+    record.key.sensor_number = sensornumber;
+
+    record.body.entity_id = 0x0;
+    record.body.entity_instance = 0x01;
+    record.body.sensor_capabilities = 0x60; // auto rearm - todo hysteresis
+    record.body.sensor_type = getSensorTypeFromPath(path);
+    std::string type = getSensorTypeStringFromPath(path);
+    auto typeCstr = type.c_str();
+    auto findUnits = sensorUnits.find(typeCstr);
+    if (findUnits != sensorUnits.end())
+    {
+        record.body.sensor_units_2_base =
+            static_cast<uint8_t>(findUnits->second);
+    } // else default 0x0 unspecified
+
+    record.body.event_reading_type = getSensorEventTypeFromPath(path);
+
+    auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value");
+    if (sensorObject == sensorMap.end())
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    auto maxObject = sensorObject->second.find("MaxValue");
+    auto minObject = sensorObject->second.find("MinValue");
+    double max = 128;
+    double min = -127;
+    if (maxObject != sensorObject->second.end())
+    {
+        max = apply_visitor(VariantToDoubleVisitor(), maxObject->second);
+    }
+
+    if (minObject != sensorObject->second.end())
+    {
+        min = apply_visitor(VariantToDoubleVisitor(), minObject->second);
+    }
+
+    int16_t mValue;
+    int8_t rExp;
+    int16_t bValue;
+    int8_t bExp;
+    bool bSigned;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    // apply M, B, and exponents, M and B are 10 bit values, exponents are 4
+    record.body.m_lsb = mValue & 0xFF;
+
+    // move the smallest bit of the MSB into place (bit 9)
+    // the MSbs are bits 7:8 in m_msb_and_tolerance
+    uint8_t mMsb = (mValue & (1 << 8)) > 0 ? (1 << 6) : 0;
+
+    // assign the negative
+    if (mValue < 0)
+    {
+        mMsb |= (1 << 7);
+    }
+    record.body.m_msb_and_tolerance = mMsb;
+
+    record.body.b_lsb = bValue & 0xFF;
+
+    // move the smallest bit of the MSB into place
+    // the MSbs are bits 7:8 in b_msb_and_accuracy_lsb
+    uint8_t bMsb = (bValue & (1 << 8)) > 0 ? (1 << 6) : 0;
+
+    // assign the negative
+    if (bValue < 0)
+    {
+        bMsb |= (1 << 7);
+    }
+    record.body.b_msb_and_accuracy_lsb = bMsb;
+
+    record.body.r_b_exponents = bExp & 0x7;
+    if (bExp < 0)
+    {
+        record.body.r_b_exponents |= 1 << 3;
+    }
+    record.body.r_b_exponents = (rExp & 0x7) << 4;
+    if (rExp < 0)
+    {
+        record.body.r_b_exponents |= 1 << 7;
+    }
+
+    // todo fill out rest of units
+    if (bSigned)
+    {
+        record.body.sensor_units_1 = 1 << 7;
+    }
+
+    // populate sensor name from path
+    std::string name;
+    size_t nameStart = path.rfind("/");
+    if (nameStart != std::string::npos)
+    {
+        name = path.substr(nameStart + 1, std::string::npos - nameStart);
+    }
+
+    std::replace(name.begin(), name.end(), '_', ' ');
+    if (name.size() > FULL_RECORD_ID_STR_MAX_LENGTH)
+    {
+        name.resize(FULL_RECORD_ID_STR_MAX_LENGTH);
+    }
+    record.body.id_string_info = name.size();
+    std::strncpy(record.body.id_string, name.c_str(),
+                 sizeof(record.body.id_string));
+
+    if (sizeof(get_sdr::SensorDataFullRecord) <
+        (req->offset + req->bytesToRead))
+    {
+        req->bytesToRead = sizeof(get_sdr::SensorDataFullRecord) - req->offset;
+    }
+
+    *dataLen =
+        2 + req->bytesToRead; // bytesToRead + MSB and LSB of next record id
+
+    std::memcpy(&resp->record_data, (char *)&record + req->offset,
+                req->bytesToRead);
+
+    return IPMI_CC_OK;
+}
+/* end storage commands */
+
+void registerSensorFunctions()
+{
+    // get firmware version information
+    ipmiPrintAndRegister(NETFUN_SENSOR, IPMI_CMD_WILDCARD, nullptr,
+                         ipmiSensorWildcardHandler, PRIVILEGE_USER);
+
+    // <Get Sensor Type>
+    ipmiPrintAndRegister(
+        NETFUN_SENSOR,
+        static_cast<ipmi_cmd_t>(IPMINetfnSensorCmds::ipmiCmdGetSensorType),
+        nullptr, ipmiSensorWildcardHandler, PRIVILEGE_USER);
+
+    // <Set Sensor Reading and Event Status>
+    ipmiPrintAndRegister(
+        NETFUN_SENSOR,
+        static_cast<ipmi_cmd_t>(
+            IPMINetfnSensorCmds::ipmiCmdSetSensorReadingAndEventStatus),
+        nullptr, ipmiSensorWildcardHandler, PRIVILEGE_OPERATOR);
+
+    // <Get Sensor Reading>
+    ipmiPrintAndRegister(
+        NETFUN_SENSOR,
+        static_cast<ipmi_cmd_t>(IPMINetfnSensorCmds::ipmiCmdGetSensorReading),
+        nullptr, ipmiSenGetSensorReading, PRIVILEGE_USER);
+
+    // <Get Sensor Threshold>
+    ipmiPrintAndRegister(
+        NETFUN_SENSOR,
+        static_cast<ipmi_cmd_t>(IPMINetfnSensorCmds::ipmiCmdGetSensorThreshold),
+        nullptr, ipmiSenGetSensorThresholds, PRIVILEGE_USER);
+
+    ipmiPrintAndRegister(
+        NETFUN_SENSOR,
+        static_cast<ipmi_cmd_t>(IPMINetfnSensorCmds::ipmiCmdSetSensorThreshold),
+        nullptr, ipmiSenSetSensorThresholds, PRIVILEGE_OPERATOR);
+
+    // <Get Sensor Event Enable>
+    ipmiPrintAndRegister(NETFUN_SENSOR,
+                         static_cast<ipmi_cmd_t>(
+                             IPMINetfnSensorCmds::ipmiCmdGetSensorEventEnable),
+                         nullptr, ipmiSenGetSensorEventEnable, PRIVILEGE_USER);
+
+    // <Get Sensor Event Status>
+    ipmiPrintAndRegister(NETFUN_SENSOR,
+                         static_cast<ipmi_cmd_t>(
+                             IPMINetfnSensorCmds::ipmiCmdGetSensorEventStatus),
+                         nullptr, ipmiSenGetSensorEventStatus, PRIVILEGE_USER);
+
+    // register all storage commands for both Sensor and Storage command
+    // versions
+
+    // <Get SDR Repository Info>
+    ipmiPrintAndRegister(
+        NETFUN_STORAGE,
+        static_cast<ipmi_cmd_t>(IPMINetfnStorageCmds::ipmiCmdGetRepositoryInfo),
+        nullptr, ipmiStorageGetSDRRepositoryInfo, PRIVILEGE_USER);
+
+    // <Get SDR Allocation Info>
+    ipmiPrintAndRegister(NETFUN_STORAGE,
+                         static_cast<ipmi_cmd_t>(
+                             IPMINetfnStorageCmds::ipmiCmdGetSDRAllocationInfo),
+                         nullptr, ipmiStorageGetSDRAllocationInfo,
+                         PRIVILEGE_USER);
+
+    // <Reserve SDR Repo>
+    ipmiPrintAndRegister(NETFUN_SENSOR,
+                         static_cast<ipmi_cmd_t>(
+                             IPMINetfnSensorCmds::ipmiCmdReserveDeviceSDRRepo),
+                         nullptr, ipmiStorageReserveSDR, PRIVILEGE_USER);
+
+    ipmiPrintAndRegister(
+        NETFUN_STORAGE,
+        static_cast<ipmi_cmd_t>(IPMINetfnStorageCmds::ipmiCmdReserveSDR),
+        nullptr, ipmiStorageReserveSDR, PRIVILEGE_USER);
+
+    // <Get Sdr>
+    ipmiPrintAndRegister(
+        NETFUN_SENSOR,
+        static_cast<ipmi_cmd_t>(IPMINetfnSensorCmds::ipmiCmdGetDeviceSDR),
+        nullptr, ipmiStorageGetSDR, PRIVILEGE_USER);
+
+    ipmiPrintAndRegister(
+        NETFUN_STORAGE,
+        static_cast<ipmi_cmd_t>(IPMINetfnStorageCmds::ipmiCmdGetSDR), nullptr,
+        ipmiStorageGetSDR, PRIVILEGE_USER);
+    return;
+}
+} // namespace ipmi
diff --git a/src/sensorutils.cpp b/src/sensorutils.cpp
new file mode 100644
index 0000000..62e2cd2
--- /dev/null
+++ b/src/sensorutils.cpp
@@ -0,0 +1,161 @@
+/*
+// Copyright (c) 2017 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 <host-ipmid/ipmid-api.h>
+
+#include <cmath>
+#include <iostream>
+#include <phosphor-logging/log.hpp>
+#include <sensorutils.hpp>
+
+namespace ipmi
+{
+static constexpr int16_t maxInt10 = 0x1FF;
+static constexpr int16_t minInt10 = -(0x200);
+static constexpr int8_t maxInt4 = 7;
+static constexpr int8_t minInt4 = -8;
+
+bool getSensorAttributes(const double max, const double min, int16_t &mValue,
+                         int8_t &rExp, int16_t &bValue, int8_t &bExp,
+                         bool &bSigned)
+{
+    // computing y = (10^rRexp) * (Mx + (B*(10^Bexp)))
+    // check for 0, assume always positive
+    double mDouble;
+    double bDouble;
+    if (!(max > min))
+    {
+        phosphor::logging::log<phosphor::logging::level::DEBUG>(
+            "getSensorAttributes: Max must be greater than min");
+        return false;
+    }
+    else
+    {
+        mDouble = (max - min) / 0xFF;
+    }
+    if (!mDouble)
+    {
+        mDouble = 1;
+    }
+
+    if (min < 0)
+    {
+        bSigned = true;
+        bDouble = floor(0.5 + ((max + min) / 2));
+    }
+    else
+    {
+        bSigned = false;
+        bDouble = min;
+    }
+
+    rExp = 0;
+
+    // M too big for 10 bit variable
+    while (mDouble > maxInt10)
+    {
+        if (rExp == maxInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "rExp Too big, Max and Min range too far");
+            return false;
+        }
+        mDouble /= 10;
+        rExp += 1;
+    }
+
+    // M too small, loop until we loose less than 1 eight bit count of precision
+    while (((mDouble - floor(mDouble)) / mDouble) > (1.0 / 255))
+    {
+        if (rExp == minInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "rExp Too Small, Max and Min range too close");
+            return false;
+        }
+        // check to see if we reached the limit of where we can adjust back the
+        // B value
+        if (bDouble / std::pow(10, rExp + minInt4 - 1) > bDouble)
+        {
+            if (mDouble < 1.0)
+            {
+                phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                    "Could not find mValue and B value with enough "
+                    "precision.");
+                return false;
+            }
+            break;
+        }
+        // can't multiply M any more, max precision reached
+        else if (mDouble * 10 > maxInt10)
+        {
+            break;
+        }
+        mDouble *= 10;
+        rExp -= 1;
+    }
+
+    bDouble /= std::pow(10, rExp);
+    bExp = 0;
+
+    // B too big for 10 bit variable
+    while (bDouble > maxInt10 || bDouble < minInt10)
+    {
+        if (bExp == maxInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "bExp Too Big, Max and Min range need to be adjusted");
+            return false;
+        }
+        bDouble /= 10;
+        bExp += 1;
+    }
+
+    while (((fabs(bDouble) - floor(fabs(bDouble))) / fabs(bDouble)) >
+           (1.0 / 255))
+    {
+        if (bExp == minInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "bExp Too Small, Max and Min range need to be adjusted");
+            return false;
+        }
+        bDouble *= 10;
+        bExp -= 1;
+    }
+
+    mValue = static_cast<int16_t>(mDouble + 0.5) & maxInt10;
+    bValue = static_cast<int16_t>(bDouble + 0.5) & maxInt10;
+
+    return true;
+}
+
+uint8_t scaleIPMIValueFromDouble(const double value, const uint16_t mValue,
+                                 const int8_t rExp, const uint16_t bValue,
+                                 const int8_t bExp, const bool bSigned)
+{
+    uint32_t scaledValue =
+        (value - (bValue * std::pow(10, bExp) * std::pow(10, rExp))) /
+        (mValue * std::pow(10, rExp));
+    if (bSigned)
+    {
+        return static_cast<int8_t>(scaledValue);
+    }
+    else
+    {
+        return static_cast<uint8_t>(scaledValue);
+    }
+}
+} // namespace ipmi
\ No newline at end of file
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
new file mode 100644
index 0000000..e71d47f
--- /dev/null
+++ b/src/storagecommands.cpp
@@ -0,0 +1,315 @@
+/*
+// Copyright (c) 2017 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 <host-ipmid/ipmid-api.h>
+
+#include <boost/container/flat_map.hpp>
+#include <commandutils.hpp>
+#include <iostream>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <sdbusplus/timer.hpp>
+#include <storagecommands.hpp>
+
+namespace ipmi
+{
+
+namespace storage
+{
+
+constexpr static const size_t maxFruSdrNameSize = 16;
+using ManagedObjectType = boost::container::flat_map<
+    sdbusplus::message::object_path,
+    boost::container::flat_map<
+        std::string, boost::container::flat_map<std::string, DbusVariant>>>;
+using ManagedEntry = std::pair<
+    sdbusplus::message::object_path,
+    boost::container::flat_map<
+        std::string, boost::container::flat_map<std::string, DbusVariant>>>;
+
+constexpr static const char* fruDeviceServiceName = "com.intel.FruDevice";
+
+static std::vector<uint8_t> fruCache;
+static uint8_t cacheBus = 0xFF;
+static uint8_t cacheAddr = 0XFF;
+
+std::unique_ptr<phosphor::Timer> cacheTimer = nullptr;
+
+// we unfortunately have to build a map of hashes in case there is a
+// collision to verify our dev-id
+boost::container::flat_map<uint8_t, std::pair<uint8_t, uint8_t>> deviceHashes;
+
+static sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
+
+bool writeFru()
+{
+    sdbusplus::message::message writeFru = dbus.new_method_call(
+        fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
+        "xyz.openbmc_project.FruDeviceManager", "WriteFru");
+    writeFru.append(cacheBus, cacheAddr, fruCache);
+    try
+    {
+        sdbusplus::message::message writeFruResp = dbus.call(writeFru);
+    }
+    catch (sdbusplus::exception_t&)
+    {
+        // todo: log sel?
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "error writing fru");
+        return false;
+    }
+    return true;
+}
+
+ipmi_ret_t replaceCacheFru(uint8_t devId)
+{
+    static uint8_t lastDevId = 0xFF;
+
+    bool timerRunning = (cacheTimer != nullptr) && !cacheTimer->isExpired();
+    if (lastDevId == devId && timerRunning)
+    {
+        return IPMI_CC_OK; // cache already up to date
+    }
+    // if timer is running, stop it and writeFru manually
+    else if (timerRunning)
+    {
+        cacheTimer->stop();
+        writeFru();
+    }
+
+    sdbusplus::message::message getObjects = dbus.new_method_call(
+        fruDeviceServiceName, "/", "org.freedesktop.DBus.ObjectManager",
+        "GetManagedObjects");
+    ManagedObjectType frus;
+    try
+    {
+        sdbusplus::message::message resp = dbus.call(getObjects);
+        resp.read(frus);
+    }
+    catch (sdbusplus::exception_t&)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "replaceCacheFru: error getting managed objects");
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    deviceHashes.clear();
+
+    // hash the object paths to create unique device id's. increment on
+    // collision
+    std::hash<std::string> hasher;
+    for (const auto& fru : frus)
+    {
+        auto fruIface = fru.second.find("xyz.openbmc_project.FruDevice");
+        if (fruIface == fru.second.end())
+        {
+            continue;
+        }
+
+        auto busFind = fruIface->second.find("BUS");
+        auto addrFind = fruIface->second.find("ADDRESS");
+        if (busFind == fruIface->second.end() ||
+            addrFind == fruIface->second.end())
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "fru device missing Bus or Address",
+                phosphor::logging::entry("FRU=%s", fru.first.str.c_str()));
+            continue;
+        }
+
+        uint8_t fruBus =
+            sdbusplus::message::variant_ns::get<uint32_t>(busFind->second);
+        uint8_t fruAddr =
+            sdbusplus::message::variant_ns::get<uint32_t>(addrFind->second);
+
+        uint8_t fruHash = 0;
+        if (fruBus != 0 || fruAddr != 0)
+        {
+            fruHash = hasher(fru.first.str);
+            // can't be 0xFF based on spec, and 0 is reserved for baseboard
+            if (fruHash == 0 || fruHash == 0xFF)
+            {
+                fruHash = 1;
+            }
+        }
+        std::pair<uint8_t, uint8_t> newDev(fruBus, fruAddr);
+
+        bool emplacePassed = false;
+        while (!emplacePassed)
+        {
+            auto resp = deviceHashes.emplace(fruHash, newDev);
+            emplacePassed = resp.second;
+            if (!emplacePassed)
+            {
+                fruHash++;
+                // can't be 0xFF based on spec, and 0 is reserved for
+                // baseboard
+                if (fruHash == 0XFF)
+                {
+                    fruHash = 0x1;
+                }
+            }
+        }
+    }
+    auto deviceFind = deviceHashes.find(devId);
+    if (deviceFind == deviceHashes.end())
+    {
+        return IPMI_CC_SENSOR_INVALID;
+    }
+
+    fruCache.clear();
+    sdbusplus::message::message getRawFru = dbus.new_method_call(
+        fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
+        "xyz.openbmc_project.FruDeviceManager", "GetRawFru");
+    cacheBus = deviceFind->second.first;
+    cacheAddr = deviceFind->second.second;
+    getRawFru.append(cacheBus, cacheAddr);
+    try
+    {
+        sdbusplus::message::message getRawResp = dbus.call(getRawFru);
+        getRawResp.read(fruCache);
+    }
+    catch (sdbusplus::exception_t&)
+    {
+        lastDevId = 0xFF;
+        cacheBus = 0xFF;
+        cacheAddr = 0xFF;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    lastDevId = devId;
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t getFruSdrCount(size_t& count)
+{
+    ipmi_ret_t ret = replaceCacheFru(0);
+    if (ret != IPMI_CC_OK)
+    {
+        return ret;
+    }
+    count = deviceHashes.size();
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t getFruSdrs(size_t index, get_sdr::SensorDataFruRecord& resp)
+{
+    ipmi_ret_t ret = replaceCacheFru(0); // this will update the hash list
+    if (ret != IPMI_CC_OK)
+    {
+        return ret;
+    }
+    if (deviceHashes.size() < index)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    auto device = deviceHashes.begin() + index;
+    uint8_t& bus = device->second.first;
+    uint8_t& address = device->second.second;
+
+    ManagedObjectType frus;
+
+    sdbusplus::message::message getObjects = dbus.new_method_call(
+        fruDeviceServiceName, "/", "org.freedesktop.DBus.ObjectManager",
+        "GetManagedObjects");
+    try
+    {
+        sdbusplus::message::message resp = dbus.call(getObjects);
+        resp.read(frus);
+    }
+    catch (sdbusplus::exception_t&)
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    boost::container::flat_map<std::string, DbusVariant>* fruData = nullptr;
+    auto fru =
+        std::find_if(frus.begin(), frus.end(),
+                     [bus, address, &fruData](ManagedEntry& entry) {
+                         auto findFruDevice =
+                             entry.second.find("xyz.openbmc_project.FruDevice");
+                         if (findFruDevice == entry.second.end())
+                         {
+                             return false;
+                         }
+                         fruData = &(findFruDevice->second);
+                         auto findBus = findFruDevice->second.find("BUS");
+                         auto findAddress =
+                             findFruDevice->second.find("ADDRESS");
+                         if (findBus == findFruDevice->second.end() ||
+                             findAddress == findFruDevice->second.end())
+                         {
+                             return false;
+                         }
+                         if (sdbusplus::message::variant_ns::get<uint32_t>(
+                                 findBus->second) != bus)
+                         {
+                             return false;
+                         }
+                         if (sdbusplus::message::variant_ns::get<uint32_t>(
+                                 findAddress->second) != address)
+                         {
+                             return false;
+                         }
+                         return true;
+                     });
+    if (fru == frus.end())
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    std::string name;
+    auto findProductName = fruData->find("BOARD_PRODUCT_NAME");
+    auto findBoardName = fruData->find("PRODUCT_PRODUCT_NAME");
+    if (findProductName != fruData->end())
+    {
+        name = sdbusplus::message::variant_ns::get<std::string>(
+            findProductName->second);
+    }
+    else if (findBoardName != fruData->end())
+    {
+        name = sdbusplus::message::variant_ns::get<std::string>(
+            findBoardName->second);
+    }
+    else
+    {
+        name = "UNKNOWN";
+    }
+    if (name.size() > maxFruSdrNameSize)
+    {
+        name = name.substr(0, maxFruSdrNameSize);
+    }
+    size_t sizeDiff = maxFruSdrNameSize - name.size();
+
+    resp.header.record_id_lsb = 0x0; // calling code is to implement these
+    resp.header.record_id_msb = 0x0;
+    resp.header.sdr_version = ipmiSdrVersion;
+    resp.header.record_type = 0x11; // FRU Device Locator
+    resp.header.record_length = sizeof(resp.body) + sizeof(resp.key) - sizeDiff;
+    resp.key.deviceAddress = 0x20;
+    resp.key.fruID = device->first;
+    resp.key.accessLun = 0x80; // logical / physical fru device
+    resp.key.channelNumber = 0x0;
+    resp.body.reserved = 0x0;
+    resp.body.deviceType = 0x10;
+    resp.body.entityID = 0x0;
+    resp.body.entityInstance = 0x1;
+    resp.body.oem = 0x0;
+    resp.body.deviceIDLen = name.size();
+    name.copy(resp.body.deviceID, name.size());
+
+    return IPMI_CC_OK;
+}
+} // namespace storage
+} // namespace ipmi
\ No newline at end of file
diff --git a/src/utils.cpp b/src/utils.cpp
new file mode 100644
index 0000000..3851e82
--- /dev/null
+++ b/src/utils.cpp
@@ -0,0 +1,567 @@
+#include "phosphor-ipmi-host/utils.hpp"
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <net/if.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;
+
+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(variant.get<std::string>()))
+        {
+            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::experimental::nullopt),
+    cachedBusName(std::experimental::nullopt)
+{
+}
+
+ServiceCache::ServiceCache(std::string&& intf, std::string&& path) :
+    intf(std::move(intf)), path(std::move(path)),
+    cachedService(std::experimental::nullopt),
+    cachedBusName(std::experimental::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::experimental::nullopt;
+    cachedService = std::experimental::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
