From 6f6dd4d733339d8e3783dd1630f365b903035dcf Mon Sep 17 00:00:00 2001 From: Tom Joseph Date: Wed, 12 Jul 2017 20:07:11 +0530 Subject: dcmi: asset-tag: Implement the Get Asset Tag command Change-Id: Ic2fb1e707174ece63fbb758bf1422c2c4d95723b Signed-off-by: Tom Joseph --- dcmihandler.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++ dcmihandler.hpp | 28 +++++++++++++++++ host-ipmid-whitelist.conf | 1 + 3 files changed, 109 insertions(+) diff --git a/dcmihandler.cpp b/dcmihandler.cpp index c7497f0..5b83ac8 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -107,12 +107,92 @@ std::string readAssetTag() } // namespace dcmi +ipmi_ret_t getAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, ipmi_response_t response, + ipmi_data_len_t data_len, ipmi_context_t context) +{ + auto requestData = reinterpret_cast + (request); + std::vector outPayload(sizeof(dcmi::GetAssetTagResponse)); + auto responseData = reinterpret_cast + (outPayload.data()); + + if (requestData->groupID != dcmi::groupExtId) + { + *data_len = 0; + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + // Verify offset to read and number of bytes to read are not exceeding the + // range. + if ((requestData->offset > dcmi::assetTagMaxOffset) || + (requestData->bytes > dcmi::maxBytes) || + ((requestData->offset + requestData->bytes) > dcmi::assetTagMaxSize)) + { + *data_len = 0; + return IPMI_CC_PARM_OUT_OF_RANGE; + } + + std::string assetTag; + + try + { + assetTag = dcmi::readAssetTag(); + } + catch (InternalFailure& e) + { + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + + responseData->groupID = dcmi::groupExtId; + + // Return if the asset tag is not populated. + if (!assetTag.size()) + { + responseData->tagLength = 0; + memcpy(response, outPayload.data(), outPayload.size()); + *data_len = outPayload.size(); + return IPMI_CC_OK; + } + + // If the asset tag is longer than 63 bytes, restrict it to 63 bytes to suit + // Get Asset Tag command. + if (assetTag.size() > dcmi::assetTagMaxSize) + { + assetTag.resize(dcmi::assetTagMaxSize); + } + + // If the requested offset is beyond the asset tag size. + if (requestData->offset >= assetTag.size()) + { + *data_len = 0; + return IPMI_CC_PARM_OUT_OF_RANGE; + } + + auto returnData = assetTag.substr(requestData->offset, requestData->bytes); + + responseData->tagLength = assetTag.size(); + + memcpy(response, outPayload.data(), outPayload.size()); + memcpy(static_cast(response) + outPayload.size(), + returnData.data(), returnData.size()); + *data_len = outPayload.size() + returnData.size(); + + return IPMI_CC_OK; +} + void register_netfn_dcmi_functions() { // printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER); ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER, NULL, ipmi_dcmi_get_power_limit, PRIVILEGE_USER); + + // + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_ASSET_TAG); + ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_ASSET_TAG, NULL, getAssetTag, + PRIVILEGE_USER); return; } // 956379 diff --git a/dcmihandler.hpp b/dcmihandler.hpp index dfe1d4e..f2369a0 100644 --- a/dcmihandler.hpp +++ b/dcmihandler.hpp @@ -10,6 +10,7 @@ enum ipmi_netfn_sen_cmds { // Get capability bits IPMI_CMD_DCMI_GET_POWER = 0x03, + IPMI_CMD_DCMI_GET_ASSET_TAG = 0x06, }; namespace dcmi @@ -30,6 +31,33 @@ namespace assettag } //namespace assettag +static constexpr auto groupExtId = 0xDC; + +static constexpr auto assetTagMaxOffset = 62; +static constexpr auto assetTagMaxSize = 63; +static constexpr auto maxBytes = 16; + +/** @struct GetAssetTagRequest + * + * DCMI payload for Get Asset Tag command request. + */ +struct GetAssetTagRequest +{ + uint8_t groupID; //!< Group extension identification. + uint8_t offset; //!< Offset to read. + uint8_t bytes; //!< Number of bytes to read. +} __attribute__((packed)); + +/** @struct GetAssetTagResponse + * + * DCMI payload for Get Asset Tag command response. + */ +struct GetAssetTagResponse +{ + uint8_t groupID; //!< Group extension identification. + uint8_t tagLength; //!< Total asset tag length. +} __attribute__((packed)); + /** @brief Read the object tree to fetch the object path that implemented the * Asset tag interface. * diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf index d921145..98353c2 100644 --- a/host-ipmid-whitelist.conf +++ b/host-ipmid-whitelist.conf @@ -25,3 +25,4 @@ 0x0C:0x02 //: 0x2C:0x00 //: 0x2C:0x03 //: +0x2C:0x06 //: -- cgit v1.2.1