BIOS: Fix readOnly BIOS attributes

Previously, the readOnly property is true when without a D-Bus section in BIOS
JSON. Now, the readOnly property should be determined by a new readOnly field,
which should be introduced in the JSON. The checks are updated to ensure that
if there is D-Bus mapping then only D-Bus lookups are done.

Tested: test with json
https://gist.github.com/lxwinspur/2afffff2e445fddf90dfed6eceef4014

busctl get-property xyz.openbmc_project.BIOSConfigManager
/xyz/openbmc_project/bios_config/manager xyz.openbmc_project.BIOSConfig.Manager
BaseBIOSTable

a{s(sbsssvva(sv))} 5
"CodeUpdatePolicy"
"xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration"
true "" "" "" s "Concurrent" s "Concurrent" 2
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.OneOf" s "Concurrent"
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.OneOf" s "Disruptive"

"Led"
"xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration"
false "" "" "" s "Off" s "Off" 2
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.OneOf" s "On"
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.OneOf" s "Off"

"Model"
"xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String"
false "" "" "" s "powersupply0" s "FP5280G2" 2
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.MinStringLength" x 1
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.MaxStringLength" x 100

"OUTLET"
"xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer"
false "" "" "" x 9149282306036291456 x 0 3
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.LowerBound" x 0
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.UpperBound" x 68002
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.ScalarIncrement" x 1

"str_example3"
"xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String"
true "" "" "" s "ef" s "ef" 2
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.MinStringLength" x 1
"xyz.openbmc_project.BIOSConfig.Manager.BoundType.MaxStringLength" x 100

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I73d2dcb9fc65a1aa8bbd060cfb9d44e708b47aae
diff --git a/libpldmresponder/bios_attribute.cpp b/libpldmresponder/bios_attribute.cpp
index b0b834e..c519cb7 100644
--- a/libpldmresponder/bios_attribute.cpp
+++ b/libpldmresponder/bios_attribute.cpp
@@ -18,16 +18,32 @@
 BIOSAttribute::BIOSAttribute(const Json& entry,
                              DBusHandler* const dbusHandler) :
     name(entry.at("attribute_name")),
-    readOnly(!entry.contains("dbus")), dbusHandler(dbusHandler)
+    readOnly(false), dbusHandler(dbusHandler)
 {
+    try
+    {
+        readOnly = entry.at("readOnly");
+    }
+    catch (const std::exception& e)
+    {
+        // No action required, readOnly is initialised to false
+    }
+
     if (!readOnly)
     {
-        std::string objectPath = entry.at("dbus").at("object_path");
-        std::string interface = entry.at("dbus").at("interface");
-        std::string propertyName = entry.at("dbus").at("property_name");
-        std::string propertyType = entry.at("dbus").at("property_type");
+        try
+        {
+            std::string objectPath = entry.at("dbus").at("object_path");
+            std::string interface = entry.at("dbus").at("interface");
+            std::string propertyName = entry.at("dbus").at("property_name");
+            std::string propertyType = entry.at("dbus").at("property_type");
 
-        dBusMap = {objectPath, interface, propertyName, propertyType};
+            dBusMap = {objectPath, interface, propertyName, propertyType};
+        }
+        catch (const std::exception& e)
+        {
+            // No action required, dBusMap whill have no value
+        }
     }
 }
 
diff --git a/libpldmresponder/bios_attribute.hpp b/libpldmresponder/bios_attribute.hpp
index 7a15c09..b812844 100644
--- a/libpldmresponder/bios_attribute.hpp
+++ b/libpldmresponder/bios_attribute.hpp
@@ -89,7 +89,7 @@
     const std::string name;
 
     /** Weather this attribute is read-only */
-    const bool readOnly;
+    bool readOnly;
 
   protected:
     /** @brief dbus backend, nullopt if this attribute is read-only*/
diff --git a/libpldmresponder/bios_enum_attribute.cpp b/libpldmresponder/bios_enum_attribute.cpp
index e799cee..a5c7ee4 100644
--- a/libpldmresponder/bios_enum_attribute.cpp
+++ b/libpldmresponder/bios_enum_attribute.cpp
@@ -32,7 +32,7 @@
     }
     assert(defaultValues.size() == 1);
     defaultValue = defaultValues[0];
-    if (!readOnly)
+    if (dBusMap.has_value())
     {
         auto dbusValues = entry.at("dbus").at("property_values");
         buildValMap(dbusValues);
@@ -123,7 +123,7 @@
 uint8_t BIOSEnumAttribute::getAttrValueIndex()
 {
     auto defaultValueIndex = getValueIndex(defaultValue, possibleValues);
-    if (readOnly)
+    if (readOnly || !dBusMap.has_value())
     {
         return defaultValueIndex;
     }
@@ -150,10 +150,6 @@
 uint8_t BIOSEnumAttribute::getAttrValueIndex(const PropertyValue& propValue)
 {
     auto defaultValueIndex = getValueIndex(defaultValue, possibleValues);
-    if (readOnly)
-    {
-        return defaultValueIndex;
-    }
 
     try
     {
@@ -176,7 +172,7 @@
     const pldm_bios_attr_table_entry* attrEntry,
     const BIOSStringTable& stringTable)
 {
-    if (readOnly)
+    if (readOnly || !dBusMap.has_value())
     {
         return;
     }
@@ -256,7 +252,19 @@
     std::string value = std::get<std::string>(attributevalue);
     entry->attr_type = 0;
     entry->value[0] = 1; // number of current values, default 1
-    entry->value[1] = getAttrValueIndex(value);
+
+    if (readOnly)
+    {
+        entry->value[1] = getValueIndex(defaultValue, possibleValues);
+    }
+    else if (!dBusMap.has_value())
+    {
+        entry->value[1] = getValueIndex(value, possibleValues);
+    }
+    else
+    {
+        entry->value[1] = getAttrValueIndex(value);
+    }
 }
 
 } // namespace bios
diff --git a/libpldmresponder/bios_integer_attribute.cpp b/libpldmresponder/bios_integer_attribute.cpp
index a4bc14b..43a94d2 100644
--- a/libpldmresponder/bios_integer_attribute.cpp
+++ b/libpldmresponder/bios_integer_attribute.cpp
@@ -46,7 +46,7 @@
     const pldm_bios_attr_val_table_entry* attrValueEntry,
     const pldm_bios_attr_table_entry*, const BIOSStringTable&)
 {
-    if (readOnly)
+    if (readOnly || !dBusMap.has_value())
     {
         return;
     }
@@ -160,7 +160,7 @@
 
 uint64_t BIOSIntegerAttribute::getAttrValue()
 {
-    if (readOnly)
+    if (readOnly || !dBusMap.has_value())
     {
         return integerInfo.defaultValue;
     }
diff --git a/libpldmresponder/bios_string_attribute.cpp b/libpldmresponder/bios_string_attribute.cpp
index 19819c9..41538b6 100644
--- a/libpldmresponder/bios_string_attribute.cpp
+++ b/libpldmresponder/bios_string_attribute.cpp
@@ -60,7 +60,7 @@
     const pldm_bios_attr_val_table_entry* attrValueEntry,
     const pldm_bios_attr_table_entry*, const BIOSStringTable&)
 {
-    if (readOnly)
+    if (readOnly || !dBusMap.has_value())
     {
         return;
     }
@@ -72,7 +72,7 @@
 
 std::string BIOSStringAttribute::getAttrValue()
 {
-    if (readOnly)
+    if (readOnly || !dBusMap.has_value())
     {
         return stringInfo.defString;
     }