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