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