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