blob: 1391def21a913cff144d53c940091ff07099108d [file] [log] [blame]
George Liua2870722020-02-11 11:09:30 +08001#pragma once
2
George Liua2870722020-02-11 11:09:30 +08003#include "libpldm/platform.h"
4
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldmresponder/pdr_utils.hpp"
6
George Liua2870722020-02-11 11:09:30 +08007namespace pldm
8{
9
10namespace responder
11{
12
13namespace pdr_state_effecter
14{
15
16using Json = nlohmann::json;
17
18static 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 */
George Liu36e81352020-07-01 14:40:30 +080027template <class DBusInterface, class Handler>
28void generateStateEffecterPDR(const DBusInterface& dBusIntf, const Json& json,
29 Handler& handler, pdr_utils::RepoInterface& repo)
George Liua2870722020-02-11 11:09:30 +080030{
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", "");
George Liu36e81352020-07-01 14:40:30 +0800107
108 try
109 {
110 auto service =
111 dBusIntf.getService(objectPath.c_str(), interface.c_str());
112 }
113 catch (const std::exception& e)
114 {
115 continue;
116 }
117
George Liua2870722020-02-11 11:09:30 +0800118 pldm::utils::DBusMapping dbusMapping{objectPath, interface,
119 propertyName, propertyType};
120 dbusMappings.emplace_back(std::move(dbusMapping));
121
122 Json propValues = dbusEntry["property_values"];
123 StatestoDbusVal dbusIdToValMap =
124 populateMapping(propertyType, propValues, stateValues);
125 if (!dbusIdToValMap.empty())
126 {
127 dbusValMaps.emplace_back(std::move(dbusIdToValMap));
128 }
129 }
130 handler.addDbusObjMaps(
131 pdr->effecter_id,
132 std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps)));
133 PdrEntry pdrEntry{};
134 pdrEntry.data = entry.data();
135 pdrEntry.size = pdrSize;
136 repo.addRecord(pdrEntry);
137 }
138}
139
140} // namespace pdr_state_effecter
141} // namespace responder
142} // namespace pldm