update sysfw version path for compatibility with new bios updater

The new BIOS updater[1] reads and writes the BIOS version from
/var/bios/host0_bios_version.txt. This change updates the version
path from /var/lib/fb-ipmi-oem/appData.json to
/var/bios/host0_bios_version.txt to ensure compatibility and allow the
new updater to retrieve the BIOS version correctly.

[1] https://gerrit.openbmc.org/c/openbmc/phosphor-bmc-code-mgmt/+/76101

Tested on Harma:
```
curl --silent $creds https://$bmc/redfish/v1/UpdateService/FirmwareInventory/Harma_BIOS_7246
{
  "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/Harma_BIOS_7246",
  "@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
  "Description": "Unknown image",
  "Id": "Harma_BIOS_7246",
  "Name": "Software Inventory",
  "Status": {
    "Health": "Warning",
    "HealthRollup": "OK",
    "State": "Disabled"
  },
  "Updateable": true,
  "Version": "F0M_2A08"
}
```

Signed-off-by: Kevin Tung <Kevin.Tung@quantatw.com>
Change-Id: If19b4b006961cd7514ac9556dfbf34845b7c1b74
diff --git a/src/appcommands.cpp b/src/appcommands.cpp
index 7ffcd2d..8f470fe 100644
--- a/src/appcommands.cpp
+++ b/src/appcommands.cpp
@@ -28,6 +28,7 @@
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/message/types.hpp>
 
+#include <format>
 #include <fstream>
 #include <iomanip>
 #include <iostream>
@@ -265,7 +266,7 @@
     return;
 }
 
-static int platSetSysFWVer(uint8_t* ver, const std::string key)
+static int platSetSysFWVer(uint8_t* ver, const size_t hostId)
 {
     std::stringstream ss;
     int i;
@@ -283,41 +284,68 @@
         ss << (char)ver[i];
     }
 
-    appData[key] = ss.str();
+    /* Save to legacy sysfw version file for backward compatibility */
+    appData[KEY_SYSFW_VER + std::to_string(hostId)] = ss.str();
     flush_app_data();
 
+    auto sysfwVersionFile = std::format(SYSFW_VER_FILE, hostId);
+    std::ofstream file(sysfwVersionFile);
+
+    if (!file)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Failed to open system firmware version file for writing",
+            phosphor::logging::entry("FILE=%s", sysfwVersionFile.c_str()));
+        return -1;
+    }
+
+    file << ss.str();
+    file.close();
+
     return 0;
 }
 
-static int platGetSysFWVer(std::vector<uint8_t>& respData,
-                           const std::string key)
+static int platGetSysFWVer(std::vector<uint8_t>& respData, const size_t hostId)
 {
-    int len = -1;
+    constexpr size_t headerSize = 3; // selector + encoding + version size
 
-    if (!appData.contains(std::string(key)))
+    std::string sysfwVersionFile = std::format(SYSFW_VER_FILE, hostId);
+    std::ifstream file(sysfwVersionFile);
+
+    if (!file)
     {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Failed to open system firmware version file for reading",
+            phosphor::logging::entry("FILE=%s", sysfwVersionFile.c_str()));
         return -1;
     }
-    std::string str = appData[key].get<std::string>();
 
-    respData.push_back(0); // byte 1: Set selector not supported
-    respData.push_back(0); // byte 2: Only ASCII supported
+    std::string version;
+    std::getline(file, version);
+    file.close();
 
-    len = str.length();
-    respData.push_back(len); // byte 3: Size of version
+    // Truncate if longer than allowed
+    if (version.size() > SIZE_SYSFW_VER - headerSize)
+    {
+        version.resize(SIZE_SYSFW_VER - headerSize);
+    }
 
-    for (auto c : str)
+    respData.push_back(0);              // Byte 1: set selector not supported
+    respData.push_back(0);              // Byte 2: only ASCII supported
+    respData.push_back(version.size()); // Byte 3: length of version
+
+    for (auto c : version)
     {
         respData.push_back(c);
     }
 
     // Remaining byte fill to 0
-    for (int i = 0; i < SIZE_SYSFW_VER - (len + 3); i++)
+    for (size_t i = 0; i < SIZE_SYSFW_VER - (version.size() + headerSize); i++)
     {
         respData.push_back(0);
     }
 
-    return (len + 3);
+    return (version.size() + headerSize);
 }
 
 //----------------------------------------------------------------------
@@ -345,8 +373,7 @@
         case SYS_INFO_PARAM_SYSFW_VER:
         {
             memcpy(sysInfoParams.sysfw_ver, &req[1], SIZE_SYSFW_VER);
-            std::string version_key = KEY_SYSFW_VER + std::to_string(*hostId);
-            if (platSetSysFWVer(sysInfoParams.sysfw_ver, version_key))
+            if (platSetSysFWVer(sysInfoParams.sysfw_ver, *hostId))
                 return ipmi::responseSystemInfoParamterNotSupportCommand();
             break;
         }
@@ -424,8 +451,7 @@
             break;
         case SYS_INFO_PARAM_SYSFW_VER:
         {
-            std::string version_key = KEY_SYSFW_VER + std::to_string(*hostId);
-            if ((platGetSysFWVer(respData, version_key)) < 0)
+            if ((platGetSysFWVer(respData, *hostId)) < 0)
                 return ipmi::responseSystemInfoParamterNotSupportCommand();
             break;
         }