Tom Joseph | 815f9f5 | 2020-07-27 12:12:13 +0530 | [diff] [blame^] | 1 | #include "pldm.hpp"
|
| 2 |
|
| 3 | #include <libpldm/entity.h>
|
| 4 | #include <libpldm/platform.h>
|
| 5 | #include <libpldm/state_set.h>
|
| 6 |
|
| 7 | #include <phosphor-logging/log.hpp>
|
| 8 |
|
| 9 | namespace pldm
|
| 10 | {
|
| 11 |
|
| 12 | using sdbusplus::exception::SdBusError;
|
| 13 | using namespace phosphor::logging;
|
| 14 |
|
| 15 | void Interface::fetchOCCSensorInfo(const PdrList& pdrs,
|
| 16 | SensorToOCCInstance& sensorInstanceMap,
|
| 17 | SensorOffset& sensorOffset)
|
| 18 | {
|
| 19 | bool offsetFound = false;
|
| 20 | auto pdr =
|
| 21 | reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
|
| 22 | auto possibleStatesPtr = pdr->possible_states;
|
| 23 | for (auto offset = 0; offset < pdr->composite_sensor_count; offset++)
|
| 24 | {
|
| 25 | auto possibleStates =
|
| 26 | reinterpret_cast<const state_sensor_possible_states*>(
|
| 27 | possibleStatesPtr);
|
| 28 |
|
| 29 | if (possibleStates->state_set_id ==
|
| 30 | PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS)
|
| 31 | {
|
| 32 | sensorOffset = offset;
|
| 33 | offsetFound = true;
|
| 34 | break;
|
| 35 | }
|
| 36 | possibleStatesPtr += sizeof(possibleStates->state_set_id) +
|
| 37 | sizeof(possibleStates->possible_states_size) +
|
| 38 | possibleStates->possible_states_size;
|
| 39 | }
|
| 40 |
|
| 41 | if (!offsetFound)
|
| 42 | {
|
| 43 | log<level::ERR>("pldm: OCC state sensor PDR with StateSetId "
|
| 44 | "PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS not found");
|
| 45 | return;
|
| 46 | }
|
| 47 |
|
| 48 | // To order SensorID based on the EntityInstance
|
| 49 | std::map<EntityInstance, SensorID> entityInstMap{};
|
| 50 | for (auto& pdr : pdrs)
|
| 51 | {
|
| 52 | auto pdrPtr =
|
| 53 | reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
|
| 54 | entityInstMap.emplace(
|
| 55 | static_cast<EntityInstance>(pdrPtr->entity_instance),
|
| 56 | static_cast<SensorID>(pdrPtr->sensor_id));
|
| 57 | }
|
| 58 |
|
| 59 | open_power::occ::instanceID count = start;
|
| 60 | for (auto const& pair : entityInstMap)
|
| 61 | {
|
| 62 | sensorInstanceMap.emplace(pair.second, count);
|
| 63 | count++;
|
| 64 | }
|
| 65 | }
|
| 66 |
|
| 67 | void Interface::sensorEvent(sdbusplus::message::message& msg)
|
| 68 | {
|
| 69 | if (!isOCCSensorCacheValid())
|
| 70 | {
|
| 71 | PdrList pdrs{};
|
| 72 |
|
| 73 | try
|
| 74 | {
|
| 75 | auto method = bus.new_method_call(
|
| 76 | "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
|
| 77 | "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
|
| 78 | method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
|
| 79 | (uint16_t)PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS);
|
| 80 |
|
| 81 | auto responseMsg = bus.call(method);
|
| 82 | responseMsg.read(pdrs);
|
| 83 | }
|
| 84 | catch (const SdBusError& e)
|
| 85 | {
|
| 86 | log<level::ERR>("pldm: Failed to fetch the OCC state sensor PDRs",
|
| 87 | entry("ERROR=%s", e.what()));
|
| 88 | }
|
| 89 |
|
| 90 | if (!pdrs.size())
|
| 91 | {
|
| 92 | log<level::ERR>("pldm: OCC state sensor PDRs not present");
|
| 93 | return;
|
| 94 | }
|
| 95 |
|
| 96 | fetchOCCSensorInfo(pdrs, sensorToOCCInstance, sensorOffset);
|
| 97 | }
|
| 98 |
|
| 99 | TerminusID tid{};
|
| 100 | SensorID sensorId{};
|
| 101 | SensorOffset msgSensorOffset{};
|
| 102 | EventState eventState{};
|
| 103 | EventState previousEventState{};
|
| 104 |
|
| 105 | msg.read(tid, sensorId, sensorOffset, eventState, previousEventState);
|
| 106 |
|
| 107 | auto sensorEntry = sensorToOCCInstance.find(sensorId);
|
| 108 | if (sensorEntry == sensorToOCCInstance.end() ||
|
| 109 | (msgSensorOffset != sensorOffset))
|
| 110 | {
|
| 111 | // No action for non matching sensorEvents
|
| 112 | return;
|
| 113 | }
|
| 114 |
|
| 115 | bool newState{};
|
| 116 | if (eventState == static_cast<EventState>(
|
| 117 | PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
|
| 118 | {
|
| 119 | newState = callBack(sensorEntry->second, true);
|
| 120 | }
|
| 121 | else if (eventState ==
|
| 122 | static_cast<EventState>(
|
| 123 | PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
|
| 124 | {
|
| 125 | newState = callBack(sensorEntry->second, false);
|
| 126 | }
|
| 127 | else
|
| 128 | {
|
| 129 | return;
|
| 130 | }
|
| 131 |
|
| 132 | log<level::INFO>("pldm: Updated OCCActive state",
|
| 133 | entry("STATE=%s", newState ? "true" : "false"));
|
| 134 | return;
|
| 135 | }
|
| 136 |
|
| 137 | void Interface::hostStateEvent(sdbusplus::message::message& msg)
|
| 138 | {
|
| 139 | std::map<std::string, std::variant<std::string>> properties{};
|
| 140 | std::string interface;
|
| 141 | msg.read(interface, properties);
|
| 142 | const auto stateEntry = properties.find("CurrentHostState");
|
| 143 | if (stateEntry != properties.end())
|
| 144 | {
|
| 145 | auto stateEntryValue = stateEntry->second;
|
| 146 | auto propVal = std::get<std::string>(stateEntryValue);
|
| 147 | if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
|
| 148 | {
|
| 149 | sensorToOCCInstance.clear();
|
| 150 | }
|
| 151 | }
|
| 152 | }
|
| 153 |
|
| 154 | } // namespace pldm |