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