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