xref: /openbmc/pldm/libpldmresponder/pdr_state_effecter.hpp (revision 3daf7a1ca0e317225e3c0cf821267e75726eabe8)
1a2870726SGeorge Liu #pragma once
2a2870726SGeorge Liu 
312afe110SSampa Misra #include "pdr.hpp"
412afe110SSampa Misra #include "pdr_utils.hpp"
56492f524SGeorge Liu 
6c453e164SGeorge Liu #include <libpldm/platform.h>
7cc5f1586SManojkiran Eda 
849cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
949cfb138SRiya Dixit 
1049cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
1149cfb138SRiya Dixit 
12a2870726SGeorge Liu namespace pldm
13a2870726SGeorge Liu {
14a2870726SGeorge Liu namespace responder
15a2870726SGeorge Liu {
16a2870726SGeorge Liu namespace pdr_state_effecter
17a2870726SGeorge Liu {
18a2870726SGeorge Liu using Json = nlohmann::json;
19a2870726SGeorge Liu 
20a2870726SGeorge Liu static const Json empty{};
21a2870726SGeorge Liu 
22a2870726SGeorge Liu /** @brief Parse PDR JSON file and generate state effecter PDR structure
23a2870726SGeorge Liu  *
24a2870726SGeorge Liu  *  @param[in] json - the JSON Object with the state effecter PDR
25a2870726SGeorge Liu  *  @param[out] handler - the Parser of PLDM command handler
26a2870726SGeorge Liu  *  @param[out] repo - pdr::RepoInterface
27a2870726SGeorge Liu  *
28a2870726SGeorge Liu  */
2936e81352SGeorge Liu template <class DBusInterface, class Handler>
3036e81352SGeorge Liu void generateStateEffecterPDR(const DBusInterface& dBusIntf, const Json& json,
3136e81352SGeorge Liu                               Handler& handler, pdr_utils::RepoInterface& repo)
32a2870726SGeorge Liu {
33a2870726SGeorge Liu     static const std::vector<Json> emptyList{};
34a2870726SGeorge Liu     auto entries = json.value("entries", emptyList);
35a2870726SGeorge Liu     for (const auto& e : entries)
36a2870726SGeorge Liu     {
37a2870726SGeorge Liu         size_t pdrSize = 0;
38a2870726SGeorge Liu         auto effecters = e.value("effecters", emptyList);
39a2870726SGeorge Liu         for (const auto& effecter : effecters)
40a2870726SGeorge Liu         {
41a2870726SGeorge Liu             auto set = effecter.value("set", empty);
42a2870726SGeorge Liu             auto statesSize = set.value("size", 0);
43a2870726SGeorge Liu             if (!statesSize)
44a2870726SGeorge Liu             {
4549cfb138SRiya Dixit                 error(
4649cfb138SRiya Dixit                     "Malformed PDR JSON return pdrEntry;- no state set info, TYPE={STATE_EFFECTER_PDR}",
4749cfb138SRiya Dixit                     "STATE_EFFECTER_PDR",
4849cfb138SRiya Dixit                     static_cast<unsigned>(PLDM_STATE_EFFECTER_PDR));
49a2870726SGeorge Liu                 throw InternalFailure();
50a2870726SGeorge Liu             }
51a2870726SGeorge Liu             pdrSize += sizeof(state_effecter_possible_states) -
52a2870726SGeorge Liu                        sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
53a2870726SGeorge Liu         }
54a2870726SGeorge Liu         pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
55a2870726SGeorge Liu 
56a2870726SGeorge Liu         std::vector<uint8_t> entry{};
57a2870726SGeorge Liu         entry.resize(pdrSize);
58a2870726SGeorge Liu 
59a2870726SGeorge Liu         pldm_state_effecter_pdr* pdr =
60a2870726SGeorge Liu             reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
61bcf91accSManojkiran Eda         if (!pdr)
62bcf91accSManojkiran Eda         {
6349cfb138SRiya Dixit             error("Failed to get state effecter PDR.");
64bcf91accSManojkiran Eda             continue;
65bcf91accSManojkiran Eda         }
66a2870726SGeorge Liu         pdr->hdr.record_handle = 0;
67a2870726SGeorge Liu         pdr->hdr.version = 1;
68a2870726SGeorge Liu         pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
69a2870726SGeorge Liu         pdr->hdr.record_change_num = 0;
70a2870726SGeorge Liu         pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
71a2870726SGeorge Liu 
72cc5f1586SManojkiran Eda         pdr->terminus_handle = TERMINUS_HANDLE;
73c4ea6a90SGeorge Liu 
74c4ea6a90SGeorge Liu         try
75c4ea6a90SGeorge Liu         {
76c4ea6a90SGeorge Liu             std::string entity_path = e.value("entity_path", "");
77c4ea6a90SGeorge Liu             auto& associatedEntityMap = handler.getAssociateEntityMap();
7806f9b29eSSagar Srinivas             if (entity_path != "" && associatedEntityMap.contains(entity_path))
79c4ea6a90SGeorge Liu             {
80c4ea6a90SGeorge Liu                 pdr->entity_type =
81c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_type;
82c4ea6a90SGeorge Liu                 pdr->entity_instance =
83c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_instance_num;
84c4ea6a90SGeorge Liu                 pdr->container_id =
85c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_container_id;
86c4ea6a90SGeorge Liu             }
87c4ea6a90SGeorge Liu             else
88c4ea6a90SGeorge Liu             {
89a2870726SGeorge Liu                 pdr->entity_type = e.value("type", 0);
90a2870726SGeorge Liu                 pdr->entity_instance = e.value("instance", 0);
91a2870726SGeorge Liu                 pdr->container_id = e.value("container", 0);
925f213471SPavithra Barithaya 
935f213471SPavithra Barithaya                 // do not create the PDR when the FRU or the entity path is not
945f213471SPavithra Barithaya                 // present
955f213471SPavithra Barithaya                 if (!pdr->entity_type)
965f213471SPavithra Barithaya                 {
975f213471SPavithra Barithaya                     continue;
985f213471SPavithra Barithaya                 }
99c4ea6a90SGeorge Liu             }
100c4ea6a90SGeorge Liu         }
10158cbcaf2SKamalkumar Patel         catch (const std::exception&)
102c4ea6a90SGeorge Liu         {
103c4ea6a90SGeorge Liu             pdr->entity_type = e.value("type", 0);
104c4ea6a90SGeorge Liu             pdr->entity_instance = e.value("instance", 0);
105c4ea6a90SGeorge Liu             pdr->container_id = e.value("container", 0);
106c4ea6a90SGeorge Liu         }
107c4ea6a90SGeorge Liu 
108a2870726SGeorge Liu         pdr->effecter_semantic_id = 0;
109a2870726SGeorge Liu         pdr->effecter_init = PLDM_NO_INIT;
110a2870726SGeorge Liu         pdr->has_description_pdr = false;
111a2870726SGeorge Liu         pdr->composite_effecter_count = effecters.size();
112a2870726SGeorge Liu 
1135079ac4aSBrad Bishop         pldm::responder::pdr_utils::DbusMappings dbusMappings{};
1145079ac4aSBrad Bishop         pldm::responder::pdr_utils::DbusValMaps dbusValMaps{};
1156da4f91bSPatrick Williams         uint8_t* start = entry.data() + sizeof(pldm_state_effecter_pdr) -
1166da4f91bSPatrick Williams                          sizeof(uint8_t);
117a2870726SGeorge Liu         for (const auto& effecter : effecters)
118a2870726SGeorge Liu         {
119a2870726SGeorge Liu             auto set = effecter.value("set", empty);
120a2870726SGeorge Liu             state_effecter_possible_states* possibleStates =
121a2870726SGeorge Liu                 reinterpret_cast<state_effecter_possible_states*>(start);
122a2870726SGeorge Liu             possibleStates->state_set_id = set.value("id", 0);
123a2870726SGeorge Liu             possibleStates->possible_states_size = set.value("size", 0);
124a2870726SGeorge Liu 
125a2870726SGeorge Liu             start += sizeof(possibleStates->state_set_id) +
126a2870726SGeorge Liu                      sizeof(possibleStates->possible_states_size);
127a2870726SGeorge Liu             static const std::vector<uint8_t> emptyStates{};
1285079ac4aSBrad Bishop             pldm::responder::pdr_utils::PossibleValues stateValues;
129a2870726SGeorge Liu             auto states = set.value("states", emptyStates);
130a2870726SGeorge Liu             for (const auto& state : states)
131a2870726SGeorge Liu             {
132a2870726SGeorge Liu                 auto index = state / 8;
133a2870726SGeorge Liu                 auto bit = state - (index * 8);
134a2870726SGeorge Liu                 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
135a2870726SGeorge Liu                 bf->byte |= 1 << bit;
136adbe1726SGeorge Liu                 stateValues.emplace_back(state);
137a2870726SGeorge Liu             }
138a2870726SGeorge Liu             start += possibleStates->possible_states_size;
139a2870726SGeorge Liu 
140a2870726SGeorge Liu             auto dbusEntry = effecter.value("dbus", empty);
141a2870726SGeorge Liu             auto objectPath = dbusEntry.value("path", "");
142a2870726SGeorge Liu             auto interface = dbusEntry.value("interface", "");
143a2870726SGeorge Liu             auto propertyName = dbusEntry.value("property_name", "");
144a2870726SGeorge Liu             auto propertyType = dbusEntry.value("property_type", "");
14536e81352SGeorge Liu 
1465079ac4aSBrad Bishop             pldm::responder::pdr_utils::StatestoDbusVal dbusIdToValMap{};
147821ebc47SGeorge Liu             pldm::utils::DBusMapping dbusMapping{};
14836e81352SGeorge Liu             try
14936e81352SGeorge Liu             {
1506da4f91bSPatrick Williams                 auto service = dBusIntf.getService(objectPath.c_str(),
1516da4f91bSPatrick Williams                                                    interface.c_str());
152821ebc47SGeorge Liu 
153821ebc47SGeorge Liu                 dbusMapping = pldm::utils::DBusMapping{
154821ebc47SGeorge Liu                     objectPath, interface, propertyName, propertyType};
1555079ac4aSBrad Bishop                 dbusIdToValMap = pldm::responder::pdr_utils::populateMapping(
156821ebc47SGeorge Liu                     propertyType, dbusEntry["property_values"], stateValues);
15736e81352SGeorge Liu             }
15836e81352SGeorge Liu             catch (const std::exception& e)
15936e81352SGeorge Liu             {
16049cfb138SRiya Dixit                 error(
161c81d1129SManojkiran Eda                     "Failed to create effecter PDR, D-Bus object '{PATH}' returned {ERROR}",
162c81d1129SManojkiran Eda                     "PATH", objectPath, "ERROR", e);
163*3daf7a1cSManojkiran Eda                 break;
16436e81352SGeorge Liu             }
165a2870726SGeorge Liu             dbusMappings.emplace_back(std::move(dbusMapping));
166a2870726SGeorge Liu             dbusValMaps.emplace_back(std::move(dbusIdToValMap));
167a2870726SGeorge Liu         }
168*3daf7a1cSManojkiran Eda         if (!(dbusMappings.empty() && dbusValMaps.empty()))
169*3daf7a1cSManojkiran Eda         {
170*3daf7a1cSManojkiran Eda             pdr->effecter_id = handler.getNextEffecterId();
171*3daf7a1cSManojkiran Eda             handler.addDbusObjMaps(pdr->effecter_id,
172*3daf7a1cSManojkiran Eda                                    std::make_tuple(std::move(dbusMappings),
173*3daf7a1cSManojkiran Eda                                                    std::move(dbusValMaps)));
1745079ac4aSBrad Bishop             pldm::responder::pdr_utils::PdrEntry pdrEntry{};
175a2870726SGeorge Liu             pdrEntry.data = entry.data();
176a2870726SGeorge Liu             pdrEntry.size = pdrSize;
177a2870726SGeorge Liu             repo.addRecord(pdrEntry);
178a2870726SGeorge Liu         }
179a2870726SGeorge Liu     }
180*3daf7a1cSManojkiran Eda }
181a2870726SGeorge Liu 
182a2870726SGeorge Liu } // namespace pdr_state_effecter
183a2870726SGeorge Liu } // namespace responder
184a2870726SGeorge Liu } // namespace pldm
185