xref: /openbmc/phosphor-host-ipmid/sensorhandler.hpp (revision 6b47d5a1da42dca58eff80c6f348eb4e719b427b)
1 #pragma once
2 
3 #include <stdint.h>
4 
5 #include <ipmid/api.hpp>
6 #include <ipmid/types.hpp>
7 
8 #include <exception>
9 
10 /**
11  * @enum device_type
12  * IPMI FRU device types
13  */
14 enum device_type
15 {
16     IPMI_PHYSICAL_FRU = 0x00,
17     IPMI_LOGICAL_FRU = 0x80,
18 };
19 
20 // Discrete sensor types.
21 enum ipmi_sensor_types
22 {
23     IPMI_SENSOR_TEMP = 0x01,
24     IPMI_SENSOR_VOLTAGE = 0x02,
25     IPMI_SENSOR_CURRENT = 0x03,
26     IPMI_SENSOR_FAN = 0x04,
27     IPMI_SENSOR_TPM = 0xCC,
28 };
29 
30 /** @brief Custom exception for reading sensors that are not funcitonal.
31  */
32 struct SensorFunctionalError : public std::exception
33 {
whatSensorFunctionalError34     const char* what() const noexcept
35     {
36         return "Sensor not functional";
37     }
38 };
39 
40 #define MAX_DBUS_PATH 128
41 struct dbus_interface_t
42 {
43     uint8_t sensornumber;
44     uint8_t sensortype;
45 
46     char bus[MAX_DBUS_PATH];
47     char path[MAX_DBUS_PATH];
48     char interface[MAX_DBUS_PATH];
49 };
50 
51 struct PlatformEventRequest
52 {
53     uint8_t eventMessageRevision;
54     uint8_t sensorType;
55     uint8_t sensorNumber;
56     uint8_t eventDirectionType;
57     uint8_t data[3];
58 };
59 
60 static constexpr const char* ipmiSELObject = "xyz.openbmc_project.Logging.IPMI";
61 static constexpr const char* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
62 static constexpr const char* ipmiSELAddInterface =
63     "xyz.openbmc_project.Logging.IPMI";
64 static const std::string ipmiSELAddMessage = "IPMI generated SEL Entry";
65 
66 static constexpr int selSystemEventSizeWith3Bytes = 8;
67 static constexpr int selSystemEventSizeWith2Bytes = 7;
68 static constexpr int selSystemEventSizeWith1Bytes = 6;
69 static constexpr int selIPMBEventSize = 7;
70 static constexpr uint8_t directionMask = 0x80;
71 static constexpr uint8_t byte3EnableMask = 0x30;
72 static constexpr uint8_t byte2EnableMask = 0xC0;
73 
74 int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
75 int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
76 int find_openbmc_path(uint8_t, dbus_interface_t*);
77 
78 ipmi::RspType<uint16_t, std::vector<uint8_t>> ipmiSensorGetSdr(
79     uint16_t, uint16_t, uint8_t, uint8_t);
80 
81 ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
82 
83 static const uint16_t FRU_RECORD_ID_START = 256;
84 static const uint16_t ENTITY_RECORD_ID_START = 512;
85 static const uint8_t SDR_VERSION = 0x51;
86 static const uint16_t END_OF_RECORD = 0xFFFF;
87 static const uint8_t LENGTH_MASK = 0x1F;
88 
89 /**
90  * Get SDR
91  */
92 namespace get_sdr
93 {
94 
95 // Record header
96 struct SensorDataRecordHeader
97 {
98     uint16_t recordId;
99     uint8_t sdrVersion;
100     uint8_t recordType;
101     uint8_t recordLength; // Length not counting the header
102 } __attribute__((packed));
103 
104 enum SensorDataRecordType
105 {
106     SENSOR_DATA_FULL_RECORD = 0x1,
107     SENSOR_DATA_COMPACT_RECORD = 0x2,
108     SENSOR_DATA_EVENT_RECORD = 0x3,
109     SENSOR_DATA_ENTITY_RECORD = 0x8,
110     SENSOR_DATA_FRU_RECORD = 0x11,
111     SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
112 };
113 
114 // Record key
115 struct SensorDataRecordKey
116 {
117     uint8_t ownerId;
118     uint8_t ownerLun;
119     uint8_t sensorNumber;
120 } __attribute__((packed));
121 
122 /** @struct SensorDataFruRecordKey
123  *
124  *  FRU Device Locator Record(key) - SDR Type 11
125  */
126 struct SensorDataFruRecordKey
127 {
128     uint8_t deviceAddress;
129     uint8_t fruID;
130     uint8_t accessLun;
131     uint8_t channelNumber;
132 } __attribute__((packed));
133 
134 /** @struct SensorDataEntityRecordKey
135  *
136  *  Entity Association Record(key) - SDR Type 8
137  */
138 struct SensorDataEntityRecordKey
139 {
140     uint8_t containerEntityId;
141     uint8_t containerEntityInstance;
142     uint8_t flags;
143     uint8_t entityId1;
144     uint8_t entityInstance1;
145 } __attribute__((packed));
146 
147 namespace key
148 {
149 
150 static constexpr uint8_t listOrRangeBit = 7;
151 static constexpr uint8_t linkedBit = 6;
152 
setOwnerIdIpmb(SensorDataRecordKey & key)153 inline void setOwnerIdIpmb(SensorDataRecordKey& key)
154 {
155     key.ownerId &= ~0x01;
156 };
157 
setOwnerIdSystemSw(SensorDataRecordKey & key)158 inline void setOwnerIdSystemSw(SensorDataRecordKey& key)
159 {
160     key.ownerId |= 0x01;
161 };
162 
setOwnerIdBmc(SensorDataRecordKey & key)163 inline void setOwnerIdBmc(SensorDataRecordKey& key)
164 {
165     key.ownerId |= 0x20;
166 };
167 
setOwnerIdAddress(uint8_t addr,SensorDataRecordKey & key)168 inline void setOwnerIdAddress(uint8_t addr, SensorDataRecordKey& key)
169 {
170     key.ownerId &= 0x01;
171     key.ownerId |= addr << 1;
172 };
173 
setOwnerLun(uint8_t lun,SensorDataRecordKey & key)174 inline void setOwnerLun(uint8_t lun, SensorDataRecordKey& key)
175 {
176     key.ownerLun &= ~0x03;
177     key.ownerLun |= (lun & 0x03);
178 };
179 
setOwnerLunChannel(uint8_t channel,SensorDataRecordKey & key)180 inline void setOwnerLunChannel(uint8_t channel, SensorDataRecordKey& key)
181 {
182     key.ownerLun &= 0x0f;
183     key.ownerLun |= ((channel & 0xf) << 4);
184 };
185 
setFlags(bool isList,bool isLinked,SensorDataEntityRecordKey & key)186 inline void setFlags(bool isList, bool isLinked, SensorDataEntityRecordKey& key)
187 {
188     key.flags = 0x00;
189     if (!isList)
190     {
191         key.flags |= 1 << listOrRangeBit;
192     }
193 
194     if (isLinked)
195     {
196         key.flags |= 1 << linkedBit;
197     }
198 };
199 
200 } // namespace key
201 
202 /** @struct GetSensorThresholdsResponse
203  *
204  *  Response structure for Get Sensor Thresholds command
205  */
206 struct GetSensorThresholdsResponse
207 {
208     uint8_t validMask;           //!< valid mask
209     uint8_t lowerNonCritical;    //!< lower non-critical threshold
210     uint8_t lowerCritical;       //!< lower critical threshold
211     uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
212     uint8_t upperNonCritical;    //!< upper non-critical threshold
213     uint8_t upperCritical;       //!< upper critical threshold
214     uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
215 } __attribute__((packed));
216 
217 // Body - full record
218 #define FULL_RECORD_ID_STR_MAX_LENGTH 16
219 
220 static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
221 
222 struct SensorDataFullRecordBody
223 {
224     uint8_t entityId;
225     uint8_t entityInstance;
226     uint8_t sensorInitialization;
227     uint8_t sensorCapabilities; // no macro support
228     uint8_t sensorType;
229     uint8_t eventReadingType;
230     uint8_t supportedAssertions[2];        // no macro support
231     uint8_t supportedDeassertions[2];      // no macro support
232     uint8_t discreteReadingSettingMask[2]; // no macro support
233     uint8_t sensorUnits1;
234     uint8_t sensorUnits2Base;
235     uint8_t sensorUnits3Modifier;
236     uint8_t linearization;
237     uint8_t mLsb;
238     uint8_t mMsbAndTolerance;
239     uint8_t bLsb;
240     uint8_t bMsbAndAccuracyLsb;
241     uint8_t accuracyAndSensorDirection;
242     uint8_t rbExponents;
243     uint8_t analogCharacteristicFlags; // no macro support
244     uint8_t nominalReading;
245     uint8_t normalMax;
246     uint8_t normalMin;
247     uint8_t sensorMax;
248     uint8_t sensorMin;
249     uint8_t upperNonrecoverableThreshold;
250     uint8_t upperCriticalThreshold;
251     uint8_t upperNoncriticalThreshold;
252     uint8_t lowerNonrecoverableThreshold;
253     uint8_t lowerCriticalThreshold;
254     uint8_t lowerNoncriticalThreshold;
255     uint8_t positiveThresholdHysteresis;
256     uint8_t negativeThresholdHysteresis;
257     uint16_t reserved;
258     uint8_t oemReserved;
259     uint8_t idStringInfo;
260     char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
261 } __attribute__((packed));
262 
263 /** @struct SensorDataCompactRecord
264  *
265  *  Compact Sensor Record(body) - SDR Type 2
266  */
267 struct SensorDataCompactRecordBody
268 {
269     uint8_t entityId;
270     uint8_t entityInstance;
271     uint8_t sensorInitialization;
272     uint8_t sensorCapabilities; // no macro support
273     uint8_t sensorType;
274     uint8_t eventReadingType;
275     uint8_t supportedAssertions[2];        // no macro support
276     uint8_t supportedDeassertions[2];      // no macro support
277     uint8_t discreteReadingSettingMask[2]; // no macro support
278     uint8_t sensorUnits1;
279     uint8_t sensorUnits2Base;
280     uint8_t sensorUnits3Modifier;
281     uint8_t record_sharing[2];
282     uint8_t positiveThresholdHysteresis;
283     uint8_t negativeThresholdHysteresis;
284     uint8_t reserved[3];
285     uint8_t oemReserved;
286     uint8_t idStringInfo;
287     char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
288 } __attribute__((packed));
289 
290 /** @struct SensorDataEventRecord
291  *
292  *  Event Only Sensor Record(body) - SDR Type 3
293  */
294 struct SensorDataEventRecordBody
295 {
296     uint8_t entityId;
297     uint8_t entityInstance;
298     uint8_t sensorType;
299     uint8_t eventReadingType;
300     uint8_t sensorRecordSharing1;
301     uint8_t sensorRecordSharing2;
302     uint8_t reserved;
303     uint8_t oemReserved;
304     uint8_t idStringInfo;
305     char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
306 } __attribute__((packed));
307 
308 /** @struct SensorDataFruRecordBody
309  *
310  *  FRU Device Locator Record(body) - SDR Type 11
311  */
312 struct SensorDataFruRecordBody
313 {
314     uint8_t reserved;
315     uint8_t deviceType;
316     uint8_t deviceTypeModifier;
317     uint8_t entityID;
318     uint8_t entityInstance;
319     uint8_t oem;
320     uint8_t deviceIDLen;
321     char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
322 } __attribute__((packed));
323 
324 /** @struct SensorDataEntityRecordBody
325  *
326  *  Entity Association Record(body) - SDR Type 8
327  */
328 struct SensorDataEntityRecordBody
329 {
330     uint8_t entityId2;
331     uint8_t entityInstance2;
332     uint8_t entityId3;
333     uint8_t entityInstance3;
334     uint8_t entityId4;
335     uint8_t entityInstance4;
336 } __attribute__((packed));
337 
338 namespace body
339 {
340 
setEntityInstanceNumber(uint8_t n,SensorDataFullRecordBody & body)341 inline void setEntityInstanceNumber(uint8_t n, SensorDataFullRecordBody& body)
342 {
343     body.entityInstance &= 1 << 7;
344     body.entityInstance |= (n & ~(1 << 7));
345 };
346 
setEntityPhysicalEntity(SensorDataFullRecordBody & body)347 inline void setEntityPhysicalEntity(SensorDataFullRecordBody& body)
348 {
349     body.entityInstance &= ~(1 << 7);
350 };
351 
setEntityLogicalContainer(SensorDataFullRecordBody & body)352 inline void setEntityLogicalContainer(SensorDataFullRecordBody& body)
353 {
354     body.entityInstance |= 1 << 7;
355 };
356 
sensorScanningState(bool enabled,SensorDataFullRecordBody & body)357 inline void sensorScanningState(bool enabled, SensorDataFullRecordBody& body)
358 {
359     if (enabled)
360     {
361         body.sensorInitialization |= 1 << 0;
362     }
363     else
364     {
365         body.sensorInitialization &= ~(1 << 0);
366     };
367 };
368 
eventGenerationState(bool enabled,SensorDataFullRecordBody & body)369 inline void eventGenerationState(bool enabled, SensorDataFullRecordBody& body)
370 {
371     if (enabled)
372     {
373         body.sensorInitialization |= 1 << 1;
374     }
375     else
376     {
377         body.sensorInitialization &= ~(1 << 1);
378     }
379 };
380 
initTypesState(bool enabled,SensorDataFullRecordBody & body)381 inline void initTypesState(bool enabled, SensorDataFullRecordBody& body)
382 {
383     if (enabled)
384     {
385         body.sensorInitialization |= 1 << 2;
386     }
387     else
388     {
389         body.sensorInitialization &= ~(1 << 2);
390     }
391 };
392 
initHystState(bool enabled,SensorDataFullRecordBody & body)393 inline void initHystState(bool enabled, SensorDataFullRecordBody& body)
394 {
395     if (enabled)
396     {
397         body.sensorInitialization |= 1 << 3;
398     }
399     else
400     {
401         body.sensorInitialization &= ~(1 << 3);
402     }
403 };
404 
initThreshState(bool enabled,SensorDataFullRecordBody & body)405 inline void initThreshState(bool enabled, SensorDataFullRecordBody& body)
406 {
407     if (enabled)
408     {
409         body.sensorInitialization |= 1 << 4;
410     }
411     else
412     {
413         body.sensorInitialization &= ~(1 << 4);
414     }
415 };
416 
initEventsState(bool enabled,SensorDataFullRecordBody & body)417 inline void initEventsState(bool enabled, SensorDataFullRecordBody& body)
418 {
419     if (enabled)
420     {
421         body.sensorInitialization |= 1 << 5;
422     }
423     else
424     {
425         body.sensorInitialization &= ~(1 << 5);
426     }
427 };
428 
initScanningState(bool enabled,SensorDataFullRecordBody & body)429 inline void initScanningState(bool enabled, SensorDataFullRecordBody& body)
430 {
431     if (enabled)
432     {
433         body.sensorInitialization |= 1 << 6;
434     }
435     else
436     {
437         body.sensorInitialization &= ~(1 << 6);
438     }
439 };
440 
initSettableState(bool enabled,SensorDataFullRecordBody & body)441 inline void initSettableState(bool enabled, SensorDataFullRecordBody& body)
442 {
443     if (enabled)
444     {
445         body.sensorInitialization |= 1 << 7;
446     }
447     else
448     {
449         body.sensorInitialization &= ~(1 << 7);
450     }
451 };
452 
setPercentage(SensorDataFullRecordBody & body)453 inline void setPercentage(SensorDataFullRecordBody& body)
454 {
455     body.sensorUnits1 |= 1 << 0;
456 };
457 
unsetPercentage(SensorDataFullRecordBody & body)458 inline void unsetPercentage(SensorDataFullRecordBody& body)
459 {
460     body.sensorUnits1 &= ~(1 << 0);
461 };
462 
setModifierOperation(uint8_t op,SensorDataFullRecordBody & body)463 inline void setModifierOperation(uint8_t op, SensorDataFullRecordBody& body)
464 {
465     body.sensorUnits1 &= ~(3 << 1);
466     body.sensorUnits1 |= (op & 0x3) << 1;
467 };
468 
setRateUnit(uint8_t unit,SensorDataFullRecordBody & body)469 inline void setRateUnit(uint8_t unit, SensorDataFullRecordBody& body)
470 {
471     body.sensorUnits1 &= ~(7 << 3);
472     body.sensorUnits1 |= (unit & 0x7) << 3;
473 };
474 
setAnalogDataFormat(uint8_t format,SensorDataFullRecordBody & body)475 inline void setAnalogDataFormat(uint8_t format, SensorDataFullRecordBody& body)
476 {
477     body.sensorUnits1 &= ~(3 << 6);
478     body.sensorUnits1 |= (format & 0x3) << 6;
479 };
480 
setM(uint16_t m,SensorDataFullRecordBody & body)481 inline void setM(uint16_t m, SensorDataFullRecordBody& body)
482 {
483     body.mLsb = m & 0xff;
484     body.mMsbAndTolerance &= ~(3 << 6);
485     body.mMsbAndTolerance |= ((m & (3 << 8)) >> 2);
486 };
487 
setTolerance(uint8_t tol,SensorDataFullRecordBody & body)488 inline void setTolerance(uint8_t tol, SensorDataFullRecordBody& body)
489 {
490     body.mMsbAndTolerance &= ~0x3f;
491     body.mMsbAndTolerance |= tol & 0x3f;
492 };
493 
setB(uint16_t b,SensorDataFullRecordBody & body)494 inline void setB(uint16_t b, SensorDataFullRecordBody& body)
495 {
496     body.bLsb = b & 0xff;
497     body.bMsbAndAccuracyLsb &= ~(3 << 6);
498     body.bMsbAndAccuracyLsb |= ((b & (3 << 8)) >> 2);
499 };
500 
setAccuracy(uint16_t acc,SensorDataFullRecordBody & body)501 inline void setAccuracy(uint16_t acc, SensorDataFullRecordBody& body)
502 {
503     // bottom 6 bits
504     body.bMsbAndAccuracyLsb &= ~0x3f;
505     body.bMsbAndAccuracyLsb |= acc & 0x3f;
506     // top 4 bits
507     body.accuracyAndSensorDirection &= 0x0f;
508     body.accuracyAndSensorDirection |= ((acc >> 6) & 0xf) << 4;
509 };
510 
setAccuracyExp(uint8_t exp,SensorDataFullRecordBody & body)511 inline void setAccuracyExp(uint8_t exp, SensorDataFullRecordBody& body)
512 {
513     body.accuracyAndSensorDirection &= ~(3 << 2);
514     body.accuracyAndSensorDirection |= (exp & 3) << 2;
515 };
516 
setSensorDir(uint8_t dir,SensorDataFullRecordBody & body)517 inline void setSensorDir(uint8_t dir, SensorDataFullRecordBody& body)
518 {
519     body.accuracyAndSensorDirection &= ~(3 << 0);
520     body.accuracyAndSensorDirection |= (dir & 3);
521 };
522 
setBexp(uint8_t exp,SensorDataFullRecordBody & body)523 inline void setBexp(uint8_t exp, SensorDataFullRecordBody& body)
524 {
525     body.rbExponents &= 0xf0;
526     body.rbExponents |= exp & 0x0f;
527 };
528 
setRexp(uint8_t exp,SensorDataFullRecordBody & body)529 inline void setRexp(uint8_t exp, SensorDataFullRecordBody& body)
530 {
531     body.rbExponents &= 0x0f;
532     body.rbExponents |= (exp & 0x0f) << 4;
533 };
534 
setIdStrLen(uint8_t len,SensorDataFullRecordBody & body)535 inline void setIdStrLen(uint8_t len, SensorDataFullRecordBody& body)
536 {
537     body.idStringInfo &= ~(0x1f);
538     body.idStringInfo |= len & 0x1f;
539 };
540 
setIdStrLen(uint8_t len,SensorDataEventRecordBody & body)541 inline void setIdStrLen(uint8_t len, SensorDataEventRecordBody& body)
542 {
543     body.idStringInfo &= ~(0x1f);
544     body.idStringInfo |= len & 0x1f;
545 };
546 
getIdStrLen(const SensorDataFullRecordBody & body)547 inline uint8_t getIdStrLen(const SensorDataFullRecordBody& body)
548 {
549     return body.idStringInfo & 0x1f;
550 };
551 
setIdType(uint8_t type,SensorDataFullRecordBody & body)552 inline void setIdType(uint8_t type, SensorDataFullRecordBody& body)
553 {
554     body.idStringInfo &= ~(3 << 6);
555     body.idStringInfo |= (type & 0x3) << 6;
556 };
557 
setIdType(uint8_t type,SensorDataEventRecordBody & body)558 inline void setIdType(uint8_t type, SensorDataEventRecordBody& body)
559 {
560     body.idStringInfo &= ~(3 << 6);
561     body.idStringInfo |= (type & 0x3) << 6;
562 };
563 
setDeviceIdStrLen(uint8_t len,SensorDataFruRecordBody & body)564 inline void setDeviceIdStrLen(uint8_t len, SensorDataFruRecordBody& body)
565 {
566     body.deviceIDLen &= ~(LENGTH_MASK);
567     body.deviceIDLen |= len & LENGTH_MASK;
568 };
569 
getDeviceIdStrLen(const SensorDataFruRecordBody & body)570 inline uint8_t getDeviceIdStrLen(const SensorDataFruRecordBody& body)
571 {
572     return body.deviceIDLen & LENGTH_MASK;
573 };
574 
setReadableMask(uint8_t mask,SensorDataFullRecordBody & body)575 inline void setReadableMask(uint8_t mask, SensorDataFullRecordBody& body)
576 {
577     body.discreteReadingSettingMask[1] = mask & 0x3F;
578 }
579 
580 } // namespace body
581 
582 // More types contained in section 43.17 Sensor Unit Type Codes,
583 // IPMI spec v2 rev 1.1
584 enum SensorUnitTypeCodes
585 {
586     SENSOR_UNIT_UNSPECIFIED = 0,
587     SENSOR_UNIT_DEGREES_C = 1,
588     SENSOR_UNIT_VOLTS = 4,
589     SENSOR_UNIT_AMPERES = 5,
590     SENSOR_UNIT_WATTS = 6,
591     SENSOR_UNIT_JOULES = 7,
592     SENSOR_UNIT_RPM = 18,
593     SENSOR_UNIT_METERS = 34,
594     SENSOR_UNIT_REVOLUTIONS = 41,
595 };
596 
597 struct SensorDataFullRecord
598 {
599     SensorDataRecordHeader header;
600     SensorDataRecordKey key;
601     SensorDataFullRecordBody body;
602 } __attribute__((packed));
603 
604 /** @struct SensorDataComapactRecord
605  *
606  *  Compact Sensor Record - SDR Type 2
607  */
608 struct SensorDataCompactRecord
609 {
610     SensorDataRecordHeader header;
611     SensorDataRecordKey key;
612     SensorDataCompactRecordBody body;
613 } __attribute__((packed));
614 
615 /** @struct SensorDataEventRecord
616  *
617  *  Event Only Sensor Record - SDR Type 3
618  */
619 struct SensorDataEventRecord
620 {
621     SensorDataRecordHeader header;
622     SensorDataRecordKey key;
623     SensorDataEventRecordBody body;
624 } __attribute__((packed));
625 
626 /** @struct SensorDataFruRecord
627  *
628  *  FRU Device Locator Record - SDR Type 11
629  */
630 struct SensorDataFruRecord
631 {
632     SensorDataRecordHeader header;
633     SensorDataFruRecordKey key;
634     SensorDataFruRecordBody body;
635 } __attribute__((packed));
636 
637 /** @struct SensorDataEntityRecord
638  *
639  *  Entity Association Record - SDR Type 8
640  */
641 struct SensorDataEntityRecord
642 {
643     SensorDataRecordHeader header;
644     SensorDataEntityRecordKey key;
645     SensorDataEntityRecordBody body;
646 } __attribute__((packed));
647 
648 } // namespace get_sdr
649 
650 namespace ipmi
651 {
652 
653 namespace sensor
654 {
655 
656 /**
657  * @brief Map offset to the corresponding bit in the assertion byte.
658  *
659  * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
660  * byte and offsets 8-14 in the second byte.
661  *
662  * @param[in] offset - offset number.
663  * @param[in/out] resp - get sensor reading response.
664  */
setOffset(uint8_t offset,ipmi::sensor::GetSensorResponse & resp)665 inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse& resp)
666 {
667     if (offset > 7)
668     {
669         resp.discreteReadingSensorStates |= 1 << (offset - 8);
670     }
671     else
672     {
673         resp.thresholdLevelsStates |= 1 << offset;
674     }
675 }
676 
677 /**
678  * @brief Set the reading field in the response.
679  *
680  * @param[in] offset - offset number.
681  * @param[in/out] resp - get sensor reading response.
682  */
setReading(uint8_t value,ipmi::sensor::GetSensorResponse & resp)683 inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse& resp)
684 {
685     resp.reading = value;
686 }
687 
688 /**
689  * @brief Map the value to the assertion bytes. The assertion states are stored
690  *        in 2 bytes.
691  *
692  * @param[in] value - value to mapped to the assertion byte.
693  * @param[in/out] resp - get sensor reading response.
694  */
setAssertionBytes(uint16_t value,ipmi::sensor::GetSensorResponse & resp)695 inline void setAssertionBytes(uint16_t value,
696                               ipmi::sensor::GetSensorResponse& resp)
697 {
698     resp.thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
699     resp.discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
700 }
701 
702 /**
703  * @brief Set the scanning enabled bit in the response.
704  *
705  * @param[in/out] resp - get sensor reading response.
706  */
enableScanning(ipmi::sensor::GetSensorResponse & resp)707 inline void enableScanning(ipmi::sensor::GetSensorResponse& resp)
708 {
709     resp.readingOrStateUnavailable = false;
710     resp.scanningEnabled = true;
711     resp.allEventMessagesEnabled = false;
712 }
713 
714 } // namespace sensor
715 
716 } // namespace ipmi
717