blob: c5203409ea36ba0497e508ac92b8a52f58bc0668 [file] [log] [blame]
Tom Joseph815f9f52020-07-27 12:12:13 +05301#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
9namespace pldm
10{
11
12using sdbusplus::exception::SdBusError;
13using namespace phosphor::logging;
14
15void 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
67void 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
137void 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