summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dcmihandler.cpp80
-rw-r--r--dcmihandler.hpp28
-rw-r--r--host-ipmid-whitelist.conf1
3 files changed, 109 insertions, 0 deletions
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<const dcmi::GetAssetTagRequest*>
+ (request);
+ std::vector<uint8_t> outPayload(sizeof(dcmi::GetAssetTagResponse));
+ auto responseData = reinterpret_cast<dcmi::GetAssetTagResponse*>
+ (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<uint8_t*>(response) + outPayload.size(),
+ returnData.data(), returnData.size());
+ *data_len = outPayload.size() + returnData.size();
+
+ return IPMI_CC_OK;
+}
+
void register_netfn_dcmi_functions()
{
// <Get Power Limit>
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);
+
+ // <Get Asset Tag>
+ 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 //<Transport>:<Get LAN Configuration Parameters>
0x2C:0x00 //<Group Extension>:<Group Extension Command>
0x2C:0x03 //<Group Extension>:<Get Power Limit>
+0x2C:0x06 //<Group Extension>:<Get Asset Tag>
OpenPOWER on IntegriCloud