xref: /openbmc/pldm/platform-mc/terminus.hpp (revision 3419e180c971ec9d30114d98d0b63c83625ec516)
1 #pragma once
2 
3 #include "common/types.hpp"
4 #include "dbus_impl_fru.hpp"
5 #include "numeric_sensor.hpp"
6 #include "requester/handler.hpp"
7 #include "terminus.hpp"
8 
9 #include <libpldm/fru.h>
10 #include <libpldm/platform.h>
11 
12 #include <sdbusplus/server/object.hpp>
13 #include <sdeventplus/event.hpp>
14 
15 #include <algorithm>
16 #include <bitset>
17 #include <string>
18 #include <tuple>
19 #include <utility>
20 #include <vector>
21 
22 namespace pldm
23 {
24 namespace platform_mc
25 {
26 
27 using namespace pldm::pdr;
28 
29 /**
30  * @brief Terminus
31  *
32  * Terminus class holds the TID, supported PLDM Type or PDRs which are needed by
33  * other manager class for sensor monitoring and control.
34  */
35 class Terminus
36 {
37   public:
38     Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes,
39              sdeventplus::Event& event);
40 
41     /** @brief Check if the terminus supports the PLDM type message
42      *
43      *  @param[in] type - PLDM Type
44      *  @return support state - True if support, otherwise False
45      */
46     bool doesSupportType(uint8_t type);
47 
48     /** @brief Check if the terminus supports the PLDM command message
49      *
50      *  @param[in] type - PLDM Type
51      *  @param[in] command - PLDM command
52      *  @return support state - True if support, otherwise False
53      */
54     bool doesSupportCommand(uint8_t type, uint8_t command);
55 
56     /** @brief Set the supported PLDM commands for terminus
57      *
58      *  @param[in] cmds - bit mask of the supported PLDM commands
59      *  @return success state - True if success, otherwise False
60      */
setSupportedCommands(const std::vector<uint8_t> & cmds)61     bool setSupportedCommands(const std::vector<uint8_t>& cmds)
62     {
63         const size_t expectedSize =
64             PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
65         if (cmds.empty() || cmds.size() != expectedSize)
66         {
67             lg2::error(
68                 "setSupportedCommands received invalid bit mask size. Expected: {EXPECTED}, Received: {RECEIVED}",
69                 "EXPECTED", expectedSize, "RECEIVED", cmds.size());
70             return false;
71         }
72 
73         /* Assign Vector supportedCmds by Vector cmds */
74         supportedCmds.resize(cmds.size());
75         std::copy(cmds.begin(), cmds.begin() + cmds.size(),
76                   supportedCmds.begin());
77 
78         return true;
79     }
80 
81     /** @brief Set the PLDM supported type version for terminus
82      *
83      *  @param[in] type - PLDM supported types
84      *  @param[in] version - PLDM supported type version
85      *  @return success state - True if success, otherwise False
86      */
setSupportedTypeVersions(const uint8_t type,const ver32_t version)87     inline bool setSupportedTypeVersions(const uint8_t type,
88                                          const ver32_t version)
89     {
90         if (type > PLDM_MAX_TYPES || type >= supportedTypeVersions.size())
91         {
92             return false;
93         }
94         supportedTypeVersions[type] = version;
95 
96         return true;
97     }
98 
99     /** @brief Parse the PDRs stored in the member variable, pdrs.
100      */
101     void parseTerminusPDRs();
102 
103     /** @brief The getter to return terminus's TID */
getTid()104     pldm_tid_t getTid()
105     {
106         return tid;
107     }
108 
109     /** @brief The setter to set terminus's mctp medium */
setTerminusName(const EntityName & tName)110     void setTerminusName(const EntityName& tName)
111     {
112         terminusName = tName;
113     }
114 
115     /** @brief The getter to get terminus's mctp medium */
getTerminusName()116     std::optional<std::string_view> getTerminusName()
117     {
118         if (terminusName.empty())
119         {
120             return std::nullopt;
121         }
122         return terminusName;
123     }
124 
125     /** @brief Parse record data from FRU table
126      *
127      *  @param[in] fruData - pointer to FRU record table
128      *  @param[in] fruLen - FRU table length
129      */
130     void updateInventoryWithFru(const uint8_t* fruData, const size_t fruLen);
131 
132     /** @brief A list of PDRs fetched from Terminus */
133     std::vector<std::vector<uint8_t>> pdrs{};
134 
135     /** @brief A flag to indicate if terminus has been initialized */
136     bool initialized = false;
137 
138     /** @brief maximum message buffer size the terminus can send and receive */
139     uint16_t maxBufferSize;
140 
141     /** @brief This value indicates the event messaging styles supported by the
142      *         terminus
143      */
144     bitfield8_t synchronyConfigurationSupported;
145 
146     /** @brief A list of numericSensors */
147     std::vector<std::shared_ptr<NumericSensor>> numericSensors{};
148 
149     /** @brief The flag indicates that the terminus FIFO contains a large
150      *         message that will require a multipart transfer via the
151      *         PollForPlatformEvent command
152      */
153     bool pollEvent;
154 
155     /** @brief The sensor id is used in pollForPlatformMessage command */
156     uint16_t pollEventId;
157 
158     /** @brief The dataTransferHandle from `pldmMessagePollEvent` event and will
159      *         be used as `dataTransferHandle` for pollForPlatformMessage
160      *         command.
161      */
162     uint32_t pollDataTransferHandle;
163 
164     /** @brief Get Sensor Auxiliary Names by sensorID
165      *
166      *  @param[in] id - sensor ID
167      *  @return sensor auxiliary names
168      */
169     std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorID id);
170 
171     /** @brief Get Numeric Sensor Object by sensorID
172      *
173      *  @param[in] id - sensor ID
174      *
175      *  @return sensor object
176      */
177     std::shared_ptr<NumericSensor> getSensorObject(SensorID id);
178 
179   private:
180     /** @brief Find the Terminus Name from the Entity Auxiliary name list
181      *         The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
182      *  @return terminus name in string option
183      */
184     std::optional<std::string_view> findTerminusName();
185 
186     /** @brief Construct the NumericSensor sensor class for the PLDM sensor.
187      *         The NumericSensor class will handle create D-Bus object path,
188      *         provide the APIs to update sensor value, threshold...
189      *
190      *  @param[in] pdr - the numeric sensor PDR info
191      */
192     void addNumericSensor(
193         const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr);
194 
195     /** @brief Parse the numeric sensor PDRs
196      *
197      *  @param[in] pdrData - the response PDRs from GetPDR command
198      *  @return pointer to numeric sensor info struct
199      */
200     std::shared_ptr<pldm_numeric_sensor_value_pdr> parseNumericSensorPDR(
201         const std::vector<uint8_t>& pdrData);
202 
203     /** @brief Parse the sensor Auxiliary name PDRs
204      *
205      *  @param[in] pdrData - the response PDRs from GetPDR command
206      *  @return pointer to sensor Auxiliary name info struct
207      */
208     std::shared_ptr<SensorAuxiliaryNames> parseSensorAuxiliaryNamesPDR(
209         const std::vector<uint8_t>& pdrData);
210 
211     /** @brief Parse the Entity Auxiliary name PDRs
212      *
213      *  @param[in] pdrData - the response PDRs from GetPDR command
214      *  @return pointer to Entity Auxiliary name info struct
215      */
216     std::shared_ptr<EntityAuxiliaryNames> parseEntityAuxiliaryNamesPDR(
217         const std::vector<uint8_t>& pdrData);
218 
219     /** @brief Construct the NumericSensor sensor class for the compact numeric
220      *         PLDM sensor.
221      *
222      *  @param[in] pdr - the compact numeric sensor PDR info
223      */
224     void addCompactNumericSensor(
225         const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr);
226 
227     /** @brief Parse the compact numeric sensor PDRs
228      *
229      *  @param[in] pdrData - the response PDRs from GetPDR command
230      *  @return pointer to compact numeric sensor info struct
231      */
232     std::shared_ptr<pldm_compact_numeric_sensor_pdr>
233         parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData);
234 
235     /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs
236      *
237      *  @param[in] pdrData - the response PDRs from GetPDR command
238      *  @return pointer to sensor Auxiliary name info struct
239      */
240     std::shared_ptr<SensorAuxiliaryNames> parseCompactNumericSensorNames(
241         const std::vector<uint8_t>& pdrData);
242 
243     /** @brief Create the terminus inventory path to
244      *         /xyz/openbmc_project/inventory/Item/Board/.
245      *
246      *  @param[in] tName - the terminus name
247      *  @return true/false: True if there is no error in creating inventory path
248      *
249      */
250     bool createInventoryPath(std::string tName);
251 
252     /** @brief Get sensor names from Sensor Auxiliary Names PDRs
253      *
254      *  @param[in] sensorId - Sensor ID
255      *  @param[in] isEffecter - This is an effecter, not a sensor
256      *  @return vector of sensor name strings
257      *
258      */
259     std::vector<std::string> getSensorNames(const SensorID& sensorId);
260 
261     /** @brief Add the next sensor PDR to this terminus, iterated by
262      *         sensorPdrIt.
263      */
264     void addNextSensorFromPDRs();
265 
266     /* @brief The terminus's TID */
267     pldm_tid_t tid;
268 
269     /* @brief The supported PLDM command types of the terminus */
270     std::bitset<64> supportedTypes;
271 
272     /** @brief Store supported PLDM commands of a terminus
273      *         Maximum number of PLDM Type is PLDM_MAX_TYPES
274      *         Maximum number of PLDM command for each type is
275      *         PLDM_MAX_CMDS_PER_TYPE.
276      *         Each uint8_t can store the supported state of 8 PLDM commands.
277      *         Size of supportedCmds will be
278      *         PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8).
279      */
280     std::vector<uint8_t> supportedCmds;
281 
282     /* @brief The PLDM supported type version */
283     std::map<uint8_t, ver32_t> supportedTypeVersions;
284 
285     /* @brief Sensor Auxiliary Name list */
286     std::vector<std::shared_ptr<SensorAuxiliaryNames>>
287         sensorAuxiliaryNamesTbl{};
288 
289     /* @brief Entity Auxiliary Name list */
290     std::vector<std::shared_ptr<EntityAuxiliaryNames>>
291         entityAuxiliaryNamesTbl{};
292 
293     /** @brief Terminus name */
294     EntityName terminusName{};
295     /* @brief The pointer of inventory D-Bus interface for the terminus */
296     std::unique_ptr<pldm::dbus_api::PldmEntityReq> inventoryItemBoardInft =
297         nullptr;
298 
299     /* @brief Inventory D-Bus object path of the terminus */
300     std::string inventoryPath;
301 
302     /** @brief reference of main event loop of pldmd, primarily used to schedule
303      *  work
304      */
305     sdeventplus::Event& event;
306 
307     /** @brief The event source to defer sensor creation tasks to event loop*/
308     std::unique_ptr<sdeventplus::source::Defer> sensorCreationEvent;
309 
310     /** @brief Numeric Sensor PDR list */
311     std::vector<std::shared_ptr<pldm_numeric_sensor_value_pdr>>
312         numericSensorPdrs{};
313 
314     /** @brief Compact Numeric Sensor PDR list */
315     std::vector<std::shared_ptr<pldm_compact_numeric_sensor_pdr>>
316         compactNumericSensorPdrs{};
317 
318     /** @brief Iteration to loop through sensor PDRs when adding sensors */
319     SensorID sensorPdrIt = 0;
320 };
321 } // namespace platform_mc
322 } // namespace pldm
323