blob: c3134bd826682283122765a5f945b97468f32e75 [file] [log] [blame]
Gilbert Chen6c7fed42022-02-22 15:40:17 +00001#pragma once
2
Dung Caob6d39432024-06-05 03:46:47 +00003#include "libpldm/fru.h"
Gilbert Chen6c7fed42022-02-22 15:40:17 +00004#include "libpldm/platform.h"
5
6#include "common/types.hpp"
Dung Caob6d39432024-06-05 03:46:47 +00007#include "dbus_impl_fru.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +00008#include "numeric_sensor.hpp"
Gilbert Chen6c7fed42022-02-22 15:40:17 +00009#include "requester/handler.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +000010#include "terminus.hpp"
Gilbert Chen6c7fed42022-02-22 15:40:17 +000011
12#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
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000142 /** @brief The getter to get terminus's mctp medium */
Thu Nguyen9fc79122024-09-10 10:15:01 +0000143 std::optional<std::string_view> getTerminusName()
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000144 {
Thu Nguyen9fc79122024-09-10 10:15:01 +0000145 if (terminusName.empty())
146 {
147 return std::nullopt;
148 }
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000149 return terminusName;
150 }
151
Dung Caob6d39432024-06-05 03:46:47 +0000152 /** @brief Parse record data from FRU table
153 *
154 * @param[in] fruData - pointer to FRU record table
155 * @param[in] fruLen - FRU table length
156 */
157 void updateInventoryWithFru(const uint8_t* fruData, const size_t fruLen);
158
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000159 /** @brief A list of PDRs fetched from Terminus */
160 std::vector<std::vector<uint8_t>> pdrs{};
161
162 /** @brief A flag to indicate if terminus has been initialized */
163 bool initialized = false;
164
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000165 /** @brief maximum message buffer size the terminus can send and receive */
166 uint16_t maxBufferSize;
167
Thu Nguyen51d66b52024-08-06 09:15:55 +0000168 /** @brief This value indicates the event messaging styles supported by the
169 * terminus
170 */
171 bitfield8_t synchronyConfigurationSupported;
172
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000173 /** @brief A list of numericSensors */
174 std::vector<std::shared_ptr<NumericSensor>> numericSensors{};
175
Dung Caof48015b2023-11-21 04:38:29 +0000176 /** @brief The flag indicates that the terminus FIFO contains a large
177 * message that will require a multipart transfer via the
178 * PollForPlatformEvent command
179 */
180 bool pollEvent;
181
182 /** @brief The sensor id is used in pollForPlatformMessage command */
183 uint16_t pollEventId;
184
185 /** @brief The dataTransferHandle from `pldmMessagePollEvent` event and will
186 * be used as `dataTransferHandle` for pollForPlatformMessage
187 * command.
188 */
189 uint32_t pollDataTransferHandle;
190
Gilbert Chende2a1322022-05-24 15:35:21 +0100191 /** @brief Get Sensor Auxiliary Names by sensorID
192 *
193 * @param[in] id - sensor ID
194 * @return sensor auxiliary names
195 */
196 std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id);
197
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000198 /** @brief Get Numeric Sensor Object by sensorID
199 *
200 * @param[in] id - sensor ID
201 *
202 * @return sensor object
203 */
204 std::shared_ptr<NumericSensor> getSensorObject(SensorId id);
205
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000206 private:
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000207 /** @brief Find the Terminus Name from the Entity Auxiliary name list
208 * The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
209 * @return terminus name in string option
210 */
211 std::optional<std::string_view> findTerminusName();
212
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000213 /** @brief Construct the NumericSensor sensor class for the PLDM sensor.
214 * The NumericSensor class will handle create D-Bus object path,
215 * provide the APIs to update sensor value, threshold...
216 *
217 * @param[in] pdr - the numeric sensor PDR info
218 */
219 void addNumericSensor(
220 const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr);
221
Gilbert Chende2a1322022-05-24 15:35:21 +0100222 /** @brief Parse the numeric sensor PDRs
223 *
224 * @param[in] pdrData - the response PDRs from GetPDR command
225 * @return pointer to numeric sensor info struct
226 */
Patrick Williams366507c2025-02-03 14:28:01 -0500227 std::shared_ptr<pldm_numeric_sensor_value_pdr> parseNumericSensorPDR(
228 const std::vector<uint8_t>& pdrData);
Gilbert Chende2a1322022-05-24 15:35:21 +0100229
230 /** @brief Parse the sensor Auxiliary name PDRs
231 *
232 * @param[in] pdrData - the response PDRs from GetPDR command
233 * @return pointer to sensor Auxiliary name info struct
234 */
Patrick Williams366507c2025-02-03 14:28:01 -0500235 std::shared_ptr<SensorAuxiliaryNames> parseSensorAuxiliaryNamesPDR(
236 const std::vector<uint8_t>& pdrData);
Gilbert Chende2a1322022-05-24 15:35:21 +0100237
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000238 /** @brief Parse the Entity Auxiliary name PDRs
239 *
240 * @param[in] pdrData - the response PDRs from GetPDR command
241 * @return pointer to Entity Auxiliary name info struct
242 */
Patrick Williams366507c2025-02-03 14:28:01 -0500243 std::shared_ptr<EntityAuxiliaryNames> parseEntityAuxiliaryNamesPDR(
244 const std::vector<uint8_t>& pdrData);
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000245
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000246 /** @brief Construct the NumericSensor sensor class for the compact numeric
247 * PLDM sensor.
248 *
249 * @param[in] pdr - the compact numeric sensor PDR info
250 */
251 void addCompactNumericSensor(
252 const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr);
253
Gilbert Chende2a1322022-05-24 15:35:21 +0100254 /** @brief Parse the compact numeric sensor PDRs
255 *
256 * @param[in] pdrData - the response PDRs from GetPDR command
257 * @return pointer to compact numeric sensor info struct
258 */
259 std::shared_ptr<pldm_compact_numeric_sensor_pdr>
260 parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData);
261
262 /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs
263 *
264 * @param[in] pdrData - the response PDRs from GetPDR command
265 * @return pointer to sensor Auxiliary name info struct
266 */
Patrick Williams366507c2025-02-03 14:28:01 -0500267 std::shared_ptr<SensorAuxiliaryNames> parseCompactNumericSensorNames(
268 const std::vector<uint8_t>& pdrData);
Gilbert Chende2a1322022-05-24 15:35:21 +0100269
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000270 /** @brief Create the terminus inventory path to
271 * /xyz/openbmc_project/inventory/Item/Board/.
272 *
273 * @param[in] tName - the terminus name
274 * @return true/false: True if there is no error in creating inventory path
275 *
276 */
277 bool createInventoryPath(std::string tName);
278
Chau Ly38a09d22025-03-05 05:47:43 +0000279 /** @brief Get sensor names from Sensor Auxiliary Names PDRs
280 *
281 * @param[in] sensorId - Sensor ID
282 * @param[in] isEffecter - This is an effecter, not a sensor
283 * @return vector of sensor name strings
284 *
285 */
286 std::vector<std::string> getSensorNames(const SensorId& sensorId);
287
Chaul Lyfdf61cc2025-01-22 07:55:45 +0000288 /** @brief Add the next sensor PDR to this terminus, iterated by
289 * sensorPdrIt.
290 */
291 void addNextSensorFromPDRs();
292
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000293 /* @brief The terminus's TID */
294 pldm_tid_t tid;
295
296 /* @brief The supported PLDM command types of the terminus */
297 std::bitset<64> supportedTypes;
298
299 /** @brief Store supported PLDM commands of a terminus
300 * Maximum number of PLDM Type is PLDM_MAX_TYPES
301 * Maximum number of PLDM command for each type is
302 * PLDM_MAX_CMDS_PER_TYPE.
303 * Each uint8_t can store the supported state of 8 PLDM commands.
304 * Size of supportedCmds will be
305 * PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8).
306 */
307 std::vector<uint8_t> supportedCmds;
Gilbert Chende2a1322022-05-24 15:35:21 +0100308
Thu Nguyen6e615622024-06-22 02:10:34 +0000309 /* @brief The PLDM supported type version */
310 std::map<uint8_t, ver32_t> supportedTypeVersions;
311
Gilbert Chende2a1322022-05-24 15:35:21 +0100312 /* @brief Sensor Auxiliary Name list */
313 std::vector<std::shared_ptr<SensorAuxiliaryNames>>
314 sensorAuxiliaryNamesTbl{};
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000315
316 /* @brief Entity Auxiliary Name list */
317 std::vector<std::shared_ptr<EntityAuxiliaryNames>>
318 entityAuxiliaryNamesTbl{};
319
320 /** @brief Terminus name */
321 EntityName terminusName{};
Dung Caob6d39432024-06-05 03:46:47 +0000322 /* @brief The pointer of inventory D-Bus interface for the terminus */
323 std::unique_ptr<pldm::dbus_api::PldmEntityReq> inventoryItemBoardInft =
324 nullptr;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000325
326 /* @brief Inventory D-Bus object path of the terminus */
327 std::string inventoryPath;
Chaul Lyfdf61cc2025-01-22 07:55:45 +0000328
329 /** @brief reference of main event loop of pldmd, primarily used to schedule
330 * work
331 */
332 sdeventplus::Event& event;
333
334 /** @brief The event source to defer sensor creation tasks to event loop*/
335 std::unique_ptr<sdeventplus::source::Defer> sensorCreationEvent;
336
337 /** @brief Numeric Sensor PDR list */
338 std::vector<std::shared_ptr<pldm_numeric_sensor_value_pdr>>
339 numericSensorPdrs{};
340
341 /** @brief Compact Numeric Sensor PDR list */
342 std::vector<std::shared_ptr<pldm_compact_numeric_sensor_pdr>>
343 compactNumericSensorPdrs{};
344
345 /** @brief Iteration to loop through sensor PDRs when adding sensors */
346 SensorId sensorPdrIt = 0;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000347};
348} // namespace platform_mc
349} // namespace pldm