blob: fd878b5a48420ffe8eb4215949404f4d632a1bdc [file] [log] [blame]
Gilbert Chen6c7fed42022-02-22 15:40:17 +00001#pragma once
2
Gilbert Chen6c7fed42022-02-22 15:40:17 +00003#include "common/types.hpp"
Dung Caob6d39432024-06-05 03:46:47 +00004#include "dbus_impl_fru.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +00005#include "numeric_sensor.hpp"
Gilbert Chen6c7fed42022-02-22 15:40:17 +00006#include "requester/handler.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +00007#include "terminus.hpp"
Gilbert Chen6c7fed42022-02-22 15:40:17 +00008
Manojkiran Edafe252792025-03-13 19:24:19 +05309#include <libpldm/fru.h>
10#include <libpldm/platform.h>
11
Gilbert Chen6c7fed42022-02-22 15:40:17 +000012#include <sdbusplus/server/object.hpp>
13#include <sdeventplus/event.hpp>
Gilbert Chen6c7fed42022-02-22 15:40:17 +000014
15#include <algorithm>
16#include <bitset>
Gilbert Chende2a1322022-05-24 15:35:21 +010017#include <string>
18#include <tuple>
19#include <utility>
Gilbert Chen6c7fed42022-02-22 15:40:17 +000020#include <vector>
21
22namespace pldm
23{
24namespace platform_mc
25{
26
Thu Nguyenb8cf46b2024-06-15 02:44:35 +000027using ContainerID = uint16_t;
28using EntityInstanceNumber = uint16_t;
29using EntityName = std::string;
30using EntityType = uint16_t;
Gilbert Chende2a1322022-05-24 15:35:21 +010031using SensorId = uint16_t;
32using SensorCnt = uint8_t;
33using NameLanguageTag = std::string;
34using SensorName = std::string;
35using SensorAuxiliaryNames = std::tuple<
36 SensorId, SensorCnt,
37 std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>>>;
38
Thu Nguyenb8cf46b2024-06-15 02:44:35 +000039/** @struct EntityKey
40 *
41 * EntityKey uniquely identifies the PLDM entity and a combination of Entity
42 * Type, Entity Instance Number, Entity Container ID
43 *
44 */
45struct EntityKey
46{
47 EntityType type; //!< Entity type
48 EntityInstanceNumber instanceIdx; //!< Entity instance number
49 ContainerID containerId; //!< Entity container ID
50
51 bool operator==(const EntityKey& e) const
52 {
53 return ((type == e.type) && (instanceIdx == e.instanceIdx) &&
54 (containerId == e.containerId));
55 }
56};
57
58using AuxiliaryNames = std::vector<std::pair<NameLanguageTag, std::string>>;
59using EntityKey = struct EntityKey;
60using EntityAuxiliaryNames = std::tuple<EntityKey, AuxiliaryNames>;
61
Gilbert Chen6c7fed42022-02-22 15:40:17 +000062/**
63 * @brief Terminus
64 *
65 * Terminus class holds the TID, supported PLDM Type or PDRs which are needed by
66 * other manager class for sensor monitoring and control.
67 */
68class Terminus
69{
70 public:
Chaul Lyfdf61cc2025-01-22 07:55:45 +000071 Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes,
72 sdeventplus::Event& event);
Gilbert Chen6c7fed42022-02-22 15:40:17 +000073
74 /** @brief Check if the terminus supports the PLDM type message
75 *
76 * @param[in] type - PLDM Type
77 * @return support state - True if support, otherwise False
78 */
79 bool doesSupportType(uint8_t type);
80
81 /** @brief Check if the terminus supports the PLDM command message
82 *
83 * @param[in] type - PLDM Type
84 * @param[in] command - PLDM command
85 * @return support state - True if support, otherwise False
86 */
87 bool doesSupportCommand(uint8_t type, uint8_t command);
88
89 /** @brief Set the supported PLDM commands for terminus
90 *
91 * @param[in] cmds - bit mask of the supported PLDM commands
92 * @return success state - True if success, otherwise False
93 */
94 bool setSupportedCommands(const std::vector<uint8_t>& cmds)
95 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040096 const size_t expectedSize =
97 PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
Gilbert Chen6c7fed42022-02-22 15:40:17 +000098 if (cmds.empty() || cmds.size() != expectedSize)
99 {
100 lg2::error(
101 "setSupportedCommands received invalid bit mask size. Expected: {EXPECTED}, Received: {RECEIVED}",
102 "EXPECTED", expectedSize, "RECEIVED", cmds.size());
103 return false;
104 }
105
106 /* Assign Vector supportedCmds by Vector cmds */
107 supportedCmds.resize(cmds.size());
108 std::copy(cmds.begin(), cmds.begin() + cmds.size(),
109 supportedCmds.begin());
110
111 return true;
112 }
Gilbert Chende2a1322022-05-24 15:35:21 +0100113
Thu Nguyen6e615622024-06-22 02:10:34 +0000114 /** @brief Set the PLDM supported type version for terminus
115 *
116 * @param[in] type - PLDM supported types
117 * @param[in] version - PLDM supported type version
118 * @return success state - True if success, otherwise False
119 */
120 inline bool setSupportedTypeVersions(const uint8_t type,
121 const ver32_t version)
122 {
123 if (type > PLDM_MAX_TYPES || type >= supportedTypeVersions.size())
124 {
125 return false;
126 }
127 supportedTypeVersions[type] = version;
128
129 return true;
130 }
131
Gilbert Chende2a1322022-05-24 15:35:21 +0100132 /** @brief Parse the PDRs stored in the member variable, pdrs.
133 */
134 void parseTerminusPDRs();
135
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000136 /** @brief The getter to return terminus's TID */
137 pldm_tid_t getTid()
138 {
139 return tid;
140 }
141
Kevin Tung502bd602025-08-01 10:05:47 +0800142 /** @brief The setter to set terminus's mctp medium */
143 void setTerminusName(const EntityName& tName)
144 {
145 terminusName = tName;
146 }
147
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000148 /** @brief The getter to get terminus's mctp medium */
Thu Nguyen9fc79122024-09-10 10:15:01 +0000149 std::optional<std::string_view> getTerminusName()
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000150 {
Thu Nguyen9fc79122024-09-10 10:15:01 +0000151 if (terminusName.empty())
152 {
153 return std::nullopt;
154 }
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000155 return terminusName;
156 }
157
Dung Caob6d39432024-06-05 03:46:47 +0000158 /** @brief Parse record data from FRU table
159 *
160 * @param[in] fruData - pointer to FRU record table
161 * @param[in] fruLen - FRU table length
162 */
163 void updateInventoryWithFru(const uint8_t* fruData, const size_t fruLen);
164
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000165 /** @brief A list of PDRs fetched from Terminus */
166 std::vector<std::vector<uint8_t>> pdrs{};
167
168 /** @brief A flag to indicate if terminus has been initialized */
169 bool initialized = false;
170
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000171 /** @brief maximum message buffer size the terminus can send and receive */
172 uint16_t maxBufferSize;
173
Thu Nguyen51d66b52024-08-06 09:15:55 +0000174 /** @brief This value indicates the event messaging styles supported by the
175 * terminus
176 */
177 bitfield8_t synchronyConfigurationSupported;
178
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000179 /** @brief A list of numericSensors */
180 std::vector<std::shared_ptr<NumericSensor>> numericSensors{};
181
Dung Caof48015b2023-11-21 04:38:29 +0000182 /** @brief The flag indicates that the terminus FIFO contains a large
183 * message that will require a multipart transfer via the
184 * PollForPlatformEvent command
185 */
186 bool pollEvent;
187
188 /** @brief The sensor id is used in pollForPlatformMessage command */
189 uint16_t pollEventId;
190
191 /** @brief The dataTransferHandle from `pldmMessagePollEvent` event and will
192 * be used as `dataTransferHandle` for pollForPlatformMessage
193 * command.
194 */
195 uint32_t pollDataTransferHandle;
196
Gilbert Chende2a1322022-05-24 15:35:21 +0100197 /** @brief Get Sensor Auxiliary Names by sensorID
198 *
199 * @param[in] id - sensor ID
200 * @return sensor auxiliary names
201 */
202 std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id);
203
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000204 /** @brief Get Numeric Sensor Object by sensorID
205 *
206 * @param[in] id - sensor ID
207 *
208 * @return sensor object
209 */
210 std::shared_ptr<NumericSensor> getSensorObject(SensorId id);
211
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000212 private:
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000213 /** @brief Find the Terminus Name from the Entity Auxiliary name list
214 * The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
215 * @return terminus name in string option
216 */
217 std::optional<std::string_view> findTerminusName();
218
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000219 /** @brief Construct the NumericSensor sensor class for the PLDM sensor.
220 * The NumericSensor class will handle create D-Bus object path,
221 * provide the APIs to update sensor value, threshold...
222 *
223 * @param[in] pdr - the numeric sensor PDR info
224 */
225 void addNumericSensor(
226 const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr);
227
Gilbert Chende2a1322022-05-24 15:35:21 +0100228 /** @brief Parse the numeric sensor PDRs
229 *
230 * @param[in] pdrData - the response PDRs from GetPDR command
231 * @return pointer to numeric sensor info struct
232 */
Patrick Williams366507c2025-02-03 14:28:01 -0500233 std::shared_ptr<pldm_numeric_sensor_value_pdr> parseNumericSensorPDR(
234 const std::vector<uint8_t>& pdrData);
Gilbert Chende2a1322022-05-24 15:35:21 +0100235
236 /** @brief Parse the sensor Auxiliary name PDRs
237 *
238 * @param[in] pdrData - the response PDRs from GetPDR command
239 * @return pointer to sensor Auxiliary name info struct
240 */
Patrick Williams366507c2025-02-03 14:28:01 -0500241 std::shared_ptr<SensorAuxiliaryNames> parseSensorAuxiliaryNamesPDR(
242 const std::vector<uint8_t>& pdrData);
Gilbert Chende2a1322022-05-24 15:35:21 +0100243
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000244 /** @brief Parse the Entity Auxiliary name PDRs
245 *
246 * @param[in] pdrData - the response PDRs from GetPDR command
247 * @return pointer to Entity Auxiliary name info struct
248 */
Patrick Williams366507c2025-02-03 14:28:01 -0500249 std::shared_ptr<EntityAuxiliaryNames> parseEntityAuxiliaryNamesPDR(
250 const std::vector<uint8_t>& pdrData);
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000251
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000252 /** @brief Construct the NumericSensor sensor class for the compact numeric
253 * PLDM sensor.
254 *
255 * @param[in] pdr - the compact numeric sensor PDR info
256 */
257 void addCompactNumericSensor(
258 const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr);
259
Gilbert Chende2a1322022-05-24 15:35:21 +0100260 /** @brief Parse the compact numeric sensor PDRs
261 *
262 * @param[in] pdrData - the response PDRs from GetPDR command
263 * @return pointer to compact numeric sensor info struct
264 */
265 std::shared_ptr<pldm_compact_numeric_sensor_pdr>
266 parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData);
267
268 /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs
269 *
270 * @param[in] pdrData - the response PDRs from GetPDR command
271 * @return pointer to sensor Auxiliary name info struct
272 */
Patrick Williams366507c2025-02-03 14:28:01 -0500273 std::shared_ptr<SensorAuxiliaryNames> parseCompactNumericSensorNames(
274 const std::vector<uint8_t>& pdrData);
Gilbert Chende2a1322022-05-24 15:35:21 +0100275
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000276 /** @brief Create the terminus inventory path to
277 * /xyz/openbmc_project/inventory/Item/Board/.
278 *
279 * @param[in] tName - the terminus name
280 * @return true/false: True if there is no error in creating inventory path
281 *
282 */
283 bool createInventoryPath(std::string tName);
284
Chau Ly38a09d22025-03-05 05:47:43 +0000285 /** @brief Get sensor names from Sensor Auxiliary Names PDRs
286 *
287 * @param[in] sensorId - Sensor ID
288 * @param[in] isEffecter - This is an effecter, not a sensor
289 * @return vector of sensor name strings
290 *
291 */
292 std::vector<std::string> getSensorNames(const SensorId& sensorId);
293
Chaul Lyfdf61cc2025-01-22 07:55:45 +0000294 /** @brief Add the next sensor PDR to this terminus, iterated by
295 * sensorPdrIt.
296 */
297 void addNextSensorFromPDRs();
298
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000299 /* @brief The terminus's TID */
300 pldm_tid_t tid;
301
302 /* @brief The supported PLDM command types of the terminus */
303 std::bitset<64> supportedTypes;
304
305 /** @brief Store supported PLDM commands of a terminus
306 * Maximum number of PLDM Type is PLDM_MAX_TYPES
307 * Maximum number of PLDM command for each type is
308 * PLDM_MAX_CMDS_PER_TYPE.
309 * Each uint8_t can store the supported state of 8 PLDM commands.
310 * Size of supportedCmds will be
311 * PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8).
312 */
313 std::vector<uint8_t> supportedCmds;
Gilbert Chende2a1322022-05-24 15:35:21 +0100314
Thu Nguyen6e615622024-06-22 02:10:34 +0000315 /* @brief The PLDM supported type version */
316 std::map<uint8_t, ver32_t> supportedTypeVersions;
317
Gilbert Chende2a1322022-05-24 15:35:21 +0100318 /* @brief Sensor Auxiliary Name list */
319 std::vector<std::shared_ptr<SensorAuxiliaryNames>>
320 sensorAuxiliaryNamesTbl{};
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000321
322 /* @brief Entity Auxiliary Name list */
323 std::vector<std::shared_ptr<EntityAuxiliaryNames>>
324 entityAuxiliaryNamesTbl{};
325
326 /** @brief Terminus name */
327 EntityName terminusName{};
Dung Caob6d39432024-06-05 03:46:47 +0000328 /* @brief The pointer of inventory D-Bus interface for the terminus */
329 std::unique_ptr<pldm::dbus_api::PldmEntityReq> inventoryItemBoardInft =
330 nullptr;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000331
332 /* @brief Inventory D-Bus object path of the terminus */
333 std::string inventoryPath;
Chaul Lyfdf61cc2025-01-22 07:55:45 +0000334
335 /** @brief reference of main event loop of pldmd, primarily used to schedule
336 * work
337 */
338 sdeventplus::Event& event;
339
340 /** @brief The event source to defer sensor creation tasks to event loop*/
341 std::unique_ptr<sdeventplus::source::Defer> sensorCreationEvent;
342
343 /** @brief Numeric Sensor PDR list */
344 std::vector<std::shared_ptr<pldm_numeric_sensor_value_pdr>>
345 numericSensorPdrs{};
346
347 /** @brief Compact Numeric Sensor PDR list */
348 std::vector<std::shared_ptr<pldm_compact_numeric_sensor_pdr>>
349 compactNumericSensorPdrs{};
350
351 /** @brief Iteration to loop through sensor PDRs when adding sensors */
352 SensorId sensorPdrIt = 0;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000353};
354} // namespace platform_mc
355} // namespace pldm