xref: /openbmc/pldm/libpldmresponder/pdr_state_sensor.hpp (revision 16c2a0a03e5daac77e204eb99e00711490fb6e26)
1adbe1726SGeorge Liu #pragma once
2adbe1726SGeorge Liu 
3adbe1726SGeorge Liu #include "libpldmresponder/pdr_utils.hpp"
4adbe1726SGeorge Liu 
5c453e164SGeorge Liu #include <libpldm/platform.h>
6c453e164SGeorge Liu 
749cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
849cfb138SRiya Dixit 
949cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
1049cfb138SRiya Dixit 
11adbe1726SGeorge Liu namespace pldm
12adbe1726SGeorge Liu {
13adbe1726SGeorge Liu namespace responder
14adbe1726SGeorge Liu {
15adbe1726SGeorge Liu namespace pdr_state_sensor
16adbe1726SGeorge Liu {
17adbe1726SGeorge Liu using Json = nlohmann::json;
18adbe1726SGeorge Liu 
19adbe1726SGeorge Liu static const Json empty{};
20adbe1726SGeorge Liu 
21adbe1726SGeorge Liu /** @brief Parse PDR JSON file and generate state sensor PDR structure
22adbe1726SGeorge Liu  *
23adbe1726SGeorge Liu  *  @param[in] json - the JSON Object with the state sensor PDR
24adbe1726SGeorge Liu  *  @param[out] handler - the Parser of PLDM command handler
25adbe1726SGeorge Liu  *  @param[out] repo - pdr::RepoInterface
26adbe1726SGeorge Liu  *
27adbe1726SGeorge Liu  */
28adbe1726SGeorge Liu template <class DBusInterface, class Handler>
generateStateSensorPDR(const DBusInterface & dBusIntf,const Json & json,Handler & handler,pdr_utils::RepoInterface & repo)29adbe1726SGeorge Liu void generateStateSensorPDR(const DBusInterface& dBusIntf, const Json& json,
30adbe1726SGeorge Liu                             Handler& handler, pdr_utils::RepoInterface& repo)
31adbe1726SGeorge Liu {
32adbe1726SGeorge Liu     static const std::vector<Json> emptyList{};
33adbe1726SGeorge Liu     auto entries = json.value("entries", emptyList);
34adbe1726SGeorge Liu     for (const auto& e : entries)
35adbe1726SGeorge Liu     {
36adbe1726SGeorge Liu         size_t pdrSize = 0;
37adbe1726SGeorge Liu         auto sensors = e.value("sensors", emptyList);
38adbe1726SGeorge Liu         for (const auto& sensor : sensors)
39adbe1726SGeorge Liu         {
40adbe1726SGeorge Liu             auto set = sensor.value("set", empty);
41adbe1726SGeorge Liu             auto statesSize = set.value("size", 0);
42adbe1726SGeorge Liu             if (!statesSize)
43adbe1726SGeorge Liu             {
4449cfb138SRiya Dixit                 error(
4589644441SRiya Dixit                     "Malformed PDR JSON return pdrEntry; no state set info for state sensor pdr '{STATE_SENSOR_PDR}'",
461e5c81e0SRiya Dixit                     "STATE_SENSOR_PDR", PLDM_STATE_SENSOR_PDR);
47adbe1726SGeorge Liu                 throw InternalFailure();
48adbe1726SGeorge Liu             }
49adbe1726SGeorge Liu             pdrSize += sizeof(state_sensor_possible_states) -
50adbe1726SGeorge Liu                        sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
51adbe1726SGeorge Liu         }
52adbe1726SGeorge Liu         pdrSize += sizeof(pldm_state_sensor_pdr) - sizeof(uint8_t);
53adbe1726SGeorge Liu 
54adbe1726SGeorge Liu         std::vector<uint8_t> entry{};
55adbe1726SGeorge Liu         entry.resize(pdrSize);
56adbe1726SGeorge Liu 
57adbe1726SGeorge Liu         pldm_state_sensor_pdr* pdr =
58adbe1726SGeorge Liu             reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
59bcf91accSManojkiran Eda         if (!pdr)
60bcf91accSManojkiran Eda         {
6149cfb138SRiya Dixit             error("Failed to get state sensor PDR.");
62bcf91accSManojkiran Eda             continue;
63bcf91accSManojkiran Eda         }
64adbe1726SGeorge Liu         pdr->hdr.record_handle = 0;
65adbe1726SGeorge Liu         pdr->hdr.version = 1;
66adbe1726SGeorge Liu         pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
67adbe1726SGeorge Liu         pdr->hdr.record_change_num = 0;
68adbe1726SGeorge Liu         pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
69adbe1726SGeorge Liu 
70adbe1726SGeorge Liu         HTOLE32(pdr->hdr.record_handle);
71adbe1726SGeorge Liu         HTOLE16(pdr->hdr.record_change_num);
72adbe1726SGeorge Liu         HTOLE16(pdr->hdr.length);
73adbe1726SGeorge Liu 
74cc5f1586SManojkiran Eda         pdr->terminus_handle = TERMINUS_HANDLE;
75c4ea6a90SGeorge Liu 
76c4ea6a90SGeorge Liu         try
77c4ea6a90SGeorge Liu         {
78c4ea6a90SGeorge Liu             std::string entity_path = e.value("entity_path", "");
79c4ea6a90SGeorge Liu             auto& associatedEntityMap = handler.getAssociateEntityMap();
8006f9b29eSSagar Srinivas             if (entity_path != "" && associatedEntityMap.contains(entity_path))
81c4ea6a90SGeorge Liu             {
82c4ea6a90SGeorge Liu                 pdr->entity_type =
83c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_type;
84c4ea6a90SGeorge Liu                 pdr->entity_instance =
85c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_instance_num;
86c4ea6a90SGeorge Liu                 pdr->container_id =
87c4ea6a90SGeorge Liu                     associatedEntityMap.at(entity_path).entity_container_id;
88c4ea6a90SGeorge Liu             }
89c4ea6a90SGeorge Liu             else
90c4ea6a90SGeorge Liu             {
91adbe1726SGeorge Liu                 pdr->entity_type = e.value("type", 0);
92adbe1726SGeorge Liu                 pdr->entity_instance = e.value("instance", 0);
93adbe1726SGeorge Liu                 pdr->container_id = e.value("container", 0);
945f213471SPavithra Barithaya 
955f213471SPavithra Barithaya                 // do not create the PDR when the FRU or the entity path is not
965f213471SPavithra Barithaya                 // present
975f213471SPavithra Barithaya                 if (!pdr->entity_type)
985f213471SPavithra Barithaya                 {
995f213471SPavithra Barithaya                     continue;
1005f213471SPavithra Barithaya                 }
101c4ea6a90SGeorge Liu             }
102c4ea6a90SGeorge Liu         }
10358cbcaf2SKamalkumar Patel         catch (const std::exception&)
104c4ea6a90SGeorge Liu         {
105c4ea6a90SGeorge Liu             pdr->entity_type = e.value("type", 0);
106c4ea6a90SGeorge Liu             pdr->entity_instance = e.value("instance", 0);
107c4ea6a90SGeorge Liu             pdr->container_id = e.value("container", 0);
108c4ea6a90SGeorge Liu         }
109c4ea6a90SGeorge Liu 
110adbe1726SGeorge Liu         pdr->sensor_init = PLDM_NO_INIT;
111adbe1726SGeorge Liu         pdr->sensor_auxiliary_names_pdr = false;
112adbe1726SGeorge Liu         if (sensors.size() > 8)
113adbe1726SGeorge Liu         {
114adbe1726SGeorge Liu             throw std::runtime_error("sensor size must be less than 8");
115adbe1726SGeorge Liu         }
116adbe1726SGeorge Liu         pdr->composite_sensor_count = sensors.size();
117adbe1726SGeorge Liu 
118adbe1726SGeorge Liu         HTOLE16(pdr->terminus_handle);
119adbe1726SGeorge Liu         HTOLE16(pdr->entity_type);
120adbe1726SGeorge Liu         HTOLE16(pdr->entity_instance);
121adbe1726SGeorge Liu         HTOLE16(pdr->container_id);
122adbe1726SGeorge Liu 
1235079ac4aSBrad Bishop         pldm::responder::pdr_utils::DbusMappings dbusMappings{};
1245079ac4aSBrad Bishop         pldm::responder::pdr_utils::DbusValMaps dbusValMaps{};
125*16c2a0a0SPatrick Williams         uint8_t* start =
126*16c2a0a0SPatrick Williams             entry.data() + sizeof(pldm_state_sensor_pdr) - sizeof(uint8_t);
127adbe1726SGeorge Liu         for (const auto& sensor : sensors)
128adbe1726SGeorge Liu         {
129adbe1726SGeorge Liu             auto set = sensor.value("set", empty);
130adbe1726SGeorge Liu             state_sensor_possible_states* possibleStates =
131adbe1726SGeorge Liu                 reinterpret_cast<state_sensor_possible_states*>(start);
132adbe1726SGeorge Liu             possibleStates->state_set_id = set.value("id", 0);
133adbe1726SGeorge Liu             HTOLE16(possibleStates->state_set_id);
134adbe1726SGeorge Liu             possibleStates->possible_states_size = set.value("size", 0);
135adbe1726SGeorge Liu 
136adbe1726SGeorge Liu             start += sizeof(possibleStates->state_set_id) +
137adbe1726SGeorge Liu                      sizeof(possibleStates->possible_states_size);
138adbe1726SGeorge Liu             static const std::vector<uint8_t> emptyStates{};
1395079ac4aSBrad Bishop             pldm::responder::pdr_utils::PossibleValues stateValues;
140adbe1726SGeorge Liu             auto states = set.value("states", emptyStates);
141adbe1726SGeorge Liu             for (const auto& state : states)
142adbe1726SGeorge Liu             {
143adbe1726SGeorge Liu                 auto index = state / 8;
144adbe1726SGeorge Liu                 auto bit = state - (index * 8);
145adbe1726SGeorge Liu                 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
146adbe1726SGeorge Liu                 bf->byte |= 1 << bit;
147adbe1726SGeorge Liu                 stateValues.emplace_back(state);
148adbe1726SGeorge Liu             }
149adbe1726SGeorge Liu             start += possibleStates->possible_states_size;
150adbe1726SGeorge Liu             auto dbusEntry = sensor.value("dbus", empty);
151adbe1726SGeorge Liu             auto objectPath = dbusEntry.value("path", "");
152adbe1726SGeorge Liu             auto interface = dbusEntry.value("interface", "");
153adbe1726SGeorge Liu             auto propertyName = dbusEntry.value("property_name", "");
154adbe1726SGeorge Liu             auto propertyType = dbusEntry.value("property_type", "");
155adbe1726SGeorge Liu 
1565079ac4aSBrad Bishop             pldm::responder::pdr_utils::StatestoDbusVal dbusIdToValMap{};
157821ebc47SGeorge Liu             pldm::utils::DBusMapping dbusMapping{};
158adbe1726SGeorge Liu             try
159adbe1726SGeorge Liu             {
160*16c2a0a0SPatrick Williams                 auto service =
161*16c2a0a0SPatrick Williams                     dBusIntf.getService(objectPath.c_str(), interface.c_str());
162821ebc47SGeorge Liu 
163821ebc47SGeorge Liu                 dbusMapping = pldm::utils::DBusMapping{
164821ebc47SGeorge Liu                     objectPath, interface, propertyName, propertyType};
1655079ac4aSBrad Bishop                 dbusIdToValMap = pldm::responder::pdr_utils::populateMapping(
166821ebc47SGeorge Liu                     propertyType, dbusEntry["property_values"], stateValues);
167adbe1726SGeorge Liu             }
168adbe1726SGeorge Liu             catch (const std::exception& e)
169adbe1726SGeorge Liu             {
17049cfb138SRiya Dixit                 error(
17189644441SRiya Dixit                     "Failed to create sensor PDR, D-Bus object '{PATH}' returned error - {ERROR}",
172819bb6f1SManojkiran Eda                     "PATH", objectPath, "ERROR", e);
1733daf7a1cSManojkiran Eda                 break;
174adbe1726SGeorge Liu             }
175adbe1726SGeorge Liu             dbusMappings.emplace_back(std::move(dbusMapping));
176adbe1726SGeorge Liu             dbusValMaps.emplace_back(std::move(dbusIdToValMap));
177adbe1726SGeorge Liu         }
178adbe1726SGeorge Liu 
1793daf7a1cSManojkiran Eda         if (!(dbusMappings.empty() && dbusValMaps.empty()))
1803daf7a1cSManojkiran Eda         {
1813daf7a1cSManojkiran Eda             pdr->sensor_id = handler.getNextSensorId();
1823daf7a1cSManojkiran Eda             HTOLE16(pdr->sensor_id);
183adbe1726SGeorge Liu             handler.addDbusObjMaps(
184adbe1726SGeorge Liu                 pdr->sensor_id,
1853daf7a1cSManojkiran Eda                 std::make_tuple(std::move(dbusMappings),
1863daf7a1cSManojkiran Eda                                 std::move(dbusValMaps)),
1875079ac4aSBrad Bishop                 pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
1885079ac4aSBrad Bishop             pldm::responder::pdr_utils::PdrEntry pdrEntry{};
189adbe1726SGeorge Liu             pdrEntry.data = entry.data();
190adbe1726SGeorge Liu             pdrEntry.size = pdrSize;
191adbe1726SGeorge Liu             repo.addRecord(pdrEntry);
192adbe1726SGeorge Liu         }
193adbe1726SGeorge Liu     }
1943daf7a1cSManojkiran Eda }
195adbe1726SGeorge Liu 
196adbe1726SGeorge Liu } // namespace pdr_state_sensor
197adbe1726SGeorge Liu } // namespace responder
198adbe1726SGeorge Liu } // namespace pldm
199