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