blob: ce25ee9e3ec5c9d0135a5f3cbbe28bf0c9bd2016 [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 {
Manojkiran Edae7cd7ce2022-08-29 12:12:38 +053055 std::cerr << "Get StateSensor EventState from dbus Error, interface : "
56 << dbusMapping.objectPath.c_str()
57 << " ,exception : " << e.what() << '\n';
George Liu362c18d2020-05-14 09:46:36 +080058 }
59
George Liu916808c2021-01-19 17:56:42 +080060 return PLDM_SENSOR_UNKNOWN;
George Liu362c18d2020-05-14 09:46:36 +080061}
62
63/** @brief Function to get the state sensor readings requested by pldm requester
64 *
65 * @tparam[in] DBusInterface - DBus interface type
66 * @tparam[in] Handler - pldm::responder::platform::Handler
67 * @param[in] dBusIntf - The interface object of DBusInterface
68 * @param[in] handler - The interface object of
69 * pldm::responder::platform::Handler
70 * @param[in] sensorId - Sensor ID sent by the requester to act on
71 * @param[in] sensorRearmCnt - Each bit location in this field corresponds to a
72 * particular sensor within the state sensor
73 * @param[out] compSensorCnt - composite sensor count
74 * @param[out] stateField - The state field data for each of the states,
75 * equal to composite sensor count in number
76 * @return - Success or failure in setting the states. Returns failure in
77 * terms of PLDM completion codes if atleast one state fails to be set
78 */
79template <class DBusInterface, class Handler>
80int getStateSensorReadingsHandler(
81 const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId,
82 uint8_t sensorRearmCnt, uint8_t& compSensorCnt,
83 std::vector<get_sensor_state_field>& stateField)
84{
85 using namespace pldm::responder::pdr;
86 using namespace pldm::utils;
87
88 pldm_state_sensor_pdr* pdr = nullptr;
89
90 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
91 pldm_pdr_init(), pldm_pdr_destroy);
Brad Bishop5079ac42021-08-19 18:35:06 -040092 pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get());
George Liu362c18d2020-05-14 09:46:36 +080093 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
94 if (stateSensorPDRs.empty())
95 {
96 std::cerr << "Failed to get record by PDR type\n";
97 return PLDM_PLATFORM_INVALID_SENSOR_ID;
98 }
99
Brad Bishop5079ac42021-08-19 18:35:06 -0400100 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu362c18d2020-05-14 09:46:36 +0800101 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
102 while (pdrRecord)
103 {
104 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
105 assert(pdr != NULL);
106 if (pdr->sensor_id != sensorId)
107 {
108 pdr = nullptr;
109 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
110 continue;
111 }
112
113 compSensorCnt = pdr->composite_sensor_count;
114 if (sensorRearmCnt > compSensorCnt)
115 {
116 std::cerr << "The requester sent wrong sensorRearm"
117 << " count for the sensor, SENSOR_ID=" << sensorId
118 << "SENSOR_REARM_COUNT=" << sensorRearmCnt << "\n";
119 return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE;
120 }
George Liu916808c2021-01-19 17:56:42 +0800121
122 if (sensorRearmCnt == 0)
123 {
124 sensorRearmCnt = compSensorCnt;
125 stateField.resize(sensorRearmCnt);
126 }
127
George Liu362c18d2020-05-14 09:46:36 +0800128 break;
129 }
130
131 if (!pdr)
132 {
133 return PLDM_PLATFORM_INVALID_SENSOR_ID;
134 }
135
136 int rc = PLDM_SUCCESS;
137 try
138 {
Brad Bishop5079ac42021-08-19 18:35:06 -0400139 const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps(
140 sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
George Liu362c18d2020-05-14 09:46:36 +0800141
142 stateField.clear();
George Liu916808c2021-01-19 17:56:42 +0800143 for (size_t i = 0; i < sensorRearmCnt; i++)
George Liu362c18d2020-05-14 09:46:36 +0800144 {
145 auto& dbusMapping = dbusMappings[i];
146
George Liu916808c2021-01-19 17:56:42 +0800147 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>(
George Liu362c18d2020-05-14 09:46:36 +0800148 dBusIntf, dbusValMaps[i], dbusMapping);
George Liu916808c2021-01-19 17:56:42 +0800149
150 uint8_t opState = PLDM_SENSOR_ENABLED;
151 if (sensorEvent == PLDM_SENSOR_UNKNOWN)
152 {
153 opState = PLDM_SENSOR_UNAVAILABLE;
154 }
155
156 stateField.push_back({opState, PLDM_SENSOR_NORMAL,
157 PLDM_SENSOR_UNKNOWN, sensorEvent});
George Liu362c18d2020-05-14 09:46:36 +0800158 }
159 }
160 catch (const std::out_of_range& e)
161 {
162 std::cerr << "the sensorId does not exist. sensor id: " << sensorId
163 << e.what() << '\n';
164 rc = PLDM_ERROR;
165 }
166
167 return rc;
168}
169
170} // namespace platform_state_sensor
171} // namespace responder
172} // namespace pldm