1 #include "pdr.hpp"
2 
3 #include <config.h>
4 #include <libpldm/platform.h>
5 
6 #include <phosphor-logging/lg2.hpp>
7 
8 #include <climits>
9 
10 PHOSPHOR_LOG2_USING;
11 
12 using namespace pldm::pdr;
13 
14 namespace pldm
15 {
16 namespace responder
17 {
18 namespace pdr_utils
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 = pldm_pdr_find_record(getPdr(), firstNum, &pdrData,
36                                        &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 = pldm_pdr_get_next_record(getPdr(), currRecord, &pdrData,
51                                            &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         error(
85             "dBusValues size is not equal to pv size, dBusValues Size: {DBUS_VAL_SIZE}, pv Size: {PV_SIZE}",
86             "DBUS_VAL_SIZE", dBusValues.size(), "PV_SIZE", pv.size());
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             error("Unknown D-Bus property type, TYPE={OTHER_TYPE}",
135                   "OTHER_TYPE", type.c_str());
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 =
161             [&possibleStates, &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 = std::make_tuple(std::move(entityInfo),
188                                       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