diff --git a/pldm.cpp b/pldm.cpp
index a65369a..d22a73d 100644
--- a/pldm.cpp
+++ b/pldm.cpp
@@ -1,355 +1,355 @@
-#include "pldm.hpp"
-
-#include "file.hpp"
-
-#include <fmt/core.h>
-#include <libpldm/entity.h>
-#include <libpldm/platform.h>
-#include <libpldm/state_set.h>
-
-#include <phosphor-logging/log.hpp>
-
-namespace pldm
-{
-
-using sdbusplus::exception::SdBusError;
-using namespace phosphor::logging;
-
-void Interface::fetchOCCSensorInfo(const PdrList& pdrs,
-                                   SensorToOCCInstance& sensorInstanceMap,
-                                   SensorOffset& sensorOffset)
-{
-    bool offsetFound = false;
-    auto pdr =
-        reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
-    auto possibleStatesPtr = pdr->possible_states;
-    for (auto offset = 0; offset < pdr->composite_sensor_count; offset++)
-    {
-        auto possibleStates =
-            reinterpret_cast<const state_sensor_possible_states*>(
-                possibleStatesPtr);
-
-        if (possibleStates->state_set_id ==
-            PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS)
-        {
-            sensorOffset = offset;
-            offsetFound = true;
-            break;
-        }
-        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
-                             sizeof(possibleStates->possible_states_size) +
-                             possibleStates->possible_states_size;
-    }
-
-    if (!offsetFound)
-    {
-        log<level::ERR>("pldm: OCC state sensor PDR with StateSetId "
-                        "PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS not found");
-        return;
-    }
-
-    // To order SensorID based on the EntityInstance.
-    // Note that when a proc is on a DCM, the PDRs for these sensors
-    // could have the same instance IDs but different container IDs.
-    std::map<uint32_t, SensorID> entityInstMap{};
-    for (auto& pdr : pdrs)
-    {
-        auto pdrPtr =
-            reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
-        uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
-                       static_cast<uint32_t>(pdrPtr->entity_instance);
-        entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->sensor_id));
-    }
-
-    open_power::occ::instanceID count = start;
-    for (auto const& pair : entityInstMap)
-    {
-        sensorInstanceMap.emplace(pair.second, count);
-        count++;
-    }
-}
-
-void Interface::sensorEvent(sdbusplus::message::message& msg)
-{
-    if (!isOCCSensorCacheValid())
-    {
-        PdrList pdrs{};
-
-        auto& bus = open_power::occ::utils::getBus();
-        try
-        {
-            auto method = bus.new_method_call(
-                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
-                "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
-            method.append(tid, (uint16_t)PLDM_ENTITY_PROC,
-                          (uint16_t)PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS);
-
-            auto responseMsg = bus.call(method);
-            responseMsg.read(pdrs);
-        }
-        catch (const SdBusError& e)
-        {
-            log<level::ERR>("pldm: Failed to fetch the OCC state sensor PDRs",
-                            entry("ERROR=%s", e.what()));
-        }
-
-        if (!pdrs.size())
-        {
-            log<level::ERR>("pldm: OCC state sensor PDRs not present");
-            return;
-        }
-
-        fetchOCCSensorInfo(pdrs, sensorToOCCInstance, sensorOffset);
-    }
-
-    TerminusID tid{};
-    SensorID sensorId{};
-    SensorOffset msgSensorOffset{};
-    EventState eventState{};
-    EventState previousEventState{};
-
-    msg.read(tid, sensorId, msgSensorOffset, eventState, previousEventState);
-
-    auto sensorEntry = sensorToOCCInstance.find(sensorId);
-    if (sensorEntry == sensorToOCCInstance.end() ||
-        (msgSensorOffset != sensorOffset))
-    {
-        // No action for non matching sensorEvents
-        return;
-    }
-
-    if (eventState == static_cast<EventState>(
-                          PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
-    {
-        log<level::INFO>(
-            fmt::format("PLDM: OCC{} is RUNNING", sensorEntry->second).c_str());
-        callBack(sensorEntry->second, true);
-    }
-    else if (eventState ==
-             static_cast<EventState>(
-                 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
-    {
-        log<level::INFO>(
-            fmt::format("PLDM: OCC{} has now STOPPED", sensorEntry->second)
-                .c_str());
-        callBack(sensorEntry->second, false);
-    }
-
-    return;
-}
-
-void Interface::hostStateEvent(sdbusplus::message::message& msg)
-{
-    std::map<std::string, std::variant<std::string>> properties{};
-    std::string interface;
-    msg.read(interface, properties);
-    const auto stateEntry = properties.find("CurrentHostState");
-    if (stateEntry != properties.end())
-    {
-        auto stateEntryValue = stateEntry->second;
-        auto propVal = std::get<std::string>(stateEntryValue);
-        if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
-        {
-            sensorToOCCInstance.clear();
-            occInstanceToEffecter.clear();
-        }
-    }
-}
-
-void Interface::fetchOCCEffecterInfo(
-    const PdrList& pdrs, OccInstanceToEffecter& instanceToEffecterMap,
-    CompositeEffecterCount& count, uint8_t& bootRestartPos)
-{
-    bool offsetFound = false;
-    auto pdr =
-        reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
-    auto possibleStatesPtr = pdr->possible_states;
-    for (auto offset = 0; offset < pdr->composite_effecter_count; offset++)
-    {
-        auto possibleStates =
-            reinterpret_cast<const state_effecter_possible_states*>(
-                possibleStatesPtr);
-
-        if (possibleStates->state_set_id == PLDM_STATE_SET_BOOT_RESTART_CAUSE)
-        {
-            bootRestartPos = offset;
-            effecterCount = pdr->composite_effecter_count;
-            offsetFound = true;
-            break;
-        }
-        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
-                             sizeof(possibleStates->possible_states_size) +
-                             possibleStates->possible_states_size;
-    }
-
-    if (!offsetFound)
-    {
-        return;
-    }
-
-    std::map<EntityInstance, EffecterID> entityInstMap{};
-    for (auto& pdr : pdrs)
-    {
-        auto pdrPtr =
-            reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
-        uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
-                       static_cast<uint32_t>(pdrPtr->entity_instance);
-        entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->effecter_id));
-    }
-
-    open_power::occ::instanceID position = start;
-    for (auto const& pair : entityInstMap)
-    {
-        occInstanceToEffecter.emplace(position, pair.second);
-        position++;
-    }
-}
-
-std::vector<uint8_t>
-    Interface::prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
-                                     CompositeEffecterCount effecterCount,
-                                     uint8_t bootRestartPos)
-{
-    std::vector<uint8_t> request(
-        sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
-        (effecterCount * sizeof(set_effecter_state_field)));
-    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
-    std::vector<set_effecter_state_field> stateField;
-
-    for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
-    {
-        if (effecterPos == bootRestartPos)
-        {
-            stateField.emplace_back(set_effecter_state_field{
-                PLDM_REQUEST_SET,
-                PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET});
-        }
-        else
-        {
-            stateField.emplace_back(
-                set_effecter_state_field{PLDM_NO_CHANGE, 0});
-        }
-    }
-    auto rc = encode_set_state_effecter_states_req(
-        instanceId, effecterId, effecterCount, stateField.data(), requestMsg);
-    if (rc != PLDM_SUCCESS)
-    {
-        log<level::ERR>("encode set effecter states request returned error ",
-                        entry("RC=%d", rc));
-        request.clear();
-    }
-    return request;
-}
-
-void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
-{
-    if (!isPDREffecterCacheValid())
-    {
-        PdrList pdrs{};
-
-        auto& bus = open_power::occ::utils::getBus();
-        try
-        {
-            auto method = bus.new_method_call(
-                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
-                "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
-            method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
-                          (uint16_t)PLDM_STATE_SET_BOOT_RESTART_CAUSE);
-
-            auto responseMsg = bus.call(method);
-            responseMsg.read(pdrs);
-        }
-        catch (const SdBusError& e)
-        {
-            log<level::ERR>("pldm: Failed to fetch the OCC state effecter PDRs",
-                            entry("ERROR=%s", e.what()));
-        }
-
-        if (!pdrs.size())
-        {
-            log<level::ERR>("pldm: OCC state effecter PDRs not present");
-            return;
-        }
-
-        fetchOCCEffecterInfo(pdrs, occInstanceToEffecter, effecterCount,
-                             bootRestartPosition);
-    }
-
-    // Find the matching effecter for the OCC instance
-    auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
-    if (effecterEntry == occInstanceToEffecter.end())
-    {
-        log<level::ERR>(
-            "pldm: Failed to find a matching effecter for OCC instance",
-            entry("OCC_INSTANCE_ID=%d", occInstanceId));
-
-        return;
-    }
-
-    uint8_t instanceId{};
-
-    auto& bus = open_power::occ::utils::getBus();
-    try
-    {
-        auto method = bus.new_method_call(
-            "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
-            "xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
-        method.append(mctpEid);
-        auto reply = bus.call(method);
-        reply.read(instanceId);
-    }
-    catch (const SdBusError& e)
-    {
-        log<level::ERR>("pldm: GetInstanceId returned error",
-                        entry("ERROR=%s", e.what()));
-        return;
-    }
-
-    // Prepare the SetStateEffecterStates request to reset the OCC
-    auto request = prepareSetEffecterReq(instanceId, effecterEntry->second,
-                                         effecterCount, bootRestartPosition);
-
-    if (request.empty())
-    {
-        log<level::ERR>("pldm: SetStateEffecterStates request message empty");
-        return;
-    }
-
-    // Connect to MCTP scoket
-    int fd = pldm_open();
-    if (fd == -1)
-    {
-        log<level::ERR>("pldm: Failed to connect to MCTP socket");
-        return;
-    }
-    open_power::occ::FileDescriptor fileFd(fd);
-
-    // Send the PLDM request message to HBRT
-    uint8_t* response = nullptr;
-    size_t responseSize{};
-    auto rc = pldm_send_recv(mctpEid, fileFd(), request.data(), request.size(),
-                             &response, &responseSize);
-    std::unique_ptr<uint8_t, decltype(std::free)*> responsePtr{response,
-                                                               std::free};
-    if (rc)
-    {
-        log<level::ERR>("pldm: pldm_send_recv failed for OCC reset",
-                        entry("RC=%d", rc));
-    }
-
-    uint8_t completionCode{};
-    auto responseMsg = reinterpret_cast<const pldm_msg*>(responsePtr.get());
-    auto rcDecode = decode_set_state_effecter_states_resp(
-        responseMsg, responseSize - sizeof(pldm_msg_hdr), &completionCode);
-    if (rcDecode || completionCode)
-    {
-        log<level::ERR>(
-            "pldm: decode_set_state_effecter_states_resp returned error",
-            entry("RC=%d", rcDecode),
-            entry("COMPLETION_CODE=%d", completionCode));
-    }
-
-    return;
-}
-
-} // namespace pldm
+#include "pldm.hpp"
+
+#include "file.hpp"
+
+#include <fmt/core.h>
+#include <libpldm/entity.h>
+#include <libpldm/platform.h>
+#include <libpldm/state_set.h>
+
+#include <phosphor-logging/log.hpp>
+
+namespace pldm
+{
+
+using sdbusplus::exception::SdBusError;
+using namespace phosphor::logging;
+
+void Interface::fetchOCCSensorInfo(const PdrList& pdrs,
+                                   SensorToOCCInstance& sensorInstanceMap,
+                                   SensorOffset& sensorOffset)
+{
+    bool offsetFound = false;
+    auto pdr =
+        reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
+    auto possibleStatesPtr = pdr->possible_states;
+    for (auto offset = 0; offset < pdr->composite_sensor_count; offset++)
+    {
+        auto possibleStates =
+            reinterpret_cast<const state_sensor_possible_states*>(
+                possibleStatesPtr);
+
+        if (possibleStates->state_set_id ==
+            PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS)
+        {
+            sensorOffset = offset;
+            offsetFound = true;
+            break;
+        }
+        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
+                             sizeof(possibleStates->possible_states_size) +
+                             possibleStates->possible_states_size;
+    }
+
+    if (!offsetFound)
+    {
+        log<level::ERR>("pldm: OCC state sensor PDR with StateSetId "
+                        "PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS not found");
+        return;
+    }
+
+    // To order SensorID based on the EntityInstance.
+    // Note that when a proc is on a DCM, the PDRs for these sensors
+    // could have the same instance IDs but different container IDs.
+    std::map<uint32_t, SensorID> entityInstMap{};
+    for (auto& pdr : pdrs)
+    {
+        auto pdrPtr =
+            reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
+        uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
+                       static_cast<uint32_t>(pdrPtr->entity_instance);
+        entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->sensor_id));
+    }
+
+    open_power::occ::instanceID count = start;
+    for (auto const& pair : entityInstMap)
+    {
+        sensorInstanceMap.emplace(pair.second, count);
+        count++;
+    }
+}
+
+void Interface::sensorEvent(sdbusplus::message::message& msg)
+{
+    if (!isOCCSensorCacheValid())
+    {
+        PdrList pdrs{};
+
+        auto& bus = open_power::occ::utils::getBus();
+        try
+        {
+            auto method = bus.new_method_call(
+                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
+                "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
+            method.append(tid, (uint16_t)PLDM_ENTITY_PROC,
+                          (uint16_t)PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS);
+
+            auto responseMsg = bus.call(method);
+            responseMsg.read(pdrs);
+        }
+        catch (const SdBusError& e)
+        {
+            log<level::ERR>("pldm: Failed to fetch the OCC state sensor PDRs",
+                            entry("ERROR=%s", e.what()));
+        }
+
+        if (!pdrs.size())
+        {
+            log<level::ERR>("pldm: OCC state sensor PDRs not present");
+            return;
+        }
+
+        fetchOCCSensorInfo(pdrs, sensorToOCCInstance, sensorOffset);
+    }
+
+    TerminusID tid{};
+    SensorID sensorId{};
+    SensorOffset msgSensorOffset{};
+    EventState eventState{};
+    EventState previousEventState{};
+
+    msg.read(tid, sensorId, msgSensorOffset, eventState, previousEventState);
+
+    auto sensorEntry = sensorToOCCInstance.find(sensorId);
+    if (sensorEntry == sensorToOCCInstance.end() ||
+        (msgSensorOffset != sensorOffset))
+    {
+        // No action for non matching sensorEvents
+        return;
+    }
+
+    if (eventState == static_cast<EventState>(
+                          PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
+    {
+        log<level::INFO>(
+            fmt::format("PLDM: OCC{} is RUNNING", sensorEntry->second).c_str());
+        callBack(sensorEntry->second, true);
+    }
+    else if (eventState ==
+             static_cast<EventState>(
+                 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
+    {
+        log<level::INFO>(
+            fmt::format("PLDM: OCC{} has now STOPPED", sensorEntry->second)
+                .c_str());
+        callBack(sensorEntry->second, false);
+    }
+
+    return;
+}
+
+void Interface::hostStateEvent(sdbusplus::message::message& msg)
+{
+    std::map<std::string, std::variant<std::string>> properties{};
+    std::string interface;
+    msg.read(interface, properties);
+    const auto stateEntry = properties.find("CurrentHostState");
+    if (stateEntry != properties.end())
+    {
+        auto stateEntryValue = stateEntry->second;
+        auto propVal = std::get<std::string>(stateEntryValue);
+        if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
+        {
+            sensorToOCCInstance.clear();
+            occInstanceToEffecter.clear();
+        }
+    }
+}
+
+void Interface::fetchOCCEffecterInfo(
+    const PdrList& pdrs, OccInstanceToEffecter& instanceToEffecterMap,
+    CompositeEffecterCount& count, uint8_t& bootRestartPos)
+{
+    bool offsetFound = false;
+    auto pdr =
+        reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
+    auto possibleStatesPtr = pdr->possible_states;
+    for (auto offset = 0; offset < pdr->composite_effecter_count; offset++)
+    {
+        auto possibleStates =
+            reinterpret_cast<const state_effecter_possible_states*>(
+                possibleStatesPtr);
+
+        if (possibleStates->state_set_id == PLDM_STATE_SET_BOOT_RESTART_CAUSE)
+        {
+            bootRestartPos = offset;
+            effecterCount = pdr->composite_effecter_count;
+            offsetFound = true;
+            break;
+        }
+        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
+                             sizeof(possibleStates->possible_states_size) +
+                             possibleStates->possible_states_size;
+    }
+
+    if (!offsetFound)
+    {
+        return;
+    }
+
+    std::map<EntityInstance, EffecterID> entityInstMap{};
+    for (auto& pdr : pdrs)
+    {
+        auto pdrPtr =
+            reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
+        uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
+                       static_cast<uint32_t>(pdrPtr->entity_instance);
+        entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->effecter_id));
+    }
+
+    open_power::occ::instanceID position = start;
+    for (auto const& pair : entityInstMap)
+    {
+        occInstanceToEffecter.emplace(position, pair.second);
+        position++;
+    }
+}
+
+std::vector<uint8_t>
+    Interface::prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
+                                     CompositeEffecterCount effecterCount,
+                                     uint8_t bootRestartPos)
+{
+    std::vector<uint8_t> request(
+        sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
+        (effecterCount * sizeof(set_effecter_state_field)));
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+    std::vector<set_effecter_state_field> stateField;
+
+    for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
+    {
+        if (effecterPos == bootRestartPos)
+        {
+            stateField.emplace_back(set_effecter_state_field{
+                PLDM_REQUEST_SET,
+                PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET});
+        }
+        else
+        {
+            stateField.emplace_back(
+                set_effecter_state_field{PLDM_NO_CHANGE, 0});
+        }
+    }
+    auto rc = encode_set_state_effecter_states_req(
+        instanceId, effecterId, effecterCount, stateField.data(), requestMsg);
+    if (rc != PLDM_SUCCESS)
+    {
+        log<level::ERR>("encode set effecter states request returned error ",
+                        entry("RC=%d", rc));
+        request.clear();
+    }
+    return request;
+}
+
+void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
+{
+    if (!isPDREffecterCacheValid())
+    {
+        PdrList pdrs{};
+
+        auto& bus = open_power::occ::utils::getBus();
+        try
+        {
+            auto method = bus.new_method_call(
+                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
+                "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
+            method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
+                          (uint16_t)PLDM_STATE_SET_BOOT_RESTART_CAUSE);
+
+            auto responseMsg = bus.call(method);
+            responseMsg.read(pdrs);
+        }
+        catch (const SdBusError& e)
+        {
+            log<level::ERR>("pldm: Failed to fetch the OCC state effecter PDRs",
+                            entry("ERROR=%s", e.what()));
+        }
+
+        if (!pdrs.size())
+        {
+            log<level::ERR>("pldm: OCC state effecter PDRs not present");
+            return;
+        }
+
+        fetchOCCEffecterInfo(pdrs, occInstanceToEffecter, effecterCount,
+                             bootRestartPosition);
+    }
+
+    // Find the matching effecter for the OCC instance
+    auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
+    if (effecterEntry == occInstanceToEffecter.end())
+    {
+        log<level::ERR>(
+            "pldm: Failed to find a matching effecter for OCC instance",
+            entry("OCC_INSTANCE_ID=%d", occInstanceId));
+
+        return;
+    }
+
+    uint8_t instanceId{};
+
+    auto& bus = open_power::occ::utils::getBus();
+    try
+    {
+        auto method = bus.new_method_call(
+            "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
+            "xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
+        method.append(mctpEid);
+        auto reply = bus.call(method);
+        reply.read(instanceId);
+    }
+    catch (const SdBusError& e)
+    {
+        log<level::ERR>("pldm: GetInstanceId returned error",
+                        entry("ERROR=%s", e.what()));
+        return;
+    }
+
+    // Prepare the SetStateEffecterStates request to reset the OCC
+    auto request = prepareSetEffecterReq(instanceId, effecterEntry->second,
+                                         effecterCount, bootRestartPosition);
+
+    if (request.empty())
+    {
+        log<level::ERR>("pldm: SetStateEffecterStates request message empty");
+        return;
+    }
+
+    // Connect to MCTP scoket
+    int fd = pldm_open();
+    if (fd == -1)
+    {
+        log<level::ERR>("pldm: Failed to connect to MCTP socket");
+        return;
+    }
+    open_power::occ::FileDescriptor fileFd(fd);
+
+    // Send the PLDM request message to HBRT
+    uint8_t* response = nullptr;
+    size_t responseSize{};
+    auto rc = pldm_send_recv(mctpEid, fileFd(), request.data(), request.size(),
+                             &response, &responseSize);
+    std::unique_ptr<uint8_t, decltype(std::free)*> responsePtr{response,
+                                                               std::free};
+    if (rc)
+    {
+        log<level::ERR>("pldm: pldm_send_recv failed for OCC reset",
+                        entry("RC=%d", rc));
+    }
+
+    uint8_t completionCode{};
+    auto responseMsg = reinterpret_cast<const pldm_msg*>(responsePtr.get());
+    auto rcDecode = decode_set_state_effecter_states_resp(
+        responseMsg, responseSize - sizeof(pldm_msg_hdr), &completionCode);
+    if (rcDecode || completionCode)
+    {
+        log<level::ERR>(
+            "pldm: decode_set_state_effecter_states_resp returned error",
+            entry("RC=%d", rcDecode),
+            entry("COMPLETION_CODE=%d", completionCode));
+    }
+
+    return;
+}
+
+} // namespace pldm
diff --git a/pldm.hpp b/pldm.hpp
index fb57456..a10284d 100644
--- a/pldm.hpp
+++ b/pldm.hpp
@@ -1,195 +1,195 @@
-#pragma once
-
-#include "occ_status.hpp"
-#include "utils.hpp"
-
-#include <libpldm/pldm.h>
-
-#include <sdbusplus/bus/match.hpp>
-
-namespace pldm
-{
-
-namespace MatchRules = sdbusplus::bus::match::rules;
-
-using CompositeEffecterCount = uint8_t;
-using EffecterID = uint16_t;
-using EntityType = uint16_t;
-using EntityInstance = uint16_t;
-using EventState = uint8_t;
-using OccInstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>;
-using PdrList = std::vector<std::vector<uint8_t>>;
-using SensorID = uint16_t;
-using SensorOffset = uint8_t;
-using SensorToOCCInstance = std::map<SensorID, open_power::occ::instanceID>;
-using TerminusID = uint8_t;
-
-/** @brief Hardcoded TID */
-constexpr TerminusID tid = 0;
-
-/** @brief OCC instance starts with 0 for example "occ0" */
-constexpr open_power::occ::instanceID start = 0;
-
-/** @brief Hardcoded mctpEid for HBRT */
-constexpr mctp_eid_t mctpEid = 10;
-
-/** @class Interface
- *
- *  @brief Abstracts the PLDM details related to the OCC
- */
-class Interface
-{
-  public:
-    Interface() = delete;
-    ~Interface() = default;
-    Interface(const Interface&) = delete;
-    Interface& operator=(const Interface&) = delete;
-    Interface(Interface&&) = delete;
-    Interface& operator=(Interface&&) = delete;
-
-    /** @brief Constructs the PLDM Interface object for OCC functions
-     *
-     *  @param[in] callBack - callBack handler to invoke when the OCC state
-     *                        changes.
-     */
-    explicit Interface(
-        std::function<bool(open_power::occ::instanceID, bool)> callBack) :
-        callBack(callBack),
-        pldmEventSignal(
-            open_power::occ::utils::getBus(),
-            MatchRules::type::signal() +
-                MatchRules::member("StateSensorEvent") +
-                MatchRules::path("/xyz/openbmc_project/pldm") +
-                MatchRules::interface("xyz.openbmc_project.PLDM.Event"),
-            std::bind(std::mem_fn(&Interface::sensorEvent), this,
-                      std::placeholders::_1)),
-        hostStateSignal(
-            open_power::occ::utils::getBus(),
-            MatchRules::propertiesChanged("/xyz/openbmc_project/state/host0",
-                                          "xyz.openbmc_project.State.Host"),
-            std::bind(std::mem_fn(&Interface::hostStateEvent), this,
-                      std::placeholders::_1))
-    {
-    }
-
-    /** @brief Fetch the OCC state sensor PDRs and populate the cache with
-     *         sensorId to OCC instance mapping information and the sensor
-     *         offset for Operational Running Status.
-     *
-     *  @param[in] pdrs - OCC state sensor PDRs
-     *  @param[out] sensorInstanceMap - map of sensorID to OCC instance
-     *  @param[out] sensorOffset - sensor offset of interested state set ID
-     */
-    void fetchOCCSensorInfo(const PdrList& pdrs,
-                            SensorToOCCInstance& sensorInstanceMap,
-                            SensorOffset& sensorOffset);
-
-    /** @brief Fetch the OCC state effecter PDRs and populate the cache with
-     *         OCC instance to EffecterID information.
-     *
-     *  @param[in] pdrs - OCC state effecter PDRs
-     *  @param[out] instanceToEffecterMap - map of OCC instance to effecterID
-     *  @param[out] count - sensor offset of interested state set ID
-     *  @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID
-     */
-    void fetchOCCEffecterInfo(const PdrList& pdrs,
-                              OccInstanceToEffecter& instanceToEffecterMap,
-                              CompositeEffecterCount& count,
-                              uint8_t& bootRestartPos);
-
-    /** @brief Prepare the request for SetStateEffecterStates command
-     *
-     *  @param[in] instanceId - PLDM instanceID
-     *  @param[in] instanceToEffecterMap - map of OCC instance to effecterID
-     *  @param[in] count - compositeEffecterCount for OCC reset effecter PDR
-     *  @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID
-     *
-     *  @return PLDM request message to be sent to host for OCC reset, empty
-     *          response in the case of failure.
-     */
-    std::vector<uint8_t>
-        prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
-                              CompositeEffecterCount effecterCount,
-                              uint8_t bootRestartPos);
-
-    /** @brief Send the PLDM message to reset the OCC
-     *
-     *  @param[in] instanceId - OCC instance to reset
-     *
-     */
-    void resetOCC(open_power::occ::instanceID occInstanceId);
-
-  private:
-    /** @brief Callback handler to be invoked when the state of the OCC
-     *         changes
-     */
-    std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
-
-    /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
-     *         processes if the event corresponds to OCC state change.
-     */
-    sdbusplus::bus::match_t pldmEventSignal;
-
-    /** @brief Used to subscribe for host state change signal */
-    sdbusplus::bus::match_t hostStateSignal;
-
-    /** @brief PLDM Sensor ID to OCC Instance mapping
-     */
-    SensorToOCCInstance sensorToOCCInstance;
-
-    /** @brief Sensor offset of state set ID
-     * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
-     */
-    SensorOffset sensorOffset;
-
-    /** @brief OCC Instance mapping to PLDM Effecter ID
-     */
-    OccInstanceToEffecter occInstanceToEffecter;
-
-    /** @brief compositeEffecterCount for OCC reset state effecter PDR */
-    CompositeEffecterCount effecterCount = 0;
-
-    /** @brief Position of Boot/Restart Cause stateSetID in OCC state
-     *         effecter PDR
-     */
-    uint8_t bootRestartPosition = 0;
-
-    /** @brief When the OCC state changes host sends PlatformEventMessage
-     *         StateSensorEvent, this function processes the D-Bus signal
-     *         with the sensor event information and invokes the callback
-     *         to change the OCC state.
-     *
-     *  @param[in] msg - data associated with the subscribed signal
-     */
-    void sensorEvent(sdbusplus::message::message& msg);
-
-    /** @brief When the host state changes and if the CurrentHostState is
-     *         xyz.openbmc_project.State.Host.HostState.Off then
-     *         the cache of OCC sensors and effecters mapping is cleared.
-     *
-     *  @param[in] msg - data associated with the subscribed signal
-     */
-    void hostStateEvent(sdbusplus::message::message& msg);
-
-    /** @brief Check if the PDR cache for PLDM OCC sensors is valid
-     *
-     *  @return true if cache is populated and false if the cache is not
-     *          populated.
-     */
-    auto isOCCSensorCacheValid()
-    {
-        return (sensorToOCCInstance.empty() ? false : true);
-    }
-
-    /** @brief Check if the PDR cache for PLDM OCC effecters is valid
-     *
-     *  @return true if cache is populated and false if the cache is not
-     *          populated.
-     */
-    auto isPDREffecterCacheValid()
-    {
-        return (occInstanceToEffecter.empty() ? false : true);
-    }
-};
-
-} // namespace pldm
+#pragma once
+
+#include "occ_status.hpp"
+#include "utils.hpp"
+
+#include <libpldm/pldm.h>
+
+#include <sdbusplus/bus/match.hpp>
+
+namespace pldm
+{
+
+namespace MatchRules = sdbusplus::bus::match::rules;
+
+using CompositeEffecterCount = uint8_t;
+using EffecterID = uint16_t;
+using EntityType = uint16_t;
+using EntityInstance = uint16_t;
+using EventState = uint8_t;
+using OccInstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>;
+using PdrList = std::vector<std::vector<uint8_t>>;
+using SensorID = uint16_t;
+using SensorOffset = uint8_t;
+using SensorToOCCInstance = std::map<SensorID, open_power::occ::instanceID>;
+using TerminusID = uint8_t;
+
+/** @brief Hardcoded TID */
+constexpr TerminusID tid = 0;
+
+/** @brief OCC instance starts with 0 for example "occ0" */
+constexpr open_power::occ::instanceID start = 0;
+
+/** @brief Hardcoded mctpEid for HBRT */
+constexpr mctp_eid_t mctpEid = 10;
+
+/** @class Interface
+ *
+ *  @brief Abstracts the PLDM details related to the OCC
+ */
+class Interface
+{
+  public:
+    Interface() = delete;
+    ~Interface() = default;
+    Interface(const Interface&) = delete;
+    Interface& operator=(const Interface&) = delete;
+    Interface(Interface&&) = delete;
+    Interface& operator=(Interface&&) = delete;
+
+    /** @brief Constructs the PLDM Interface object for OCC functions
+     *
+     *  @param[in] callBack - callBack handler to invoke when the OCC state
+     *                        changes.
+     */
+    explicit Interface(
+        std::function<bool(open_power::occ::instanceID, bool)> callBack) :
+        callBack(callBack),
+        pldmEventSignal(
+            open_power::occ::utils::getBus(),
+            MatchRules::type::signal() +
+                MatchRules::member("StateSensorEvent") +
+                MatchRules::path("/xyz/openbmc_project/pldm") +
+                MatchRules::interface("xyz.openbmc_project.PLDM.Event"),
+            std::bind(std::mem_fn(&Interface::sensorEvent), this,
+                      std::placeholders::_1)),
+        hostStateSignal(
+            open_power::occ::utils::getBus(),
+            MatchRules::propertiesChanged("/xyz/openbmc_project/state/host0",
+                                          "xyz.openbmc_project.State.Host"),
+            std::bind(std::mem_fn(&Interface::hostStateEvent), this,
+                      std::placeholders::_1))
+    {
+    }
+
+    /** @brief Fetch the OCC state sensor PDRs and populate the cache with
+     *         sensorId to OCC instance mapping information and the sensor
+     *         offset for Operational Running Status.
+     *
+     *  @param[in] pdrs - OCC state sensor PDRs
+     *  @param[out] sensorInstanceMap - map of sensorID to OCC instance
+     *  @param[out] sensorOffset - sensor offset of interested state set ID
+     */
+    void fetchOCCSensorInfo(const PdrList& pdrs,
+                            SensorToOCCInstance& sensorInstanceMap,
+                            SensorOffset& sensorOffset);
+
+    /** @brief Fetch the OCC state effecter PDRs and populate the cache with
+     *         OCC instance to EffecterID information.
+     *
+     *  @param[in] pdrs - OCC state effecter PDRs
+     *  @param[out] instanceToEffecterMap - map of OCC instance to effecterID
+     *  @param[out] count - sensor offset of interested state set ID
+     *  @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID
+     */
+    void fetchOCCEffecterInfo(const PdrList& pdrs,
+                              OccInstanceToEffecter& instanceToEffecterMap,
+                              CompositeEffecterCount& count,
+                              uint8_t& bootRestartPos);
+
+    /** @brief Prepare the request for SetStateEffecterStates command
+     *
+     *  @param[in] instanceId - PLDM instanceID
+     *  @param[in] instanceToEffecterMap - map of OCC instance to effecterID
+     *  @param[in] count - compositeEffecterCount for OCC reset effecter PDR
+     *  @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID
+     *
+     *  @return PLDM request message to be sent to host for OCC reset, empty
+     *          response in the case of failure.
+     */
+    std::vector<uint8_t>
+        prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
+                              CompositeEffecterCount effecterCount,
+                              uint8_t bootRestartPos);
+
+    /** @brief Send the PLDM message to reset the OCC
+     *
+     *  @param[in] instanceId - OCC instance to reset
+     *
+     */
+    void resetOCC(open_power::occ::instanceID occInstanceId);
+
+  private:
+    /** @brief Callback handler to be invoked when the state of the OCC
+     *         changes
+     */
+    std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
+
+    /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
+     *         processes if the event corresponds to OCC state change.
+     */
+    sdbusplus::bus::match_t pldmEventSignal;
+
+    /** @brief Used to subscribe for host state change signal */
+    sdbusplus::bus::match_t hostStateSignal;
+
+    /** @brief PLDM Sensor ID to OCC Instance mapping
+     */
+    SensorToOCCInstance sensorToOCCInstance;
+
+    /** @brief Sensor offset of state set ID
+     * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
+     */
+    SensorOffset sensorOffset;
+
+    /** @brief OCC Instance mapping to PLDM Effecter ID
+     */
+    OccInstanceToEffecter occInstanceToEffecter;
+
+    /** @brief compositeEffecterCount for OCC reset state effecter PDR */
+    CompositeEffecterCount effecterCount = 0;
+
+    /** @brief Position of Boot/Restart Cause stateSetID in OCC state
+     *         effecter PDR
+     */
+    uint8_t bootRestartPosition = 0;
+
+    /** @brief When the OCC state changes host sends PlatformEventMessage
+     *         StateSensorEvent, this function processes the D-Bus signal
+     *         with the sensor event information and invokes the callback
+     *         to change the OCC state.
+     *
+     *  @param[in] msg - data associated with the subscribed signal
+     */
+    void sensorEvent(sdbusplus::message::message& msg);
+
+    /** @brief When the host state changes and if the CurrentHostState is
+     *         xyz.openbmc_project.State.Host.HostState.Off then
+     *         the cache of OCC sensors and effecters mapping is cleared.
+     *
+     *  @param[in] msg - data associated with the subscribed signal
+     */
+    void hostStateEvent(sdbusplus::message::message& msg);
+
+    /** @brief Check if the PDR cache for PLDM OCC sensors is valid
+     *
+     *  @return true if cache is populated and false if the cache is not
+     *          populated.
+     */
+    auto isOCCSensorCacheValid()
+    {
+        return (sensorToOCCInstance.empty() ? false : true);
+    }
+
+    /** @brief Check if the PDR cache for PLDM OCC effecters is valid
+     *
+     *  @return true if cache is populated and false if the cache is not
+     *          populated.
+     */
+    auto isPDREffecterCacheValid()
+    {
+        return (occInstanceToEffecter.empty() ? false : true);
+    }
+};
+
+} // namespace pldm
diff --git a/pldm.mk b/pldm.mk
index 0733508..bcdaba1 100644
--- a/pldm.mk
+++ b/pldm.mk
@@ -1,12 +1,12 @@
-if ENABLE_PLDM
-
-noinst_HEADERS += \
-	pldm.hpp
-libocc_control_la_SOURCES += \
-	pldm.cpp
-openpower_occ_control_LDADD += \
-	$(LIBPLDM_LIBS)
-openpower_occ_control_CXXFLAGS += \
-	$(LIBPLDM_CFLAGS)
-
-endif
+if ENABLE_PLDM
+
+noinst_HEADERS += \
+	pldm.hpp
+libocc_control_la_SOURCES += \
+	pldm.cpp
+openpower_occ_control_LDADD += \
+	$(LIBPLDM_LIBS)
+openpower_occ_control_CXXFLAGS += \
+	$(LIBPLDM_CFLAGS)
+
+endif
diff --git a/powermode.mk b/powermode.mk
index ffa3aa9..4e9ac9f 100644
--- a/powermode.mk
+++ b/powermode.mk
@@ -1,8 +1,8 @@
-if POWER10_SUPPORT
-
-noinst_HEADERS += \
-	powermode.hpp
-libocc_control_la_SOURCES += \
-	powermode.cpp
-
-endif
+if POWER10_SUPPORT
+
+noinst_HEADERS += \
+	powermode.hpp
+libocc_control_la_SOURCES += \
+	powermode.cpp
+
+endif
