| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 1 | #pragma once | 
|  | 2 |  | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 3 | #include "libpldm/platform.h" | 
|  | 4 |  | 
| Sampa Misra | 12afe11 | 2020-05-25 11:40:44 -0500 | [diff] [blame] | 5 | #include "pdr.hpp" | 
|  | 6 | #include "pdr_utils.hpp" | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 7 |  | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 8 | namespace pldm | 
|  | 9 | { | 
|  | 10 |  | 
|  | 11 | namespace responder | 
|  | 12 | { | 
|  | 13 |  | 
|  | 14 | namespace pdr_state_effecter | 
|  | 15 | { | 
|  | 16 |  | 
|  | 17 | using Json = nlohmann::json; | 
|  | 18 |  | 
|  | 19 | static const Json empty{}; | 
|  | 20 |  | 
|  | 21 | /** @brief Parse PDR JSON file and generate state effecter PDR structure | 
|  | 22 | * | 
|  | 23 | *  @param[in] json - the JSON Object with the state effecter PDR | 
|  | 24 | *  @param[out] handler - the Parser of PLDM command handler | 
|  | 25 | *  @param[out] repo - pdr::RepoInterface | 
|  | 26 | * | 
|  | 27 | */ | 
| George Liu | 36e8135 | 2020-07-01 14:40:30 +0800 | [diff] [blame] | 28 | template <class DBusInterface, class Handler> | 
|  | 29 | void generateStateEffecterPDR(const DBusInterface& dBusIntf, const Json& json, | 
|  | 30 | Handler& handler, pdr_utils::RepoInterface& repo) | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 31 | { | 
|  | 32 | static const std::vector<Json> emptyList{}; | 
|  | 33 | auto entries = json.value("entries", emptyList); | 
|  | 34 | for (const auto& e : entries) | 
|  | 35 | { | 
|  | 36 | size_t pdrSize = 0; | 
|  | 37 | auto effecters = e.value("effecters", emptyList); | 
|  | 38 | for (const auto& effecter : effecters) | 
|  | 39 | { | 
|  | 40 | auto set = effecter.value("set", empty); | 
|  | 41 | auto statesSize = set.value("size", 0); | 
|  | 42 | if (!statesSize) | 
|  | 43 | { | 
|  | 44 | std::cerr << "Malformed PDR JSON return " | 
|  | 45 | "pdrEntry;- no state set " | 
|  | 46 | "info, TYPE=" | 
|  | 47 | << PLDM_STATE_EFFECTER_PDR << "\n"; | 
|  | 48 | throw InternalFailure(); | 
|  | 49 | } | 
|  | 50 | pdrSize += sizeof(state_effecter_possible_states) - | 
|  | 51 | sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize); | 
|  | 52 | } | 
|  | 53 | pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t); | 
|  | 54 |  | 
|  | 55 | std::vector<uint8_t> entry{}; | 
|  | 56 | entry.resize(pdrSize); | 
|  | 57 |  | 
|  | 58 | pldm_state_effecter_pdr* pdr = | 
|  | 59 | reinterpret_cast<pldm_state_effecter_pdr*>(entry.data()); | 
|  | 60 | pdr->hdr.record_handle = 0; | 
|  | 61 | pdr->hdr.version = 1; | 
|  | 62 | pdr->hdr.type = PLDM_STATE_EFFECTER_PDR; | 
|  | 63 | pdr->hdr.record_change_num = 0; | 
|  | 64 | pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr); | 
|  | 65 |  | 
| Sampa Misra | 12afe11 | 2020-05-25 11:40:44 -0500 | [diff] [blame] | 66 | pdr->terminus_handle = pdr::BmcPldmTerminusHandle; | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 67 | pdr->effecter_id = handler.getNextEffecterId(); | 
| George Liu | c4ea6a9 | 2020-07-14 15:48:44 +0800 | [diff] [blame] | 68 |  | 
|  | 69 | try | 
|  | 70 | { | 
|  | 71 | std::string entity_path = e.value("entity_path", ""); | 
|  | 72 | auto& associatedEntityMap = handler.getAssociateEntityMap(); | 
|  | 73 | if (entity_path != "" && associatedEntityMap.find(entity_path) != | 
|  | 74 | associatedEntityMap.end()) | 
|  | 75 | { | 
|  | 76 | pdr->entity_type = | 
|  | 77 | associatedEntityMap.at(entity_path).entity_type; | 
|  | 78 | pdr->entity_instance = | 
|  | 79 | associatedEntityMap.at(entity_path).entity_instance_num; | 
|  | 80 | pdr->container_id = | 
|  | 81 | associatedEntityMap.at(entity_path).entity_container_id; | 
|  | 82 | } | 
|  | 83 | else | 
|  | 84 | { | 
|  | 85 | pdr->entity_type = e.value("type", 0); | 
|  | 86 | pdr->entity_instance = e.value("instance", 0); | 
|  | 87 | pdr->container_id = e.value("container", 0); | 
|  | 88 | } | 
|  | 89 | } | 
|  | 90 | catch (const std::exception& ex) | 
|  | 91 | { | 
|  | 92 | pdr->entity_type = e.value("type", 0); | 
|  | 93 | pdr->entity_instance = e.value("instance", 0); | 
|  | 94 | pdr->container_id = e.value("container", 0); | 
|  | 95 | } | 
|  | 96 |  | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 97 | pdr->effecter_semantic_id = 0; | 
|  | 98 | pdr->effecter_init = PLDM_NO_INIT; | 
|  | 99 | pdr->has_description_pdr = false; | 
|  | 100 | pdr->composite_effecter_count = effecters.size(); | 
|  | 101 |  | 
|  | 102 | DbusMappings dbusMappings{}; | 
|  | 103 | DbusValMaps dbusValMaps{}; | 
|  | 104 | uint8_t* start = | 
|  | 105 | entry.data() + sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t); | 
|  | 106 | for (const auto& effecter : effecters) | 
|  | 107 | { | 
|  | 108 | auto set = effecter.value("set", empty); | 
|  | 109 | state_effecter_possible_states* possibleStates = | 
|  | 110 | reinterpret_cast<state_effecter_possible_states*>(start); | 
|  | 111 | possibleStates->state_set_id = set.value("id", 0); | 
|  | 112 | possibleStates->possible_states_size = set.value("size", 0); | 
|  | 113 |  | 
|  | 114 | start += sizeof(possibleStates->state_set_id) + | 
|  | 115 | sizeof(possibleStates->possible_states_size); | 
|  | 116 | static const std::vector<uint8_t> emptyStates{}; | 
|  | 117 | PossibleValues stateValues; | 
|  | 118 | auto states = set.value("states", emptyStates); | 
|  | 119 | for (const auto& state : states) | 
|  | 120 | { | 
|  | 121 | auto index = state / 8; | 
|  | 122 | auto bit = state - (index * 8); | 
|  | 123 | bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index); | 
|  | 124 | bf->byte |= 1 << bit; | 
| George Liu | adbe172 | 2020-05-09 19:20:19 +0800 | [diff] [blame] | 125 | stateValues.emplace_back(state); | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 126 | } | 
|  | 127 | start += possibleStates->possible_states_size; | 
|  | 128 |  | 
|  | 129 | auto dbusEntry = effecter.value("dbus", empty); | 
|  | 130 | auto objectPath = dbusEntry.value("path", ""); | 
|  | 131 | auto interface = dbusEntry.value("interface", ""); | 
|  | 132 | auto propertyName = dbusEntry.value("property_name", ""); | 
|  | 133 | auto propertyType = dbusEntry.value("property_type", ""); | 
| George Liu | 36e8135 | 2020-07-01 14:40:30 +0800 | [diff] [blame] | 134 |  | 
| George Liu | 821ebc4 | 2021-01-26 14:36:11 +0800 | [diff] [blame] | 135 | StatestoDbusVal dbusIdToValMap{}; | 
|  | 136 | pldm::utils::DBusMapping dbusMapping{}; | 
| George Liu | 36e8135 | 2020-07-01 14:40:30 +0800 | [diff] [blame] | 137 | try | 
|  | 138 | { | 
|  | 139 | auto service = | 
|  | 140 | dBusIntf.getService(objectPath.c_str(), interface.c_str()); | 
| George Liu | 821ebc4 | 2021-01-26 14:36:11 +0800 | [diff] [blame] | 141 |  | 
|  | 142 | dbusMapping = pldm::utils::DBusMapping{ | 
|  | 143 | objectPath, interface, propertyName, propertyType}; | 
|  | 144 | dbusIdToValMap = populateMapping( | 
|  | 145 | propertyType, dbusEntry["property_values"], stateValues); | 
| George Liu | 36e8135 | 2020-07-01 14:40:30 +0800 | [diff] [blame] | 146 | } | 
|  | 147 | catch (const std::exception& e) | 
|  | 148 | { | 
| George Liu | 821ebc4 | 2021-01-26 14:36:11 +0800 | [diff] [blame] | 149 | std::cerr << "D-Bus object path does not exist, effecter ID: " | 
|  | 150 | << pdr->effecter_id << "\n"; | 
| George Liu | 36e8135 | 2020-07-01 14:40:30 +0800 | [diff] [blame] | 151 | } | 
|  | 152 |  | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 153 | dbusMappings.emplace_back(std::move(dbusMapping)); | 
| George Liu | 821ebc4 | 2021-01-26 14:36:11 +0800 | [diff] [blame] | 154 | dbusValMaps.emplace_back(std::move(dbusIdToValMap)); | 
| George Liu | a287072 | 2020-02-11 11:09:30 +0800 | [diff] [blame] | 155 | } | 
|  | 156 | handler.addDbusObjMaps( | 
|  | 157 | pdr->effecter_id, | 
|  | 158 | std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps))); | 
|  | 159 | PdrEntry pdrEntry{}; | 
|  | 160 | pdrEntry.data = entry.data(); | 
|  | 161 | pdrEntry.size = pdrSize; | 
|  | 162 | repo.addRecord(pdrEntry); | 
|  | 163 | } | 
|  | 164 | } | 
|  | 165 |  | 
|  | 166 | } // namespace pdr_state_effecter | 
|  | 167 | } // namespace responder | 
|  | 168 | } // namespace pldm |