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