diff options
-rw-r--r-- | dcmihandler.cpp | 23 | ||||
-rw-r--r-- | dcmihandler.hpp | 2 |
2 files changed, 17 insertions, 8 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp index e858416..cb14005 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -784,16 +784,23 @@ ipmi_ret_t getDCMICapabilities(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // If the data is beyond first byte boundary, insert in a // 16bit pattern for example number of SEL entries are represented // in 12bits. - if ((cap.length + cap.position) > 8) + if ((cap.length + cap.position) > dcmi::gByteBitSize) { - // Read the value corresponding to capability name and assign to - // 16bit bitset. - std::bitset<16> val(data.value(cap.name.c_str(), 0)); + uint16_t val = data.value(cap.name.c_str(), 0); + // According to DCMI spec v1.5, max number of SEL entries is + // 4096, but bit 12b of DCMI capabilities Mandatory Platform + // Attributes field is reserved and therefore we can use only + // the provided 12 bits with maximum value of 4095. + // We're playing safe here by applying the mask + // to ensure that provided value will fit into 12 bits. + if (cap.length > dcmi::gByteBitSize) + { + val &= dcmi::gMaxSELEntriesMask; + } val <<= cap.position; - reinterpret_cast<uint16_t*>( - responseData - ->data)[(cap.bytePosition - 1) / sizeof(uint16_t)] |= - val.to_ulong(); + responseData->data[cap.bytePosition - 1] |= + static_cast<uint8_t>(val); + responseData->data[cap.bytePosition] |= val >> dcmi::gByteBitSize; } else { diff --git a/dcmihandler.hpp b/dcmihandler.hpp index 8b16e3d..a188c25 100644 --- a/dcmihandler.hpp +++ b/dcmihandler.hpp @@ -58,6 +58,8 @@ static constexpr auto gDCMICapabilitiesConfig = "/usr/share/ipmi-providers/dcmi_cap.json"; static constexpr auto gDCMIPowerMgmtCapability = "PowerManagement"; static constexpr auto gDCMIPowerMgmtSupported = 0x1; +static constexpr auto gMaxSELEntriesMask = 0xFFF; +static constexpr auto gByteBitSize = 8; namespace assettag { |