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 // IPMI commands for net functions. 11 enum ipmi_netfn_sen_cmds 12 { 13 IPMI_CMD_PLATFORM_EVENT = 0x2, 14 IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20, 15 IPMI_CMD_GET_DEVICE_SDR = 0x21, 16 IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22, 17 IPMI_CMD_GET_SENSOR_READING = 0x2D, 18 IPMI_CMD_GET_SENSOR_TYPE = 0x2F, 19 IPMI_CMD_SET_SENSOR = 0x30, 20 IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27, 21 }; 22 23 /** 24 * @enum device_type 25 * IPMI FRU device types 26 */ 27 enum device_type 28 { 29 IPMI_PHYSICAL_FRU = 0x00, 30 IPMI_LOGICAL_FRU = 0x80, 31 }; 32 33 // Discrete sensor types. 34 enum ipmi_sensor_types 35 { 36 IPMI_SENSOR_TEMP = 0x01, 37 IPMI_SENSOR_VOLTAGE = 0x02, 38 IPMI_SENSOR_CURRENT = 0x03, 39 IPMI_SENSOR_FAN = 0x04, 40 IPMI_SENSOR_TPM = 0xCC, 41 }; 42 43 /** @brief Custom exception for reading sensors that are not funcitonal. 44 */ 45 struct SensorFunctionalError : public std::exception 46 { 47 const char* what() const noexcept 48 { 49 return "Sensor not functional"; 50 } 51 }; 52 53 #define MAX_DBUS_PATH 128 54 struct dbus_interface_t 55 { 56 uint8_t sensornumber; 57 uint8_t sensortype; 58 59 char bus[MAX_DBUS_PATH]; 60 char path[MAX_DBUS_PATH]; 61 char interface[MAX_DBUS_PATH]; 62 }; 63 64 struct PlatformEventRequest 65 { 66 uint8_t eventMessageRevision; 67 uint8_t sensorType; 68 uint8_t sensorNumber; 69 uint8_t eventDirectionType; 70 uint8_t data[3]; 71 }; 72 73 static constexpr const char* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI"; 74 static constexpr const char* ipmiSELAddInterface = 75 "xyz.openbmc_project.Logging.IPMI"; 76 static const std::string ipmiSELAddMessage = "SEL Entry"; 77 78 static constexpr int selSystemEventSizeWith3Bytes = 8; 79 static constexpr int selSystemEventSizeWith2Bytes = 7; 80 static constexpr int selSystemEventSizeWith1Bytes = 6; 81 static constexpr int selIPMBEventSize = 7; 82 static constexpr uint8_t directionMask = 0x80; 83 static constexpr uint8_t byte3EnableMask = 0x30; 84 static constexpr uint8_t byte2EnableMask = 0xC0; 85 86 int set_sensor_dbus_state_s(uint8_t, const char*, const char*); 87 int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t); 88 int find_openbmc_path(uint8_t, dbus_interface_t*); 89 90 ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 91 ipmi_request_t request, ipmi_response_t response, 92 ipmi_data_len_t data_len, ipmi_context_t context); 93 94 ipmi::RspType<uint16_t> ipmiSensorReserveSdr(); 95 96 static const uint16_t FRU_RECORD_ID_START = 256; 97 static const uint16_t ENTITY_RECORD_ID_START = 512; 98 static const uint8_t SDR_VERSION = 0x51; 99 static const uint16_t END_OF_RECORD = 0xFFFF; 100 static const uint8_t LENGTH_MASK = 0x1F; 101 102 /** 103 * Get SDR Info 104 */ 105 106 namespace get_sdr_info 107 { 108 namespace request 109 { 110 // Note: for some reason the ipmi_request_t appears to be the 111 // raw value for this call. 112 inline bool get_count(void* req) 113 { 114 return (bool)((uint64_t)(req)&1); 115 } 116 } // namespace request 117 } // namespace get_sdr_info 118 119 /** 120 * Get SDR 121 */ 122 namespace get_sdr 123 { 124 125 struct GetSdrReq 126 { 127 uint8_t reservation_id_lsb; 128 uint8_t reservation_id_msb; 129 uint8_t record_id_lsb; 130 uint8_t record_id_msb; 131 uint8_t offset; 132 uint8_t bytes_to_read; 133 } __attribute__((packed)); 134 135 namespace request 136 { 137 138 inline uint16_t get_reservation_id(GetSdrReq* req) 139 { 140 return (req->reservation_id_lsb + (req->reservation_id_msb << 8)); 141 }; 142 143 inline uint16_t get_record_id(GetSdrReq* req) 144 { 145 return (req->record_id_lsb + (req->record_id_msb << 8)); 146 }; 147 148 } // namespace request 149 150 // Response 151 struct GetSdrResp 152 { 153 uint8_t next_record_id_lsb; 154 uint8_t next_record_id_msb; 155 uint8_t record_data[64]; 156 } __attribute__((packed)); 157 158 namespace response 159 { 160 161 inline void set_next_record_id(uint16_t next, GetSdrResp* resp) 162 { 163 resp->next_record_id_lsb = next & 0xff; 164 resp->next_record_id_msb = (next >> 8) & 0xff; 165 }; 166 167 } // namespace response 168 169 // Record header 170 struct SensorDataRecordHeader 171 { 172 uint8_t record_id_lsb; 173 uint8_t record_id_msb; 174 uint8_t sdr_version; 175 uint8_t record_type; 176 uint8_t record_length; // Length not counting the header 177 } __attribute__((packed)); 178 179 namespace header 180 { 181 182 inline void set_record_id(int id, SensorDataRecordHeader* hdr) 183 { 184 hdr->record_id_lsb = (id & 0xFF); 185 hdr->record_id_msb = (id >> 8) & 0xFF; 186 }; 187 188 } // namespace header 189 190 enum SensorDataRecordType 191 { 192 SENSOR_DATA_FULL_RECORD = 0x1, 193 SENSOR_DATA_COMPACT_RECORD = 0x2, 194 SENSOR_DATA_EVENT_RECORD = 0x3, 195 SENSOR_DATA_ENTITY_RECORD = 0x8, 196 SENSOR_DATA_FRU_RECORD = 0x11, 197 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12, 198 }; 199 200 // Record key 201 struct SensorDataRecordKey 202 { 203 uint8_t owner_id; 204 uint8_t owner_lun; 205 uint8_t sensor_number; 206 } __attribute__((packed)); 207 208 /** @struct SensorDataFruRecordKey 209 * 210 * FRU Device Locator Record(key) - SDR Type 11 211 */ 212 struct SensorDataFruRecordKey 213 { 214 uint8_t deviceAddress; 215 uint8_t fruID; 216 uint8_t accessLun; 217 uint8_t channelNumber; 218 } __attribute__((packed)); 219 220 /** @struct SensorDataEntityRecordKey 221 * 222 * Entity Association Record(key) - SDR Type 8 223 */ 224 struct SensorDataEntityRecordKey 225 { 226 uint8_t containerEntityId; 227 uint8_t containerEntityInstance; 228 uint8_t flags; 229 uint8_t entityId1; 230 uint8_t entityInstance1; 231 } __attribute__((packed)); 232 233 namespace key 234 { 235 236 static constexpr uint8_t listOrRangeBit = 7; 237 static constexpr uint8_t linkedBit = 6; 238 239 inline void set_owner_id_ipmb(SensorDataRecordKey* key) 240 { 241 key->owner_id &= ~0x01; 242 }; 243 244 inline void set_owner_id_system_sw(SensorDataRecordKey* key) 245 { 246 key->owner_id |= 0x01; 247 }; 248 249 inline void set_owner_id_bmc(SensorDataRecordKey* key) 250 { 251 key->owner_id |= 0x20; 252 }; 253 254 inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key) 255 { 256 key->owner_id &= 0x01; 257 key->owner_id |= addr << 1; 258 }; 259 260 inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key) 261 { 262 key->owner_lun &= ~0x03; 263 key->owner_lun |= (lun & 0x03); 264 }; 265 266 inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key) 267 { 268 key->owner_lun &= 0x0f; 269 key->owner_lun |= ((channel & 0xf) << 4); 270 }; 271 272 inline void set_flags(bool isList, bool isLinked, 273 SensorDataEntityRecordKey* key) 274 { 275 key->flags = 0x00; 276 if (!isList) 277 key->flags |= 1 << listOrRangeBit; 278 279 if (isLinked) 280 key->flags |= 1 << linkedBit; 281 }; 282 283 } // namespace key 284 285 /** @struct GetSensorThresholdsResponse 286 * 287 * Response structure for Get Sensor Thresholds command 288 */ 289 struct GetSensorThresholdsResponse 290 { 291 uint8_t validMask; //!< valid mask 292 uint8_t lowerNonCritical; //!< lower non-critical threshold 293 uint8_t lowerCritical; //!< lower critical threshold 294 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold 295 uint8_t upperNonCritical; //!< upper non-critical threshold 296 uint8_t upperCritical; //!< upper critical threshold 297 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold 298 } __attribute__((packed)); 299 300 // Body - full record 301 #define FULL_RECORD_ID_STR_MAX_LENGTH 16 302 303 static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16; 304 305 struct SensorDataFullRecordBody 306 { 307 uint8_t entity_id; 308 uint8_t entity_instance; 309 uint8_t sensor_initialization; 310 uint8_t sensor_capabilities; // no macro support 311 uint8_t sensor_type; 312 uint8_t event_reading_type; 313 uint8_t supported_assertions[2]; // no macro support 314 uint8_t supported_deassertions[2]; // no macro support 315 uint8_t discrete_reading_setting_mask[2]; // no macro support 316 uint8_t sensor_units_1; 317 uint8_t sensor_units_2_base; 318 uint8_t sensor_units_3_modifier; 319 uint8_t linearization; 320 uint8_t m_lsb; 321 uint8_t m_msb_and_tolerance; 322 uint8_t b_lsb; 323 uint8_t b_msb_and_accuracy_lsb; 324 uint8_t accuracy_and_sensor_direction; 325 uint8_t r_b_exponents; 326 uint8_t analog_characteristic_flags; // no macro support 327 uint8_t nominal_reading; 328 uint8_t normal_max; 329 uint8_t normal_min; 330 uint8_t sensor_max; 331 uint8_t sensor_min; 332 uint8_t upper_nonrecoverable_threshold; 333 uint8_t upper_critical_threshold; 334 uint8_t upper_noncritical_threshold; 335 uint8_t lower_nonrecoverable_threshold; 336 uint8_t lower_critical_threshold; 337 uint8_t lower_noncritical_threshold; 338 uint8_t positive_threshold_hysteresis; 339 uint8_t negative_threshold_hysteresis; 340 uint16_t reserved; 341 uint8_t oem_reserved; 342 uint8_t id_string_info; 343 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH]; 344 } __attribute__((packed)); 345 346 /** @struct SensorDataCompactRecord 347 * 348 * Compact Sensor Record(body) - SDR Type 2 349 */ 350 struct SensorDataCompactRecordBody 351 { 352 uint8_t entity_id; 353 uint8_t entity_instance; 354 uint8_t sensor_initialization; 355 uint8_t sensor_capabilities; // no macro support 356 uint8_t sensor_type; 357 uint8_t event_reading_type; 358 uint8_t supported_assertions[2]; // no macro support 359 uint8_t supported_deassertions[2]; // no macro support 360 uint8_t discrete_reading_setting_mask[2]; // no macro support 361 uint8_t sensor_units_1; 362 uint8_t sensor_units_2_base; 363 uint8_t sensor_units_3_modifier; 364 uint8_t record_sharing[2]; 365 uint8_t positive_threshold_hysteresis; 366 uint8_t negative_threshold_hysteresis; 367 uint8_t reserved[3]; 368 uint8_t oem_reserved; 369 uint8_t id_string_info; 370 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH]; 371 } __attribute__((packed)); 372 373 /** @struct SensorDataEventRecord 374 * 375 * Event Only Sensor Record(body) - SDR Type 3 376 */ 377 struct SensorDataEventRecordBody 378 { 379 uint8_t entity_id; 380 uint8_t entity_instance; 381 uint8_t sensor_type; 382 uint8_t event_reading_type; 383 uint8_t sensor_record_sharing_1; 384 uint8_t sensor_record_sharing_2; 385 uint8_t reserved; 386 uint8_t oem_reserved; 387 uint8_t id_string_info; 388 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH]; 389 } __attribute__((packed)); 390 391 /** @struct SensorDataFruRecordBody 392 * 393 * FRU Device Locator Record(body) - SDR Type 11 394 */ 395 struct SensorDataFruRecordBody 396 { 397 uint8_t reserved; 398 uint8_t deviceType; 399 uint8_t deviceTypeModifier; 400 uint8_t entityID; 401 uint8_t entityInstance; 402 uint8_t oem; 403 uint8_t deviceIDLen; 404 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH]; 405 } __attribute__((packed)); 406 407 /** @struct SensorDataEntityRecordBody 408 * 409 * Entity Association Record(body) - SDR Type 8 410 */ 411 struct SensorDataEntityRecordBody 412 { 413 uint8_t entityId2; 414 uint8_t entityInstance2; 415 uint8_t entityId3; 416 uint8_t entityInstance3; 417 uint8_t entityId4; 418 uint8_t entityInstance4; 419 } __attribute__((packed)); 420 421 namespace body 422 { 423 424 inline void set_entity_instance_number(uint8_t n, 425 SensorDataFullRecordBody* body) 426 { 427 body->entity_instance &= 1 << 7; 428 body->entity_instance |= (n & ~(1 << 7)); 429 }; 430 inline void set_entity_physical_entity(SensorDataFullRecordBody* body) 431 { 432 body->entity_instance &= ~(1 << 7); 433 }; 434 inline void set_entity_logical_container(SensorDataFullRecordBody* body) 435 { 436 body->entity_instance |= 1 << 7; 437 }; 438 439 inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body) 440 { 441 if (enabled) 442 { 443 body->sensor_initialization |= 1 << 0; 444 } 445 else 446 { 447 body->sensor_initialization &= ~(1 << 0); 448 }; 449 }; 450 inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body) 451 { 452 if (enabled) 453 { 454 body->sensor_initialization |= 1 << 1; 455 } 456 else 457 { 458 body->sensor_initialization &= ~(1 << 1); 459 } 460 }; 461 inline void init_types_state(bool enabled, SensorDataFullRecordBody* body) 462 { 463 if (enabled) 464 { 465 body->sensor_initialization |= 1 << 2; 466 } 467 else 468 { 469 body->sensor_initialization &= ~(1 << 2); 470 } 471 }; 472 inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body) 473 { 474 if (enabled) 475 { 476 body->sensor_initialization |= 1 << 3; 477 } 478 else 479 { 480 body->sensor_initialization &= ~(1 << 3); 481 } 482 }; 483 inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body) 484 { 485 if (enabled) 486 { 487 body->sensor_initialization |= 1 << 4; 488 } 489 else 490 { 491 body->sensor_initialization &= ~(1 << 4); 492 } 493 }; 494 inline void init_events_state(bool enabled, SensorDataFullRecordBody* body) 495 { 496 if (enabled) 497 { 498 body->sensor_initialization |= 1 << 5; 499 } 500 else 501 { 502 body->sensor_initialization &= ~(1 << 5); 503 } 504 }; 505 inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body) 506 { 507 if (enabled) 508 { 509 body->sensor_initialization |= 1 << 6; 510 } 511 else 512 { 513 body->sensor_initialization &= ~(1 << 6); 514 } 515 }; 516 inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body) 517 { 518 if (enabled) 519 { 520 body->sensor_initialization |= 1 << 7; 521 } 522 else 523 { 524 body->sensor_initialization &= ~(1 << 7); 525 } 526 }; 527 528 inline void set_percentage(SensorDataFullRecordBody* body) 529 { 530 body->sensor_units_1 |= 1 << 0; 531 }; 532 inline void unset_percentage(SensorDataFullRecordBody* body) 533 { 534 body->sensor_units_1 &= ~(1 << 0); 535 }; 536 inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body) 537 { 538 body->sensor_units_1 &= ~(3 << 1); 539 body->sensor_units_1 |= (op & 0x3) << 1; 540 }; 541 inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body) 542 { 543 body->sensor_units_1 &= ~(7 << 3); 544 body->sensor_units_1 |= (unit & 0x7) << 3; 545 }; 546 inline void set_analog_data_format(uint8_t format, 547 SensorDataFullRecordBody* body) 548 { 549 body->sensor_units_1 &= ~(3 << 6); 550 body->sensor_units_1 |= (format & 0x3) << 6; 551 }; 552 553 inline void set_m(uint16_t m, SensorDataFullRecordBody* body) 554 { 555 body->m_lsb = m & 0xff; 556 body->m_msb_and_tolerance &= ~(3 << 6); 557 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2); 558 }; 559 inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body) 560 { 561 body->m_msb_and_tolerance &= ~0x3f; 562 body->m_msb_and_tolerance |= tol & 0x3f; 563 }; 564 565 inline void set_b(uint16_t b, SensorDataFullRecordBody* body) 566 { 567 body->b_lsb = b & 0xff; 568 body->b_msb_and_accuracy_lsb &= ~(3 << 6); 569 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2); 570 }; 571 inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body) 572 { 573 // bottom 6 bits 574 body->b_msb_and_accuracy_lsb &= ~0x3f; 575 body->b_msb_and_accuracy_lsb |= acc & 0x3f; 576 // top 4 bits 577 body->accuracy_and_sensor_direction &= 0x0f; 578 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4; 579 }; 580 inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body) 581 { 582 body->accuracy_and_sensor_direction &= ~(3 << 2); 583 body->accuracy_and_sensor_direction |= (exp & 3) << 2; 584 }; 585 inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body) 586 { 587 body->accuracy_and_sensor_direction &= ~(3 << 0); 588 body->accuracy_and_sensor_direction |= (dir & 3); 589 }; 590 591 inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body) 592 { 593 body->r_b_exponents &= 0xf0; 594 body->r_b_exponents |= exp & 0x0f; 595 }; 596 inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body) 597 { 598 body->r_b_exponents &= 0x0f; 599 body->r_b_exponents |= (exp & 0x0f) << 4; 600 }; 601 602 inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body) 603 { 604 body->id_string_info &= ~(0x1f); 605 body->id_string_info |= len & 0x1f; 606 }; 607 inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body) 608 { 609 body->id_string_info &= ~(0x1f); 610 body->id_string_info |= len & 0x1f; 611 }; 612 inline uint8_t get_id_strlen(SensorDataFullRecordBody* body) 613 { 614 return body->id_string_info & 0x1f; 615 }; 616 inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body) 617 { 618 body->id_string_info &= ~(3 << 6); 619 body->id_string_info |= (type & 0x3) << 6; 620 }; 621 inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body) 622 { 623 body->id_string_info &= ~(3 << 6); 624 body->id_string_info |= (type & 0x3) << 6; 625 }; 626 627 inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body) 628 { 629 body->deviceIDLen &= ~(LENGTH_MASK); 630 body->deviceIDLen |= len & LENGTH_MASK; 631 }; 632 633 inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body) 634 { 635 return body->deviceIDLen & LENGTH_MASK; 636 }; 637 638 inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body) 639 { 640 body->discrete_reading_setting_mask[1] = mask & 0x3F; 641 } 642 643 } // namespace body 644 645 // More types contained in section 43.17 Sensor Unit Type Codes, 646 // IPMI spec v2 rev 1.1 647 enum SensorUnitTypeCodes 648 { 649 SENSOR_UNIT_UNSPECIFIED = 0, 650 SENSOR_UNIT_DEGREES_C = 1, 651 SENSOR_UNIT_VOLTS = 4, 652 SENSOR_UNIT_AMPERES = 5, 653 SENSOR_UNIT_WATTS = 6, 654 SENSOR_UNIT_JOULES = 7, 655 SENSOR_UNIT_RPM = 18, 656 SENSOR_UNIT_METERS = 34, 657 SENSOR_UNIT_REVOLUTIONS = 41, 658 }; 659 660 struct SensorDataFullRecord 661 { 662 SensorDataRecordHeader header; 663 SensorDataRecordKey key; 664 SensorDataFullRecordBody body; 665 } __attribute__((packed)); 666 667 /** @struct SensorDataComapactRecord 668 * 669 * Compact Sensor Record - SDR Type 2 670 */ 671 struct SensorDataCompactRecord 672 { 673 SensorDataRecordHeader header; 674 SensorDataRecordKey key; 675 SensorDataCompactRecordBody body; 676 } __attribute__((packed)); 677 678 /** @struct SensorDataEventRecord 679 * 680 * Event Only Sensor Record - SDR Type 3 681 */ 682 struct SensorDataEventRecord 683 { 684 SensorDataRecordHeader header; 685 SensorDataRecordKey key; 686 SensorDataEventRecordBody body; 687 } __attribute__((packed)); 688 689 /** @struct SensorDataFruRecord 690 * 691 * FRU Device Locator Record - SDR Type 11 692 */ 693 struct SensorDataFruRecord 694 { 695 SensorDataRecordHeader header; 696 SensorDataFruRecordKey key; 697 SensorDataFruRecordBody body; 698 } __attribute__((packed)); 699 700 /** @struct SensorDataEntityRecord 701 * 702 * Entity Association Record - SDR Type 8 703 */ 704 struct SensorDataEntityRecord 705 { 706 SensorDataRecordHeader header; 707 SensorDataEntityRecordKey key; 708 SensorDataEntityRecordBody body; 709 } __attribute__((packed)); 710 711 } // namespace get_sdr 712 713 namespace ipmi 714 { 715 716 namespace sensor 717 { 718 719 /** 720 * @brief Map offset to the corresponding bit in the assertion byte. 721 * 722 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one 723 * byte and offsets 8-14 in the second byte. 724 * 725 * @param[in] offset - offset number. 726 * @param[in/out] resp - get sensor reading response. 727 */ 728 inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp) 729 { 730 if (offset > 7) 731 { 732 resp->discreteReadingSensorStates |= 1 << (offset - 8); 733 } 734 else 735 { 736 resp->thresholdLevelsStates |= 1 << offset; 737 } 738 } 739 740 /** 741 * @brief Set the reading field in the response. 742 * 743 * @param[in] offset - offset number. 744 * @param[in/out] resp - get sensor reading response. 745 */ 746 inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp) 747 { 748 resp->reading = value; 749 } 750 751 /** 752 * @brief Map the value to the assertion bytes. The assertion states are stored 753 * in 2 bytes. 754 * 755 * @param[in] value - value to mapped to the assertion byte. 756 * @param[in/out] resp - get sensor reading response. 757 */ 758 inline void setAssertionBytes(uint16_t value, 759 ipmi::sensor::GetSensorResponse* resp) 760 { 761 resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF); 762 resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8); 763 } 764 765 /** 766 * @brief Set the scanning enabled bit in the response. 767 * 768 * @param[in/out] resp - get sensor reading response. 769 */ 770 inline void enableScanning(ipmi::sensor::GetSensorResponse* resp) 771 { 772 resp->readingOrStateUnavailable = false; 773 resp->scanningEnabled = true; 774 resp->allEventMessagesEnabled = false; 775 } 776 777 } // namespace sensor 778 779 } // namespace ipmi 780