bios: Add SetBIOSAttributeCurrentValue
Update the persisted attribute value table and the d-bus property
corresponding to the attribute.
Tested:
Tested on fp5280g2, with json files:
https://gist.github.com/wangzqbj/b24558331cb35d14fca3b555ef03e458
Build Tables:
pldmtool raw --data 0x80 0x03 0x01 0x00 0x00 0x00 0x00 0x00 0x00
pldmtool raw --data 0x80 0x03 0x01 0x00 0x00 0x00 0x00 0x00 0x01
pldmtool raw --data 0x80 0x03 0x01 0x00 0x00 0x00 0x00 0x00 0x02
enum attribute:
Get Attribute Value By Handle:
root@fp5280g2:/tmp# pldmtool raw --data 0x80 0x03 0x08 0x00 0x00 0x00 0x00 0x00 0x01 0x00
...
...
Response Message:
08 01 00 03 08 00 00 00 00 00 05 01 00
Check Dbus Property:
root@fp5280g2:/tmp# busctl get-property xyz.openbmc_project.LED.Controller.front_memory /xyz/openbmc_project/led/physical/front_memory xyz.openbmc_project.Led.Physical State
s "xyz.openbmc_project.Led.Physical.Action.Off"
Set Attribute Value:
root@fp5280g2:/tmp# pldmtool raw --data 0x80 0x03 0x07 0x00 0x00 0x00 0x00 0x05 0x01 0x00 0x00 0x01 0x01
...
...
Response Message:
08 01 00 03 07 00 //exec successfully
Get Attribute Value By Handle:
root@fp5280g2:/tmp# pldmtool raw --data 0x80 0x03 0x08 0x00 0x00 0x00 0x00 0x00 0x01 0x00
...
...
Response Message:
08 01 00 03 08 00 00 00 00 00 05 01 01 // attribute value table was updated.
Check Dbus Property:
root@fp5280g2:/tmp# busctl get-property xyz.openbmc_project.LED.Controller.front_memory /xyz/openbmc_project/led/physical/front_memory xyz.openbmc_project.Led.Physical State
s "xyz.openbmc_project.Led.Physical.Action.On" // dbus property was updated
Verified that string/integer attributes can be updated as expected.
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I8dab1870396061037284c1683de2502c8da68c98
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index 082ac0f..fe20140 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -130,6 +130,11 @@
return this->getBIOSAttributeCurrentValueByHandle(
request, payloadLength);
});
+ handlers.emplace(PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->setBIOSAttributeCurrentValue(
+ request, payloadLength);
+ });
}
Response Handler::getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
@@ -955,6 +960,66 @@
return response;
}
+Response Handler::setBIOSAttributeCurrentValue(const pldm_msg* request,
+ size_t payloadLength)
+{
+ uint32_t transferHandle;
+ uint8_t transferOpFlag;
+ variable_field attributeField;
+
+ auto rc = decode_set_bios_attribute_current_value_req(
+ request, payloadLength, &transferHandle, &transferOpFlag,
+ &attributeField);
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ fs::path tablesPath(BIOS_TABLES_DIR);
+ auto stringTablePath = tablesPath / stringTableFile;
+ BIOSStringTable biosStringTable(stringTablePath.c_str());
+ auto attrTablePath = tablesPath / attrTableFile;
+ BIOSTable biosAttributeTable(attrTablePath.c_str());
+ auto attrValueTablePath = tablesPath / attrValTableFile;
+ BIOSTable biosAttributeValueTable(attrValueTablePath.c_str());
+ // TODO: Construct attribute value table if it's empty. (another commit)
+
+ Response srcTable;
+ biosAttributeValueTable.load(srcTable);
+
+ // Replace the old attribute with the new attribute, the size of table will
+ // change:
+ // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
+ // sizeof(oldAttribute) + pad(4-byte alignment, max =
+ // 3)
+ // For simplicity, we use
+ // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
+ size_t destBufferLength = srcTable.size() + attributeField.length + 3;
+ Response destTable(destBufferLength);
+ size_t destTableLen = destTable.size();
+
+ rc = pldm_bios_table_attr_value_copy_and_update(
+ srcTable.data(), srcTable.size(), destTable.data(), &destTableLen,
+ attributeField.ptr, attributeField.length);
+ destTable.resize(destTableLen);
+
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ rc = setAttributeValueOnDbus(&attributeField, biosAttributeTable,
+ biosStringTable);
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ biosAttributeValueTable.store(destTable);
+
+ return ccOnlyResponse(request, PLDM_SUCCESS);
+}
+
namespace internal
{
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index 4a42bf4..d023ce9 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -85,6 +85,15 @@
* @return Response - PLDM Response message
*/
Response setDateTime(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for setBIOSAttributeCurrentValue
+ *
+ * @param[in] request - Request message
+ * @param[in] payloadLength - Request message payload length
+ * @return Response - PLDM Response message
+ */
+ Response setBIOSAttributeCurrentValue(const pldm_msg* request,
+ size_t payloadLength);
};
} // namespace bios