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