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 using namespace pldm::responder::pdr; 17 18 namespace pldm 19 { 20 namespace responder 21 { 22 namespace 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 */ 34 template <class DBusInterface> 35 uint8_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 59 return PLDM_SENSOR_UNKNOWN; 60 } 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 */ 78 template <class DBusInterface, class Handler> 79 int 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 } 120 121 if (sensorRearmCnt == 0) 122 { 123 sensorRearmCnt = compSensorCnt; 124 stateField.resize(sensorRearmCnt); 125 } 126 127 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(); 142 for (size_t i = 0; i < sensorRearmCnt; i++) 143 { 144 auto& dbusMapping = dbusMappings[i]; 145 146 uint8_t sensorEvent = getStateSensorEventState<DBusInterface>( 147 dBusIntf, dbusValMaps[i], dbusMapping); 148 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}); 157 } 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 172