blob: 5093dcf3fc0b495a7af82a0b26e24af9c5ccb78b [file] [log] [blame]
George Liuadbe1722020-05-09 19:20:19 +08001#pragma once
2
3#include "libpldm/platform.h"
4
5#include "libpldmresponder/pdr_utils.hpp"
6
7namespace pldm
8{
9
10namespace responder
11{
12
13namespace pdr_state_sensor
14{
15
16using Json = nlohmann::json;
17
18static const Json empty{};
19
20/** @brief Parse PDR JSON file and generate state sensor PDR structure
21 *
22 * @param[in] json - the JSON Object with the state sensor PDR
23 * @param[out] handler - the Parser of PLDM command handler
24 * @param[out] repo - pdr::RepoInterface
25 *
26 */
27template <class DBusInterface, class Handler>
28void generateStateSensorPDR(const DBusInterface& dBusIntf, const Json& json,
29 Handler& handler, pdr_utils::RepoInterface& repo)
30{
31 static const std::vector<Json> emptyList{};
32 auto entries = json.value("entries", emptyList);
33 for (const auto& e : entries)
34 {
35 size_t pdrSize = 0;
36 auto sensors = e.value("sensors", emptyList);
37 for (const auto& sensor : sensors)
38 {
39 auto set = sensor.value("set", empty);
40 auto statesSize = set.value("size", 0);
41 if (!statesSize)
42 {
43 std::cerr << "Malformed PDR JSON return "
44 "pdrEntry;- no state set "
45 "info, TYPE="
46 << PLDM_STATE_SENSOR_PDR << "\n";
47 throw InternalFailure();
48 }
49 pdrSize += sizeof(state_sensor_possible_states) -
50 sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
51 }
52 pdrSize += sizeof(pldm_state_sensor_pdr) - sizeof(uint8_t);
53
54 std::vector<uint8_t> entry{};
55 entry.resize(pdrSize);
56
57 pldm_state_sensor_pdr* pdr =
58 reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
Manojkiran Edabcf91ac2021-03-14 13:50:48 +053059 if (!pdr)
60 {
61 std::cerr << "Failed to get state sensor PDR.\n";
62 continue;
63 }
George Liuadbe1722020-05-09 19:20:19 +080064 pdr->hdr.record_handle = 0;
65 pdr->hdr.version = 1;
66 pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
67 pdr->hdr.record_change_num = 0;
68 pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
69
70 HTOLE32(pdr->hdr.record_handle);
71 HTOLE16(pdr->hdr.record_change_num);
72 HTOLE16(pdr->hdr.length);
73
74 pdr->terminus_handle = 0;
75 pdr->sensor_id = handler.getNextSensorId();
George Liuc4ea6a92020-07-14 15:48:44 +080076
77 try
78 {
79 std::string entity_path = e.value("entity_path", "");
80 auto& associatedEntityMap = handler.getAssociateEntityMap();
81 if (entity_path != "" && associatedEntityMap.find(entity_path) !=
82 associatedEntityMap.end())
83 {
84 pdr->entity_type =
85 associatedEntityMap.at(entity_path).entity_type;
86 pdr->entity_instance =
87 associatedEntityMap.at(entity_path).entity_instance_num;
88 pdr->container_id =
89 associatedEntityMap.at(entity_path).entity_container_id;
90 }
91 else
92 {
93 pdr->entity_type = e.value("type", 0);
94 pdr->entity_instance = e.value("instance", 0);
95 pdr->container_id = e.value("container", 0);
96 }
97 }
98 catch (const std::exception& ex)
99 {
100 pdr->entity_type = e.value("type", 0);
101 pdr->entity_instance = e.value("instance", 0);
102 pdr->container_id = e.value("container", 0);
103 }
104
George Liuadbe1722020-05-09 19:20:19 +0800105 pdr->sensor_init = PLDM_NO_INIT;
106 pdr->sensor_auxiliary_names_pdr = false;
107 if (sensors.size() > 8)
108 {
109 throw std::runtime_error("sensor size must be less than 8");
110 }
111 pdr->composite_sensor_count = sensors.size();
112
113 HTOLE16(pdr->terminus_handle);
114 HTOLE16(pdr->sensor_id);
115 HTOLE16(pdr->entity_type);
116 HTOLE16(pdr->entity_instance);
117 HTOLE16(pdr->container_id);
118
119 DbusMappings dbusMappings{};
120 DbusValMaps dbusValMaps{};
121 uint8_t* start =
122 entry.data() + sizeof(pldm_state_sensor_pdr) - sizeof(uint8_t);
123 for (const auto& sensor : sensors)
124 {
125 auto set = sensor.value("set", empty);
126 state_sensor_possible_states* possibleStates =
127 reinterpret_cast<state_sensor_possible_states*>(start);
128 possibleStates->state_set_id = set.value("id", 0);
129 HTOLE16(possibleStates->state_set_id);
130 possibleStates->possible_states_size = set.value("size", 0);
131
132 start += sizeof(possibleStates->state_set_id) +
133 sizeof(possibleStates->possible_states_size);
134 static const std::vector<uint8_t> emptyStates{};
135 PossibleValues stateValues;
136 auto states = set.value("states", emptyStates);
137 for (const auto& state : states)
138 {
139 auto index = state / 8;
140 auto bit = state - (index * 8);
141 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
142 bf->byte |= 1 << bit;
143 stateValues.emplace_back(state);
144 }
145 start += possibleStates->possible_states_size;
146 auto dbusEntry = sensor.value("dbus", empty);
147 auto objectPath = dbusEntry.value("path", "");
148 auto interface = dbusEntry.value("interface", "");
149 auto propertyName = dbusEntry.value("property_name", "");
150 auto propertyType = dbusEntry.value("property_type", "");
151
George Liu821ebc42021-01-26 14:36:11 +0800152 StatestoDbusVal dbusIdToValMap{};
153 pldm::utils::DBusMapping dbusMapping{};
George Liuadbe1722020-05-09 19:20:19 +0800154 try
155 {
156 auto service =
157 dBusIntf.getService(objectPath.c_str(), interface.c_str());
George Liu821ebc42021-01-26 14:36:11 +0800158
159 dbusMapping = pldm::utils::DBusMapping{
160 objectPath, interface, propertyName, propertyType};
161 dbusIdToValMap = populateMapping(
162 propertyType, dbusEntry["property_values"], stateValues);
George Liuadbe1722020-05-09 19:20:19 +0800163 }
164 catch (const std::exception& e)
165 {
George Liu821ebc42021-01-26 14:36:11 +0800166 std::cerr << "D-Bus object path does not exist, sensor ID: "
167 << pdr->sensor_id << "\n";
George Liuadbe1722020-05-09 19:20:19 +0800168 }
169
George Liuadbe1722020-05-09 19:20:19 +0800170 dbusMappings.emplace_back(std::move(dbusMapping));
George Liu821ebc42021-01-26 14:36:11 +0800171 dbusValMaps.emplace_back(std::move(dbusIdToValMap));
George Liuadbe1722020-05-09 19:20:19 +0800172 }
173
174 handler.addDbusObjMaps(
175 pdr->sensor_id,
176 std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps)),
177 TypeId::PLDM_SENSOR_ID);
178 PdrEntry pdrEntry{};
179 pdrEntry.data = entry.data();
180 pdrEntry.size = pdrSize;
181 repo.addRecord(pdrEntry);
182 }
183}
184
185} // namespace pdr_state_sensor
186} // namespace responder
187} // namespace pldm