129683b53SJohn Wang #include "bios_string_attribute.hpp"
229683b53SJohn Wang
3d130e1a3SDeepak Kodihalli #include "common/utils.hpp"
429683b53SJohn Wang
549cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
649cfb138SRiya Dixit
729683b53SJohn Wang #include <tuple>
829683b53SJohn Wang #include <variant>
929683b53SJohn Wang
1049cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
1149cfb138SRiya Dixit
125079ac4aSBrad Bishop using namespace pldm::utils;
135079ac4aSBrad Bishop
1429683b53SJohn Wang namespace pldm
1529683b53SJohn Wang {
1629683b53SJohn Wang namespace responder
1729683b53SJohn Wang {
1829683b53SJohn Wang namespace bios
1929683b53SJohn Wang {
BIOSStringAttribute(const Json & entry,DBusHandler * const dbusHandler)2029683b53SJohn Wang BIOSStringAttribute::BIOSStringAttribute(const Json& entry,
2129683b53SJohn Wang DBusHandler* const dbusHandler) :
2229683b53SJohn Wang BIOSAttribute(entry, dbusHandler)
2329683b53SJohn Wang {
2429683b53SJohn Wang std::string strTypeTmp = entry.at("string_type");
2529683b53SJohn Wang auto iter = strTypeMap.find(strTypeTmp);
2629683b53SJohn Wang if (iter == strTypeMap.end())
2729683b53SJohn Wang {
2889644441SRiya Dixit error("Wrong string type '{TYPE}' for attribute '{ATTRIBUTE}'", "TYPE",
2989644441SRiya Dixit strTypeTmp, "ATTRIBUTE", name);
3029683b53SJohn Wang throw std::invalid_argument("Wrong string type");
3129683b53SJohn Wang }
3229683b53SJohn Wang stringInfo.stringType = static_cast<uint8_t>(iter->second);
3329683b53SJohn Wang
3429683b53SJohn Wang stringInfo.minLength = entry.at("minimum_string_length");
3529683b53SJohn Wang stringInfo.maxLength = entry.at("maximum_string_length");
3629683b53SJohn Wang stringInfo.defString = entry.at("default_string");
37*7d47570cSArchana Kakani stringInfo.defLength =
38*7d47570cSArchana Kakani static_cast<uint16_t>((stringInfo.defString).length());
3929683b53SJohn Wang
4029683b53SJohn Wang pldm_bios_table_attr_entry_string_info info = {
4129683b53SJohn Wang 0,
4229683b53SJohn Wang readOnly,
4329683b53SJohn Wang stringInfo.stringType,
4429683b53SJohn Wang stringInfo.minLength,
4529683b53SJohn Wang stringInfo.maxLength,
4629683b53SJohn Wang stringInfo.defLength,
4729683b53SJohn Wang stringInfo.defString.data(),
4829683b53SJohn Wang };
4929683b53SJohn Wang
5029683b53SJohn Wang const char* errmsg;
5129683b53SJohn Wang auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
5229683b53SJohn Wang if (rc != PLDM_SUCCESS)
5329683b53SJohn Wang {
5449cfb138SRiya Dixit error(
5589644441SRiya Dixit "Wrong field for string attribute '{ATTRIBUTE}', error '{ERROR}', minimum string length '{MINIMUM_STRING_LENGTH}', maximum string length '{MAXIMUM_STRING_LENGTH}', default string length '{DEFAULT_STRING_LENGTH}' and default string '{DEFAULT_STRING}'",
5689644441SRiya Dixit "ATTRIBUTE", name, "ERROR", errmsg, "MINIMUM_STRING_LENGTH",
5789644441SRiya Dixit stringInfo.minLength, "MAXIMUM_STRING_LENGTH", stringInfo.maxLength,
5889644441SRiya Dixit "DEFAULT_STRING_LENGTH", stringInfo.defLength, "DEFAULT_STRING",
5989644441SRiya Dixit stringInfo.defString);
6029683b53SJohn Wang throw std::invalid_argument("Wrong field for string attribute");
6129683b53SJohn Wang }
6229683b53SJohn Wang }
6329683b53SJohn Wang
setAttrValueOnDbus(const pldm_bios_attr_val_table_entry * attrValueEntry,const pldm_bios_attr_table_entry *,const BIOSStringTable &)6429683b53SJohn Wang void BIOSStringAttribute::setAttrValueOnDbus(
6529683b53SJohn Wang const pldm_bios_attr_val_table_entry* attrValueEntry,
6629683b53SJohn Wang const pldm_bios_attr_table_entry*, const BIOSStringTable&)
6729683b53SJohn Wang {
685bb9edb9SGeorge Liu if (!dBusMap.has_value())
6929683b53SJohn Wang {
7029683b53SJohn Wang return;
7129683b53SJohn Wang }
7229683b53SJohn Wang
7329683b53SJohn Wang PropertyValue value =
7429683b53SJohn Wang table::attribute_value::decodeStringEntry(attrValueEntry);
7529683b53SJohn Wang dbusHandler->setDbusProperty(*dBusMap, value);
7629683b53SJohn Wang }
7729683b53SJohn Wang
getAttrValue()7829683b53SJohn Wang std::string BIOSStringAttribute::getAttrValue()
7929683b53SJohn Wang {
805bb9edb9SGeorge Liu if (!dBusMap.has_value())
8129683b53SJohn Wang {
8229683b53SJohn Wang return stringInfo.defString;
8329683b53SJohn Wang }
8429683b53SJohn Wang try
8529683b53SJohn Wang {
8629683b53SJohn Wang return dbusHandler->getDbusProperty<std::string>(
8729683b53SJohn Wang dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
8829683b53SJohn Wang dBusMap->interface.c_str());
8929683b53SJohn Wang }
9029683b53SJohn Wang catch (const std::exception& e)
9129683b53SJohn Wang {
9258cbcaf2SKamalkumar Patel error(
9389644441SRiya Dixit "Failed to get string attribute '{ATTRIBUTE}' at path '{PATH}' and interface '{INTERFACE}' for property '{PROPERTY}', error - {ERROR}",
9489644441SRiya Dixit "ATTRIBUTE", name, "PATH", dBusMap->objectPath, "INTERFACE",
9589644441SRiya Dixit dBusMap->interface, "PROPERTY", dBusMap->propertyName, "ERROR", e);
9629683b53SJohn Wang return stringInfo.defString;
9729683b53SJohn Wang }
9829683b53SJohn Wang }
9929683b53SJohn Wang
constructEntry(const BIOSStringTable & stringTable,Table & attrTable,Table & attrValueTable,std::optional<std::variant<int64_t,std::string>> optAttributeValue)100ca7b2524STom Joseph void BIOSStringAttribute::constructEntry(
101ca7b2524STom Joseph const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable,
102ca7b2524STom Joseph std::optional<std::variant<int64_t, std::string>> optAttributeValue)
10329683b53SJohn Wang {
10429683b53SJohn Wang pldm_bios_table_attr_entry_string_info info = {
10529683b53SJohn Wang stringTable.findHandle(name), readOnly,
10629683b53SJohn Wang stringInfo.stringType, stringInfo.minLength,
10729683b53SJohn Wang stringInfo.maxLength, stringInfo.defLength,
10829683b53SJohn Wang stringInfo.defString.data(),
10929683b53SJohn Wang };
11029683b53SJohn Wang
1116da4f91bSPatrick Williams auto attrTableEntry = table::attribute::constructStringEntry(attrTable,
1126da4f91bSPatrick Williams &info);
1136da4f91bSPatrick Williams auto [attrHandle, attrType,
1146da4f91bSPatrick Williams _] = table::attribute::decodeHeader(attrTableEntry);
115ca7b2524STom Joseph
116ca7b2524STom Joseph std::string currStr{};
117ca7b2524STom Joseph if (optAttributeValue.has_value())
118ca7b2524STom Joseph {
119ca7b2524STom Joseph auto attributeValue = optAttributeValue.value();
120ca7b2524STom Joseph if (attributeValue.index() == 1)
121ca7b2524STom Joseph {
122ca7b2524STom Joseph currStr = std::get<std::string>(attributeValue);
123ca7b2524STom Joseph }
124ca7b2524STom Joseph else
125ca7b2524STom Joseph {
126ca7b2524STom Joseph currStr = getAttrValue();
127ca7b2524STom Joseph }
128ca7b2524STom Joseph }
129ca7b2524STom Joseph else
130ca7b2524STom Joseph {
131ca7b2524STom Joseph currStr = getAttrValue();
132ca7b2524STom Joseph }
133ca7b2524STom Joseph
13429683b53SJohn Wang table::attribute_value::constructStringEntry(attrValueTable, attrHandle,
13529683b53SJohn Wang attrType, currStr);
13629683b53SJohn Wang }
13729683b53SJohn Wang
updateAttrVal(Table & newValue,uint16_t attrHdl,uint8_t attrType,const PropertyValue & newPropVal)13846ece063SSampa Misra int BIOSStringAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl,
13946ece063SSampa Misra uint8_t attrType,
14046ece063SSampa Misra const PropertyValue& newPropVal)
14146ece063SSampa Misra {
14246ece063SSampa Misra try
14346ece063SSampa Misra {
14446ece063SSampa Misra const auto& newStringValue = std::get<std::string>(newPropVal);
14546ece063SSampa Misra table::attribute_value::constructStringEntry(newValue, attrHdl,
14646ece063SSampa Misra attrType, newStringValue);
14746ece063SSampa Misra }
14846ece063SSampa Misra catch (const std::bad_variant_access& e)
14946ece063SSampa Misra {
15089644441SRiya Dixit error("Invalid value passed for the property - {ERROR}", "ERROR", e);
15146ece063SSampa Misra return PLDM_ERROR;
15246ece063SSampa Misra }
15346ece063SSampa Misra return PLDM_SUCCESS;
15446ece063SSampa Misra }
15546ece063SSampa Misra
generateAttributeEntry(const std::variant<int64_t,std::string> & attributevalue,Table & attrValueEntry)1561244acfdSGeorge Liu void BIOSStringAttribute::generateAttributeEntry(
1571244acfdSGeorge Liu const std::variant<int64_t, std::string>& attributevalue,
1581244acfdSGeorge Liu Table& attrValueEntry)
1591244acfdSGeorge Liu {
1601244acfdSGeorge Liu std::string value = std::get<std::string>(attributevalue);
1611244acfdSGeorge Liu uint16_t len = value.size();
1621244acfdSGeorge Liu
1631244acfdSGeorge Liu attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) +
1641244acfdSGeorge Liu sizeof(uint16_t) + len - 1);
1651244acfdSGeorge Liu
1661244acfdSGeorge Liu auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
1671244acfdSGeorge Liu attrValueEntry.data());
1681244acfdSGeorge Liu
1691244acfdSGeorge Liu entry->attr_type = 1;
1701244acfdSGeorge Liu memcpy(entry->value, &len, sizeof(uint16_t));
1711244acfdSGeorge Liu memcpy(entry->value + sizeof(uint16_t), value.c_str(), value.size());
1721244acfdSGeorge Liu }
1731244acfdSGeorge Liu
17429683b53SJohn Wang } // namespace bios
17529683b53SJohn Wang } // namespace responder
17629683b53SJohn Wang } // namespace pldm
177