diff options
-rw-r--r-- | dcmihandler.cpp | 65 | ||||
-rw-r--r-- | dcmihandler.hpp | 22 |
2 files changed, 87 insertions, 0 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp index 5b83ac8..0b98036 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -182,6 +182,66 @@ ipmi_ret_t getAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return IPMI_CC_OK; } +ipmi_ret_t setAssetTag(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<const dcmi::SetAssetTagRequest*> + (request); + std::vector<uint8_t> outPayload(sizeof(dcmi::SetAssetTagResponse)); + auto responseData = reinterpret_cast<dcmi::SetAssetTagResponse*> + (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(); + + if (requestData->offset > assetTag.size()) + { + *data_len = 0; + return IPMI_CC_PARM_OUT_OF_RANGE; + } + + assetTag.replace(requestData->offset, + assetTag.size() - requestData->offset, + static_cast<const char*>(request) + + sizeof(dcmi::SetAssetTagRequest), + requestData->bytes); + + dcmi::writeAssetTag(assetTag); + + responseData->groupID = dcmi::groupExtId; + responseData->tagLength = assetTag.size(); + memcpy(response, outPayload.data(), outPayload.size()); + *data_len = outPayload.size(); + + return IPMI_CC_OK; + } + catch (InternalFailure& e) + { + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } +} + void register_netfn_dcmi_functions() { // <Get Power Limit> @@ -193,6 +253,11 @@ void register_netfn_dcmi_functions() 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); + + // <Set Asset Tag> + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_SET_ASSET_TAG); + ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_SET_ASSET_TAG, NULL, setAssetTag, + PRIVILEGE_OPERATOR); return; } // 956379 diff --git a/dcmihandler.hpp b/dcmihandler.hpp index f2369a0..c64e56b 100644 --- a/dcmihandler.hpp +++ b/dcmihandler.hpp @@ -11,6 +11,7 @@ enum ipmi_netfn_sen_cmds // Get capability bits IPMI_CMD_DCMI_GET_POWER = 0x03, IPMI_CMD_DCMI_GET_ASSET_TAG = 0x06, + IPMI_CMD_DCMI_SET_ASSET_TAG = 0x08, }; namespace dcmi @@ -58,6 +59,27 @@ struct GetAssetTagResponse uint8_t tagLength; //!< Total asset tag length. } __attribute__((packed)); +/** @struct SetAssetTagRequest + * + * DCMI payload for Set Asset Tag command request. + */ +struct SetAssetTagRequest +{ + uint8_t groupID; //!< Group extension identification. + uint8_t offset; //!< Offset to write. + uint8_t bytes; //!< Number of bytes to write. +} __attribute__((packed)); + +/** @struct SetAssetTagResponse + * + * DCMI payload for Set Asset Tag command response. + */ +struct SetAssetTagResponse +{ + 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. * |