1 #pragma once
2 
3 #include <openssl/crypto.h>
4 #include <stdint.h>
5 
6 #include <sdbusplus/server.hpp>
7 
8 #include <map>
9 #include <string>
10 #include <variant>
11 
12 namespace ipmi
13 {
14 
15 using DbusObjectPath = std::string;
16 using DbusService = std::string;
17 using DbusInterface = std::string;
18 using DbusObjectInfo = std::pair<DbusObjectPath, DbusService>;
19 using DbusProperty = std::string;
20 
21 using Association = std::tuple<std::string, std::string, std::string>;
22 
23 using Value =
24     std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
25                  uint64_t, double, std::string, std::vector<uint8_t>,
26                  std::vector<uint16_t>, std::vector<uint32_t>,
27                  std::vector<std::string>, std::vector<Association>>;
28 
29 using PropertyMap = std::map<DbusProperty, Value>;
30 
31 using ObjectTree =
32     std::map<DbusObjectPath, std::map<DbusService, std::vector<DbusInterface>>>;
33 
34 using InterfaceList = std::vector<std::string>;
35 
36 using DbusInterfaceMap = std::map<DbusInterface, PropertyMap>;
37 
38 using ObjectValueTree =
39     std::map<sdbusplus::message::object_path, DbusInterfaceMap>;
40 
41 namespace sensor
42 {
43 
44 using Offset = uint8_t;
45 
46 /**
47  * @enum SkipAssertion
48  * Matching value for skipping the update
49  */
50 enum class SkipAssertion
51 {
52     NONE,     // No skip defined
53     ASSERT,   // Skip on Assert
54     DEASSERT, // Skip on Deassert
55 };
56 
57 struct Values
58 {
59     SkipAssertion skip;
60     Value assert;
61     Value deassert;
62 };
63 
64 /**
65  * @enum PreReqValues
66  * Pre-req conditions for a property.
67  */
68 struct PreReqValues
69 {
70     Value assert;   // Value in case of assert.
71     Value deassert; // Value in case of deassert.
72 };
73 
74 using PreReqOffsetValueMap = std::map<Offset, PreReqValues>;
75 
76 /**
77  * @struct SetSensorReadingReq
78  *
79  * IPMI Request data for Set Sensor Reading and Event Status Command
80  */
81 struct SetSensorReadingReq
82 {
83     uint8_t number;
84     uint8_t operation;
85     uint8_t reading;
86     uint8_t assertOffset0_7;
87     uint8_t assertOffset8_14;
88     uint8_t deassertOffset0_7;
89     uint8_t deassertOffset8_14;
90     uint8_t eventData1;
91     uint8_t eventData2;
92     uint8_t eventData3;
93 } __attribute__((packed));
94 
95 /**
96  * @struct GetReadingResponse
97  *
98  * IPMI response data for Get Sensor Reading command.
99  */
100 struct GetReadingResponse
101 {
102     uint8_t reading;          //!< Sensor reading.
103     uint8_t operation;        //!< Sensor scanning status / reading state.
104     uint8_t assertOffset0_7;  //!< Discrete assertion states(0-7).
105     uint8_t assertOffset8_14; //!< Discrete assertion states(8-14).
106 } __attribute__((packed));
107 
108 constexpr auto inventoryRoot = "/xyz/openbmc_project/inventory";
109 
110 struct GetSensorResponse
111 {
112     uint8_t reading;                     // sensor reading
113     bool readingOrStateUnavailable;      // 1 = reading/state unavailable
114     bool scanningEnabled;                // 0 = sensor scanning disabled
115     bool allEventMessagesEnabled;        // 0 = All Event Messages disabled
116     uint8_t thresholdLevelsStates;       // threshold/discrete sensor states
117     uint8_t discreteReadingSensorStates; // discrete-only, optional states
118 };
119 
120 using OffsetValueMap = std::map<Offset, Values>;
121 
122 using DbusPropertyValues = std::pair<PreReqOffsetValueMap, OffsetValueMap>;
123 
124 using DbusPropertyMap = std::map<DbusProperty, DbusPropertyValues>;
125 
126 using DbusInterfaceMap = std::map<DbusInterface, DbusPropertyMap>;
127 
128 using InstancePath = std::string;
129 using Type = uint8_t;
130 using ReadingType = uint8_t;
131 using Multiplier = uint16_t;
132 using OffsetB = int16_t;
133 using Exponent = int8_t;
134 using ScaledOffset = double;
135 using Scale = int16_t;
136 using Unit = std::string;
137 using EntityType = uint8_t;
138 using EntityInst = uint8_t;
139 using SensorName = std::string;
140 using SensorUnits1 = uint8_t;
141 
142 enum class Mutability
143 {
144     Read = 1 << 0,
145     Write = 1 << 1,
146 };
147 
operator |(Mutability lhs,Mutability rhs)148 inline Mutability operator|(Mutability lhs, Mutability rhs)
149 {
150     return static_cast<Mutability>(
151         static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
152 }
153 
operator &(Mutability lhs,Mutability rhs)154 inline Mutability operator&(Mutability lhs, Mutability rhs)
155 {
156     return static_cast<Mutability>(
157         static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
158 }
159 
160 struct Info
161 {
162     EntityType entityType;
163     EntityInst instance;
164     Type sensorType;
165     InstancePath sensorPath;
166     DbusInterface sensorInterface;
167     ReadingType sensorReadingType;
168     Multiplier coefficientM;
169     OffsetB coefficientB;
170     Exponent exponentB;
171     ScaledOffset scaledOffset;
172     Exponent exponentR;
173     bool hasScale;
174     Scale scale;
175     SensorUnits1 sensorUnits1;
176     Unit unit;
177     std::function<uint8_t(SetSensorReadingReq&, const Info&)> updateFunc;
178 #ifndef FEATURE_SENSORS_CACHE
179     std::function<GetSensorResponse(const Info&)> getFunc;
180 #else
181     std::function<std::optional<GetSensorResponse>(uint8_t, const Info&,
182                                                    const ipmi::PropertyMap&)>
183         getFunc;
184 #endif
185     Mutability mutability;
186     SensorName sensorName;
187     std::function<SensorName(const Info&)> sensorNameFunc;
188     DbusInterfaceMap propertyInterfaces;
189 };
190 
191 using Id = uint8_t;
192 using IdInfoMap = std::map<Id, Info>;
193 
194 using PropertyMap = ipmi::PropertyMap;
195 
196 using InterfaceMap = std::map<DbusInterface, PropertyMap>;
197 
198 using Object = sdbusplus::message::object_path;
199 using ObjectMap = std::map<Object, InterfaceMap>;
200 
201 using IpmiUpdateData = sdbusplus::message_t;
202 
203 struct SelData
204 {
205     Id sensorID;
206     Type sensorType;
207     ReadingType eventReadingType;
208     Offset eventOffset;
209 };
210 
211 using InventoryPath = std::string;
212 
213 using InvObjectIDMap = std::map<InventoryPath, SelData>;
214 
215 enum class ThresholdMask
216 {
217     NON_CRITICAL_LOW_MASK = 0x01,
218     CRITICAL_LOW_MASK = 0x02,
219     NON_CRITICAL_HIGH_MASK = 0x08,
220     CRITICAL_HIGH_MASK = 0x10,
221 };
222 
223 static constexpr uint8_t maxContainedEntities = 4;
224 using ContainedEntitiesArray =
225     std::array<std::pair<uint8_t, uint8_t>, maxContainedEntities>;
226 
227 struct EntityInfo
228 {
229     uint8_t containerEntityId;
230     uint8_t containerEntityInstance;
231     bool isList;
232     bool isLinked;
233     ContainedEntitiesArray containedEntities;
234 };
235 
236 using EntityInfoMap = std::map<Id, EntityInfo>;
237 
238 #ifdef FEATURE_SENSORS_CACHE
239 /**
240  * @struct SensorData
241  *
242  * The data to cache for sensors
243  */
244 struct SensorData
245 {
246     double value;
247     bool available;
248     bool functional;
249     GetSensorResponse response;
250 };
251 
252 using SensorCacheMap = std::map<uint8_t, std::optional<SensorData>>;
253 #endif
254 
255 } // namespace sensor
256 
257 namespace network
258 {
259 constexpr auto MAC_ADDRESS_FORMAT = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
260 
261 constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
262 constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
263 
264 constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
265 constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
266 
267 } // namespace network
268 
269 template <typename T>
270 class SecureAllocator : public std::allocator<T>
271 {
272   public:
273     template <typename U>
274     struct rebind
275     {
276         typedef SecureAllocator<U> other;
277     };
278 
deallocate(T * p,size_t n)279     void deallocate(T* p, size_t n)
280     {
281         OPENSSL_cleanse(p, n);
282         return std::allocator<T>::deallocate(p, n);
283     }
284 };
285 
286 using SecureStringBase =
287     std::basic_string<char, std::char_traits<char>, SecureAllocator<char>>;
288 class SecureString : public SecureStringBase
289 {
290   public:
291     using SecureStringBase::basic_string;
SecureString(const SecureStringBase & other)292     SecureString(const SecureStringBase& other) : SecureStringBase(other) {};
293     SecureString(SecureString&) = default;
294     SecureString(const SecureString&) = default;
295     SecureString(SecureString&&) = default;
296     SecureString& operator=(SecureString&&) = default;
297     SecureString& operator=(const SecureString&) = default;
298 
~SecureString()299     ~SecureString()
300     {
301         OPENSSL_cleanse(this->data(), this->size());
302     }
303 };
304 
305 using SecureBufferBase = std::vector<uint8_t, SecureAllocator<uint8_t>>;
306 
307 class SecureBuffer : public SecureBufferBase
308 {
309   public:
310     using SecureBufferBase::vector;
SecureBuffer(const SecureBufferBase & other)311     SecureBuffer(const SecureBufferBase& other) : SecureBufferBase(other) {};
312     SecureBuffer(SecureBuffer&) = default;
313     SecureBuffer(const SecureBuffer&) = default;
314     SecureBuffer(SecureBuffer&&) = default;
315     SecureBuffer& operator=(SecureBuffer&&) = default;
316     SecureBuffer& operator=(const SecureBuffer&) = default;
317 
~SecureBuffer()318     ~SecureBuffer()
319     {
320         OPENSSL_cleanse(this->data(), this->size());
321     }
322 };
323 } // namespace ipmi
324