blob: d0276e543e4786b9deb7714db584ed7425982c55 [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(
Riya Dixit89644442024-03-31 05:39:59 -050057 "Failed to get state sensor event state from dbus interface '{PATH}', error - {ERROR}.",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050058 "PATH", dbusMapping.objectPath, "ERROR", e);
George Liu362c18d2020-05-14 09:46:36 +080059 }
60
George Liu916808c2021-01-19 17:56:42 +080061 return PLDM_SENSOR_UNKNOWN;
George Liu362c18d2020-05-14 09:46:36 +080062}
63
64/** @brief Function to get the state sensor readings requested by pldm requester
65 *
66 * @tparam[in] DBusInterface - DBus interface type
67 * @tparam[in] Handler - pldm::responder::platform::Handler
68 * @param[in] dBusIntf - The interface object of DBusInterface
69 * @param[in] handler - The interface object of
70 * pldm::responder::platform::Handler
71 * @param[in] sensorId - Sensor ID sent by the requester to act on
72 * @param[in] sensorRearmCnt - Each bit location in this field corresponds to a
73 * particular sensor within the state sensor
74 * @param[out] compSensorCnt - composite sensor count
75 * @param[out] stateField - The state field data for each of the states,
76 * equal to composite sensor count in number
77 * @return - Success or failure in setting the states. Returns failure in
Manojkiran Eda2576aec2024-06-17 12:05:17 +053078 * terms of PLDM completion codes if at least one state fails to be set
George Liu362c18d2020-05-14 09:46:36 +080079 */
80template <class DBusInterface, class Handler>
81int getStateSensorReadingsHandler(
82 const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId,
83 uint8_t sensorRearmCnt, uint8_t& compSensorCnt,
Manojkiran Edaae933cc2024-02-21 17:19:21 +053084 std::vector<get_sensor_state_field>& stateField,
85 const stateSensorCacheMaps& sensorCache)
George Liu362c18d2020-05-14 09:46:36 +080086{
87 using namespace pldm::responder::pdr;
88 using namespace pldm::utils;
89
90 pldm_state_sensor_pdr* pdr = nullptr;
91
92 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
93 pldm_pdr_init(), pldm_pdr_destroy);
Andrew Jefferyacb20292023-06-30 11:47:44 +093094 if (!stateSensorPdrRepo)
95 {
96 throw std::runtime_error(
97 "Failed to instantiate state sensor PDR repository");
98 }
Brad Bishop5079ac42021-08-19 18:35:06 -040099 pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get());
George Liu362c18d2020-05-14 09:46:36 +0800100 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
101 if (stateSensorPDRs.empty())
102 {
Riya Dixit89644442024-03-31 05:39:59 -0500103 error("Failed to get StateSensorPDR record.");
George Liu362c18d2020-05-14 09:46:36 +0800104 return PLDM_PLATFORM_INVALID_SENSOR_ID;
105 }
106
Brad Bishop5079ac42021-08-19 18:35:06 -0400107 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu362c18d2020-05-14 09:46:36 +0800108 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
109 while (pdrRecord)
110 {
111 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
112 assert(pdr != NULL);
113 if (pdr->sensor_id != sensorId)
114 {
115 pdr = nullptr;
116 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
117 continue;
118 }
119
120 compSensorCnt = pdr->composite_sensor_count;
121 if (sensorRearmCnt > compSensorCnt)
122 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600123 error(
Riya Dixit89644442024-03-31 05:39:59 -0500124 "The requester sent wrong sensor rearm count '{SENSOR_REARM_COUNT}' for the sensor ID '{SENSORID}'",
125 "SENSORID", sensorId, "SENSOR_REARM_COUNT", sensorRearmCnt);
George Liu362c18d2020-05-14 09:46:36 +0800126 return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE;
127 }
George Liu916808c2021-01-19 17:56:42 +0800128
129 if (sensorRearmCnt == 0)
130 {
131 sensorRearmCnt = compSensorCnt;
132 stateField.resize(sensorRearmCnt);
133 }
134
George Liu362c18d2020-05-14 09:46:36 +0800135 break;
136 }
137
138 if (!pdr)
139 {
140 return PLDM_PLATFORM_INVALID_SENSOR_ID;
141 }
142
143 int rc = PLDM_SUCCESS;
144 try
145 {
Brad Bishop5079ac42021-08-19 18:35:06 -0400146 const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps(
147 sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
George Liu362c18d2020-05-14 09:46:36 +0800148
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530149 if (dbusMappings.empty() || dbusValMaps.empty())
150 {
Riya Dixit89644442024-03-31 05:39:59 -0500151 error("DbusMappings for sensor ID '{SENSOR_ID}' is missing",
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530152 "SENSOR_ID", sensorId);
153 return PLDM_ERROR;
154 }
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530155 pldm::responder::pdr_utils::EventStates sensorCacheforSensor{};
156 if (sensorCache.contains(sensorId))
157 {
158 sensorCacheforSensor = sensorCache.at(sensorId);
159 }
George Liu362c18d2020-05-14 09:46:36 +0800160 stateField.clear();
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530161 for (std::size_t offset{0};
162 offset < sensorRearmCnt && offset < dbusMappings.size() &&
163 offset < dbusValMaps.size();
164 offset++)
George Liu362c18d2020-05-14 09:46:36 +0800165 {
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530166 auto& dbusMapping = dbusMappings[offset];
George Liu362c18d2020-05-14 09:46:36 +0800167
George Liu916808c2021-01-19 17:56:42 +0800168 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>(
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530169 dBusIntf, dbusValMaps[offset], dbusMapping);
George Liu916808c2021-01-19 17:56:42 +0800170
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530171 uint8_t previousState = PLDM_SENSOR_UNKNOWN;
172
173 // if sensor cache is empty, then its the first
174 // get_state_sensor_reading on this sensor, set the previous state
175 // as the current state
176
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530177 if (sensorCacheforSensor.at(offset) == PLDM_SENSOR_UNKNOWN)
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530178 {
179 previousState = sensorEvent;
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530180 handler.updateSensorCache(sensorId, offset, previousState);
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530181 }
182 else
183 {
184 // sensor cache is not empty, so get the previous state from
185 // the sensor cache
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530186 previousState = sensorCacheforSensor[offset];
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530187 }
George Liu916808c2021-01-19 17:56:42 +0800188 uint8_t opState = PLDM_SENSOR_ENABLED;
189 if (sensorEvent == PLDM_SENSOR_UNKNOWN)
190 {
191 opState = PLDM_SENSOR_UNAVAILABLE;
192 }
193
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530194 stateField.push_back(
195 {opState, PLDM_SENSOR_NORMAL, previousState, sensorEvent});
George Liu362c18d2020-05-14 09:46:36 +0800196 }
197 }
198 catch (const std::out_of_range& e)
199 {
Riya Dixit89644442024-03-31 05:39:59 -0500200 error("The sensor ID '{SENSORID}' does not exist, error - {ERROR}",
201 "SENSORID", sensorId, "ERROR", e);
George Liu362c18d2020-05-14 09:46:36 +0800202 rc = PLDM_ERROR;
203 }
204
205 return rc;
206}
207
208} // namespace platform_state_sensor
209} // namespace responder
210} // namespace pldm