xref: /openbmc/pldm/platform-mc/terminus.hpp (revision 6e615622)
1 #pragma once
2 
3 #include "libpldm/platform.h"
4 
5 #include "common/types.hpp"
6 #include "numeric_sensor.hpp"
7 #include "requester/handler.hpp"
8 #include "terminus.hpp"
9 
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>
16 #include <string>
17 #include <tuple>
18 #include <utility>
19 #include <vector>
20 
21 namespace pldm
22 {
23 namespace platform_mc
24 {
25 
26 using ContainerID = uint16_t;
27 using EntityInstanceNumber = uint16_t;
28 using EntityName = std::string;
29 using EntityType = uint16_t;
30 using SensorId = uint16_t;
31 using SensorCnt = uint8_t;
32 using NameLanguageTag = std::string;
33 using SensorName = std::string;
34 using SensorAuxiliaryNames = std::tuple<
35     SensorId, SensorCnt,
36     std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>>>;
37 using InventoryItemBoardIntf = sdbusplus::server::object_t<
38     sdbusplus::xyz::openbmc_project::Inventory::Item::server::Board>;
39 
40 /** @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  */
46 struct EntityKey
47 {
48     EntityType type;                  //!< Entity type
49     EntityInstanceNumber instanceIdx; //!< Entity instance number
50     ContainerID containerId;          //!< Entity container ID
51 
operator ==pldm::platform_mc::EntityKey52     bool operator==(const EntityKey& e) const
53     {
54         return ((type == e.type) && (instanceIdx == e.instanceIdx) &&
55                 (containerId == e.containerId));
56     }
57 };
58 
59 using AuxiliaryNames = std::vector<std::pair<NameLanguageTag, std::string>>;
60 using EntityKey = struct EntityKey;
61 using EntityAuxiliaryNames = std::tuple<EntityKey, AuxiliaryNames>;
62 
63 /**
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  */
69 class 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      */
setSupportedCommands(const std::vector<uint8_t> & cmds)94     bool setSupportedCommands(const std::vector<uint8_t>& cmds)
95     {
96         const size_t expectedSize =
97             PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
98         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     }
113 
114     /** @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      */
setSupportedTypeVersions(const uint8_t type,const ver32_t version)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 
132     /** @brief Parse the PDRs stored in the member variable, pdrs.
133      */
134     void parseTerminusPDRs();
135 
136     /** @brief The getter to return terminus's TID */
getTid()137     pldm_tid_t getTid()
138     {
139         return tid;
140     }
141 
142     /** @brief The getter to get terminus's mctp medium */
getTerminusName()143     std::optional<std::string_view> getTerminusName()
144     {
145         if (terminusName.empty())
146         {
147             return std::nullopt;
148         }
149         return terminusName;
150     }
151 
152     /** @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 
158     /** @brief maximum message buffer size the terminus can send and receive */
159     uint16_t maxBufferSize;
160 
161     /** @brief This value indicates the event messaging styles supported by the
162      *         terminus
163      */
164     bitfield8_t synchronyConfigurationSupported;
165 
166     /** @brief A list of numericSensors */
167     std::vector<std::shared_ptr<NumericSensor>> numericSensors{};
168 
169     /** @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 
184     /** @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 
191     /** @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 
199   private:
200     /** @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 
206     /** @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 
215     /** @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 
231     /** @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 
239     /** @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 
247     /** @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 
263     /** @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 
272     /* @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;
287 
288     /* @brief The PLDM supported type version */
289     std::map<uint8_t, ver32_t> supportedTypeVersions;
290 
291     /* @brief Sensor Auxiliary Name list */
292     std::vector<std::shared_ptr<SensorAuxiliaryNames>>
293         sensorAuxiliaryNamesTbl{};
294 
295     /* @brief Entity Auxiliary Name list */
296     std::vector<std::shared_ptr<EntityAuxiliaryNames>>
297         entityAuxiliaryNamesTbl{};
298 
299     /** @brief Terminus name */
300     EntityName terminusName{};
301     /* @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;
306 };
307 } // namespace platform_mc
308 } // namespace pldm
309