1a2870726SGeorge Liu #pragma once 2a2870726SGeorge Liu 312afe110SSampa Misra #include "pdr.hpp" 412afe110SSampa Misra #include "pdr_utils.hpp" 56492f524SGeorge Liu 6c453e164SGeorge Liu #include <libpldm/platform.h> 7cc5f1586SManojkiran Eda 849cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp> 949cfb138SRiya Dixit 1049cfb138SRiya Dixit PHOSPHOR_LOG2_USING; 1149cfb138SRiya Dixit 12a2870726SGeorge Liu namespace pldm 13a2870726SGeorge Liu { 14a2870726SGeorge Liu namespace responder 15a2870726SGeorge Liu { 16a2870726SGeorge Liu namespace pdr_state_effecter 17a2870726SGeorge Liu { 18a2870726SGeorge Liu using Json = nlohmann::json; 19a2870726SGeorge Liu 20a2870726SGeorge Liu static const Json empty{}; 21a2870726SGeorge Liu 22a2870726SGeorge Liu /** @brief Parse PDR JSON file and generate state effecter PDR structure 23a2870726SGeorge Liu * 24a2870726SGeorge Liu * @param[in] json - the JSON Object with the state effecter PDR 25a2870726SGeorge Liu * @param[out] handler - the Parser of PLDM command handler 26a2870726SGeorge Liu * @param[out] repo - pdr::RepoInterface 27a2870726SGeorge Liu * 28a2870726SGeorge Liu */ 2936e81352SGeorge Liu template <class DBusInterface, class Handler> 3036e81352SGeorge Liu void generateStateEffecterPDR(const DBusInterface& dBusIntf, const Json& json, 3136e81352SGeorge Liu Handler& handler, pdr_utils::RepoInterface& repo) 32a2870726SGeorge Liu { 33a2870726SGeorge Liu static const std::vector<Json> emptyList{}; 34a2870726SGeorge Liu auto entries = json.value("entries", emptyList); 35a2870726SGeorge Liu for (const auto& e : entries) 36a2870726SGeorge Liu { 37a2870726SGeorge Liu size_t pdrSize = 0; 38a2870726SGeorge Liu auto effecters = e.value("effecters", emptyList); 39a2870726SGeorge Liu for (const auto& effecter : effecters) 40a2870726SGeorge Liu { 41a2870726SGeorge Liu auto set = effecter.value("set", empty); 42a2870726SGeorge Liu auto statesSize = set.value("size", 0); 43a2870726SGeorge Liu if (!statesSize) 44a2870726SGeorge Liu { 4549cfb138SRiya Dixit error( 4649cfb138SRiya Dixit "Malformed PDR JSON return pdrEntry;- no state set info, TYPE={STATE_EFFECTER_PDR}", 4749cfb138SRiya Dixit "STATE_EFFECTER_PDR", 4849cfb138SRiya Dixit static_cast<unsigned>(PLDM_STATE_EFFECTER_PDR)); 49a2870726SGeorge Liu throw InternalFailure(); 50a2870726SGeorge Liu } 51a2870726SGeorge Liu pdrSize += sizeof(state_effecter_possible_states) - 52a2870726SGeorge Liu sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize); 53a2870726SGeorge Liu } 54a2870726SGeorge Liu pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t); 55a2870726SGeorge Liu 56a2870726SGeorge Liu std::vector<uint8_t> entry{}; 57a2870726SGeorge Liu entry.resize(pdrSize); 58a2870726SGeorge Liu 59a2870726SGeorge Liu pldm_state_effecter_pdr* pdr = 60a2870726SGeorge Liu reinterpret_cast<pldm_state_effecter_pdr*>(entry.data()); 61bcf91accSManojkiran Eda if (!pdr) 62bcf91accSManojkiran Eda { 6349cfb138SRiya Dixit error("Failed to get state effecter PDR."); 64bcf91accSManojkiran Eda continue; 65bcf91accSManojkiran Eda } 66a2870726SGeorge Liu pdr->hdr.record_handle = 0; 67a2870726SGeorge Liu pdr->hdr.version = 1; 68a2870726SGeorge Liu pdr->hdr.type = PLDM_STATE_EFFECTER_PDR; 69a2870726SGeorge Liu pdr->hdr.record_change_num = 0; 70a2870726SGeorge Liu pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr); 71a2870726SGeorge Liu 72cc5f1586SManojkiran Eda pdr->terminus_handle = TERMINUS_HANDLE; 73c4ea6a90SGeorge Liu 74c4ea6a90SGeorge Liu try 75c4ea6a90SGeorge Liu { 76c4ea6a90SGeorge Liu std::string entity_path = e.value("entity_path", ""); 77c4ea6a90SGeorge Liu auto& associatedEntityMap = handler.getAssociateEntityMap(); 7806f9b29eSSagar Srinivas if (entity_path != "" && associatedEntityMap.contains(entity_path)) 79c4ea6a90SGeorge Liu { 80c4ea6a90SGeorge Liu pdr->entity_type = 81c4ea6a90SGeorge Liu associatedEntityMap.at(entity_path).entity_type; 82c4ea6a90SGeorge Liu pdr->entity_instance = 83c4ea6a90SGeorge Liu associatedEntityMap.at(entity_path).entity_instance_num; 84c4ea6a90SGeorge Liu pdr->container_id = 85c4ea6a90SGeorge Liu associatedEntityMap.at(entity_path).entity_container_id; 86c4ea6a90SGeorge Liu } 87c4ea6a90SGeorge Liu else 88c4ea6a90SGeorge Liu { 89a2870726SGeorge Liu pdr->entity_type = e.value("type", 0); 90a2870726SGeorge Liu pdr->entity_instance = e.value("instance", 0); 91a2870726SGeorge Liu pdr->container_id = e.value("container", 0); 925f213471SPavithra Barithaya 935f213471SPavithra Barithaya // do not create the PDR when the FRU or the entity path is not 945f213471SPavithra Barithaya // present 955f213471SPavithra Barithaya if (!pdr->entity_type) 965f213471SPavithra Barithaya { 975f213471SPavithra Barithaya continue; 985f213471SPavithra Barithaya } 99c4ea6a90SGeorge Liu } 100c4ea6a90SGeorge Liu } 10158cbcaf2SKamalkumar Patel catch (const std::exception&) 102c4ea6a90SGeorge Liu { 103c4ea6a90SGeorge Liu pdr->entity_type = e.value("type", 0); 104c4ea6a90SGeorge Liu pdr->entity_instance = e.value("instance", 0); 105c4ea6a90SGeorge Liu pdr->container_id = e.value("container", 0); 106c4ea6a90SGeorge Liu } 107c4ea6a90SGeorge Liu 108a2870726SGeorge Liu pdr->effecter_semantic_id = 0; 109a2870726SGeorge Liu pdr->effecter_init = PLDM_NO_INIT; 110a2870726SGeorge Liu pdr->has_description_pdr = false; 111a2870726SGeorge Liu pdr->composite_effecter_count = effecters.size(); 112a2870726SGeorge Liu 1135079ac4aSBrad Bishop pldm::responder::pdr_utils::DbusMappings dbusMappings{}; 1145079ac4aSBrad Bishop pldm::responder::pdr_utils::DbusValMaps dbusValMaps{}; 1156da4f91bSPatrick Williams uint8_t* start = entry.data() + sizeof(pldm_state_effecter_pdr) - 1166da4f91bSPatrick Williams sizeof(uint8_t); 117a2870726SGeorge Liu for (const auto& effecter : effecters) 118a2870726SGeorge Liu { 119a2870726SGeorge Liu auto set = effecter.value("set", empty); 120a2870726SGeorge Liu state_effecter_possible_states* possibleStates = 121a2870726SGeorge Liu reinterpret_cast<state_effecter_possible_states*>(start); 122a2870726SGeorge Liu possibleStates->state_set_id = set.value("id", 0); 123a2870726SGeorge Liu possibleStates->possible_states_size = set.value("size", 0); 124a2870726SGeorge Liu 125a2870726SGeorge Liu start += sizeof(possibleStates->state_set_id) + 126a2870726SGeorge Liu sizeof(possibleStates->possible_states_size); 127a2870726SGeorge Liu static const std::vector<uint8_t> emptyStates{}; 1285079ac4aSBrad Bishop pldm::responder::pdr_utils::PossibleValues stateValues; 129a2870726SGeorge Liu auto states = set.value("states", emptyStates); 130a2870726SGeorge Liu for (const auto& state : states) 131a2870726SGeorge Liu { 132a2870726SGeorge Liu auto index = state / 8; 133a2870726SGeorge Liu auto bit = state - (index * 8); 134a2870726SGeorge Liu bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index); 135a2870726SGeorge Liu bf->byte |= 1 << bit; 136adbe1726SGeorge Liu stateValues.emplace_back(state); 137a2870726SGeorge Liu } 138a2870726SGeorge Liu start += possibleStates->possible_states_size; 139a2870726SGeorge Liu 140a2870726SGeorge Liu auto dbusEntry = effecter.value("dbus", empty); 141a2870726SGeorge Liu auto objectPath = dbusEntry.value("path", ""); 142a2870726SGeorge Liu auto interface = dbusEntry.value("interface", ""); 143a2870726SGeorge Liu auto propertyName = dbusEntry.value("property_name", ""); 144a2870726SGeorge Liu auto propertyType = dbusEntry.value("property_type", ""); 14536e81352SGeorge Liu 1465079ac4aSBrad Bishop pldm::responder::pdr_utils::StatestoDbusVal dbusIdToValMap{}; 147821ebc47SGeorge Liu pldm::utils::DBusMapping dbusMapping{}; 14836e81352SGeorge Liu try 14936e81352SGeorge Liu { 1506da4f91bSPatrick Williams auto service = dBusIntf.getService(objectPath.c_str(), 1516da4f91bSPatrick Williams interface.c_str()); 152821ebc47SGeorge Liu 153821ebc47SGeorge Liu dbusMapping = pldm::utils::DBusMapping{ 154821ebc47SGeorge Liu objectPath, interface, propertyName, propertyType}; 1555079ac4aSBrad Bishop dbusIdToValMap = pldm::responder::pdr_utils::populateMapping( 156821ebc47SGeorge Liu propertyType, dbusEntry["property_values"], stateValues); 15736e81352SGeorge Liu } 15836e81352SGeorge Liu catch (const std::exception& e) 15936e81352SGeorge Liu { 16049cfb138SRiya Dixit error( 161c81d1129SManojkiran Eda "Failed to create effecter PDR, D-Bus object '{PATH}' returned {ERROR}", 162c81d1129SManojkiran Eda "PATH", objectPath, "ERROR", e); 163*3daf7a1cSManojkiran Eda break; 16436e81352SGeorge Liu } 165a2870726SGeorge Liu dbusMappings.emplace_back(std::move(dbusMapping)); 166a2870726SGeorge Liu dbusValMaps.emplace_back(std::move(dbusIdToValMap)); 167a2870726SGeorge Liu } 168*3daf7a1cSManojkiran Eda if (!(dbusMappings.empty() && dbusValMaps.empty())) 169*3daf7a1cSManojkiran Eda { 170*3daf7a1cSManojkiran Eda pdr->effecter_id = handler.getNextEffecterId(); 171*3daf7a1cSManojkiran Eda handler.addDbusObjMaps(pdr->effecter_id, 172*3daf7a1cSManojkiran Eda std::make_tuple(std::move(dbusMappings), 173*3daf7a1cSManojkiran Eda std::move(dbusValMaps))); 1745079ac4aSBrad Bishop pldm::responder::pdr_utils::PdrEntry pdrEntry{}; 175a2870726SGeorge Liu pdrEntry.data = entry.data(); 176a2870726SGeorge Liu pdrEntry.size = pdrSize; 177a2870726SGeorge Liu repo.addRecord(pdrEntry); 178a2870726SGeorge Liu } 179a2870726SGeorge Liu } 180*3daf7a1cSManojkiran Eda } 181a2870726SGeorge Liu 182a2870726SGeorge Liu } // namespace pdr_state_effecter 183a2870726SGeorge Liu } // namespace responder 184a2870726SGeorge Liu } // namespace pldm 185