1 #include "libpldm/platform.h"
2 
3 #include "pdr.hpp"
4 
5 #include <climits>
6 
7 namespace pldm
8 {
9 
10 namespace responder
11 {
12 
13 namespace pdr_utils
14 {
15 
16 pldm_pdr* Repo::getPdr() const
17 {
18     return repo;
19 }
20 
21 RecordHandle Repo::addRecord(const PdrEntry& pdrEntry)
22 {
23     return pldm_pdr_add(repo, pdrEntry.data, pdrEntry.size,
24                         pdrEntry.handle.recordHandle, false);
25 }
26 
27 const pldm_pdr_record* Repo::getFirstRecord(PdrEntry& pdrEntry)
28 {
29     constexpr uint32_t firstNum = 0;
30     uint8_t* pdrData = nullptr;
31     auto record =
32         pldm_pdr_find_record(getPdr(), firstNum, &pdrData, &pdrEntry.size,
33                              &pdrEntry.handle.nextRecordHandle);
34     if (record)
35     {
36         pdrEntry.data = pdrData;
37     }
38 
39     return record;
40 }
41 
42 const pldm_pdr_record* Repo::getNextRecord(const pldm_pdr_record* currRecord,
43                                            PdrEntry& pdrEntry)
44 {
45     uint8_t* pdrData = nullptr;
46     auto record =
47         pldm_pdr_get_next_record(getPdr(), currRecord, &pdrData, &pdrEntry.size,
48                                  &pdrEntry.handle.nextRecordHandle);
49     if (record)
50     {
51         pdrEntry.data = pdrData;
52     }
53 
54     return record;
55 }
56 
57 uint32_t Repo::getRecordHandle(const pldm_pdr_record* record) const
58 {
59     return pldm_pdr_get_record_handle(getPdr(), record);
60 }
61 
62 uint32_t Repo::getRecordCount()
63 {
64     return pldm_pdr_get_record_count(getPdr());
65 }
66 
67 bool Repo::empty()
68 {
69     return !getRecordCount();
70 }
71 
72 StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues,
73                                 const PossibleValues& pv)
74 {
75     size_t pos = 0;
76     pldm::utils::PropertyValue value;
77     StatestoDbusVal valueMap;
78     if (dBusValues.size() != pv.size())
79     {
80         std::cerr
81             << "dBusValues size is not equal to pv size, dBusValues Size: "
82             << dBusValues.size() << ", pv Size: " << pv.size() << "\n";
83 
84         return {};
85     }
86 
87     for (auto it = dBusValues.begin(); it != dBusValues.end(); ++it, ++pos)
88     {
89         if (type == "uint8_t")
90         {
91             value = static_cast<uint8_t>(it.value());
92         }
93         else if (type == "uint16_t")
94         {
95             value = static_cast<uint16_t>(it.value());
96         }
97         else if (type == "uint32_t")
98         {
99             value = static_cast<uint32_t>(it.value());
100         }
101         else if (type == "uint64_t")
102         {
103             value = static_cast<uint64_t>(it.value());
104         }
105         else if (type == "int16_t")
106         {
107             value = static_cast<int16_t>(it.value());
108         }
109         else if (type == "int32_t")
110         {
111             value = static_cast<int32_t>(it.value());
112         }
113         else if (type == "int64_t")
114         {
115             value = static_cast<int64_t>(it.value());
116         }
117         else if (type == "bool")
118         {
119             value = static_cast<bool>(it.value());
120         }
121         else if (type == "double")
122         {
123             value = static_cast<double>(it.value());
124         }
125         else if (type == "string")
126         {
127             value = static_cast<std::string>(it.value());
128         }
129         else
130         {
131             std::cerr << "Unknown D-Bus property type, TYPE=" << type.c_str()
132                       << "\n";
133             return {};
134         }
135 
136         valueMap.emplace(pv[pos], value);
137     }
138 
139     return valueMap;
140 }
141 
142 std::tuple<TerminusHandle, SensorID, SensorInfo>
143     parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr)
144 {
145     auto pdr =
146         reinterpret_cast<const pldm_state_sensor_pdr*>(stateSensorPdr.data());
147     CompositeSensorStates sensors{};
148     auto statesPtr = pdr->possible_states;
149     auto compositeSensorCount = pdr->composite_sensor_count;
150 
151     while (compositeSensorCount--)
152     {
153         auto state =
154             reinterpret_cast<const state_sensor_possible_states*>(statesPtr);
155         PossibleStates possibleStates{};
156         uint8_t possibleStatesPos{};
157         auto updateStates = [&possibleStates,
158                              &possibleStatesPos](const bitfield8_t& val) {
159             for (int i = 0; i < CHAR_BIT; i++)
160             {
161                 if (val.byte & (1 << i))
162                 {
163                     possibleStates.insert(possibleStatesPos * CHAR_BIT + i);
164                 }
165             }
166             possibleStatesPos++;
167         };
168         std::for_each(&state->states[0],
169                       &state->states[state->possible_states_size],
170                       updateStates);
171 
172         sensors.emplace_back(std::move(possibleStates));
173         if (compositeSensorCount)
174         {
175             statesPtr += sizeof(state_sensor_possible_states) +
176                          state->possible_states_size - 1;
177         }
178     }
179 
180     auto entityInfo =
181         std::make_tuple(static_cast<ContainerID>(pdr->container_id),
182                         static_cast<EntityType>(pdr->entity_type),
183                         static_cast<EntityInstance>(pdr->entity_instance));
184     auto sensorInfo =
185         std::make_tuple(std::move(entityInfo), std::move(sensors));
186     return std::make_tuple(pdr->terminus_handle, pdr->sensor_id,
187                            std::move(sensorInfo));
188 }
189 
190 } // namespace pdr_utils
191 } // namespace responder
192 } // namespace pldm
193