appcommands: support multi-host set/get fw version

Support multi-host set/get fw version in IPMI set/get system info command

Test case:
Get bios version from different host success.

Signed-off-by: Bonnie Lo <Bonnie_Lo@wiwynn.com>
Change-Id: Id2e1598bbe8f7d834fe3c31710384a7dbbe537e0
diff --git a/src/appcommands.cpp b/src/appcommands.cpp
index a4aa3cc..e0ae4ed 100644
--- a/src/appcommands.cpp
+++ b/src/appcommands.cpp
@@ -51,6 +51,11 @@
 int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
                std::vector<uint8_t>&);
 
+static inline auto responseSystemInfoParamterNotSupportCommand()
+{
+    return response(IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED);
+}
+
 void printGUID(uint8_t* guid, off_t offset)
 {
     std::cout << "Read GUID from offset : " << offset << " :\n";
@@ -247,7 +252,7 @@
     return;
 }
 
-static int platSetSysFWVer(uint8_t* ver)
+static int platSetSysFWVer(uint8_t* ver, const std::string key)
 {
     std::stringstream ss;
     int i;
@@ -265,23 +270,39 @@
         ss << (char)ver[i];
     }
 
-    appData[KEY_SYSFW_VER] = ss.str();
+    appData[key] = ss.str();
     flush_app_data();
 
     return 0;
 }
 
-static int platGetSysFWVer(uint8_t* ver)
+static int platGetSysFWVer(std::vector<uint8_t>& respData,
+                           const std::string key)
 {
-    std::string str = appData[KEY_SYSFW_VER].get<std::string>();
-    int len;
+    int len = -1;
 
-    *ver++ = 0; // byte 1: Set selector not supported
-    *ver++ = 0; // byte 2: Only ASCII supported
+    if (!appData.contains(std::string(key)))
+    {
+        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
 
     len = str.length();
-    *ver++ = len;
-    memcpy(ver, str.data(), len);
+    respData.push_back(len); // byte 3: Size of version
+
+    for (auto c : str)
+    {
+        respData.push_back(c);
+    }
+
+    // Remaining byte fill to 0
+    for (int i = 0; i < SIZE_SYSFW_VER - (len + 3); i++)
+    {
+        respData.push_back(0);
+    }
 
     return (len + 3);
 }
@@ -289,16 +310,20 @@
 //----------------------------------------------------------------------
 // Set Sys Info Params (IPMI/Sec 22.14a) (CMD_APP_SET_SYS_INFO_PARAMS)
 //----------------------------------------------------------------------
-ipmi_ret_t ipmiAppSetSysInfoParams(ipmi_netfn_t, ipmi_cmd_t,
-                                   ipmi_request_t request, ipmi_response_t,
-                                   ipmi_data_len_t data_len, ipmi_context_t)
+ipmi::RspType<uint8_t> ipmiAppSetSysInfoParams(ipmi::Context::ptr ctx,
+                                               std::vector<uint8_t> req)
 {
-    uint8_t* req = reinterpret_cast<uint8_t*>(request);
 
     uint8_t param = req[0];
-    uint8_t req_len = *data_len;
+    uint8_t req_len = req.size();
+    std::optional<size_t> hostId = findHost(ctx->hostIdx);
 
-    *data_len = 0;
+    if (!hostId)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Host Id received");
+        return ipmi::responseInvalidCommand();
+    }
 
     switch (param)
     {
@@ -306,10 +331,13 @@
             sysInfoParams.set_in_prog = req[1];
             break;
         case SYS_INFO_PARAM_SYSFW_VER:
+        {
             memcpy(sysInfoParams.sysfw_ver, &req[1], SIZE_SYSFW_VER);
-            if (platSetSysFWVer(sysInfoParams.sysfw_ver))
-                return IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED;
+            std::string version_key = KEY_SYSFW_VER + std::to_string(*hostId);
+            if (platSetSysFWVer(sysInfoParams.sysfw_ver, version_key))
+                return ipmi::responseSystemInfoParamterNotSupportCommand();
             break;
+        }
         case SYS_INFO_PARAM_SYS_NAME:
             memcpy(sysInfoParams.sys_name, &req[1], SIZE_SYS_NAME);
             break;
@@ -351,89 +379,100 @@
             memcpy(sysInfoParams.last_boot_time, &req[1], SIZE_LAST_BOOT_TIME);
             break;
         default:
-            return IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED;
+            return ipmi::responseSystemInfoParamterNotSupportCommand();
             break;
     }
 
-    return IPMI_CC_OK;
+    return ipmi::responseSuccess();
 }
 
 //----------------------------------------------------------------------
 // Get Sys Info Params (IPMI/Sec 22.14b) (CMD_APP_GET_SYS_INFO_PARAMS)
 //----------------------------------------------------------------------
-ipmi_ret_t ipmiAppGetSysInfoParams(ipmi_netfn_t, ipmi_cmd_t,
-                                   ipmi_request_t request,
-                                   ipmi_response_t response,
-                                   ipmi_data_len_t data_len, ipmi_context_t)
+ipmi::RspType<std::vector<uint8_t>>
+    ipmiAppGetSysInfoParams(ipmi::Context::ptr ctx, uint8_t, uint8_t param,
+                            uint8_t, uint8_t)
 {
-    uint8_t* req = reinterpret_cast<uint8_t*>(request);
-    uint8_t* res = reinterpret_cast<uint8_t*>(response);
-
-    uint8_t param = req[1];
     int len;
+    std::vector<uint8_t> respData;
+    respData.push_back(1); // Parameter revision
 
-    *res++ = 1; // Parameter revision
-    *data_len = 1;
+    std::optional<size_t> hostId = findHost(ctx->hostIdx);
+
+    if (!hostId)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Host Id received");
+        return ipmi::responseInvalidCommand();
+    }
 
     switch (param)
     {
         case SYS_INFO_PARAM_SET_IN_PROG:
-            *res++ = sysInfoParams.set_in_prog;
-            *data_len += 1;
+            respData.push_back(sysInfoParams.set_in_prog);
             break;
         case SYS_INFO_PARAM_SYSFW_VER:
-            if ((len = platGetSysFWVer(res)) < 0)
-                return IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED;
-            *data_len += SIZE_SYSFW_VER;
+        {
+            std::string version_key = KEY_SYSFW_VER + std::to_string(*hostId);
+            if ((platGetSysFWVer(respData, version_key)) < 0)
+                return ipmi::responseSystemInfoParamterNotSupportCommand();
             break;
+        }
         case SYS_INFO_PARAM_SYS_NAME:
-            memcpy(res, sysInfoParams.sys_name, SIZE_SYS_NAME);
-            *data_len += SIZE_SYS_NAME;
+            respData.insert(respData.end(), std::begin(sysInfoParams.sys_name),
+                            std::end(sysInfoParams.sys_name));
             break;
         case SYS_INFO_PARAM_PRI_OS_NAME:
-            memcpy(res, sysInfoParams.pri_os_name, SIZE_OS_NAME);
-            *data_len += SIZE_OS_NAME;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.pri_os_name),
+                            std::end(sysInfoParams.pri_os_name));
             break;
         case SYS_INFO_PARAM_PRESENT_OS_NAME:
-            memcpy(res, sysInfoParams.present_os_name, SIZE_OS_NAME);
-            *data_len += SIZE_OS_NAME;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.present_os_name),
+                            std::end(sysInfoParams.present_os_name));
             break;
         case SYS_INFO_PARAM_PRESENT_OS_VER:
-            memcpy(res, sysInfoParams.present_os_ver, SIZE_OS_VER);
-            *data_len += SIZE_OS_VER;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.present_os_ver),
+                            std::end(sysInfoParams.present_os_ver));
             break;
         case SYS_INFO_PARAM_BMC_URL:
-            memcpy(res, sysInfoParams.bmc_url, SIZE_BMC_URL);
-            *data_len += SIZE_BMC_URL;
+            respData.insert(respData.end(), std::begin(sysInfoParams.bmc_url),
+                            std::end(sysInfoParams.bmc_url));
             break;
         case SYS_INFO_PARAM_OS_HV_URL:
-            memcpy(res, sysInfoParams.os_hv_url, SIZE_OS_HV_URL);
-            *data_len += SIZE_OS_HV_URL;
+            respData.insert(respData.end(), std::begin(sysInfoParams.os_hv_url),
+                            std::end(sysInfoParams.os_hv_url));
             break;
         case SYS_INFO_PARAM_BIOS_CURRENT_BOOT_LIST:
             len = appData[KEY_BIOS_BOOT_LEN].get<uint8_t>();
-            memcpy(res, sysInfoParams.bios_current_boot_list, len);
-            *data_len += len;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.bios_current_boot_list),
+                            std::begin(sysInfoParams.bios_current_boot_list) +
+                                len);
             break;
         case SYS_INFO_PARAM_BIOS_FIXED_BOOT_DEVICE:
-            memcpy(res, sysInfoParams.bios_fixed_boot_device,
-                   SIZE_BIOS_FIXED_BOOT_DEVICE);
-            *data_len += SIZE_BIOS_FIXED_BOOT_DEVICE;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.bios_fixed_boot_device),
+                            std::end(sysInfoParams.bios_fixed_boot_device));
             break;
         case SYS_INFO_PARAM_BIOS_RSTR_DFLT_SETTING:
-            memcpy(res, sysInfoParams.bios_rstr_dflt_setting,
-                   SIZE_BIOS_RSTR_DFLT_SETTING);
-            *data_len += SIZE_BIOS_RSTR_DFLT_SETTING;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.bios_rstr_dflt_setting),
+                            std::end(sysInfoParams.bios_rstr_dflt_setting));
             break;
         case SYS_INFO_PARAM_LAST_BOOT_TIME:
-            memcpy(res, sysInfoParams.last_boot_time, SIZE_LAST_BOOT_TIME);
-            *data_len += SIZE_LAST_BOOT_TIME;
+            respData.insert(respData.end(),
+                            std::begin(sysInfoParams.last_boot_time),
+                            std::end(sysInfoParams.last_boot_time));
             break;
         default:
-            return IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED;
+            return ipmi::responseSystemInfoParamterNotSupportCommand();
             break;
     }
-    return IPMI_CC_OK;
+
+    return ipmi::responseSuccess(respData);
 }
 
 void registerAPPFunctions()
@@ -470,12 +509,13 @@
                          ipmiAppGetSysGUID,
                          PRIVILEGE_USER); // Get System GUID
 #endif
-    ipmiPrintAndRegister(NETFUN_APP, CMD_APP_SET_SYS_INFO_PARAMS, NULL,
-                         ipmiAppSetSysInfoParams,
-                         PRIVILEGE_USER); // Set Sys Info Params
-    ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SYS_INFO_PARAMS, NULL,
-                         ipmiAppGetSysInfoParams,
-                         PRIVILEGE_USER); // Get Sys Info Params
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetSystemInfoParameters,
+                          ipmi::Privilege::User, ipmiAppSetSysInfoParams);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetSystemInfoParameters,
+                          ipmi::Privilege::User, ipmiAppGetSysInfoParams);
     return;
 }
 
diff --git a/src/usb-dbg.cpp b/src/usb-dbg.cpp
index 9a718b7..19adbe8 100644
--- a/src/usb-dbg.cpp
+++ b/src/usb-dbg.cpp
@@ -795,7 +795,7 @@
     return 0;
 }
 
-static int getBiosVer(std::string& ver)
+static int getBiosVer(std::string& ver, size_t hostPosition)
 {
     nlohmann::json appObj;
 
@@ -804,9 +804,11 @@
     {
         file >> appObj;
         file.close();
-        if (appObj.find(KEY_SYSFW_VER) != appObj.end())
+        std::string version_key = KEY_SYSFW_VER + std::to_string(hostPosition);
+
+        if (appObj.find(version_key) != appObj.end())
         {
-            ver = appObj[KEY_SYSFW_VER].get<std::string>();
+            ver = appObj[version_key].get<std::string>();
             return 0;
         }
     }
@@ -1025,7 +1027,7 @@
         {
             // BIOS ver
             std::string biosVer;
-            if (getBiosVer(biosVer) == 0)
+            if (getBiosVer(biosVer, hostPosition) == 0)
             {
                 frame_info.append("BIOS_FW_ver:", 0);
                 frame_info.append(biosVer.c_str(), 1);