blob: e818d322643e0e23c6b492baa7cf0c85193ef978 [file] [log] [blame]
Gilbert Chen6c7fed42022-02-22 15:40:17 +00001#pragma once
2
3#include "libpldm/platform.h"
4
5#include "common/types.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +00006#include "numeric_sensor.hpp"
Gilbert Chen6c7fed42022-02-22 15:40:17 +00007#include "requester/handler.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +00008#include "terminus.hpp"
Gilbert Chen6c7fed42022-02-22 15:40:17 +00009
10#include <sdbusplus/server/object.hpp>
11#include <sdeventplus/event.hpp>
12#include <xyz/openbmc_project/Inventory/Item/Board/server.hpp>
13
14#include <algorithm>
15#include <bitset>
Gilbert Chende2a1322022-05-24 15:35:21 +010016#include <string>
17#include <tuple>
18#include <utility>
Gilbert Chen6c7fed42022-02-22 15:40:17 +000019#include <vector>
20
21namespace pldm
22{
23namespace platform_mc
24{
25
Thu Nguyenb8cf46b2024-06-15 02:44:35 +000026using ContainerID = uint16_t;
27using EntityInstanceNumber = uint16_t;
28using EntityName = std::string;
29using EntityType = uint16_t;
Gilbert Chende2a1322022-05-24 15:35:21 +010030using SensorId = uint16_t;
31using SensorCnt = uint8_t;
32using NameLanguageTag = std::string;
33using SensorName = std::string;
34using SensorAuxiliaryNames = std::tuple<
35 SensorId, SensorCnt,
36 std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>>>;
Thu Nguyen3c5486d2024-08-01 08:03:08 +000037using InventoryItemBoardIntf = sdbusplus::server::object_t<
38 sdbusplus::xyz::openbmc_project::Inventory::Item::server::Board>;
Gilbert Chende2a1322022-05-24 15:35:21 +010039
Thu Nguyenb8cf46b2024-06-15 02:44:35 +000040/** @struct EntityKey
41 *
42 * EntityKey uniquely identifies the PLDM entity and a combination of Entity
43 * Type, Entity Instance Number, Entity Container ID
44 *
45 */
46struct EntityKey
47{
48 EntityType type; //!< Entity type
49 EntityInstanceNumber instanceIdx; //!< Entity instance number
50 ContainerID containerId; //!< Entity container ID
51
52 bool operator==(const EntityKey& e) const
53 {
54 return ((type == e.type) && (instanceIdx == e.instanceIdx) &&
55 (containerId == e.containerId));
56 }
57};
58
59using AuxiliaryNames = std::vector<std::pair<NameLanguageTag, std::string>>;
60using EntityKey = struct EntityKey;
61using EntityAuxiliaryNames = std::tuple<EntityKey, AuxiliaryNames>;
62
Gilbert Chen6c7fed42022-02-22 15:40:17 +000063/**
64 * @brief Terminus
65 *
66 * Terminus class holds the TID, supported PLDM Type or PDRs which are needed by
67 * other manager class for sensor monitoring and control.
68 */
69class Terminus
70{
71 public:
72 Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes);
73
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
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000152 /** @brief A list of PDRs fetched from Terminus */
153 std::vector<std::vector<uint8_t>> pdrs{};
154
155 /** @brief A flag to indicate if terminus has been initialized */
156 bool initialized = false;
157
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000158 /** @brief maximum message buffer size the terminus can send and receive */
159 uint16_t maxBufferSize;
160
Thu Nguyen51d66b52024-08-06 09:15:55 +0000161 /** @brief This value indicates the event messaging styles supported by the
162 * terminus
163 */
164 bitfield8_t synchronyConfigurationSupported;
165
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000166 /** @brief A list of numericSensors */
167 std::vector<std::shared_ptr<NumericSensor>> numericSensors{};
168
Dung Caof48015b2023-11-21 04:38:29 +0000169 /** @brief The flag indicates that the terminus FIFO contains a large
170 * message that will require a multipart transfer via the
171 * PollForPlatformEvent command
172 */
173 bool pollEvent;
174
175 /** @brief The sensor id is used in pollForPlatformMessage command */
176 uint16_t pollEventId;
177
178 /** @brief The dataTransferHandle from `pldmMessagePollEvent` event and will
179 * be used as `dataTransferHandle` for pollForPlatformMessage
180 * command.
181 */
182 uint32_t pollDataTransferHandle;
183
Gilbert Chende2a1322022-05-24 15:35:21 +0100184 /** @brief Get Sensor Auxiliary Names by sensorID
185 *
186 * @param[in] id - sensor ID
187 * @return sensor auxiliary names
188 */
189 std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id);
190
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000191 /** @brief Get Numeric Sensor Object by sensorID
192 *
193 * @param[in] id - sensor ID
194 *
195 * @return sensor object
196 */
197 std::shared_ptr<NumericSensor> getSensorObject(SensorId id);
198
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000199 private:
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000200 /** @brief Find the Terminus Name from the Entity Auxiliary name list
201 * The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
202 * @return terminus name in string option
203 */
204 std::optional<std::string_view> findTerminusName();
205
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000206 /** @brief Construct the NumericSensor sensor class for the PLDM sensor.
207 * The NumericSensor class will handle create D-Bus object path,
208 * provide the APIs to update sensor value, threshold...
209 *
210 * @param[in] pdr - the numeric sensor PDR info
211 */
212 void addNumericSensor(
213 const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr);
214
Gilbert Chende2a1322022-05-24 15:35:21 +0100215 /** @brief Parse the numeric sensor PDRs
216 *
217 * @param[in] pdrData - the response PDRs from GetPDR command
218 * @return pointer to numeric sensor info struct
219 */
220 std::shared_ptr<pldm_numeric_sensor_value_pdr>
221 parseNumericSensorPDR(const std::vector<uint8_t>& pdrData);
222
223 /** @brief Parse the sensor Auxiliary name PDRs
224 *
225 * @param[in] pdrData - the response PDRs from GetPDR command
226 * @return pointer to sensor Auxiliary name info struct
227 */
228 std::shared_ptr<SensorAuxiliaryNames>
229 parseSensorAuxiliaryNamesPDR(const std::vector<uint8_t>& pdrData);
230
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000231 /** @brief Parse the Entity Auxiliary name PDRs
232 *
233 * @param[in] pdrData - the response PDRs from GetPDR command
234 * @return pointer to Entity Auxiliary name info struct
235 */
236 std::shared_ptr<EntityAuxiliaryNames>
237 parseEntityAuxiliaryNamesPDR(const std::vector<uint8_t>& pdrData);
238
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000239 /** @brief Construct the NumericSensor sensor class for the compact numeric
240 * PLDM sensor.
241 *
242 * @param[in] pdr - the compact numeric sensor PDR info
243 */
244 void addCompactNumericSensor(
245 const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr);
246
Gilbert Chende2a1322022-05-24 15:35:21 +0100247 /** @brief Parse the compact numeric sensor PDRs
248 *
249 * @param[in] pdrData - the response PDRs from GetPDR command
250 * @return pointer to compact numeric sensor info struct
251 */
252 std::shared_ptr<pldm_compact_numeric_sensor_pdr>
253 parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData);
254
255 /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs
256 *
257 * @param[in] pdrData - the response PDRs from GetPDR command
258 * @return pointer to sensor Auxiliary name info struct
259 */
260 std::shared_ptr<SensorAuxiliaryNames>
261 parseCompactNumericSensorNames(const std::vector<uint8_t>& pdrData);
262
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000263 /** @brief Create the terminus inventory path to
264 * /xyz/openbmc_project/inventory/Item/Board/.
265 *
266 * @param[in] tName - the terminus name
267 * @return true/false: True if there is no error in creating inventory path
268 *
269 */
270 bool createInventoryPath(std::string tName);
271
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000272 /* @brief The terminus's TID */
273 pldm_tid_t tid;
274
275 /* @brief The supported PLDM command types of the terminus */
276 std::bitset<64> supportedTypes;
277
278 /** @brief Store supported PLDM commands of a terminus
279 * Maximum number of PLDM Type is PLDM_MAX_TYPES
280 * Maximum number of PLDM command for each type is
281 * PLDM_MAX_CMDS_PER_TYPE.
282 * Each uint8_t can store the supported state of 8 PLDM commands.
283 * Size of supportedCmds will be
284 * PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8).
285 */
286 std::vector<uint8_t> supportedCmds;
Gilbert Chende2a1322022-05-24 15:35:21 +0100287
Thu Nguyen6e615622024-06-22 02:10:34 +0000288 /* @brief The PLDM supported type version */
289 std::map<uint8_t, ver32_t> supportedTypeVersions;
290
Gilbert Chende2a1322022-05-24 15:35:21 +0100291 /* @brief Sensor Auxiliary Name list */
292 std::vector<std::shared_ptr<SensorAuxiliaryNames>>
293 sensorAuxiliaryNamesTbl{};
Thu Nguyenb8cf46b2024-06-15 02:44:35 +0000294
295 /* @brief Entity Auxiliary Name list */
296 std::vector<std::shared_ptr<EntityAuxiliaryNames>>
297 entityAuxiliaryNamesTbl{};
298
299 /** @brief Terminus name */
300 EntityName terminusName{};
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000301 /* @brief The pointer of iventory D-Bus interface for the terminus */
302 std::unique_ptr<InventoryItemBoardIntf> inventoryItemBoardInft = nullptr;
303
304 /* @brief Inventory D-Bus object path of the terminus */
305 std::string inventoryPath;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000306};
307} // namespace platform_mc
308} // namespace pldm