1 #include "bios_string_attribute.hpp" 2 3 #include "common/utils.hpp" 4 5 #include <phosphor-logging/lg2.hpp> 6 7 #include <tuple> 8 #include <variant> 9 10 PHOSPHOR_LOG2_USING; 11 12 using namespace pldm::utils; 13 14 namespace pldm 15 { 16 namespace responder 17 { 18 namespace bios 19 { 20 BIOSStringAttribute::BIOSStringAttribute(const Json& entry, 21 DBusHandler* const dbusHandler) : 22 BIOSAttribute(entry, dbusHandler) 23 { 24 std::string strTypeTmp = entry.at("string_type"); 25 auto iter = strTypeMap.find(strTypeTmp); 26 if (iter == strTypeMap.end()) 27 { 28 error( 29 "Wrong string type, STRING_TYPE={STR_TYPE} ATTRIBUTE_NAME={ATTR_NAME}", 30 "STR_TYP", strTypeTmp, "ATTR_NAME", name); 31 throw std::invalid_argument("Wrong string type"); 32 } 33 stringInfo.stringType = static_cast<uint8_t>(iter->second); 34 35 stringInfo.minLength = entry.at("minimum_string_length"); 36 stringInfo.maxLength = entry.at("maximum_string_length"); 37 stringInfo.defLength = entry.at("default_string_length"); 38 stringInfo.defString = entry.at("default_string"); 39 40 pldm_bios_table_attr_entry_string_info info = { 41 0, 42 readOnly, 43 stringInfo.stringType, 44 stringInfo.minLength, 45 stringInfo.maxLength, 46 stringInfo.defLength, 47 stringInfo.defString.data(), 48 }; 49 50 const char* errmsg; 51 auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg); 52 if (rc != PLDM_SUCCESS) 53 { 54 error( 55 "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}", 56 "ATTR_NAME", name, "ERR_MSG", errmsg, "MIN_LEN", 57 stringInfo.minLength, "MAX_LEN", stringInfo.maxLength, "DEF_LEN", 58 stringInfo.defLength, "DEF_STR", stringInfo.defString); 59 throw std::invalid_argument("Wrong field for string attribute"); 60 } 61 } 62 63 void BIOSStringAttribute::setAttrValueOnDbus( 64 const pldm_bios_attr_val_table_entry* attrValueEntry, 65 const pldm_bios_attr_table_entry*, const BIOSStringTable&) 66 { 67 if (!dBusMap.has_value()) 68 { 69 return; 70 } 71 72 PropertyValue value = 73 table::attribute_value::decodeStringEntry(attrValueEntry); 74 dbusHandler->setDbusProperty(*dBusMap, value); 75 } 76 77 std::string BIOSStringAttribute::getAttrValue() 78 { 79 if (!dBusMap.has_value()) 80 { 81 return stringInfo.defString; 82 } 83 try 84 { 85 return dbusHandler->getDbusProperty<std::string>( 86 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(), 87 dBusMap->interface.c_str()); 88 } 89 catch (const std::exception& e) 90 { 91 error( 92 "Error getting string attribute '{ATTR}' from '{INTERFACE}': {ERROR}", 93 "ATTR", name, "INTERFACE", dBusMap->interface, "ERROR", e); 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