1 #pragma once 2 3 #include "common/utils.hpp" 4 #include "libpldmresponder/pdr.hpp" 5 #include "pdr_utils.hpp" 6 #include "pldmd/handler.hpp" 7 8 #include <libpldm/platform.h> 9 #include <libpldm/states.h> 10 11 #include <phosphor-logging/lg2.hpp> 12 13 #include <cstdint> 14 #include <map> 15 16 PHOSPHOR_LOG2_USING; 17 18 namespace pldm 19 { 20 namespace responder 21 { 22 namespace platform_state_sensor 23 { 24 /** @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 */ 33 template <class DBusInterface> 34 uint8_t getStateSensorEventState( 35 const DBusInterface& dBusIntf, 36 const std::map<pldm::responder::pdr_utils::State, 37 pldm::utils::PropertyValue>& stateToDbusValue, 38 const pldm::utils::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 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()); 60 } 61 62 return PLDM_SENSOR_UNKNOWN; 63 } 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 */ 81 template <class DBusInterface, class Handler> 82 int getStateSensorReadingsHandler( 83 const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId, 84 uint8_t sensorRearmCnt, uint8_t& compSensorCnt, 85 std::vector<get_sensor_state_field>& stateField) 86 { 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); 94 if (!stateSensorPdrRepo) 95 { 96 throw std::runtime_error( 97 "Failed to instantiate state sensor PDR repository"); 98 } 99 pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get()); 100 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR); 101 if (stateSensorPDRs.empty()) 102 { 103 error("Failed to get record by PDR type"); 104 return PLDM_PLATFORM_INVALID_SENSOR_ID; 105 } 106 107 pldm::responder::pdr_utils::PdrEntry pdrEntry{}; 108 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 { 123 error( 124 "The requester sent wrong sensorRearm count for the sensor, SENSOR_ID={SENSOR_ID} SENSOR_REARM_COUNT={SENSOR_REARM_CNT}", 125 "SENSOR_ID", sensorId, "SENSOR_REARM_CNT", sensorRearmCnt); 126 return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE; 127 } 128 129 if (sensorRearmCnt == 0) 130 { 131 sensorRearmCnt = compSensorCnt; 132 stateField.resize(sensorRearmCnt); 133 } 134 135 break; 136 } 137 138 if (!pdr) 139 { 140 return PLDM_PLATFORM_INVALID_SENSOR_ID; 141 } 142 143 int rc = PLDM_SUCCESS; 144 try 145 { 146 const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps( 147 sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID); 148 149 stateField.clear(); 150 for (size_t i = 0; i < sensorRearmCnt; i++) 151 { 152 auto& dbusMapping = dbusMappings[i]; 153 154 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>( 155 dBusIntf, dbusValMaps[i], dbusMapping); 156 157 uint8_t opState = PLDM_SENSOR_ENABLED; 158 if (sensorEvent == PLDM_SENSOR_UNKNOWN) 159 { 160 opState = PLDM_SENSOR_UNAVAILABLE; 161 } 162 163 stateField.push_back({opState, PLDM_SENSOR_NORMAL, 164 PLDM_SENSOR_UNKNOWN, sensorEvent}); 165 } 166 } 167 catch (const std::out_of_range& e) 168 { 169 error("the sensorId does not exist. sensor id: {SENSOR_ID} {ERR_EXCEP}", 170 "SENSOR_ID", sensorId, "ERR_EXCEP", e.what()); 171 rc = PLDM_ERROR; 172 } 173 174 return rc; 175 } 176 177 } // namespace platform_state_sensor 178 } // namespace responder 179 } // namespace pldm 180