1 #include "bios_string_attribute.hpp" 2 3 #include "common/utils.hpp" 4 5 #include <phosphor-logging/lg2.hpp> 6 7 #include <iostream> 8 #include <tuple> 9 #include <variant> 10 11 PHOSPHOR_LOG2_USING; 12 13 using namespace pldm::utils; 14 15 namespace pldm 16 { 17 namespace responder 18 { 19 namespace bios 20 { 21 BIOSStringAttribute::BIOSStringAttribute(const Json& entry, 22 DBusHandler* const dbusHandler) : 23 BIOSAttribute(entry, dbusHandler) 24 { 25 std::string strTypeTmp = entry.at("string_type"); 26 auto iter = strTypeMap.find(strTypeTmp); 27 if (iter == strTypeMap.end()) 28 { 29 error( 30 "Wrong string type, STRING_TYPE={STR_TYPE} ATTRIBUTE_NAME={ATTR_NAME}", 31 "STR_TYP", strTypeTmp, "ATTR_NAME", name); 32 throw std::invalid_argument("Wrong string type"); 33 } 34 stringInfo.stringType = static_cast<uint8_t>(iter->second); 35 36 stringInfo.minLength = entry.at("minimum_string_length"); 37 stringInfo.maxLength = entry.at("maximum_string_length"); 38 stringInfo.defLength = entry.at("default_string_length"); 39 stringInfo.defString = entry.at("default_string"); 40 41 pldm_bios_table_attr_entry_string_info info = { 42 0, 43 readOnly, 44 stringInfo.stringType, 45 stringInfo.minLength, 46 stringInfo.maxLength, 47 stringInfo.defLength, 48 stringInfo.defString.data(), 49 }; 50 51 const char* errmsg; 52 auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg); 53 if (rc != PLDM_SUCCESS) 54 { 55 error( 56 "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}", 57 "ATTR_NAME", name, "ERR_MSG", errmsg, "MIN_LEN", 58 stringInfo.minLength, "MAX_LEN", stringInfo.maxLength, "DEF_LEN", 59 stringInfo.defLength, "DEF_STR", stringInfo.defString); 60 throw std::invalid_argument("Wrong field for string attribute"); 61 } 62 } 63 64 void BIOSStringAttribute::setAttrValueOnDbus( 65 const pldm_bios_attr_val_table_entry* attrValueEntry, 66 const pldm_bios_attr_table_entry*, const BIOSStringTable&) 67 { 68 if (!dBusMap.has_value()) 69 { 70 return; 71 } 72 73 PropertyValue value = 74 table::attribute_value::decodeStringEntry(attrValueEntry); 75 dbusHandler->setDbusProperty(*dBusMap, value); 76 } 77 78 std::string BIOSStringAttribute::getAttrValue() 79 { 80 if (!dBusMap.has_value()) 81 { 82 return stringInfo.defString; 83 } 84 try 85 { 86 return dbusHandler->getDbusProperty<std::string>( 87 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(), 88 dBusMap->interface.c_str()); 89 } 90 catch (const std::exception& e) 91 { 92 error("Get String Attribute Value Error: AttributeName = {ATTR_NAME}", 93 "ATTR_NAME", name); 94 return stringInfo.defString; 95 } 96 } 97 98 void BIOSStringAttribute::constructEntry( 99 const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable, 100 std::optional<std::variant<int64_t, std::string>> optAttributeValue) 101 { 102 pldm_bios_table_attr_entry_string_info info = { 103 stringTable.findHandle(name), readOnly, 104 stringInfo.stringType, stringInfo.minLength, 105 stringInfo.maxLength, stringInfo.defLength, 106 stringInfo.defString.data(), 107 }; 108 109 auto attrTableEntry = table::attribute::constructStringEntry(attrTable, 110 &info); 111 auto [attrHandle, attrType, 112 _] = table::attribute::decodeHeader(attrTableEntry); 113 114 std::string currStr{}; 115 if (optAttributeValue.has_value()) 116 { 117 auto attributeValue = optAttributeValue.value(); 118 if (attributeValue.index() == 1) 119 { 120 currStr = std::get<std::string>(attributeValue); 121 } 122 else 123 { 124 currStr = getAttrValue(); 125 } 126 } 127 else 128 { 129 currStr = getAttrValue(); 130 } 131 132 table::attribute_value::constructStringEntry(attrValueTable, attrHandle, 133 attrType, currStr); 134 } 135 136 int BIOSStringAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl, 137 uint8_t attrType, 138 const PropertyValue& newPropVal) 139 { 140 try 141 { 142 const auto& newStringValue = std::get<std::string>(newPropVal); 143 table::attribute_value::constructStringEntry(newValue, attrHdl, 144 attrType, newStringValue); 145 } 146 catch (const std::bad_variant_access& e) 147 { 148 error("invalid value passed for the property, error: {ERR_EXCEP}", 149 "ERR_EXCEP", e.what()); 150 return PLDM_ERROR; 151 } 152 return PLDM_SUCCESS; 153 } 154 155 void BIOSStringAttribute::generateAttributeEntry( 156 const std::variant<int64_t, std::string>& attributevalue, 157 Table& attrValueEntry) 158 { 159 std::string value = std::get<std::string>(attributevalue); 160 uint16_t len = value.size(); 161 162 attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) + 163 sizeof(uint16_t) + len - 1); 164 165 auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>( 166 attrValueEntry.data()); 167 168 entry->attr_type = 1; 169 memcpy(entry->value, &len, sizeof(uint16_t)); 170 memcpy(entry->value + sizeof(uint16_t), value.c_str(), value.size()); 171 } 172 173 } // namespace bios 174 } // namespace responder 175 } // namespace pldm 176