xref: /openbmc/pldm/platform-mc/terminus.hpp (revision 51cc5bda)
1 #pragma once
2 
3 #include "libpldm/platform.h"
4 
5 #include "common/types.hpp"
6 #include "requester/handler.hpp"
7 
8 #include <sdbusplus/server/object.hpp>
9 #include <sdeventplus/event.hpp>
10 #include <xyz/openbmc_project/Inventory/Item/Board/server.hpp>
11 
12 #include <algorithm>
13 #include <bitset>
14 #include <string>
15 #include <tuple>
16 #include <utility>
17 #include <vector>
18 
19 namespace pldm
20 {
21 namespace platform_mc
22 {
23 
24 using ContainerID = uint16_t;
25 using EntityInstanceNumber = uint16_t;
26 using EntityName = std::string;
27 using EntityType = uint16_t;
28 using SensorId = uint16_t;
29 using SensorCnt = uint8_t;
30 using NameLanguageTag = std::string;
31 using SensorName = std::string;
32 using SensorAuxiliaryNames = std::tuple<
33     SensorId, SensorCnt,
34     std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>>>;
35 
36 /** @struct EntityKey
37  *
38  *  EntityKey uniquely identifies the PLDM entity and a combination of Entity
39  *  Type, Entity Instance Number, Entity Container ID
40  *
41  */
42 struct EntityKey
43 {
44     EntityType type;                  //!< Entity type
45     EntityInstanceNumber instanceIdx; //!< Entity instance number
46     ContainerID containerId;          //!< Entity container ID
47 
48     bool operator==(const EntityKey& e) const
49     {
50         return ((type == e.type) && (instanceIdx == e.instanceIdx) &&
51                 (containerId == e.containerId));
52     }
53 };
54 
55 using AuxiliaryNames = std::vector<std::pair<NameLanguageTag, std::string>>;
56 using EntityKey = struct EntityKey;
57 using EntityAuxiliaryNames = std::tuple<EntityKey, AuxiliaryNames>;
58 
59 /**
60  * @brief Terminus
61  *
62  * Terminus class holds the TID, supported PLDM Type or PDRs which are needed by
63  * other manager class for sensor monitoring and control.
64  */
65 class Terminus
66 {
67   public:
68     Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes);
69 
70     /** @brief Check if the terminus supports the PLDM type message
71      *
72      *  @param[in] type - PLDM Type
73      *  @return support state - True if support, otherwise False
74      */
75     bool doesSupportType(uint8_t type);
76 
77     /** @brief Check if the terminus supports the PLDM command message
78      *
79      *  @param[in] type - PLDM Type
80      *  @param[in] command - PLDM command
81      *  @return support state - True if support, otherwise False
82      */
83     bool doesSupportCommand(uint8_t type, uint8_t command);
84 
85     /** @brief Set the supported PLDM commands for terminus
86      *
87      *  @param[in] cmds - bit mask of the supported PLDM commands
88      *  @return success state - True if success, otherwise False
89      */
90     bool setSupportedCommands(const std::vector<uint8_t>& cmds)
91     {
92         const size_t expectedSize = PLDM_MAX_TYPES *
93                                     (PLDM_MAX_CMDS_PER_TYPE / 8);
94         if (cmds.empty() || cmds.size() != expectedSize)
95         {
96             lg2::error(
97                 "setSupportedCommands received invalid bit mask size. Expected: {EXPECTED}, Received: {RECEIVED}",
98                 "EXPECTED", expectedSize, "RECEIVED", cmds.size());
99             return false;
100         }
101 
102         /* Assign Vector supportedCmds by Vector cmds */
103         supportedCmds.resize(cmds.size());
104         std::copy(cmds.begin(), cmds.begin() + cmds.size(),
105                   supportedCmds.begin());
106 
107         return true;
108     }
109 
110     /** @brief Parse the PDRs stored in the member variable, pdrs.
111      */
112     void parseTerminusPDRs();
113 
114     /** @brief The getter to return terminus's TID */
115     pldm_tid_t getTid()
116     {
117         return tid;
118     }
119 
120     /** @brief The getter to get terminus's mctp medium */
121     std::string_view getTerminusName()
122     {
123         return terminusName;
124     }
125 
126     /** @brief A list of PDRs fetched from Terminus */
127     std::vector<std::vector<uint8_t>> pdrs{};
128 
129     /** @brief A flag to indicate if terminus has been initialized */
130     bool initialized = false;
131 
132     /** @brief Get Sensor Auxiliary Names by sensorID
133      *
134      *  @param[in] id - sensor ID
135      *  @return sensor auxiliary names
136      */
137     std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id);
138 
139   private:
140     /** @brief Find the Terminus Name from the Entity Auxiliary name list
141      *         The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
142      *  @return terminus name in string option
143      */
144     std::optional<std::string_view> findTerminusName();
145 
146     /** @brief Parse the numeric sensor PDRs
147      *
148      *  @param[in] pdrData - the response PDRs from GetPDR command
149      *  @return pointer to numeric sensor info struct
150      */
151     std::shared_ptr<pldm_numeric_sensor_value_pdr>
152         parseNumericSensorPDR(const std::vector<uint8_t>& pdrData);
153 
154     /** @brief Parse the sensor Auxiliary name PDRs
155      *
156      *  @param[in] pdrData - the response PDRs from GetPDR command
157      *  @return pointer to sensor Auxiliary name info struct
158      */
159     std::shared_ptr<SensorAuxiliaryNames>
160         parseSensorAuxiliaryNamesPDR(const std::vector<uint8_t>& pdrData);
161 
162     /** @brief Parse the Entity Auxiliary name PDRs
163      *
164      *  @param[in] pdrData - the response PDRs from GetPDR command
165      *  @return pointer to Entity Auxiliary name info struct
166      */
167     std::shared_ptr<EntityAuxiliaryNames>
168         parseEntityAuxiliaryNamesPDR(const std::vector<uint8_t>& pdrData);
169 
170     /** @brief Parse the compact numeric sensor PDRs
171      *
172      *  @param[in] pdrData - the response PDRs from GetPDR command
173      *  @return pointer to compact numeric sensor info struct
174      */
175     std::shared_ptr<pldm_compact_numeric_sensor_pdr>
176         parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData);
177 
178     /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs
179      *
180      *  @param[in] pdrData - the response PDRs from GetPDR command
181      *  @return pointer to sensor Auxiliary name info struct
182      */
183     std::shared_ptr<SensorAuxiliaryNames>
184         parseCompactNumericSensorNames(const std::vector<uint8_t>& pdrData);
185 
186     /* @brief The terminus's TID */
187     pldm_tid_t tid;
188 
189     /* @brief The supported PLDM command types of the terminus */
190     std::bitset<64> supportedTypes;
191 
192     /** @brief Store supported PLDM commands of a terminus
193      *         Maximum number of PLDM Type is PLDM_MAX_TYPES
194      *         Maximum number of PLDM command for each type is
195      *         PLDM_MAX_CMDS_PER_TYPE.
196      *         Each uint8_t can store the supported state of 8 PLDM commands.
197      *         Size of supportedCmds will be
198      *         PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8).
199      */
200     std::vector<uint8_t> supportedCmds;
201 
202     /* @brief Sensor Auxiliary Name list */
203     std::vector<std::shared_ptr<SensorAuxiliaryNames>>
204         sensorAuxiliaryNamesTbl{};
205 
206     /* @brief Entity Auxiliary Name list */
207     std::vector<std::shared_ptr<EntityAuxiliaryNames>>
208         entityAuxiliaryNamesTbl{};
209 
210     /** @brief Terminus name */
211     EntityName terminusName{};
212 };
213 } // namespace platform_mc
214 } // namespace pldm
215