1 #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 16 namespace pldm 17 { 18 namespace responder 19 { 20 namespace 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 */ 32 template <class DBusInterface> 33 uint8_t getStateSensorEventState( 34 const DBusInterface& dBusIntf, 35 const std::map<pldm::responder::pdr_utils::State, 36 pldm::utils::PropertyValue>& stateToDbusValue, 37 const pldm::utils::DBusMapping& dbusMapping) 38 { 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 << "Get StateSensor EventState from dbus Error, interface : " 56 << dbusMapping.objectPath.c_str() 57 << " ,exception : " << e.what() << '\n'; 58 } 59 60 return PLDM_SENSOR_UNKNOWN; 61 } 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 */ 79 template <class DBusInterface, class Handler> 80 int 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); 92 pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get()); 93 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 100 pldm::responder::pdr_utils::PdrEntry pdrEntry{}; 101 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 } 121 122 if (sensorRearmCnt == 0) 123 { 124 sensorRearmCnt = compSensorCnt; 125 stateField.resize(sensorRearmCnt); 126 } 127 128 break; 129 } 130 131 if (!pdr) 132 { 133 return PLDM_PLATFORM_INVALID_SENSOR_ID; 134 } 135 136 int rc = PLDM_SUCCESS; 137 try 138 { 139 const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps( 140 sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID); 141 142 stateField.clear(); 143 for (size_t i = 0; i < sensorRearmCnt; i++) 144 { 145 auto& dbusMapping = dbusMappings[i]; 146 147 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>( 148 dBusIntf, dbusValMaps[i], dbusMapping); 149 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}); 158 } 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 173