1a2870726SGeorge Liu #pragma once 2a2870726SGeorge Liu 3a2870726SGeorge Liu #include "libpldm/platform.h" 4a2870726SGeorge Liu 512afe110SSampa Misra #include "pdr.hpp" 612afe110SSampa Misra #include "pdr_utils.hpp" 76492f524SGeorge Liu 8a2870726SGeorge Liu namespace pldm 9a2870726SGeorge Liu { 10a2870726SGeorge Liu 11a2870726SGeorge Liu namespace responder 12a2870726SGeorge Liu { 13a2870726SGeorge Liu 14a2870726SGeorge Liu namespace pdr_state_effecter 15a2870726SGeorge Liu { 16a2870726SGeorge Liu 17a2870726SGeorge Liu using Json = nlohmann::json; 18a2870726SGeorge Liu 19a2870726SGeorge Liu static const Json empty{}; 20a2870726SGeorge Liu 21a2870726SGeorge Liu /** @brief Parse PDR JSON file and generate state effecter PDR structure 22a2870726SGeorge Liu * 23a2870726SGeorge Liu * @param[in] json - the JSON Object with the state effecter PDR 24a2870726SGeorge Liu * @param[out] handler - the Parser of PLDM command handler 25a2870726SGeorge Liu * @param[out] repo - pdr::RepoInterface 26a2870726SGeorge Liu * 27a2870726SGeorge Liu */ 2836e81352SGeorge Liu template <class DBusInterface, class Handler> 2936e81352SGeorge Liu void generateStateEffecterPDR(const DBusInterface& dBusIntf, const Json& json, 3036e81352SGeorge Liu Handler& handler, pdr_utils::RepoInterface& repo) 31a2870726SGeorge Liu { 32a2870726SGeorge Liu static const std::vector<Json> emptyList{}; 33a2870726SGeorge Liu auto entries = json.value("entries", emptyList); 34a2870726SGeorge Liu for (const auto& e : entries) 35a2870726SGeorge Liu { 36a2870726SGeorge Liu size_t pdrSize = 0; 37a2870726SGeorge Liu auto effecters = e.value("effecters", emptyList); 38a2870726SGeorge Liu for (const auto& effecter : effecters) 39a2870726SGeorge Liu { 40a2870726SGeorge Liu auto set = effecter.value("set", empty); 41a2870726SGeorge Liu auto statesSize = set.value("size", 0); 42a2870726SGeorge Liu if (!statesSize) 43a2870726SGeorge Liu { 44a2870726SGeorge Liu std::cerr << "Malformed PDR JSON return " 45a2870726SGeorge Liu "pdrEntry;- no state set " 46a2870726SGeorge Liu "info, TYPE=" 47a2870726SGeorge Liu << PLDM_STATE_EFFECTER_PDR << "\n"; 48a2870726SGeorge Liu throw InternalFailure(); 49a2870726SGeorge Liu } 50a2870726SGeorge Liu pdrSize += sizeof(state_effecter_possible_states) - 51a2870726SGeorge Liu sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize); 52a2870726SGeorge Liu } 53a2870726SGeorge Liu pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t); 54a2870726SGeorge Liu 55a2870726SGeorge Liu std::vector<uint8_t> entry{}; 56a2870726SGeorge Liu entry.resize(pdrSize); 57a2870726SGeorge Liu 58a2870726SGeorge Liu pldm_state_effecter_pdr* pdr = 59a2870726SGeorge Liu reinterpret_cast<pldm_state_effecter_pdr*>(entry.data()); 60a2870726SGeorge Liu pdr->hdr.record_handle = 0; 61a2870726SGeorge Liu pdr->hdr.version = 1; 62a2870726SGeorge Liu pdr->hdr.type = PLDM_STATE_EFFECTER_PDR; 63a2870726SGeorge Liu pdr->hdr.record_change_num = 0; 64a2870726SGeorge Liu pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr); 65a2870726SGeorge Liu 6612afe110SSampa Misra pdr->terminus_handle = pdr::BmcPldmTerminusHandle; 67a2870726SGeorge Liu pdr->effecter_id = handler.getNextEffecterId(); 68a2870726SGeorge Liu pdr->entity_type = e.value("type", 0); 69a2870726SGeorge Liu pdr->entity_instance = e.value("instance", 0); 70a2870726SGeorge Liu pdr->container_id = e.value("container", 0); 71a2870726SGeorge Liu pdr->effecter_semantic_id = 0; 72a2870726SGeorge Liu pdr->effecter_init = PLDM_NO_INIT; 73a2870726SGeorge Liu pdr->has_description_pdr = false; 74a2870726SGeorge Liu pdr->composite_effecter_count = effecters.size(); 75a2870726SGeorge Liu 76a2870726SGeorge Liu DbusMappings dbusMappings{}; 77a2870726SGeorge Liu DbusValMaps dbusValMaps{}; 78a2870726SGeorge Liu uint8_t* start = 79a2870726SGeorge Liu entry.data() + sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t); 80a2870726SGeorge Liu for (const auto& effecter : effecters) 81a2870726SGeorge Liu { 82a2870726SGeorge Liu auto set = effecter.value("set", empty); 83a2870726SGeorge Liu state_effecter_possible_states* possibleStates = 84a2870726SGeorge Liu reinterpret_cast<state_effecter_possible_states*>(start); 85a2870726SGeorge Liu possibleStates->state_set_id = set.value("id", 0); 86a2870726SGeorge Liu possibleStates->possible_states_size = set.value("size", 0); 87a2870726SGeorge Liu 88a2870726SGeorge Liu start += sizeof(possibleStates->state_set_id) + 89a2870726SGeorge Liu sizeof(possibleStates->possible_states_size); 90a2870726SGeorge Liu static const std::vector<uint8_t> emptyStates{}; 91a2870726SGeorge Liu PossibleValues stateValues; 92a2870726SGeorge Liu auto states = set.value("states", emptyStates); 93a2870726SGeorge Liu for (const auto& state : states) 94a2870726SGeorge Liu { 95a2870726SGeorge Liu auto index = state / 8; 96a2870726SGeorge Liu auto bit = state - (index * 8); 97a2870726SGeorge Liu bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index); 98a2870726SGeorge Liu bf->byte |= 1 << bit; 99*adbe1726SGeorge Liu stateValues.emplace_back(state); 100a2870726SGeorge Liu } 101a2870726SGeorge Liu start += possibleStates->possible_states_size; 102a2870726SGeorge Liu 103a2870726SGeorge Liu auto dbusEntry = effecter.value("dbus", empty); 104a2870726SGeorge Liu auto objectPath = dbusEntry.value("path", ""); 105a2870726SGeorge Liu auto interface = dbusEntry.value("interface", ""); 106a2870726SGeorge Liu auto propertyName = dbusEntry.value("property_name", ""); 107a2870726SGeorge Liu auto propertyType = dbusEntry.value("property_type", ""); 10836e81352SGeorge Liu 10936e81352SGeorge Liu try 11036e81352SGeorge Liu { 11136e81352SGeorge Liu auto service = 11236e81352SGeorge Liu dBusIntf.getService(objectPath.c_str(), interface.c_str()); 11336e81352SGeorge Liu } 11436e81352SGeorge Liu catch (const std::exception& e) 11536e81352SGeorge Liu { 11636e81352SGeorge Liu continue; 11736e81352SGeorge Liu } 11836e81352SGeorge Liu 119a2870726SGeorge Liu pldm::utils::DBusMapping dbusMapping{objectPath, interface, 120a2870726SGeorge Liu propertyName, propertyType}; 121a2870726SGeorge Liu dbusMappings.emplace_back(std::move(dbusMapping)); 122a2870726SGeorge Liu 123a2870726SGeorge Liu Json propValues = dbusEntry["property_values"]; 124a2870726SGeorge Liu StatestoDbusVal dbusIdToValMap = 125a2870726SGeorge Liu populateMapping(propertyType, propValues, stateValues); 126a2870726SGeorge Liu if (!dbusIdToValMap.empty()) 127a2870726SGeorge Liu { 128a2870726SGeorge Liu dbusValMaps.emplace_back(std::move(dbusIdToValMap)); 129a2870726SGeorge Liu } 130a2870726SGeorge Liu } 131a2870726SGeorge Liu handler.addDbusObjMaps( 132a2870726SGeorge Liu pdr->effecter_id, 133a2870726SGeorge Liu std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps))); 134a2870726SGeorge Liu PdrEntry pdrEntry{}; 135a2870726SGeorge Liu pdrEntry.data = entry.data(); 136a2870726SGeorge Liu pdrEntry.size = pdrSize; 137a2870726SGeorge Liu repo.addRecord(pdrEntry); 138a2870726SGeorge Liu } 139a2870726SGeorge Liu } 140a2870726SGeorge Liu 141a2870726SGeorge Liu } // namespace pdr_state_effecter 142a2870726SGeorge Liu } // namespace responder 143a2870726SGeorge Liu } // namespace pldm 144