blob: 53477ff950ae66da8f804022ba2b52423289353e [file] [log] [blame]
George Liu362c18d2020-05-14 09:46:36 +08001#pragma once
2
3#include "config.h"
4
5#include "libpldm/platform.h"
6#include "libpldm/states.h"
7
8#include "common/utils.hpp"
9#include "libpldmresponder/pdr.hpp"
10#include "pdr_utils.hpp"
11#include "pldmd/handler.hpp"
12
13#include <cstdint>
14#include <map>
15
George Liu362c18d2020-05-14 09:46:36 +080016namespace pldm
17{
18namespace responder
19{
20namespace platform_state_sensor
21{
22
23/** @brief Function to get the sensor state
24 *
25 * @tparam[in] DBusInterface - DBus interface type
26 * @param[in] dBusIntf - The interface object of DBusInterface
27 * @param[in] stateToDbusValue - Map of DBus property State to attribute value
28 * @param[in] dbusMapping - The d-bus object
29 *
30 * @return - Enumeration of SensorState
31 */
32template <class DBusInterface>
33uint8_t getStateSensorEventState(
34 const DBusInterface& dBusIntf,
Brad Bishop5079ac42021-08-19 18:35:06 -040035 const std::map<pldm::responder::pdr_utils::State,
36 pldm::utils::PropertyValue>& stateToDbusValue,
37 const pldm::utils::DBusMapping& dbusMapping)
George Liu362c18d2020-05-14 09:46:36 +080038{
39 try
40 {
41 auto propertyValue = dBusIntf.getDbusPropertyVariant(
42 dbusMapping.objectPath.c_str(), dbusMapping.propertyName.c_str(),
43 dbusMapping.interface.c_str());
44
45 for (const auto& stateValue : stateToDbusValue)
46 {
47 if (stateValue.second == propertyValue)
48 {
49 return stateValue.first;
50 }
51 }
52 }
53 catch (const std::exception& e)
54 {
55 std::cerr << e.what() << '\n';
56 }
57
George Liu916808c2021-01-19 17:56:42 +080058 return PLDM_SENSOR_UNKNOWN;
George Liu362c18d2020-05-14 09:46:36 +080059}
60
61/** @brief Function to get the state sensor readings requested by pldm requester
62 *
63 * @tparam[in] DBusInterface - DBus interface type
64 * @tparam[in] Handler - pldm::responder::platform::Handler
65 * @param[in] dBusIntf - The interface object of DBusInterface
66 * @param[in] handler - The interface object of
67 * pldm::responder::platform::Handler
68 * @param[in] sensorId - Sensor ID sent by the requester to act on
69 * @param[in] sensorRearmCnt - Each bit location in this field corresponds to a
70 * particular sensor within the state sensor
71 * @param[out] compSensorCnt - composite sensor count
72 * @param[out] stateField - The state field data for each of the states,
73 * equal to composite sensor count in number
74 * @return - Success or failure in setting the states. Returns failure in
75 * terms of PLDM completion codes if atleast one state fails to be set
76 */
77template <class DBusInterface, class Handler>
78int getStateSensorReadingsHandler(
79 const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId,
80 uint8_t sensorRearmCnt, uint8_t& compSensorCnt,
81 std::vector<get_sensor_state_field>& stateField)
82{
83 using namespace pldm::responder::pdr;
84 using namespace pldm::utils;
85
86 pldm_state_sensor_pdr* pdr = nullptr;
87
88 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
89 pldm_pdr_init(), pldm_pdr_destroy);
Brad Bishop5079ac42021-08-19 18:35:06 -040090 pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get());
George Liu362c18d2020-05-14 09:46:36 +080091 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
92 if (stateSensorPDRs.empty())
93 {
94 std::cerr << "Failed to get record by PDR type\n";
95 return PLDM_PLATFORM_INVALID_SENSOR_ID;
96 }
97
Brad Bishop5079ac42021-08-19 18:35:06 -040098 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu362c18d2020-05-14 09:46:36 +080099 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
100 while (pdrRecord)
101 {
102 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
103 assert(pdr != NULL);
104 if (pdr->sensor_id != sensorId)
105 {
106 pdr = nullptr;
107 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
108 continue;
109 }
110
111 compSensorCnt = pdr->composite_sensor_count;
112 if (sensorRearmCnt > compSensorCnt)
113 {
114 std::cerr << "The requester sent wrong sensorRearm"
115 << " count for the sensor, SENSOR_ID=" << sensorId
116 << "SENSOR_REARM_COUNT=" << sensorRearmCnt << "\n";
117 return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE;
118 }
George Liu916808c2021-01-19 17:56:42 +0800119
120 if (sensorRearmCnt == 0)
121 {
122 sensorRearmCnt = compSensorCnt;
123 stateField.resize(sensorRearmCnt);
124 }
125
George Liu362c18d2020-05-14 09:46:36 +0800126 break;
127 }
128
129 if (!pdr)
130 {
131 return PLDM_PLATFORM_INVALID_SENSOR_ID;
132 }
133
134 int rc = PLDM_SUCCESS;
135 try
136 {
Brad Bishop5079ac42021-08-19 18:35:06 -0400137 const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps(
138 sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
George Liu362c18d2020-05-14 09:46:36 +0800139
140 stateField.clear();
George Liu916808c2021-01-19 17:56:42 +0800141 for (size_t i = 0; i < sensorRearmCnt; i++)
George Liu362c18d2020-05-14 09:46:36 +0800142 {
143 auto& dbusMapping = dbusMappings[i];
144
George Liu916808c2021-01-19 17:56:42 +0800145 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>(
George Liu362c18d2020-05-14 09:46:36 +0800146 dBusIntf, dbusValMaps[i], dbusMapping);
George Liu916808c2021-01-19 17:56:42 +0800147
148 uint8_t opState = PLDM_SENSOR_ENABLED;
149 if (sensorEvent == PLDM_SENSOR_UNKNOWN)
150 {
151 opState = PLDM_SENSOR_UNAVAILABLE;
152 }
153
154 stateField.push_back({opState, PLDM_SENSOR_NORMAL,
155 PLDM_SENSOR_UNKNOWN, sensorEvent});
George Liu362c18d2020-05-14 09:46:36 +0800156 }
157 }
158 catch (const std::out_of_range& e)
159 {
160 std::cerr << "the sensorId does not exist. sensor id: " << sensorId
161 << e.what() << '\n';
162 rc = PLDM_ERROR;
163 }
164
165 return rc;
166}
167
168} // namespace platform_state_sensor
169} // namespace responder
170} // namespace pldm