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
