blob: 6effc533837f5d1416fbc38b9015a5543ab03287 [file] [log] [blame]
George Liuadbe1722020-05-09 19:20:19 +08001#pragma once
2
George Liuadbe1722020-05-09 19:20:19 +08003#include "libpldmresponder/pdr_utils.hpp"
4
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/platform.h>
6
George Liuadbe1722020-05-09 19:20:19 +08007namespace pldm
8{
George Liuadbe1722020-05-09 19:20:19 +08009namespace responder
10{
George Liuadbe1722020-05-09 19:20:19 +080011namespace pdr_state_sensor
12{
George Liuadbe1722020-05-09 19:20:19 +080013using Json = nlohmann::json;
14
15static const Json empty{};
16
17/** @brief Parse PDR JSON file and generate state sensor PDR structure
18 *
19 * @param[in] json - the JSON Object with the state sensor PDR
20 * @param[out] handler - the Parser of PLDM command handler
21 * @param[out] repo - pdr::RepoInterface
22 *
23 */
24template <class DBusInterface, class Handler>
25void generateStateSensorPDR(const DBusInterface& dBusIntf, const Json& json,
26 Handler& handler, pdr_utils::RepoInterface& repo)
27{
28 static const std::vector<Json> emptyList{};
29 auto entries = json.value("entries", emptyList);
30 for (const auto& e : entries)
31 {
32 size_t pdrSize = 0;
33 auto sensors = e.value("sensors", emptyList);
34 for (const auto& sensor : sensors)
35 {
36 auto set = sensor.value("set", empty);
37 auto statesSize = set.value("size", 0);
38 if (!statesSize)
39 {
40 std::cerr << "Malformed PDR JSON return "
41 "pdrEntry;- no state set "
42 "info, TYPE="
43 << PLDM_STATE_SENSOR_PDR << "\n";
44 throw InternalFailure();
45 }
46 pdrSize += sizeof(state_sensor_possible_states) -
47 sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
48 }
49 pdrSize += sizeof(pldm_state_sensor_pdr) - sizeof(uint8_t);
50
51 std::vector<uint8_t> entry{};
52 entry.resize(pdrSize);
53
54 pldm_state_sensor_pdr* pdr =
55 reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
Manojkiran Edabcf91ac2021-03-14 13:50:48 +053056 if (!pdr)
57 {
58 std::cerr << "Failed to get state sensor PDR.\n";
59 continue;
60 }
George Liuadbe1722020-05-09 19:20:19 +080061 pdr->hdr.record_handle = 0;
62 pdr->hdr.version = 1;
63 pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
64 pdr->hdr.record_change_num = 0;
65 pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
66
67 HTOLE32(pdr->hdr.record_handle);
68 HTOLE16(pdr->hdr.record_change_num);
69 HTOLE16(pdr->hdr.length);
70
Manojkiran Edacc5f1582021-09-29 17:03:06 +053071 pdr->terminus_handle = TERMINUS_HANDLE;
George Liuadbe1722020-05-09 19:20:19 +080072 pdr->sensor_id = handler.getNextSensorId();
George Liuc4ea6a92020-07-14 15:48:44 +080073
74 try
75 {
76 std::string entity_path = e.value("entity_path", "");
77 auto& associatedEntityMap = handler.getAssociateEntityMap();
78 if (entity_path != "" && associatedEntityMap.find(entity_path) !=
79 associatedEntityMap.end())
80 {
81 pdr->entity_type =
82 associatedEntityMap.at(entity_path).entity_type;
83 pdr->entity_instance =
84 associatedEntityMap.at(entity_path).entity_instance_num;
85 pdr->container_id =
86 associatedEntityMap.at(entity_path).entity_container_id;
87 }
88 else
89 {
90 pdr->entity_type = e.value("type", 0);
91 pdr->entity_instance = e.value("instance", 0);
92 pdr->container_id = e.value("container", 0);
Pavithra Barithaya5f213472022-08-29 02:20:19 -050093
94 // do not create the PDR when the FRU or the entity path is not
95 // present
96 if (!pdr->entity_type)
97 {
98 std::cerr << "The entity path for the FRU is not present."
99 << std::endl;
100 continue;
101 }
George Liuc4ea6a92020-07-14 15:48:44 +0800102 }
103 }
104 catch (const std::exception& ex)
105 {
106 pdr->entity_type = e.value("type", 0);
107 pdr->entity_instance = e.value("instance", 0);
108 pdr->container_id = e.value("container", 0);
109 }
110
George Liuadbe1722020-05-09 19:20:19 +0800111 pdr->sensor_init = PLDM_NO_INIT;
112 pdr->sensor_auxiliary_names_pdr = false;
113 if (sensors.size() > 8)
114 {
115 throw std::runtime_error("sensor size must be less than 8");
116 }
117 pdr->composite_sensor_count = sensors.size();
118
119 HTOLE16(pdr->terminus_handle);
120 HTOLE16(pdr->sensor_id);
121 HTOLE16(pdr->entity_type);
122 HTOLE16(pdr->entity_instance);
123 HTOLE16(pdr->container_id);
124
Brad Bishop5079ac42021-08-19 18:35:06 -0400125 pldm::responder::pdr_utils::DbusMappings dbusMappings{};
126 pldm::responder::pdr_utils::DbusValMaps dbusValMaps{};
George Liuadbe1722020-05-09 19:20:19 +0800127 uint8_t* start =
128 entry.data() + sizeof(pldm_state_sensor_pdr) - sizeof(uint8_t);
129 for (const auto& sensor : sensors)
130 {
131 auto set = sensor.value("set", empty);
132 state_sensor_possible_states* possibleStates =
133 reinterpret_cast<state_sensor_possible_states*>(start);
134 possibleStates->state_set_id = set.value("id", 0);
135 HTOLE16(possibleStates->state_set_id);
136 possibleStates->possible_states_size = set.value("size", 0);
137
138 start += sizeof(possibleStates->state_set_id) +
139 sizeof(possibleStates->possible_states_size);
140 static const std::vector<uint8_t> emptyStates{};
Brad Bishop5079ac42021-08-19 18:35:06 -0400141 pldm::responder::pdr_utils::PossibleValues stateValues;
George Liuadbe1722020-05-09 19:20:19 +0800142 auto states = set.value("states", emptyStates);
143 for (const auto& state : states)
144 {
145 auto index = state / 8;
146 auto bit = state - (index * 8);
147 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
148 bf->byte |= 1 << bit;
149 stateValues.emplace_back(state);
150 }
151 start += possibleStates->possible_states_size;
152 auto dbusEntry = sensor.value("dbus", empty);
153 auto objectPath = dbusEntry.value("path", "");
154 auto interface = dbusEntry.value("interface", "");
155 auto propertyName = dbusEntry.value("property_name", "");
156 auto propertyType = dbusEntry.value("property_type", "");
157
Brad Bishop5079ac42021-08-19 18:35:06 -0400158 pldm::responder::pdr_utils::StatestoDbusVal dbusIdToValMap{};
George Liu821ebc42021-01-26 14:36:11 +0800159 pldm::utils::DBusMapping dbusMapping{};
George Liuadbe1722020-05-09 19:20:19 +0800160 try
161 {
162 auto service =
163 dBusIntf.getService(objectPath.c_str(), interface.c_str());
George Liu821ebc42021-01-26 14:36:11 +0800164
165 dbusMapping = pldm::utils::DBusMapping{
166 objectPath, interface, propertyName, propertyType};
Brad Bishop5079ac42021-08-19 18:35:06 -0400167 dbusIdToValMap = pldm::responder::pdr_utils::populateMapping(
George Liu821ebc42021-01-26 14:36:11 +0800168 propertyType, dbusEntry["property_values"], stateValues);
George Liuadbe1722020-05-09 19:20:19 +0800169 }
170 catch (const std::exception& e)
171 {
George Liu821ebc42021-01-26 14:36:11 +0800172 std::cerr << "D-Bus object path does not exist, sensor ID: "
173 << pdr->sensor_id << "\n";
George Liuadbe1722020-05-09 19:20:19 +0800174 }
175
George Liuadbe1722020-05-09 19:20:19 +0800176 dbusMappings.emplace_back(std::move(dbusMapping));
George Liu821ebc42021-01-26 14:36:11 +0800177 dbusValMaps.emplace_back(std::move(dbusIdToValMap));
George Liuadbe1722020-05-09 19:20:19 +0800178 }
179
180 handler.addDbusObjMaps(
181 pdr->sensor_id,
182 std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps)),
Brad Bishop5079ac42021-08-19 18:35:06 -0400183 pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
184 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liuadbe1722020-05-09 19:20:19 +0800185 pdrEntry.data = entry.data();
186 pdrEntry.size = pdrSize;
187 repo.addRecord(pdrEntry);
188 }
189}
190
191} // namespace pdr_state_sensor
192} // namespace responder
193} // namespace pldm