blob: 12e4b04d9d185d6293bd10623203c19505ed2e20 [file] [log] [blame]
George Liu362c18d2020-05-14 09:46:36 +08001#pragma once
2
George Liu362c18d2020-05-14 09:46:36 +08003#include "common/utils.hpp"
4#include "libpldmresponder/pdr.hpp"
5#include "pdr_utils.hpp"
6#include "pldmd/handler.hpp"
7
George Liuc453e162022-12-21 17:16:23 +08008#include <libpldm/platform.h>
9#include <libpldm/states.h>
10
Riya Dixit49cfb132023-03-02 04:26:53 -060011#include <phosphor-logging/lg2.hpp>
12
George Liu362c18d2020-05-14 09:46:36 +080013#include <cstdint>
14#include <map>
15
Riya Dixit49cfb132023-03-02 04:26:53 -060016PHOSPHOR_LOG2_USING;
17
George Liu362c18d2020-05-14 09:46:36 +080018namespace pldm
19{
20namespace responder
21{
22namespace platform_state_sensor
23{
George Liu362c18d2020-05-14 09:46:36 +080024/** @brief Function to get the sensor state
25 *
26 * @tparam[in] DBusInterface - DBus interface type
27 * @param[in] dBusIntf - The interface object of DBusInterface
28 * @param[in] stateToDbusValue - Map of DBus property State to attribute value
29 * @param[in] dbusMapping - The d-bus object
30 *
31 * @return - Enumeration of SensorState
32 */
33template <class DBusInterface>
34uint8_t getStateSensorEventState(
35 const DBusInterface& dBusIntf,
Brad Bishop5079ac42021-08-19 18:35:06 -040036 const std::map<pldm::responder::pdr_utils::State,
37 pldm::utils::PropertyValue>& stateToDbusValue,
38 const pldm::utils::DBusMapping& dbusMapping)
George Liu362c18d2020-05-14 09:46:36 +080039{
40 try
41 {
42 auto propertyValue = dBusIntf.getDbusPropertyVariant(
43 dbusMapping.objectPath.c_str(), dbusMapping.propertyName.c_str(),
44 dbusMapping.interface.c_str());
45
46 for (const auto& stateValue : stateToDbusValue)
47 {
48 if (stateValue.second == propertyValue)
49 {
50 return stateValue.first;
51 }
52 }
53 }
54 catch (const std::exception& e)
55 {
Riya Dixit49cfb132023-03-02 04:26:53 -060056 error(
57 "Get StateSensor EventState from dbus Error, interface : {DBUS_OBJ_PATH}, exception : {ERR_EXCEP}",
58 "DBUS_OBJ_PATH", dbusMapping.objectPath.c_str(), "ERR_EXCEP",
59 e.what());
George Liu362c18d2020-05-14 09:46:36 +080060 }
61
George Liu916808c2021-01-19 17:56:42 +080062 return PLDM_SENSOR_UNKNOWN;
George Liu362c18d2020-05-14 09:46:36 +080063}
64
65/** @brief Function to get the state sensor readings requested by pldm requester
66 *
67 * @tparam[in] DBusInterface - DBus interface type
68 * @tparam[in] Handler - pldm::responder::platform::Handler
69 * @param[in] dBusIntf - The interface object of DBusInterface
70 * @param[in] handler - The interface object of
71 * pldm::responder::platform::Handler
72 * @param[in] sensorId - Sensor ID sent by the requester to act on
73 * @param[in] sensorRearmCnt - Each bit location in this field corresponds to a
74 * particular sensor within the state sensor
75 * @param[out] compSensorCnt - composite sensor count
76 * @param[out] stateField - The state field data for each of the states,
77 * equal to composite sensor count in number
78 * @return - Success or failure in setting the states. Returns failure in
79 * terms of PLDM completion codes if atleast one state fails to be set
80 */
81template <class DBusInterface, class Handler>
82int getStateSensorReadingsHandler(
83 const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId,
84 uint8_t sensorRearmCnt, uint8_t& compSensorCnt,
Manojkiran Edaae933cc2024-02-21 17:19:21 +053085 std::vector<get_sensor_state_field>& stateField,
86 const stateSensorCacheMaps& sensorCache)
George Liu362c18d2020-05-14 09:46:36 +080087{
88 using namespace pldm::responder::pdr;
89 using namespace pldm::utils;
90
91 pldm_state_sensor_pdr* pdr = nullptr;
92
93 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
94 pldm_pdr_init(), pldm_pdr_destroy);
Andrew Jefferyacb20292023-06-30 11:47:44 +093095 if (!stateSensorPdrRepo)
96 {
97 throw std::runtime_error(
98 "Failed to instantiate state sensor PDR repository");
99 }
Brad Bishop5079ac42021-08-19 18:35:06 -0400100 pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get());
George Liu362c18d2020-05-14 09:46:36 +0800101 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
102 if (stateSensorPDRs.empty())
103 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600104 error("Failed to get record by PDR type");
George Liu362c18d2020-05-14 09:46:36 +0800105 return PLDM_PLATFORM_INVALID_SENSOR_ID;
106 }
107
Brad Bishop5079ac42021-08-19 18:35:06 -0400108 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu362c18d2020-05-14 09:46:36 +0800109 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
110 while (pdrRecord)
111 {
112 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
113 assert(pdr != NULL);
114 if (pdr->sensor_id != sensorId)
115 {
116 pdr = nullptr;
117 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
118 continue;
119 }
120
121 compSensorCnt = pdr->composite_sensor_count;
122 if (sensorRearmCnt > compSensorCnt)
123 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600124 error(
125 "The requester sent wrong sensorRearm count for the sensor, SENSOR_ID={SENSOR_ID} SENSOR_REARM_COUNT={SENSOR_REARM_CNT}",
126 "SENSOR_ID", sensorId, "SENSOR_REARM_CNT", sensorRearmCnt);
George Liu362c18d2020-05-14 09:46:36 +0800127 return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE;
128 }
George Liu916808c2021-01-19 17:56:42 +0800129
130 if (sensorRearmCnt == 0)
131 {
132 sensorRearmCnt = compSensorCnt;
133 stateField.resize(sensorRearmCnt);
134 }
135
George Liu362c18d2020-05-14 09:46:36 +0800136 break;
137 }
138
139 if (!pdr)
140 {
141 return PLDM_PLATFORM_INVALID_SENSOR_ID;
142 }
143
144 int rc = PLDM_SUCCESS;
145 try
146 {
Brad Bishop5079ac42021-08-19 18:35:06 -0400147 const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps(
148 sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
George Liu362c18d2020-05-14 09:46:36 +0800149
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530150 pldm::responder::pdr_utils::EventStates sensorCacheforSensor{};
151 if (sensorCache.contains(sensorId))
152 {
153 sensorCacheforSensor = sensorCache.at(sensorId);
154 }
George Liu362c18d2020-05-14 09:46:36 +0800155 stateField.clear();
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530156 for (std::size_t i{0}; i < sensorRearmCnt; i++)
George Liu362c18d2020-05-14 09:46:36 +0800157 {
158 auto& dbusMapping = dbusMappings[i];
159
George Liu916808c2021-01-19 17:56:42 +0800160 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>(
George Liu362c18d2020-05-14 09:46:36 +0800161 dBusIntf, dbusValMaps[i], dbusMapping);
George Liu916808c2021-01-19 17:56:42 +0800162
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530163 uint8_t previousState = PLDM_SENSOR_UNKNOWN;
164
165 // if sensor cache is empty, then its the first
166 // get_state_sensor_reading on this sensor, set the previous state
167 // as the current state
168
169 if (sensorCacheforSensor.at(i) == PLDM_SENSOR_UNKNOWN)
170 {
171 previousState = sensorEvent;
172 handler.updateSensorCache(sensorId, i, previousState);
173 }
174 else
175 {
176 // sensor cache is not empty, so get the previous state from
177 // the sensor cache
178 previousState = sensorCacheforSensor[i];
179 }
George Liu916808c2021-01-19 17:56:42 +0800180 uint8_t opState = PLDM_SENSOR_ENABLED;
181 if (sensorEvent == PLDM_SENSOR_UNKNOWN)
182 {
183 opState = PLDM_SENSOR_UNAVAILABLE;
184 }
185
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530186 stateField.push_back(
187 {opState, PLDM_SENSOR_NORMAL, previousState, sensorEvent});
George Liu362c18d2020-05-14 09:46:36 +0800188 }
189 }
190 catch (const std::out_of_range& e)
191 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600192 error("the sensorId does not exist. sensor id: {SENSOR_ID} {ERR_EXCEP}",
193 "SENSOR_ID", sensorId, "ERR_EXCEP", e.what());
George Liu362c18d2020-05-14 09:46:36 +0800194 rc = PLDM_ERROR;
195 }
196
197 return rc;
198}
199
200} // namespace platform_state_sensor
201} // namespace responder
202} // namespace pldm