xref: /openbmc/pldm/platform-mc/terminus.hpp (revision fe2527954be36a3013dc6b8c8ff13ae649bb58a6)
16c7fed4cSGilbert Chen #pragma once
26c7fed4cSGilbert Chen 
36c7fed4cSGilbert Chen #include "common/types.hpp"
4b6d3943dSDung Cao #include "dbus_impl_fru.hpp"
53c5486d4SThu Nguyen #include "numeric_sensor.hpp"
66c7fed4cSGilbert Chen #include "requester/handler.hpp"
73c5486d4SThu Nguyen #include "terminus.hpp"
86c7fed4cSGilbert Chen 
9*fe252795SManojkiran Eda #include <libpldm/fru.h>
10*fe252795SManojkiran Eda #include <libpldm/platform.h>
11*fe252795SManojkiran Eda 
126c7fed4cSGilbert Chen #include <sdbusplus/server/object.hpp>
136c7fed4cSGilbert Chen #include <sdeventplus/event.hpp>
146c7fed4cSGilbert Chen 
156c7fed4cSGilbert Chen #include <algorithm>
166c7fed4cSGilbert Chen #include <bitset>
17de2a132aSGilbert Chen #include <string>
18de2a132aSGilbert Chen #include <tuple>
19de2a132aSGilbert Chen #include <utility>
206c7fed4cSGilbert Chen #include <vector>
216c7fed4cSGilbert Chen 
226c7fed4cSGilbert Chen namespace pldm
236c7fed4cSGilbert Chen {
246c7fed4cSGilbert Chen namespace platform_mc
256c7fed4cSGilbert Chen {
266c7fed4cSGilbert Chen 
27b8cf46b8SThu Nguyen using ContainerID = uint16_t;
28b8cf46b8SThu Nguyen using EntityInstanceNumber = uint16_t;
29b8cf46b8SThu Nguyen using EntityName = std::string;
30b8cf46b8SThu Nguyen using EntityType = uint16_t;
31de2a132aSGilbert Chen using SensorId = uint16_t;
32de2a132aSGilbert Chen using SensorCnt = uint8_t;
33de2a132aSGilbert Chen using NameLanguageTag = std::string;
34de2a132aSGilbert Chen using SensorName = std::string;
35de2a132aSGilbert Chen using SensorAuxiliaryNames = std::tuple<
36de2a132aSGilbert Chen     SensorId, SensorCnt,
37de2a132aSGilbert Chen     std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>>>;
38de2a132aSGilbert Chen 
39b8cf46b8SThu Nguyen /** @struct EntityKey
40b8cf46b8SThu Nguyen  *
41b8cf46b8SThu Nguyen  *  EntityKey uniquely identifies the PLDM entity and a combination of Entity
42b8cf46b8SThu Nguyen  *  Type, Entity Instance Number, Entity Container ID
43b8cf46b8SThu Nguyen  *
44b8cf46b8SThu Nguyen  */
45b8cf46b8SThu Nguyen struct EntityKey
46b8cf46b8SThu Nguyen {
47b8cf46b8SThu Nguyen     EntityType type;                  //!< Entity type
48b8cf46b8SThu Nguyen     EntityInstanceNumber instanceIdx; //!< Entity instance number
49b8cf46b8SThu Nguyen     ContainerID containerId;          //!< Entity container ID
50b8cf46b8SThu Nguyen 
operator ==pldm::platform_mc::EntityKey51b8cf46b8SThu Nguyen     bool operator==(const EntityKey& e) const
52b8cf46b8SThu Nguyen     {
53b8cf46b8SThu Nguyen         return ((type == e.type) && (instanceIdx == e.instanceIdx) &&
54b8cf46b8SThu Nguyen                 (containerId == e.containerId));
55b8cf46b8SThu Nguyen     }
56b8cf46b8SThu Nguyen };
57b8cf46b8SThu Nguyen 
58b8cf46b8SThu Nguyen using AuxiliaryNames = std::vector<std::pair<NameLanguageTag, std::string>>;
59b8cf46b8SThu Nguyen using EntityKey = struct EntityKey;
60b8cf46b8SThu Nguyen using EntityAuxiliaryNames = std::tuple<EntityKey, AuxiliaryNames>;
61b8cf46b8SThu Nguyen 
626c7fed4cSGilbert Chen /**
636c7fed4cSGilbert Chen  * @brief Terminus
646c7fed4cSGilbert Chen  *
656c7fed4cSGilbert Chen  * Terminus class holds the TID, supported PLDM Type or PDRs which are needed by
666c7fed4cSGilbert Chen  * other manager class for sensor monitoring and control.
676c7fed4cSGilbert Chen  */
686c7fed4cSGilbert Chen class Terminus
696c7fed4cSGilbert Chen {
706c7fed4cSGilbert Chen   public:
71fdf61cc3SChaul Ly     Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes,
72fdf61cc3SChaul Ly              sdeventplus::Event& event);
736c7fed4cSGilbert Chen 
746c7fed4cSGilbert Chen     /** @brief Check if the terminus supports the PLDM type message
756c7fed4cSGilbert Chen      *
766c7fed4cSGilbert Chen      *  @param[in] type - PLDM Type
776c7fed4cSGilbert Chen      *  @return support state - True if support, otherwise False
786c7fed4cSGilbert Chen      */
796c7fed4cSGilbert Chen     bool doesSupportType(uint8_t type);
806c7fed4cSGilbert Chen 
816c7fed4cSGilbert Chen     /** @brief Check if the terminus supports the PLDM command message
826c7fed4cSGilbert Chen      *
836c7fed4cSGilbert Chen      *  @param[in] type - PLDM Type
846c7fed4cSGilbert Chen      *  @param[in] command - PLDM command
856c7fed4cSGilbert Chen      *  @return support state - True if support, otherwise False
866c7fed4cSGilbert Chen      */
876c7fed4cSGilbert Chen     bool doesSupportCommand(uint8_t type, uint8_t command);
886c7fed4cSGilbert Chen 
896c7fed4cSGilbert Chen     /** @brief Set the supported PLDM commands for terminus
906c7fed4cSGilbert Chen      *
916c7fed4cSGilbert Chen      *  @param[in] cmds - bit mask of the supported PLDM commands
926c7fed4cSGilbert Chen      *  @return success state - True if success, otherwise False
936c7fed4cSGilbert Chen      */
setSupportedCommands(const std::vector<uint8_t> & cmds)946c7fed4cSGilbert Chen     bool setSupportedCommands(const std::vector<uint8_t>& cmds)
956c7fed4cSGilbert Chen     {
9616c2a0a0SPatrick Williams         const size_t expectedSize =
9716c2a0a0SPatrick Williams             PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
986c7fed4cSGilbert Chen         if (cmds.empty() || cmds.size() != expectedSize)
996c7fed4cSGilbert Chen         {
1006c7fed4cSGilbert Chen             lg2::error(
1016c7fed4cSGilbert Chen                 "setSupportedCommands received invalid bit mask size. Expected: {EXPECTED}, Received: {RECEIVED}",
1026c7fed4cSGilbert Chen                 "EXPECTED", expectedSize, "RECEIVED", cmds.size());
1036c7fed4cSGilbert Chen             return false;
1046c7fed4cSGilbert Chen         }
1056c7fed4cSGilbert Chen 
1066c7fed4cSGilbert Chen         /* Assign Vector supportedCmds by Vector cmds */
1076c7fed4cSGilbert Chen         supportedCmds.resize(cmds.size());
1086c7fed4cSGilbert Chen         std::copy(cmds.begin(), cmds.begin() + cmds.size(),
1096c7fed4cSGilbert Chen                   supportedCmds.begin());
1106c7fed4cSGilbert Chen 
1116c7fed4cSGilbert Chen         return true;
1126c7fed4cSGilbert Chen     }
113de2a132aSGilbert Chen 
1146e615622SThu Nguyen     /** @brief Set the PLDM supported type version for terminus
1156e615622SThu Nguyen      *
1166e615622SThu Nguyen      *  @param[in] type - PLDM supported types
1176e615622SThu Nguyen      *  @param[in] version - PLDM supported type version
1186e615622SThu Nguyen      *  @return success state - True if success, otherwise False
1196e615622SThu Nguyen      */
setSupportedTypeVersions(const uint8_t type,const ver32_t version)1206e615622SThu Nguyen     inline bool setSupportedTypeVersions(const uint8_t type,
1216e615622SThu Nguyen                                          const ver32_t version)
1226e615622SThu Nguyen     {
1236e615622SThu Nguyen         if (type > PLDM_MAX_TYPES || type >= supportedTypeVersions.size())
1246e615622SThu Nguyen         {
1256e615622SThu Nguyen             return false;
1266e615622SThu Nguyen         }
1276e615622SThu Nguyen         supportedTypeVersions[type] = version;
1286e615622SThu Nguyen 
1296e615622SThu Nguyen         return true;
1306e615622SThu Nguyen     }
1316e615622SThu Nguyen 
132de2a132aSGilbert Chen     /** @brief Parse the PDRs stored in the member variable, pdrs.
133de2a132aSGilbert Chen      */
134de2a132aSGilbert Chen     void parseTerminusPDRs();
135de2a132aSGilbert Chen 
1366c7fed4cSGilbert Chen     /** @brief The getter to return terminus's TID */
getTid()1376c7fed4cSGilbert Chen     pldm_tid_t getTid()
1386c7fed4cSGilbert Chen     {
1396c7fed4cSGilbert Chen         return tid;
1406c7fed4cSGilbert Chen     }
1416c7fed4cSGilbert Chen 
142b8cf46b8SThu Nguyen     /** @brief The getter to get terminus's mctp medium */
getTerminusName()1439fc79128SThu Nguyen     std::optional<std::string_view> getTerminusName()
144b8cf46b8SThu Nguyen     {
1459fc79128SThu Nguyen         if (terminusName.empty())
1469fc79128SThu Nguyen         {
1479fc79128SThu Nguyen             return std::nullopt;
1489fc79128SThu Nguyen         }
149b8cf46b8SThu Nguyen         return terminusName;
150b8cf46b8SThu Nguyen     }
151b8cf46b8SThu Nguyen 
152b6d3943dSDung Cao     /** @brief Parse record data from FRU table
153b6d3943dSDung Cao      *
154b6d3943dSDung Cao      *  @param[in] fruData - pointer to FRU record table
155b6d3943dSDung Cao      *  @param[in] fruLen - FRU table length
156b6d3943dSDung Cao      */
157b6d3943dSDung Cao     void updateInventoryWithFru(const uint8_t* fruData, const size_t fruLen);
158b6d3943dSDung Cao 
1596c7fed4cSGilbert Chen     /** @brief A list of PDRs fetched from Terminus */
1606c7fed4cSGilbert Chen     std::vector<std::vector<uint8_t>> pdrs{};
1616c7fed4cSGilbert Chen 
1626c7fed4cSGilbert Chen     /** @brief A flag to indicate if terminus has been initialized */
1636c7fed4cSGilbert Chen     bool initialized = false;
1646c7fed4cSGilbert Chen 
16577e6fe7aSGilbert Chen     /** @brief maximum message buffer size the terminus can send and receive */
16677e6fe7aSGilbert Chen     uint16_t maxBufferSize;
16777e6fe7aSGilbert Chen 
16851d66b59SThu Nguyen     /** @brief This value indicates the event messaging styles supported by the
16951d66b59SThu Nguyen      *         terminus
17051d66b59SThu Nguyen      */
17151d66b59SThu Nguyen     bitfield8_t synchronyConfigurationSupported;
17251d66b59SThu Nguyen 
1733c5486d4SThu Nguyen     /** @brief A list of numericSensors */
1743c5486d4SThu Nguyen     std::vector<std::shared_ptr<NumericSensor>> numericSensors{};
1753c5486d4SThu Nguyen 
176f48015b3SDung Cao     /** @brief The flag indicates that the terminus FIFO contains a large
177f48015b3SDung Cao      *         message that will require a multipart transfer via the
178f48015b3SDung Cao      *         PollForPlatformEvent command
179f48015b3SDung Cao      */
180f48015b3SDung Cao     bool pollEvent;
181f48015b3SDung Cao 
182f48015b3SDung Cao     /** @brief The sensor id is used in pollForPlatformMessage command */
183f48015b3SDung Cao     uint16_t pollEventId;
184f48015b3SDung Cao 
185f48015b3SDung Cao     /** @brief The dataTransferHandle from `pldmMessagePollEvent` event and will
186f48015b3SDung Cao      *         be used as `dataTransferHandle` for pollForPlatformMessage
187f48015b3SDung Cao      *         command.
188f48015b3SDung Cao      */
189f48015b3SDung Cao     uint32_t pollDataTransferHandle;
190f48015b3SDung Cao 
191de2a132aSGilbert Chen     /** @brief Get Sensor Auxiliary Names by sensorID
192de2a132aSGilbert Chen      *
193de2a132aSGilbert Chen      *  @param[in] id - sensor ID
194de2a132aSGilbert Chen      *  @return sensor auxiliary names
195de2a132aSGilbert Chen      */
196de2a132aSGilbert Chen     std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id);
197de2a132aSGilbert Chen 
19877e6fe7aSGilbert Chen     /** @brief Get Numeric Sensor Object by sensorID
19977e6fe7aSGilbert Chen      *
20077e6fe7aSGilbert Chen      *  @param[in] id - sensor ID
20177e6fe7aSGilbert Chen      *
20277e6fe7aSGilbert Chen      *  @return sensor object
20377e6fe7aSGilbert Chen      */
20477e6fe7aSGilbert Chen     std::shared_ptr<NumericSensor> getSensorObject(SensorId id);
20577e6fe7aSGilbert Chen 
2066c7fed4cSGilbert Chen   private:
207b8cf46b8SThu Nguyen     /** @brief Find the Terminus Name from the Entity Auxiliary name list
208b8cf46b8SThu Nguyen      *         The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
209b8cf46b8SThu Nguyen      *  @return terminus name in string option
210b8cf46b8SThu Nguyen      */
211b8cf46b8SThu Nguyen     std::optional<std::string_view> findTerminusName();
212b8cf46b8SThu Nguyen 
2133c5486d4SThu Nguyen     /** @brief Construct the NumericSensor sensor class for the PLDM sensor.
2143c5486d4SThu Nguyen      *         The NumericSensor class will handle create D-Bus object path,
2153c5486d4SThu Nguyen      *         provide the APIs to update sensor value, threshold...
2163c5486d4SThu Nguyen      *
2173c5486d4SThu Nguyen      *  @param[in] pdr - the numeric sensor PDR info
2183c5486d4SThu Nguyen      */
2193c5486d4SThu Nguyen     void addNumericSensor(
2203c5486d4SThu Nguyen         const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr);
2213c5486d4SThu Nguyen 
222de2a132aSGilbert Chen     /** @brief Parse the numeric sensor PDRs
223de2a132aSGilbert Chen      *
224de2a132aSGilbert Chen      *  @param[in] pdrData - the response PDRs from GetPDR command
225de2a132aSGilbert Chen      *  @return pointer to numeric sensor info struct
226de2a132aSGilbert Chen      */
227366507c8SPatrick Williams     std::shared_ptr<pldm_numeric_sensor_value_pdr> parseNumericSensorPDR(
228366507c8SPatrick Williams         const std::vector<uint8_t>& pdrData);
229de2a132aSGilbert Chen 
230de2a132aSGilbert Chen     /** @brief Parse the sensor Auxiliary name PDRs
231de2a132aSGilbert Chen      *
232de2a132aSGilbert Chen      *  @param[in] pdrData - the response PDRs from GetPDR command
233de2a132aSGilbert Chen      *  @return pointer to sensor Auxiliary name info struct
234de2a132aSGilbert Chen      */
235366507c8SPatrick Williams     std::shared_ptr<SensorAuxiliaryNames> parseSensorAuxiliaryNamesPDR(
236366507c8SPatrick Williams         const std::vector<uint8_t>& pdrData);
237de2a132aSGilbert Chen 
238b8cf46b8SThu Nguyen     /** @brief Parse the Entity Auxiliary name PDRs
239b8cf46b8SThu Nguyen      *
240b8cf46b8SThu Nguyen      *  @param[in] pdrData - the response PDRs from GetPDR command
241b8cf46b8SThu Nguyen      *  @return pointer to Entity Auxiliary name info struct
242b8cf46b8SThu Nguyen      */
243366507c8SPatrick Williams     std::shared_ptr<EntityAuxiliaryNames> parseEntityAuxiliaryNamesPDR(
244366507c8SPatrick Williams         const std::vector<uint8_t>& pdrData);
245b8cf46b8SThu Nguyen 
2463c5486d4SThu Nguyen     /** @brief Construct the NumericSensor sensor class for the compact numeric
2473c5486d4SThu Nguyen      *         PLDM sensor.
2483c5486d4SThu Nguyen      *
2493c5486d4SThu Nguyen      *  @param[in] pdr - the compact numeric sensor PDR info
2503c5486d4SThu Nguyen      */
2513c5486d4SThu Nguyen     void addCompactNumericSensor(
2523c5486d4SThu Nguyen         const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr);
2533c5486d4SThu Nguyen 
254de2a132aSGilbert Chen     /** @brief Parse the compact numeric sensor PDRs
255de2a132aSGilbert Chen      *
256de2a132aSGilbert Chen      *  @param[in] pdrData - the response PDRs from GetPDR command
257de2a132aSGilbert Chen      *  @return pointer to compact numeric sensor info struct
258de2a132aSGilbert Chen      */
259de2a132aSGilbert Chen     std::shared_ptr<pldm_compact_numeric_sensor_pdr>
260de2a132aSGilbert Chen         parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData);
261de2a132aSGilbert Chen 
262de2a132aSGilbert Chen     /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs
263de2a132aSGilbert Chen      *
264de2a132aSGilbert Chen      *  @param[in] pdrData - the response PDRs from GetPDR command
265de2a132aSGilbert Chen      *  @return pointer to sensor Auxiliary name info struct
266de2a132aSGilbert Chen      */
267366507c8SPatrick Williams     std::shared_ptr<SensorAuxiliaryNames> parseCompactNumericSensorNames(
268366507c8SPatrick Williams         const std::vector<uint8_t>& pdrData);
269de2a132aSGilbert Chen 
2703c5486d4SThu Nguyen     /** @brief Create the terminus inventory path to
2713c5486d4SThu Nguyen      *         /xyz/openbmc_project/inventory/Item/Board/.
2723c5486d4SThu Nguyen      *
2733c5486d4SThu Nguyen      *  @param[in] tName - the terminus name
2743c5486d4SThu Nguyen      *  @return true/false: True if there is no error in creating inventory path
2753c5486d4SThu Nguyen      *
2763c5486d4SThu Nguyen      */
2773c5486d4SThu Nguyen     bool createInventoryPath(std::string tName);
2783c5486d4SThu Nguyen 
27938a09d25SChau Ly     /** @brief Get sensor names from Sensor Auxiliary Names PDRs
28038a09d25SChau Ly      *
28138a09d25SChau Ly      *  @param[in] sensorId - Sensor ID
28238a09d25SChau Ly      *  @param[in] isEffecter - This is an effecter, not a sensor
28338a09d25SChau Ly      *  @return vector of sensor name strings
28438a09d25SChau Ly      *
28538a09d25SChau Ly      */
28638a09d25SChau Ly     std::vector<std::string> getSensorNames(const SensorId& sensorId);
28738a09d25SChau Ly 
288fdf61cc3SChaul Ly     /** @brief Add the next sensor PDR to this terminus, iterated by
289fdf61cc3SChaul Ly      *         sensorPdrIt.
290fdf61cc3SChaul Ly      */
291fdf61cc3SChaul Ly     void addNextSensorFromPDRs();
292fdf61cc3SChaul Ly 
2936c7fed4cSGilbert Chen     /* @brief The terminus's TID */
2946c7fed4cSGilbert Chen     pldm_tid_t tid;
2956c7fed4cSGilbert Chen 
2966c7fed4cSGilbert Chen     /* @brief The supported PLDM command types of the terminus */
2976c7fed4cSGilbert Chen     std::bitset<64> supportedTypes;
2986c7fed4cSGilbert Chen 
2996c7fed4cSGilbert Chen     /** @brief Store supported PLDM commands of a terminus
3006c7fed4cSGilbert Chen      *         Maximum number of PLDM Type is PLDM_MAX_TYPES
3016c7fed4cSGilbert Chen      *         Maximum number of PLDM command for each type is
3026c7fed4cSGilbert Chen      *         PLDM_MAX_CMDS_PER_TYPE.
3036c7fed4cSGilbert Chen      *         Each uint8_t can store the supported state of 8 PLDM commands.
3046c7fed4cSGilbert Chen      *         Size of supportedCmds will be
3056c7fed4cSGilbert Chen      *         PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8).
3066c7fed4cSGilbert Chen      */
3076c7fed4cSGilbert Chen     std::vector<uint8_t> supportedCmds;
308de2a132aSGilbert Chen 
3096e615622SThu Nguyen     /* @brief The PLDM supported type version */
3106e615622SThu Nguyen     std::map<uint8_t, ver32_t> supportedTypeVersions;
3116e615622SThu Nguyen 
312de2a132aSGilbert Chen     /* @brief Sensor Auxiliary Name list */
313de2a132aSGilbert Chen     std::vector<std::shared_ptr<SensorAuxiliaryNames>>
314de2a132aSGilbert Chen         sensorAuxiliaryNamesTbl{};
315b8cf46b8SThu Nguyen 
316b8cf46b8SThu Nguyen     /* @brief Entity Auxiliary Name list */
317b8cf46b8SThu Nguyen     std::vector<std::shared_ptr<EntityAuxiliaryNames>>
318b8cf46b8SThu Nguyen         entityAuxiliaryNamesTbl{};
319b8cf46b8SThu Nguyen 
320b8cf46b8SThu Nguyen     /** @brief Terminus name */
321b8cf46b8SThu Nguyen     EntityName terminusName{};
322b6d3943dSDung Cao     /* @brief The pointer of inventory D-Bus interface for the terminus */
323b6d3943dSDung Cao     std::unique_ptr<pldm::dbus_api::PldmEntityReq> inventoryItemBoardInft =
324b6d3943dSDung Cao         nullptr;
3253c5486d4SThu Nguyen 
3263c5486d4SThu Nguyen     /* @brief Inventory D-Bus object path of the terminus */
3273c5486d4SThu Nguyen     std::string inventoryPath;
328fdf61cc3SChaul Ly 
329fdf61cc3SChaul Ly     /** @brief reference of main event loop of pldmd, primarily used to schedule
330fdf61cc3SChaul Ly      *  work
331fdf61cc3SChaul Ly      */
332fdf61cc3SChaul Ly     sdeventplus::Event& event;
333fdf61cc3SChaul Ly 
334fdf61cc3SChaul Ly     /** @brief The event source to defer sensor creation tasks to event loop*/
335fdf61cc3SChaul Ly     std::unique_ptr<sdeventplus::source::Defer> sensorCreationEvent;
336fdf61cc3SChaul Ly 
337fdf61cc3SChaul Ly     /** @brief Numeric Sensor PDR list */
338fdf61cc3SChaul Ly     std::vector<std::shared_ptr<pldm_numeric_sensor_value_pdr>>
339fdf61cc3SChaul Ly         numericSensorPdrs{};
340fdf61cc3SChaul Ly 
341fdf61cc3SChaul Ly     /** @brief Compact Numeric Sensor PDR list */
342fdf61cc3SChaul Ly     std::vector<std::shared_ptr<pldm_compact_numeric_sensor_pdr>>
343fdf61cc3SChaul Ly         compactNumericSensorPdrs{};
344fdf61cc3SChaul Ly 
345fdf61cc3SChaul Ly     /** @brief Iteration to loop through sensor PDRs when adding sensors */
346fdf61cc3SChaul Ly     SensorId sensorPdrIt = 0;
3476c7fed4cSGilbert Chen };
3486c7fed4cSGilbert Chen } // namespace platform_mc
3496c7fed4cSGilbert Chen } // namespace pldm
350