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_RECOVERABLE_LOW_MASK = 0x4,
220     NON_CRITICAL_HIGH_MASK = 0x08,
221     CRITICAL_HIGH_MASK = 0x10,
222     NON_RECOVERABLE_HIGH_MASK = 0x20,
223 };
224 
225 static constexpr uint8_t maxContainedEntities = 4;
226 using ContainedEntitiesArray =
227     std::array<std::pair<uint8_t, uint8_t>, maxContainedEntities>;
228 
229 struct EntityInfo
230 {
231     uint8_t containerEntityId;
232     uint8_t containerEntityInstance;
233     bool isList;
234     bool isLinked;
235     ContainedEntitiesArray containedEntities;
236 };
237 
238 using EntityInfoMap = std::map<Id, EntityInfo>;
239 
240 #ifdef FEATURE_SENSORS_CACHE
241 /**
242  * @struct SensorData
243  *
244  * The data to cache for sensors
245  */
246 struct SensorData
247 {
248     double value;
249     bool available;
250     bool functional;
251     GetSensorResponse response;
252 };
253 
254 using SensorCacheMap = std::map<uint8_t, std::optional<SensorData>>;
255 #endif
256 
257 } // namespace sensor
258 
259 namespace network
260 {
261 constexpr auto MAC_ADDRESS_FORMAT = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
262 
263 constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
264 constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
265 
266 constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
267 constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
268 
269 } // namespace network
270 
271 template <typename T>
272 class SecureAllocator : public std::allocator<T>
273 {
274   public:
275     template <typename U>
276     struct rebind
277     {
278         typedef SecureAllocator<U> other;
279     };
280 
deallocate(T * p,size_t n)281     void deallocate(T* p, size_t n)
282     {
283         OPENSSL_cleanse(p, n);
284         return std::allocator<T>::deallocate(p, n);
285     }
286 };
287 
288 using SecureStringBase =
289     std::basic_string<char, std::char_traits<char>, SecureAllocator<char>>;
290 class SecureString : public SecureStringBase
291 {
292   public:
293     using SecureStringBase::basic_string;
SecureString(const SecureStringBase & other)294     SecureString(const SecureStringBase& other) : SecureStringBase(other) {};
295     SecureString(SecureString&) = default;
296     SecureString(const SecureString&) = default;
297     SecureString(SecureString&&) = default;
298     SecureString& operator=(SecureString&&) = default;
299     SecureString& operator=(const SecureString&) = default;
300 
~SecureString()301     ~SecureString()
302     {
303         OPENSSL_cleanse(this->data(), this->size());
304     }
305 };
306 
307 using SecureBufferBase = std::vector<uint8_t, SecureAllocator<uint8_t>>;
308 
309 class SecureBuffer : public SecureBufferBase
310 {
311   public:
312     using SecureBufferBase::vector;
SecureBuffer(const SecureBufferBase & other)313     SecureBuffer(const SecureBufferBase& other) : SecureBufferBase(other) {};
314     SecureBuffer(SecureBuffer&) = default;
315     SecureBuffer(const SecureBuffer&) = default;
316     SecureBuffer(SecureBuffer&&) = default;
317     SecureBuffer& operator=(SecureBuffer&&) = default;
318     SecureBuffer& operator=(const SecureBuffer&) = default;
319 
~SecureBuffer()320     ~SecureBuffer()
321     {
322         OPENSSL_cleanse(this->data(), this->size());
323     }
324 };
325 } // namespace ipmi
326