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 <iostream>
829683b53SJohn Wang #include <tuple>
929683b53SJohn Wang #include <variant>
1029683b53SJohn Wang 
1149cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
1249cfb138SRiya Dixit 
135079ac4aSBrad Bishop using namespace pldm::utils;
145079ac4aSBrad Bishop 
1529683b53SJohn Wang namespace pldm
1629683b53SJohn Wang {
1729683b53SJohn Wang namespace responder
1829683b53SJohn Wang {
1929683b53SJohn Wang namespace bios
2029683b53SJohn Wang {
2129683b53SJohn Wang BIOSStringAttribute::BIOSStringAttribute(const Json& entry,
2229683b53SJohn Wang                                          DBusHandler* const dbusHandler) :
2329683b53SJohn Wang     BIOSAttribute(entry, dbusHandler)
2429683b53SJohn Wang {
2529683b53SJohn Wang     std::string strTypeTmp = entry.at("string_type");
2629683b53SJohn Wang     auto iter = strTypeMap.find(strTypeTmp);
2729683b53SJohn Wang     if (iter == strTypeMap.end())
2829683b53SJohn Wang     {
2949cfb138SRiya Dixit         error(
3049cfb138SRiya Dixit             "Wrong string type, STRING_TYPE={STR_TYPE} ATTRIBUTE_NAME={ATTR_NAME}",
3149cfb138SRiya Dixit             "STR_TYP", strTypeTmp, "ATTR_NAME", name);
3229683b53SJohn Wang         throw std::invalid_argument("Wrong string type");
3329683b53SJohn Wang     }
3429683b53SJohn Wang     stringInfo.stringType = static_cast<uint8_t>(iter->second);
3529683b53SJohn Wang 
3629683b53SJohn Wang     stringInfo.minLength = entry.at("minimum_string_length");
3729683b53SJohn Wang     stringInfo.maxLength = entry.at("maximum_string_length");
3829683b53SJohn Wang     stringInfo.defLength = entry.at("default_string_length");
3929683b53SJohn Wang     stringInfo.defString = entry.at("default_string");
4029683b53SJohn Wang 
4129683b53SJohn Wang     pldm_bios_table_attr_entry_string_info info = {
4229683b53SJohn Wang         0,
4329683b53SJohn Wang         readOnly,
4429683b53SJohn Wang         stringInfo.stringType,
4529683b53SJohn Wang         stringInfo.minLength,
4629683b53SJohn Wang         stringInfo.maxLength,
4729683b53SJohn Wang         stringInfo.defLength,
4829683b53SJohn Wang         stringInfo.defString.data(),
4929683b53SJohn Wang     };
5029683b53SJohn Wang 
5129683b53SJohn Wang     const char* errmsg;
5229683b53SJohn Wang     auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
5329683b53SJohn Wang     if (rc != PLDM_SUCCESS)
5429683b53SJohn Wang     {
5549cfb138SRiya Dixit         error(
5649cfb138SRiya Dixit             "Wrong field for string attribute, ATTRIBUTE_NAME={ATTR_NAME} ERRMSG={ERR_MSG} MINIMUM_STRING_LENGTH={MIN_LEN} MAXIMUM_STRING_LENGTH={MAX_LEN} DEFAULT_STRING_LENGTH={DEF_LEN} DEFAULT_STRING={DEF_STR}",
5749cfb138SRiya Dixit             "ATTR_NAME", name, "ERR_MSG", errmsg, "MIN_LEN",
5849cfb138SRiya Dixit             stringInfo.minLength, "MAX_LEN", stringInfo.maxLength, "DEF_LEN",
5949cfb138SRiya Dixit             stringInfo.defLength, "DEF_STR", stringInfo.defString);
6029683b53SJohn Wang         throw std::invalid_argument("Wrong field for string attribute");
6129683b53SJohn Wang     }
6229683b53SJohn Wang }
6329683b53SJohn Wang 
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 
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     {
9249cfb138SRiya Dixit         error("Get String Attribute Value Error: AttributeName = {ATTR_NAME}",
9349cfb138SRiya Dixit               "ATTR_NAME", name);
9429683b53SJohn Wang         return stringInfo.defString;
9529683b53SJohn Wang     }
9629683b53SJohn Wang }
9729683b53SJohn Wang 
98ca7b2524STom Joseph void BIOSStringAttribute::constructEntry(
99ca7b2524STom Joseph     const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable,
100ca7b2524STom Joseph     std::optional<std::variant<int64_t, std::string>> optAttributeValue)
10129683b53SJohn Wang {
10229683b53SJohn Wang     pldm_bios_table_attr_entry_string_info info = {
10329683b53SJohn Wang         stringTable.findHandle(name), readOnly,
10429683b53SJohn Wang         stringInfo.stringType,        stringInfo.minLength,
10529683b53SJohn Wang         stringInfo.maxLength,         stringInfo.defLength,
10629683b53SJohn Wang         stringInfo.defString.data(),
10729683b53SJohn Wang     };
10829683b53SJohn Wang 
109*6da4f91bSPatrick Williams     auto attrTableEntry = table::attribute::constructStringEntry(attrTable,
110*6da4f91bSPatrick Williams                                                                  &info);
111*6da4f91bSPatrick Williams     auto [attrHandle, attrType,
112*6da4f91bSPatrick Williams           _] = table::attribute::decodeHeader(attrTableEntry);
113ca7b2524STom Joseph 
114ca7b2524STom Joseph     std::string currStr{};
115ca7b2524STom Joseph     if (optAttributeValue.has_value())
116ca7b2524STom Joseph     {
117ca7b2524STom Joseph         auto attributeValue = optAttributeValue.value();
118ca7b2524STom Joseph         if (attributeValue.index() == 1)
119ca7b2524STom Joseph         {
120ca7b2524STom Joseph             currStr = std::get<std::string>(attributeValue);
121ca7b2524STom Joseph         }
122ca7b2524STom Joseph         else
123ca7b2524STom Joseph         {
124ca7b2524STom Joseph             currStr = getAttrValue();
125ca7b2524STom Joseph         }
126ca7b2524STom Joseph     }
127ca7b2524STom Joseph     else
128ca7b2524STom Joseph     {
129ca7b2524STom Joseph         currStr = getAttrValue();
130ca7b2524STom Joseph     }
131ca7b2524STom Joseph 
13229683b53SJohn Wang     table::attribute_value::constructStringEntry(attrValueTable, attrHandle,
13329683b53SJohn Wang                                                  attrType, currStr);
13429683b53SJohn Wang }
13529683b53SJohn Wang 
13646ece063SSampa Misra int BIOSStringAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl,
13746ece063SSampa Misra                                        uint8_t attrType,
13846ece063SSampa Misra                                        const PropertyValue& newPropVal)
13946ece063SSampa Misra {
14046ece063SSampa Misra     try
14146ece063SSampa Misra     {
14246ece063SSampa Misra         const auto& newStringValue = std::get<std::string>(newPropVal);
14346ece063SSampa Misra         table::attribute_value::constructStringEntry(newValue, attrHdl,
14446ece063SSampa Misra                                                      attrType, newStringValue);
14546ece063SSampa Misra     }
14646ece063SSampa Misra     catch (const std::bad_variant_access& e)
14746ece063SSampa Misra     {
14849cfb138SRiya Dixit         error("invalid value passed for the property, error: {ERR_EXCEP}",
14949cfb138SRiya Dixit               "ERR_EXCEP", e.what());
15046ece063SSampa Misra         return PLDM_ERROR;
15146ece063SSampa Misra     }
15246ece063SSampa Misra     return PLDM_SUCCESS;
15346ece063SSampa Misra }
15446ece063SSampa Misra 
1551244acfdSGeorge Liu void BIOSStringAttribute::generateAttributeEntry(
1561244acfdSGeorge Liu     const std::variant<int64_t, std::string>& attributevalue,
1571244acfdSGeorge Liu     Table& attrValueEntry)
1581244acfdSGeorge Liu {
1591244acfdSGeorge Liu     std::string value = std::get<std::string>(attributevalue);
1601244acfdSGeorge Liu     uint16_t len = value.size();
1611244acfdSGeorge Liu 
1621244acfdSGeorge Liu     attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) +
1631244acfdSGeorge Liu                           sizeof(uint16_t) + len - 1);
1641244acfdSGeorge Liu 
1651244acfdSGeorge Liu     auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
1661244acfdSGeorge Liu         attrValueEntry.data());
1671244acfdSGeorge Liu 
1681244acfdSGeorge Liu     entry->attr_type = 1;
1691244acfdSGeorge Liu     memcpy(entry->value, &len, sizeof(uint16_t));
1701244acfdSGeorge Liu     memcpy(entry->value + sizeof(uint16_t), value.c_str(), value.size());
1711244acfdSGeorge Liu }
1721244acfdSGeorge Liu 
17329683b53SJohn Wang } // namespace bios
17429683b53SJohn Wang } // namespace responder
17529683b53SJohn Wang } // namespace pldm
176