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