blob: 48a750a75a3aceccf216899ed0a2e988e55f3ff4 [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
16using namespace pldm::responder::pdr;
17
18namespace pldm
19{
20namespace responder
21{
22namespace platform_state_sensor
23{
24
25/** @brief Function to get the sensor state
26 *
27 * @tparam[in] DBusInterface - DBus interface type
28 * @param[in] dBusIntf - The interface object of DBusInterface
29 * @param[in] stateToDbusValue - Map of DBus property State to attribute value
30 * @param[in] dbusMapping - The d-bus object
31 *
32 * @return - Enumeration of SensorState
33 */
34template <class DBusInterface>
35uint8_t getStateSensorEventState(
36 const DBusInterface& dBusIntf,
37 const std::map<State, pldm::utils::PropertyValue>& stateToDbusValue,
38 const DBusMapping& dbusMapping)
39{
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 {
56 std::cerr << e.what() << '\n';
57 }
58
George Liu916808c2021-01-19 17:56:42 +080059 return PLDM_SENSOR_UNKNOWN;
George Liu362c18d2020-05-14 09:46:36 +080060}
61
62/** @brief Function to get the state sensor readings requested by pldm requester
63 *
64 * @tparam[in] DBusInterface - DBus interface type
65 * @tparam[in] Handler - pldm::responder::platform::Handler
66 * @param[in] dBusIntf - The interface object of DBusInterface
67 * @param[in] handler - The interface object of
68 * pldm::responder::platform::Handler
69 * @param[in] sensorId - Sensor ID sent by the requester to act on
70 * @param[in] sensorRearmCnt - Each bit location in this field corresponds to a
71 * particular sensor within the state sensor
72 * @param[out] compSensorCnt - composite sensor count
73 * @param[out] stateField - The state field data for each of the states,
74 * equal to composite sensor count in number
75 * @return - Success or failure in setting the states. Returns failure in
76 * terms of PLDM completion codes if atleast one state fails to be set
77 */
78template <class DBusInterface, class Handler>
79int getStateSensorReadingsHandler(
80 const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId,
81 uint8_t sensorRearmCnt, uint8_t& compSensorCnt,
82 std::vector<get_sensor_state_field>& stateField)
83{
84 using namespace pldm::responder::pdr;
85 using namespace pldm::utils;
86
87 pldm_state_sensor_pdr* pdr = nullptr;
88
89 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
90 pldm_pdr_init(), pldm_pdr_destroy);
91 Repo stateSensorPDRs(stateSensorPdrRepo.get());
92 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
93 if (stateSensorPDRs.empty())
94 {
95 std::cerr << "Failed to get record by PDR type\n";
96 return PLDM_PLATFORM_INVALID_SENSOR_ID;
97 }
98
99 PdrEntry pdrEntry{};
100 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
101 while (pdrRecord)
102 {
103 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
104 assert(pdr != NULL);
105 if (pdr->sensor_id != sensorId)
106 {
107 pdr = nullptr;
108 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
109 continue;
110 }
111
112 compSensorCnt = pdr->composite_sensor_count;
113 if (sensorRearmCnt > compSensorCnt)
114 {
115 std::cerr << "The requester sent wrong sensorRearm"
116 << " count for the sensor, SENSOR_ID=" << sensorId
117 << "SENSOR_REARM_COUNT=" << sensorRearmCnt << "\n";
118 return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE;
119 }
George Liu916808c2021-01-19 17:56:42 +0800120
121 if (sensorRearmCnt == 0)
122 {
123 sensorRearmCnt = compSensorCnt;
124 stateField.resize(sensorRearmCnt);
125 }
126
George Liu362c18d2020-05-14 09:46:36 +0800127 break;
128 }
129
130 if (!pdr)
131 {
132 return PLDM_PLATFORM_INVALID_SENSOR_ID;
133 }
134
135 int rc = PLDM_SUCCESS;
136 try
137 {
138 const auto& [dbusMappings, dbusValMaps] =
139 handler.getDbusObjMaps(sensorId, TypeId::PLDM_SENSOR_ID);
140
141 stateField.clear();
George Liu916808c2021-01-19 17:56:42 +0800142 for (size_t i = 0; i < sensorRearmCnt; i++)
George Liu362c18d2020-05-14 09:46:36 +0800143 {
144 auto& dbusMapping = dbusMappings[i];
145
George Liu916808c2021-01-19 17:56:42 +0800146 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>(
George Liu362c18d2020-05-14 09:46:36 +0800147 dBusIntf, dbusValMaps[i], dbusMapping);
George Liu916808c2021-01-19 17:56:42 +0800148
149 uint8_t opState = PLDM_SENSOR_ENABLED;
150 if (sensorEvent == PLDM_SENSOR_UNKNOWN)
151 {
152 opState = PLDM_SENSOR_UNAVAILABLE;
153 }
154
155 stateField.push_back({opState, PLDM_SENSOR_NORMAL,
156 PLDM_SENSOR_UNKNOWN, sensorEvent});
George Liu362c18d2020-05-14 09:46:36 +0800157 }
158 }
159 catch (const std::out_of_range& e)
160 {
161 std::cerr << "the sensorId does not exist. sensor id: " << sensorId
162 << e.what() << '\n';
163 rc = PLDM_ERROR;
164 }
165
166 return rc;
167}
168
169} // namespace platform_state_sensor
170} // namespace responder
171} // namespace pldm