xref: /openbmc/pldm/libpldmresponder/pdr_state_effecter.hpp (revision bcf91acc5afab2a01393f299e4f663de93b1a4cd)
1a2870726SGeorge Liu #pragma once
2a2870726SGeorge Liu 
3a2870726SGeorge Liu #include "libpldm/platform.h"
4a2870726SGeorge Liu 
512afe110SSampa Misra #include "pdr.hpp"
612afe110SSampa Misra #include "pdr_utils.hpp"
76492f524SGeorge Liu 
8a2870726SGeorge Liu namespace pldm
9a2870726SGeorge Liu {
10a2870726SGeorge Liu 
11a2870726SGeorge Liu namespace responder
12a2870726SGeorge Liu {
13a2870726SGeorge Liu 
14a2870726SGeorge Liu namespace pdr_state_effecter
15a2870726SGeorge Liu {
16a2870726SGeorge Liu 
17a2870726SGeorge Liu using Json = nlohmann::json;
18a2870726SGeorge Liu 
19a2870726SGeorge Liu static const Json empty{};
20a2870726SGeorge Liu 
21a2870726SGeorge Liu /** @brief Parse PDR JSON file and generate state effecter PDR structure
22a2870726SGeorge Liu  *
23a2870726SGeorge Liu  *  @param[in] json - the JSON Object with the state effecter PDR
24a2870726SGeorge Liu  *  @param[out] handler - the Parser of PLDM command handler
25a2870726SGeorge Liu  *  @param[out] repo - pdr::RepoInterface
26a2870726SGeorge Liu  *
27a2870726SGeorge Liu  */
2836e81352SGeorge Liu template <class DBusInterface, class Handler>
2936e81352SGeorge Liu void generateStateEffecterPDR(const DBusInterface& dBusIntf, const Json& json,
3036e81352SGeorge Liu                               Handler& handler, pdr_utils::RepoInterface& repo)
31a2870726SGeorge Liu {
32a2870726SGeorge Liu     static const std::vector<Json> emptyList{};
33a2870726SGeorge Liu     auto entries = json.value("entries", emptyList);
34a2870726SGeorge Liu     for (const auto& e : entries)
35a2870726SGeorge Liu     {
36a2870726SGeorge Liu         size_t pdrSize = 0;
37a2870726SGeorge Liu         auto effecters = e.value("effecters", emptyList);
38a2870726SGeorge Liu         for (const auto& effecter : effecters)
39a2870726SGeorge Liu         {
40a2870726SGeorge Liu             auto set = effecter.value("set", empty);
41a2870726SGeorge Liu             auto statesSize = set.value("size", 0);
42a2870726SGeorge Liu             if (!statesSize)
43a2870726SGeorge Liu             {
44a2870726SGeorge Liu                 std::cerr << "Malformed PDR JSON return "
45a2870726SGeorge Liu                              "pdrEntry;- no state set "
46a2870726SGeorge Liu                              "info, TYPE="
47a2870726SGeorge Liu                           << PLDM_STATE_EFFECTER_PDR << "\n";
48a2870726SGeorge Liu                 throw InternalFailure();
49a2870726SGeorge Liu             }
50a2870726SGeorge Liu             pdrSize += sizeof(state_effecter_possible_states) -
51a2870726SGeorge Liu                        sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
52a2870726SGeorge Liu         }
53a2870726SGeorge Liu         pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
54a2870726SGeorge Liu 
55a2870726SGeorge Liu         std::vector<uint8_t> entry{};
56a2870726SGeorge Liu         entry.resize(pdrSize);
57a2870726SGeorge Liu 
58a2870726SGeorge Liu         pldm_state_effecter_pdr* pdr =
59a2870726SGeorge Liu             reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
60*bcf91accSManojkiran Eda         if (!pdr)
61*bcf91accSManojkiran Eda         {
62*bcf91accSManojkiran Eda             std::cerr << "Failed to get state effecter PDR.\n";
63*bcf91accSManojkiran Eda             continue;
64*bcf91accSManojkiran Eda         }
65a2870726SGeorge Liu         pdr->hdr.record_handle = 0;
66a2870726SGeorge Liu         pdr->hdr.version = 1;
67a2870726SGeorge Liu         pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
68a2870726SGeorge Liu         pdr->hdr.record_change_num = 0;
69a2870726SGeorge Liu         pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
70a2870726SGeorge Liu 
7112afe110SSampa Misra         pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
72a2870726SGeorge Liu         pdr->effecter_id = handler.getNextEffecterId();
73c4ea6a90SGeorge Liu 
74c4ea6a90SGeorge Liu         try
75c4ea6a90SGeorge Liu         {
76c4ea6a90SGeorge Liu             std::string entity_path = e.value("entity_path", "");
77c4ea6a90SGeorge Liu             auto& associatedEntityMap = handler.getAssociateEntityMap();
78c4ea6a90SGeorge Liu             if (entity_path != "" && associatedEntityMap.find(entity_path) !=
79c4ea6a90SGeorge Liu                                          associatedEntityMap.end())
80c4ea6a90SGeorge Liu             {
81c4ea6a90SGeorge Liu                 pdr->entity_type =
82c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_type;
83c4ea6a90SGeorge Liu                 pdr->entity_instance =
84c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_instance_num;
85c4ea6a90SGeorge Liu                 pdr->container_id =
86c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_container_id;
87c4ea6a90SGeorge Liu             }
88c4ea6a90SGeorge Liu             else
89c4ea6a90SGeorge Liu             {
90a2870726SGeorge Liu                 pdr->entity_type = e.value("type", 0);
91a2870726SGeorge Liu                 pdr->entity_instance = e.value("instance", 0);
92a2870726SGeorge Liu                 pdr->container_id = e.value("container", 0);
93c4ea6a90SGeorge Liu             }
94c4ea6a90SGeorge Liu         }
95c4ea6a90SGeorge Liu         catch (const std::exception& ex)
96c4ea6a90SGeorge Liu         {
97c4ea6a90SGeorge Liu             pdr->entity_type = e.value("type", 0);
98c4ea6a90SGeorge Liu             pdr->entity_instance = e.value("instance", 0);
99c4ea6a90SGeorge Liu             pdr->container_id = e.value("container", 0);
100c4ea6a90SGeorge Liu         }
101c4ea6a90SGeorge Liu 
102a2870726SGeorge Liu         pdr->effecter_semantic_id = 0;
103a2870726SGeorge Liu         pdr->effecter_init = PLDM_NO_INIT;
104a2870726SGeorge Liu         pdr->has_description_pdr = false;
105a2870726SGeorge Liu         pdr->composite_effecter_count = effecters.size();
106a2870726SGeorge Liu 
107a2870726SGeorge Liu         DbusMappings dbusMappings{};
108a2870726SGeorge Liu         DbusValMaps dbusValMaps{};
109a2870726SGeorge Liu         uint8_t* start =
110a2870726SGeorge Liu             entry.data() + sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
111a2870726SGeorge Liu         for (const auto& effecter : effecters)
112a2870726SGeorge Liu         {
113a2870726SGeorge Liu             auto set = effecter.value("set", empty);
114a2870726SGeorge Liu             state_effecter_possible_states* possibleStates =
115a2870726SGeorge Liu                 reinterpret_cast<state_effecter_possible_states*>(start);
116a2870726SGeorge Liu             possibleStates->state_set_id = set.value("id", 0);
117a2870726SGeorge Liu             possibleStates->possible_states_size = set.value("size", 0);
118a2870726SGeorge Liu 
119a2870726SGeorge Liu             start += sizeof(possibleStates->state_set_id) +
120a2870726SGeorge Liu                      sizeof(possibleStates->possible_states_size);
121a2870726SGeorge Liu             static const std::vector<uint8_t> emptyStates{};
122a2870726SGeorge Liu             PossibleValues stateValues;
123a2870726SGeorge Liu             auto states = set.value("states", emptyStates);
124a2870726SGeorge Liu             for (const auto& state : states)
125a2870726SGeorge Liu             {
126a2870726SGeorge Liu                 auto index = state / 8;
127a2870726SGeorge Liu                 auto bit = state - (index * 8);
128a2870726SGeorge Liu                 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
129a2870726SGeorge Liu                 bf->byte |= 1 << bit;
130adbe1726SGeorge Liu                 stateValues.emplace_back(state);
131a2870726SGeorge Liu             }
132a2870726SGeorge Liu             start += possibleStates->possible_states_size;
133a2870726SGeorge Liu 
134a2870726SGeorge Liu             auto dbusEntry = effecter.value("dbus", empty);
135a2870726SGeorge Liu             auto objectPath = dbusEntry.value("path", "");
136a2870726SGeorge Liu             auto interface = dbusEntry.value("interface", "");
137a2870726SGeorge Liu             auto propertyName = dbusEntry.value("property_name", "");
138a2870726SGeorge Liu             auto propertyType = dbusEntry.value("property_type", "");
13936e81352SGeorge Liu 
140821ebc47SGeorge Liu             StatestoDbusVal dbusIdToValMap{};
141821ebc47SGeorge Liu             pldm::utils::DBusMapping dbusMapping{};
14236e81352SGeorge Liu             try
14336e81352SGeorge Liu             {
14436e81352SGeorge Liu                 auto service =
14536e81352SGeorge Liu                     dBusIntf.getService(objectPath.c_str(), interface.c_str());
146821ebc47SGeorge Liu 
147821ebc47SGeorge Liu                 dbusMapping = pldm::utils::DBusMapping{
148821ebc47SGeorge Liu                     objectPath, interface, propertyName, propertyType};
149821ebc47SGeorge Liu                 dbusIdToValMap = populateMapping(
150821ebc47SGeorge Liu                     propertyType, dbusEntry["property_values"], stateValues);
15136e81352SGeorge Liu             }
15236e81352SGeorge Liu             catch (const std::exception& e)
15336e81352SGeorge Liu             {
154821ebc47SGeorge Liu                 std::cerr << "D-Bus object path does not exist, effecter ID: "
155821ebc47SGeorge Liu                           << pdr->effecter_id << "\n";
15636e81352SGeorge Liu             }
15736e81352SGeorge Liu 
158a2870726SGeorge Liu             dbusMappings.emplace_back(std::move(dbusMapping));
159a2870726SGeorge Liu             dbusValMaps.emplace_back(std::move(dbusIdToValMap));
160a2870726SGeorge Liu         }
161a2870726SGeorge Liu         handler.addDbusObjMaps(
162a2870726SGeorge Liu             pdr->effecter_id,
163a2870726SGeorge Liu             std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps)));
164a2870726SGeorge Liu         PdrEntry pdrEntry{};
165a2870726SGeorge Liu         pdrEntry.data = entry.data();
166a2870726SGeorge Liu         pdrEntry.size = pdrSize;
167a2870726SGeorge Liu         repo.addRecord(pdrEntry);
168a2870726SGeorge Liu     }
169a2870726SGeorge Liu }
170a2870726SGeorge Liu 
171a2870726SGeorge Liu } // namespace pdr_state_effecter
172a2870726SGeorge Liu } // namespace responder
173a2870726SGeorge Liu } // namespace pldm
174