1 #include "pdr.hpp" 2 3 #include <libpldm/platform.h> 4 5 #include <phosphor-logging/lg2.hpp> 6 7 #include <climits> 8 9 PHOSPHOR_LOG2_USING; 10 11 using namespace pldm::pdr; 12 13 namespace pldm 14 { 15 namespace responder 16 { 17 namespace pdr_utils 18 { 19 pldm_pdr* Repo::getPdr() const 20 { 21 return repo; 22 } 23 24 RecordHandle Repo::addRecord(const PdrEntry& pdrEntry) 25 { 26 uint32_t handle = pdrEntry.handle.recordHandle; 27 int rc = pldm_pdr_add_check(repo, pdrEntry.data, pdrEntry.size, false, 28 TERMINUS_HANDLE, &handle); 29 if (rc) 30 { 31 // pldm_pdr_add() assert()ed on failure to add PDR 32 throw std::runtime_error("Failed to add PDR"); 33 } 34 return handle; 35 } 36 37 const pldm_pdr_record* Repo::getFirstRecord(PdrEntry& pdrEntry) 38 { 39 constexpr uint32_t firstNum = 0; 40 uint8_t* pdrData = nullptr; 41 auto record = pldm_pdr_find_record(getPdr(), firstNum, &pdrData, 42 &pdrEntry.size, 43 &pdrEntry.handle.nextRecordHandle); 44 if (record) 45 { 46 pdrEntry.data = pdrData; 47 } 48 49 return record; 50 } 51 52 const pldm_pdr_record* Repo::getNextRecord(const pldm_pdr_record* currRecord, 53 PdrEntry& pdrEntry) 54 { 55 uint8_t* pdrData = nullptr; 56 auto record = pldm_pdr_get_next_record(getPdr(), currRecord, &pdrData, 57 &pdrEntry.size, 58 &pdrEntry.handle.nextRecordHandle); 59 if (record) 60 { 61 pdrEntry.data = pdrData; 62 } 63 64 return record; 65 } 66 67 uint32_t Repo::getRecordHandle(const pldm_pdr_record* record) const 68 { 69 return pldm_pdr_get_record_handle(getPdr(), record); 70 } 71 72 uint32_t Repo::getRecordCount() 73 { 74 return pldm_pdr_get_record_count(getPdr()); 75 } 76 77 bool Repo::empty() 78 { 79 return !getRecordCount(); 80 } 81 82 StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues, 83 const PossibleValues& pv) 84 { 85 size_t pos = 0; 86 pldm::utils::PropertyValue value; 87 StatestoDbusVal valueMap; 88 if (dBusValues.size() != pv.size()) 89 { 90 error( 91 "dBusValues size is not equal to pv size, dBusValues Size: {DBUS_VAL_SIZE}, pv Size: {PV_SIZE}", 92 "DBUS_VAL_SIZE", dBusValues.size(), "PV_SIZE", pv.size()); 93 return {}; 94 } 95 96 for (auto it = dBusValues.begin(); it != dBusValues.end(); ++it, ++pos) 97 { 98 if (type == "uint8_t") 99 { 100 value = static_cast<uint8_t>(it.value()); 101 } 102 else if (type == "uint16_t") 103 { 104 value = static_cast<uint16_t>(it.value()); 105 } 106 else if (type == "uint32_t") 107 { 108 value = static_cast<uint32_t>(it.value()); 109 } 110 else if (type == "uint64_t") 111 { 112 value = static_cast<uint64_t>(it.value()); 113 } 114 else if (type == "int16_t") 115 { 116 value = static_cast<int16_t>(it.value()); 117 } 118 else if (type == "int32_t") 119 { 120 value = static_cast<int32_t>(it.value()); 121 } 122 else if (type == "int64_t") 123 { 124 value = static_cast<int64_t>(it.value()); 125 } 126 else if (type == "bool") 127 { 128 value = static_cast<bool>(it.value()); 129 } 130 else if (type == "double") 131 { 132 value = static_cast<double>(it.value()); 133 } 134 else if (type == "string") 135 { 136 value = static_cast<std::string>(it.value()); 137 } 138 else 139 { 140 error("Unknown D-Bus property type, TYPE={OTHER_TYPE}", 141 "OTHER_TYPE", type.c_str()); 142 return {}; 143 } 144 145 valueMap.emplace(pv[pos], value); 146 } 147 148 return valueMap; 149 } 150 151 std::tuple<TerminusHandle, SensorID, SensorInfo> 152 parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr) 153 { 154 auto pdr = 155 reinterpret_cast<const pldm_state_sensor_pdr*>(stateSensorPdr.data()); 156 CompositeSensorStates sensors{}; 157 auto statesPtr = pdr->possible_states; 158 auto compositeSensorCount = pdr->composite_sensor_count; 159 160 while (compositeSensorCount--) 161 { 162 auto state = 163 reinterpret_cast<const state_sensor_possible_states*>(statesPtr); 164 PossibleStates possibleStates{}; 165 uint8_t possibleStatesPos{}; 166 auto updateStates = 167 [&possibleStates, &possibleStatesPos](const bitfield8_t& val) { 168 for (int i = 0; i < CHAR_BIT; i++) 169 { 170 if (val.byte & (1 << i)) 171 { 172 possibleStates.insert(possibleStatesPos * CHAR_BIT + i); 173 } 174 } 175 possibleStatesPos++; 176 }; 177 std::for_each(&state->states[0], 178 &state->states[state->possible_states_size], 179 updateStates); 180 181 sensors.emplace_back(std::move(possibleStates)); 182 if (compositeSensorCount) 183 { 184 statesPtr += sizeof(state_sensor_possible_states) + 185 state->possible_states_size - 1; 186 } 187 } 188 189 auto entityInfo = 190 std::make_tuple(static_cast<ContainerID>(pdr->container_id), 191 static_cast<EntityType>(pdr->entity_type), 192 static_cast<EntityInstance>(pdr->entity_instance)); 193 auto sensorInfo = std::make_tuple(std::move(entityInfo), 194 std::move(sensors)); 195 return std::make_tuple(pdr->terminus_handle, pdr->sensor_id, 196 std::move(sensorInfo)); 197 } 198 199 } // namespace pdr_utils 200 } // namespace responder 201 } // namespace pldm 202