bios: Implement BIOSStringAttribute
Implement BIOSStringAttribute, most of the code is copied from
bios/bios_parser.cpp.
Implement SetAttrValueOnDbus and constructEntry for string attribute
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: Ic7c6b35d32738d698d7649f97cb7843606b8a2ba
diff --git a/libpldmresponder/bios_string_attribute.cpp b/libpldmresponder/bios_string_attribute.cpp
new file mode 100644
index 0000000..1d9ec5d
--- /dev/null
+++ b/libpldmresponder/bios_string_attribute.cpp
@@ -0,0 +1,115 @@
+#include "bios_string_attribute.hpp"
+
+#include "utils.hpp"
+
+#include <iostream>
+#include <tuple>
+#include <variant>
+
+namespace pldm
+{
+namespace responder
+{
+namespace bios
+{
+
+BIOSStringAttribute::BIOSStringAttribute(const Json& entry,
+ DBusHandler* const dbusHandler) :
+ BIOSAttribute(entry, dbusHandler)
+{
+ std::string strTypeTmp = entry.at("string_type");
+ auto iter = strTypeMap.find(strTypeTmp);
+ if (iter == strTypeMap.end())
+ {
+ std::cerr << "Wrong string type, STRING_TYPE=" << strTypeTmp
+ << " ATTRIBUTE_NAME=" << name << "\n";
+ throw std::invalid_argument("Wrong string type");
+ }
+ stringInfo.stringType = static_cast<uint8_t>(iter->second);
+
+ stringInfo.minLength = entry.at("minimum_string_length");
+ stringInfo.maxLength = entry.at("maximum_string_length");
+ stringInfo.defLength = entry.at("default_string_length");
+ stringInfo.defString = entry.at("default_string");
+
+ pldm_bios_table_attr_entry_string_info info = {
+ 0,
+ readOnly,
+ stringInfo.stringType,
+ stringInfo.minLength,
+ stringInfo.maxLength,
+ stringInfo.defLength,
+ stringInfo.defString.data(),
+ };
+
+ const char* errmsg;
+ auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
+ if (rc != PLDM_SUCCESS)
+ {
+ std::cerr << "Wrong field for string attribute, ATTRIBUTE_NAME=" << name
+ << " ERRMSG=" << errmsg
+ << " MINIMUM_STRING_LENGTH=" << stringInfo.minLength
+ << " MAXIMUM_STRING_LENGTH=" << stringInfo.maxLength
+ << " DEFAULT_STRING_LENGTH=" << stringInfo.defLength
+ << " DEFAULT_STRING=" << stringInfo.defString << "\n";
+ throw std::invalid_argument("Wrong field for string attribute");
+ }
+}
+
+void BIOSStringAttribute::setAttrValueOnDbus(
+ const pldm_bios_attr_val_table_entry* attrValueEntry,
+ const pldm_bios_attr_table_entry*, const BIOSStringTable&)
+{
+ if (readOnly)
+ {
+ return;
+ }
+
+ PropertyValue value =
+ table::attribute_value::decodeStringEntry(attrValueEntry);
+ dbusHandler->setDbusProperty(*dBusMap, value);
+}
+
+std::string BIOSStringAttribute::getAttrValue()
+{
+ if (readOnly)
+ {
+ return stringInfo.defString;
+ }
+ try
+ {
+ return dbusHandler->getDbusProperty<std::string>(
+ dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
+ dBusMap->interface.c_str());
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "Get String Attribute Value Error: AttributeName = "
+ << name << std::endl;
+ return stringInfo.defString;
+ }
+}
+
+void BIOSStringAttribute::constructEntry(const BIOSStringTable& stringTable,
+ Table& attrTable,
+ Table& attrValueTable)
+{
+ pldm_bios_table_attr_entry_string_info info = {
+ stringTable.findHandle(name), readOnly,
+ stringInfo.stringType, stringInfo.minLength,
+ stringInfo.maxLength, stringInfo.defLength,
+ stringInfo.defString.data(),
+ };
+
+ auto attrTableEntry =
+ table::attribute::constructStringEntry(attrTable, &info);
+ auto [attrHandle, attrType, _] =
+ table::attribute::decodeHeader(attrTableEntry);
+ auto currStr = getAttrValue();
+ table::attribute_value::constructStringEntry(attrValueTable, attrHandle,
+ attrType, currStr);
+}
+
+} // namespace bios
+} // namespace responder
+} // namespace pldm
diff --git a/libpldmresponder/bios_string_attribute.hpp b/libpldmresponder/bios_string_attribute.hpp
new file mode 100644
index 0000000..48b0d2d
--- /dev/null
+++ b/libpldmresponder/bios_string_attribute.hpp
@@ -0,0 +1,83 @@
+#pragma once
+#include "bios_attribute.hpp"
+
+#include <string>
+
+class TestBIOSStringAttribute;
+
+namespace pldm
+{
+namespace responder
+{
+namespace bios
+{
+
+/** @class BIOSStringAttribute
+ * @brief Associate string entry(attr table and attribute value table) and dbus
+ * attribute
+ */
+class BIOSStringAttribute : public BIOSAttribute
+{
+ public:
+ friend class ::TestBIOSStringAttribute;
+
+ /** @brief BIOS string types */
+ enum class Encoding : uint8_t
+ {
+ UNKNOWN = 0x00,
+ ASCII = 0x01,
+ HEX = 0x02,
+ UTF_8 = 0x03,
+ UTF_16LE = 0x04,
+ UTF_16BE = 0x05,
+ VENDOR_SPECIFIC = 0xFF
+ };
+
+ /** brief Mapping of string to enum for string type */
+ inline static const std::map<std::string, Encoding> strTypeMap{
+ {"Unknown", Encoding::UNKNOWN},
+ {"ASCII", Encoding::ASCII},
+ {"Hex", Encoding::HEX},
+ {"UTF-8", Encoding::UTF_8},
+ {"UTF-16LE", Encoding::UTF_16LE},
+ {"UTF-16LE", Encoding::UTF_16LE},
+ {"Vendor Specific", Encoding::VENDOR_SPECIFIC}};
+
+ /** @brief Construct a bios string attribute
+ * @param[in] entry - Json Object
+ * @param[in] dbusHandler - Dbus Handler
+ */
+ BIOSStringAttribute(const Json& entry, DBusHandler* const dbusHandler);
+
+ /** @brief Set Attribute value On Dbus according to the attribute value
+ * entry
+ * @param[in] attrValueEntry - The attribute value entry
+ * @param[in] attrEntry - The attribute entry corresponding to the
+ * attribute value entry
+ * @param[in] stringTable - The string table
+ */
+ void
+ setAttrValueOnDbus(const pldm_bios_attr_val_table_entry* attrValueEntry,
+ const pldm_bios_attr_table_entry* attrEntry,
+ const BIOSStringTable& stringTable) override;
+
+ /** @brief Construct corresponding entries at the end of the attribute table
+ * and attribute value tables
+ * @param[in] stringTable - The string Table
+ * @param[in,out] attrTable - The attribute table
+ * @param[in,out] attrValueTable - The attribute value table
+ */
+ void constructEntry(const BIOSStringTable& stringTable, Table& attrTable,
+ Table& attrValueTable) override;
+
+ private:
+ /** @brief string field from json */
+ table::attribute::StringField stringInfo;
+
+ /** @brief Get attribute value on dbus */
+ std::string getAttrValue();
+};
+
+} // namespace bios
+} // namespace responder
+} // namespace pldm
diff --git a/libpldmresponder/bios_table.cpp b/libpldmresponder/bios_table.cpp
index 5fd6ece..e68884b 100644
--- a/libpldmresponder/bios_table.cpp
+++ b/libpldmresponder/bios_table.cpp
@@ -64,7 +64,7 @@
{
throw std::invalid_argument("Invalid String Handle");
}
- return decodeString(stringEntry);
+ return table::string::decodeString(stringEntry);
}
uint16_t BIOSStringTable::findHandle(const std::string& name) const
@@ -76,17 +76,21 @@
throw std::invalid_argument("Invalid String Name");
}
- return decodeHandle(stringEntry);
+ return table::string::decodeHandle(stringEntry);
}
-uint16_t
- BIOSStringTable::decodeHandle(const pldm_bios_string_table_entry* entry)
+namespace table
+{
+
+namespace string
+{
+
+uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
{
return pldm_bios_table_string_entry_decode_handle(entry);
}
-std::string
- BIOSStringTable::decodeString(const pldm_bios_string_table_entry* entry)
+std::string decodeString(const pldm_bios_string_table_entry* entry)
{
auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
@@ -95,6 +99,91 @@
return std::string(buffer.data(), buffer.data() + strLength);
}
+} // namespace string
+
+namespace attribute
+{
+
+TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
+{
+ auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
+ auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
+ auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
+ return {attrHandle, attrType, stringHandle};
+}
+
+const pldm_bios_attr_table_entry*
+ constructStringEntry(Table& table,
+ pldm_bios_table_attr_entry_string_info* info)
+{
+ auto entryLength =
+ pldm_bios_table_attr_entry_string_encode_length(info->def_length);
+
+ auto tableSize = table.size();
+ table.resize(tableSize + entryLength, 0);
+ pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
+ entryLength, info);
+ return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
+ tableSize);
+}
+
+StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
+{
+ auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
+ auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
+ auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
+ auto defLength =
+ pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
+
+ std::vector<char> buffer(defLength + 1);
+ pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
+ buffer.size());
+ return {strType, minLength, maxLength, defLength,
+ std::string(buffer.data(), buffer.data() + defLength)};
+}
+
+} // namespace attribute
+
+namespace attribute_value
+{
+
+TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
+{
+ auto handle =
+ pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
+ auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
+ return {handle, type};
+}
+
+std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
+{
+ variable_field currentString{};
+ pldm_bios_table_attr_value_entry_string_decode_string(entry,
+ ¤tString);
+ return std::string(currentString.ptr,
+ currentString.ptr + currentString.length);
+}
+
+const pldm_bios_attr_val_table_entry*
+ constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
+ const std::string& str)
+{
+ auto strLen = str.size();
+ auto entryLength =
+ pldm_bios_table_attr_value_entry_encode_string_length(strLen);
+ auto tableSize = table.size();
+ table.resize(tableSize + entryLength);
+ pldm_bios_table_attr_value_entry_encode_string(
+ table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
+ str.c_str());
+ return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
+ tableSize);
+}
+
+} // namespace attribute_value
+
+} // namespace table
+
} // namespace bios
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/bios_table.hpp b/libpldmresponder/bios_table.hpp
index 7b28d49..d1dc7c9 100644
--- a/libpldmresponder/bios_table.hpp
+++ b/libpldmresponder/bios_table.hpp
@@ -7,6 +7,7 @@
#include <vector>
#include "libpldm/bios.h"
+#include "libpldm/bios_table.h"
namespace pldm
{
@@ -129,22 +130,119 @@
*/
uint16_t findHandle(const std::string& name) const override;
- /** @brief Get the string handle for the entry
- * @param[in] entry - Pointer to a bios string table entry
- * @return Handle to identify a string in the bios string table
- */
- static uint16_t decodeHandle(const pldm_bios_string_table_entry* entry);
-
- /** @brief Get the string from the entry
- * @param[in] entry - Pointer to a bios string table entry
- * @return The String
- */
- static std::string decodeString(const pldm_bios_string_table_entry* entry);
-
private:
Table stringTable;
};
+namespace table
+{
+
+namespace string
+{
+
+/** @brief Get the string handle for the entry
+ * @param[in] entry - Pointer to a bios string table entry
+ * @return Handle to identify a string in the bios string table
+ */
+uint16_t decodeHandle(const pldm_bios_string_table_entry* entry);
+
+/** @brief Get the string from the entry
+ * @param[in] entry - Pointer to a bios string table entry
+ * @return The String
+ */
+std::string decodeString(const pldm_bios_string_table_entry* entry);
+
+} // namespace string
+
+namespace attribute
+{
+
+/** @struct TableHeader
+ * @brief Header of attribute table
+ */
+struct TableHeader
+{
+ uint16_t attrHandle;
+ uint8_t attrType;
+ uint16_t stringHandle;
+};
+
+/** @brief Decode header of attribute table entry
+ * @param[in] entry - Pointer to an attribute table entry
+ * @return Attribute table header
+ */
+TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry);
+
+/** @struct StringField
+ * @brief String field of attribute table
+ */
+struct StringField
+{
+ uint8_t stringType;
+ uint16_t minLength;
+ uint16_t maxLength;
+ uint16_t defLength;
+ std::string defString;
+};
+
+/** @brief decode string entry of attribute table
+ * @param[in] entry - Pointer to an attribute table entry
+ * @return String field of the entry
+ */
+StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry);
+
+/** @brief construct string entry of attribute table at the end of the given
+ * table
+ * @param[in,out] table - The given table
+ * @param[in] info - string info
+ * @return pointer to the constructed entry
+ */
+const pldm_bios_attr_table_entry*
+ constructStringEntry(Table& table,
+ pldm_bios_table_attr_entry_string_info* info);
+
+} // namespace attribute
+
+namespace attribute_value
+{
+
+/** @struct TableHeader
+ * @brief Header of attribute value table
+ */
+struct TableHeader
+{
+ uint16_t attrHandle;
+ uint8_t attrType;
+};
+
+/** @brief Decode header of attribute value table
+ * @param[in] entry - Pointer to an attribute value table entry
+ * @return Attribute value table header
+ */
+TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry);
+
+/** @brief Decode string entry of attribute value table
+ * @param[in] entry - Pointer to an attribute value table entry
+ * @return The decoded string
+ */
+std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry);
+
+/** @brief Construct string entry of attribute value table at the end of the
+ * given table
+ * @param[in] table - The given table
+ * @param[in] attrHandle - attribute handle
+ * @param[in] attrType - attribute type
+ * @param[in] str - The string
+ * @return Pointer to the constructed entry
+ */
+const pldm_bios_attr_val_table_entry*
+ constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
+ const std::string& str);
+
+} // namespace attribute_value
+
+} // namespace table
+
} // namespace bios
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 2797f51..372cae0 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -11,6 +11,7 @@
'bios_table.cpp',
'bios_parser.cpp',
'bios_attribute.cpp',
+ 'bios_string_attribute.cpp',
'pdr_utils.cpp',
'pdr.cpp',
'platform.cpp',