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>
generateStateEffecterPDR(const DBusInterface & dBusIntf,const Json & json,Handler & handler,pdr_utils::RepoInterface & repo)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(
4689644441SRiya Dixit "Malformed PDR JSON return pdrEntry; no state set info for state effecter pdr '{STATE_EFFECTER_PDR}'",
471e5c81e0SRiya Dixit "STATE_EFFECTER_PDR", PLDM_STATE_EFFECTER_PDR);
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());
60bcf91accSManojkiran Eda if (!pdr)
61bcf91accSManojkiran Eda {
6249cfb138SRiya Dixit error("Failed to get state effecter PDR.");
63bcf91accSManojkiran Eda continue;
64bcf91accSManojkiran 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
71cc5f1586SManojkiran Eda pdr->terminus_handle = TERMINUS_HANDLE;
72c4ea6a90SGeorge Liu
73c4ea6a90SGeorge Liu try
74c4ea6a90SGeorge Liu {
75c4ea6a90SGeorge Liu std::string entity_path = e.value("entity_path", "");
76c4ea6a90SGeorge Liu auto& associatedEntityMap = handler.getAssociateEntityMap();
7706f9b29eSSagar Srinivas if (entity_path != "" && associatedEntityMap.contains(entity_path))
78c4ea6a90SGeorge Liu {
79c4ea6a90SGeorge Liu pdr->entity_type =
80c4ea6a90SGeorge Liu associatedEntityMap.at(entity_path).entity_type;
81c4ea6a90SGeorge Liu pdr->entity_instance =
82c4ea6a90SGeorge Liu associatedEntityMap.at(entity_path).entity_instance_num;
83c4ea6a90SGeorge Liu pdr->container_id =
84c4ea6a90SGeorge Liu associatedEntityMap.at(entity_path).entity_container_id;
85c4ea6a90SGeorge Liu }
86c4ea6a90SGeorge Liu else
87c4ea6a90SGeorge Liu {
88a2870726SGeorge Liu pdr->entity_type = e.value("type", 0);
89a2870726SGeorge Liu pdr->entity_instance = e.value("instance", 0);
90a2870726SGeorge Liu pdr->container_id = e.value("container", 0);
915f213471SPavithra Barithaya
925f213471SPavithra Barithaya // do not create the PDR when the FRU or the entity path is not
935f213471SPavithra Barithaya // present
945f213471SPavithra Barithaya if (!pdr->entity_type)
955f213471SPavithra Barithaya {
965f213471SPavithra Barithaya continue;
975f213471SPavithra Barithaya }
98c4ea6a90SGeorge Liu }
99c4ea6a90SGeorge Liu }
10058cbcaf2SKamalkumar Patel catch (const std::exception&)
101c4ea6a90SGeorge Liu {
102c4ea6a90SGeorge Liu pdr->entity_type = e.value("type", 0);
103c4ea6a90SGeorge Liu pdr->entity_instance = e.value("instance", 0);
104c4ea6a90SGeorge Liu pdr->container_id = e.value("container", 0);
105c4ea6a90SGeorge Liu }
106c4ea6a90SGeorge Liu
107a2870726SGeorge Liu pdr->effecter_semantic_id = 0;
108a2870726SGeorge Liu pdr->effecter_init = PLDM_NO_INIT;
109a2870726SGeorge Liu pdr->has_description_pdr = false;
110a2870726SGeorge Liu pdr->composite_effecter_count = effecters.size();
111a2870726SGeorge Liu
1125079ac4aSBrad Bishop pldm::responder::pdr_utils::DbusMappings dbusMappings{};
1135079ac4aSBrad Bishop pldm::responder::pdr_utils::DbusValMaps dbusValMaps{};
114*16c2a0a0SPatrick Williams uint8_t* start =
115*16c2a0a0SPatrick Williams entry.data() + sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
116a2870726SGeorge Liu for (const auto& effecter : effecters)
117a2870726SGeorge Liu {
118a2870726SGeorge Liu auto set = effecter.value("set", empty);
119a2870726SGeorge Liu state_effecter_possible_states* possibleStates =
120a2870726SGeorge Liu reinterpret_cast<state_effecter_possible_states*>(start);
121a2870726SGeorge Liu possibleStates->state_set_id = set.value("id", 0);
122a2870726SGeorge Liu possibleStates->possible_states_size = set.value("size", 0);
123a2870726SGeorge Liu
124a2870726SGeorge Liu start += sizeof(possibleStates->state_set_id) +
125a2870726SGeorge Liu sizeof(possibleStates->possible_states_size);
126a2870726SGeorge Liu static const std::vector<uint8_t> emptyStates{};
1275079ac4aSBrad Bishop pldm::responder::pdr_utils::PossibleValues stateValues;
128a2870726SGeorge Liu auto states = set.value("states", emptyStates);
129a2870726SGeorge Liu for (const auto& state : states)
130a2870726SGeorge Liu {
131a2870726SGeorge Liu auto index = state / 8;
132a2870726SGeorge Liu auto bit = state - (index * 8);
133a2870726SGeorge Liu bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
134a2870726SGeorge Liu bf->byte |= 1 << bit;
135adbe1726SGeorge Liu stateValues.emplace_back(state);
136a2870726SGeorge Liu }
137a2870726SGeorge Liu start += possibleStates->possible_states_size;
138a2870726SGeorge Liu
139a2870726SGeorge Liu auto dbusEntry = effecter.value("dbus", empty);
140a2870726SGeorge Liu auto objectPath = dbusEntry.value("path", "");
141a2870726SGeorge Liu auto interface = dbusEntry.value("interface", "");
142a2870726SGeorge Liu auto propertyName = dbusEntry.value("property_name", "");
143a2870726SGeorge Liu auto propertyType = dbusEntry.value("property_type", "");
14436e81352SGeorge Liu
1455079ac4aSBrad Bishop pldm::responder::pdr_utils::StatestoDbusVal dbusIdToValMap{};
146821ebc47SGeorge Liu pldm::utils::DBusMapping dbusMapping{};
14736e81352SGeorge Liu try
14836e81352SGeorge Liu {
149*16c2a0a0SPatrick Williams auto service =
150*16c2a0a0SPatrick Williams dBusIntf.getService(objectPath.c_str(), interface.c_str());
151821ebc47SGeorge Liu
152821ebc47SGeorge Liu dbusMapping = pldm::utils::DBusMapping{
153821ebc47SGeorge Liu objectPath, interface, propertyName, propertyType};
1545079ac4aSBrad Bishop dbusIdToValMap = pldm::responder::pdr_utils::populateMapping(
155821ebc47SGeorge Liu propertyType, dbusEntry["property_values"], stateValues);
15636e81352SGeorge Liu }
15736e81352SGeorge Liu catch (const std::exception& e)
15836e81352SGeorge Liu {
15949cfb138SRiya Dixit error(
16089644441SRiya Dixit "Failed to create effecter PDR, D-Bus object '{PATH}' returned error - {ERROR}",
161c81d1129SManojkiran Eda "PATH", objectPath, "ERROR", e);
1623daf7a1cSManojkiran Eda break;
16336e81352SGeorge Liu }
164a2870726SGeorge Liu dbusMappings.emplace_back(std::move(dbusMapping));
165a2870726SGeorge Liu dbusValMaps.emplace_back(std::move(dbusIdToValMap));
166a2870726SGeorge Liu }
1673daf7a1cSManojkiran Eda if (!(dbusMappings.empty() && dbusValMaps.empty()))
1683daf7a1cSManojkiran Eda {
1693daf7a1cSManojkiran Eda pdr->effecter_id = handler.getNextEffecterId();
1703daf7a1cSManojkiran Eda handler.addDbusObjMaps(pdr->effecter_id,
1713daf7a1cSManojkiran Eda std::make_tuple(std::move(dbusMappings),
1723daf7a1cSManojkiran Eda std::move(dbusValMaps)));
1735079ac4aSBrad Bishop pldm::responder::pdr_utils::PdrEntry pdrEntry{};
174a2870726SGeorge Liu pdrEntry.data = entry.data();
175a2870726SGeorge Liu pdrEntry.size = pdrSize;
176a2870726SGeorge Liu repo.addRecord(pdrEntry);
177a2870726SGeorge Liu }
178a2870726SGeorge Liu }
1793daf7a1cSManojkiran Eda }
180a2870726SGeorge Liu
181a2870726SGeorge Liu } // namespace pdr_state_effecter
182a2870726SGeorge Liu } // namespace responder
183a2870726SGeorge Liu } // namespace pldm
184