xref: /openbmc/fb-ipmi-oem/src/appcommands.cpp (revision 2405ae98)
1a2d52f12SVijay Khemka /*
2a2d52f12SVijay Khemka  * Copyright (c)  2018 Intel Corporation.
3a2d52f12SVijay Khemka  * Copyright (c)  2018-present Facebook.
4a2d52f12SVijay Khemka  *
5a2d52f12SVijay Khemka  * Licensed under the Apache License, Version 2.0 (the "License");
6a2d52f12SVijay Khemka  * you may not use this file except in compliance with the License.
7a2d52f12SVijay Khemka  * You may obtain a copy of the License at
8a2d52f12SVijay Khemka  *
9a2d52f12SVijay Khemka  *      http://www.apache.org/licenses/LICENSE-2.0
10a2d52f12SVijay Khemka  *
11a2d52f12SVijay Khemka  * Unless required by applicable law or agreed to in writing, software
12a2d52f12SVijay Khemka  * distributed under the License is distributed on an "AS IS" BASIS,
13a2d52f12SVijay Khemka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14a2d52f12SVijay Khemka  * See the License for the specific language governing permissions and
15a2d52f12SVijay Khemka  * limitations under the License.
16a2d52f12SVijay Khemka  */
17a2d52f12SVijay Khemka 
18a2d52f12SVijay Khemka #include <fcntl.h>
1963c99be4SVijay Khemka #include <ipmid/api.h>
2063c99be4SVijay Khemka #include <sys/stat.h>
21a2d52f12SVijay Khemka #include <unistd.h>
2263c99be4SVijay Khemka 
2363c99be4SVijay Khemka #include <appcommands.hpp>
24a2d52f12SVijay Khemka #include <commandutils.hpp>
25*2405ae98SPatrick Williams #include <ipmid/api-types.hpp>
26*2405ae98SPatrick Williams #include <ipmid/api.hpp>
2763c99be4SVijay Khemka #include <nlohmann/json.hpp>
28a2d52f12SVijay Khemka #include <phosphor-logging/log.hpp>
29a2d52f12SVijay Khemka #include <sdbusplus/message/types.hpp>
3063c99be4SVijay Khemka 
3163c99be4SVijay Khemka #include <fstream>
3263c99be4SVijay Khemka #include <iomanip>
3363c99be4SVijay Khemka #include <iostream>
3463c99be4SVijay Khemka #include <sstream>
35a2d52f12SVijay Khemka 
36a2d52f12SVijay Khemka namespace ipmi
37a2d52f12SVijay Khemka {
38a2d52f12SVijay Khemka 
39a2d52f12SVijay Khemka static void registerAPPFunctions() __attribute__((constructor));
40a2d52f12SVijay Khemka static constexpr size_t GUID_SIZE = 16;
41a2d52f12SVijay Khemka // TODO Make offset and location runtime configurable to ensure we
42a2d52f12SVijay Khemka // can make each define their own locations.
43a2d52f12SVijay Khemka static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
44a2d52f12SVijay Khemka static constexpr const char* FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
45666a4d95SVijay Khemka 
46666a4d95SVijay Khemka // TODO: Need to store this info after identifying proper storage
47a2d52f12SVijay Khemka static uint8_t globEna = 0x09;
48666a4d95SVijay Khemka static SysInfoParam sysInfoParams;
49802ccb11SVijay Khemka nlohmann::json appData __attribute__((init_priority(101)));
50a2d52f12SVijay Khemka 
515f8e3435SManikandan Elumalai int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
525f8e3435SManikandan Elumalai                std::vector<uint8_t>&);
535f8e3435SManikandan Elumalai 
54e9baaff1SBonnie Lo static inline auto responseSystemInfoParamterNotSupportCommand()
55e9baaff1SBonnie Lo {
56e9baaff1SBonnie Lo     return response(IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED);
57e9baaff1SBonnie Lo }
58e9baaff1SBonnie Lo 
59a2d52f12SVijay Khemka void printGUID(uint8_t* guid, off_t offset)
60a2d52f12SVijay Khemka {
61a2d52f12SVijay Khemka     std::cout << "Read GUID from offset : " << offset << " :\n";
62e39f9393SWilly Tu     for (size_t i = 0; i < GUID_SIZE; i++)
63a2d52f12SVijay Khemka     {
64a2d52f12SVijay Khemka         int data = guid[i];
65a2d52f12SVijay Khemka         std::cout << std::hex << data << " ";
66a2d52f12SVijay Khemka     }
67a2d52f12SVijay Khemka     std::cout << std::endl;
68a2d52f12SVijay Khemka }
69a2d52f12SVijay Khemka 
70a2d52f12SVijay Khemka int getGUID(off_t offset, uint8_t* guid)
71a2d52f12SVijay Khemka {
72a2d52f12SVijay Khemka     int fd = -1;
73a2d52f12SVijay Khemka     ssize_t bytes_rd;
74a2d52f12SVijay Khemka     int ret = 0;
75a2d52f12SVijay Khemka 
76a2d52f12SVijay Khemka     errno = 0;
77a2d52f12SVijay Khemka 
78a2d52f12SVijay Khemka     // Check if file is present
79a2d52f12SVijay Khemka     if (access(FRU_EEPROM, F_OK) == -1)
80a2d52f12SVijay Khemka     {
81a2d52f12SVijay Khemka         std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
82a2d52f12SVijay Khemka         return errno;
83a2d52f12SVijay Khemka     }
84a2d52f12SVijay Khemka 
85a2d52f12SVijay Khemka     // Open the file
86a2d52f12SVijay Khemka     fd = open(FRU_EEPROM, O_RDONLY);
87a2d52f12SVijay Khemka     if (fd == -1)
88a2d52f12SVijay Khemka     {
89a2d52f12SVijay Khemka         std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
90a2d52f12SVijay Khemka         return errno;
91a2d52f12SVijay Khemka     }
92a2d52f12SVijay Khemka 
93a2d52f12SVijay Khemka     // seek to the offset
94a2d52f12SVijay Khemka     lseek(fd, offset, SEEK_SET);
95a2d52f12SVijay Khemka 
96a2d52f12SVijay Khemka     // Read bytes from location
97a2d52f12SVijay Khemka     bytes_rd = read(fd, guid, GUID_SIZE);
98a2d52f12SVijay Khemka     if (bytes_rd != GUID_SIZE)
99a2d52f12SVijay Khemka     {
100a2d52f12SVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
101a2d52f12SVijay Khemka             "GUID read data from EEPROM failed");
102a2d52f12SVijay Khemka         ret = errno;
103a2d52f12SVijay Khemka     }
104a2d52f12SVijay Khemka     else
105a2d52f12SVijay Khemka     {
106a2d52f12SVijay Khemka         printGUID(guid, offset);
107a2d52f12SVijay Khemka     }
108a2d52f12SVijay Khemka     close(fd);
109a2d52f12SVijay Khemka     return ret;
110a2d52f12SVijay Khemka }
111a2d52f12SVijay Khemka 
112a2d52f12SVijay Khemka int getSystemGUID(uint8_t* guid)
113a2d52f12SVijay Khemka {
114a2d52f12SVijay Khemka     return getGUID(OFFSET_SYS_GUID, guid);
115a2d52f12SVijay Khemka }
116a2d52f12SVijay Khemka 
117a2d52f12SVijay Khemka //----------------------------------------------------------------------
118666a4d95SVijay Khemka // Get Self Test Results (IPMI/Section 20.4) (CMD_APP_GET_SELFTEST_RESULTS)
119666a4d95SVijay Khemka //----------------------------------------------------------------------
120e39f9393SWilly Tu ipmi_ret_t ipmiAppGetSTResults(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
121e39f9393SWilly Tu                                ipmi_response_t response,
122e39f9393SWilly Tu                                ipmi_data_len_t data_len, ipmi_context_t)
123666a4d95SVijay Khemka {
124666a4d95SVijay Khemka     uint8_t* res = reinterpret_cast<uint8_t*>(response);
125666a4d95SVijay Khemka 
126666a4d95SVijay Khemka     // TODO: Following data needs to be updated based on self-test results
127666a4d95SVijay Khemka     *res++ = 0x55; // Self-Test result
128666a4d95SVijay Khemka     *res++ = 0x00; // Extra error info in case of failure
129666a4d95SVijay Khemka 
130666a4d95SVijay Khemka     *data_len = 2;
131666a4d95SVijay Khemka 
132666a4d95SVijay Khemka     return IPMI_CC_OK;
133666a4d95SVijay Khemka }
134666a4d95SVijay Khemka 
135666a4d95SVijay Khemka //----------------------------------------------------------------------
136666a4d95SVijay Khemka // Manufacturing Test On (IPMI/Section 20.5) (CMD_APP_MFR_TEST_ON)
137666a4d95SVijay Khemka //----------------------------------------------------------------------
138e39f9393SWilly Tu ipmi_ret_t ipmiAppMfrTestOn(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
139e39f9393SWilly Tu                             ipmi_response_t, ipmi_data_len_t data_len,
140e39f9393SWilly Tu                             ipmi_context_t)
141666a4d95SVijay Khemka {
142666a4d95SVijay Khemka     uint8_t* req = reinterpret_cast<uint8_t*>(request);
143666a4d95SVijay Khemka     std::string mfrTest = "sled-cycle";
14435208459SPatrick Williams     ipmi_ret_t rc = IPMI_CC_OK;
145666a4d95SVijay Khemka 
146666a4d95SVijay Khemka     if (!memcmp(req, mfrTest.data(), mfrTest.length()) &&
147666a4d95SVijay Khemka         (*data_len == mfrTest.length()))
148666a4d95SVijay Khemka     {
149666a4d95SVijay Khemka         /* sled-cycle the BMC */
15035208459SPatrick Williams         auto ret = system("/usr/sbin/power-util sled-cycle");
15135208459SPatrick Williams         if (ret)
15235208459SPatrick Williams         {
15335208459SPatrick Williams             rc = IPMI_CC_UNSPECIFIED_ERROR;
15435208459SPatrick Williams         }
155666a4d95SVijay Khemka     }
156666a4d95SVijay Khemka     else
157666a4d95SVijay Khemka     {
15835208459SPatrick Williams         rc = IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED;
159666a4d95SVijay Khemka     }
160666a4d95SVijay Khemka 
161666a4d95SVijay Khemka     *data_len = 0;
162666a4d95SVijay Khemka 
16335208459SPatrick Williams     return rc;
164666a4d95SVijay Khemka }
165666a4d95SVijay Khemka 
166666a4d95SVijay Khemka //----------------------------------------------------------------------
167a2d52f12SVijay Khemka // Set Global Enables (CMD_APP_SET_GLOBAL_ENABLES)
168a2d52f12SVijay Khemka //----------------------------------------------------------------------
169e39f9393SWilly Tu ipmi_ret_t ipmiAppSetGlobalEnables(ipmi_netfn_t, ipmi_cmd_t,
170e39f9393SWilly Tu                                    ipmi_request_t request, ipmi_response_t,
171e39f9393SWilly Tu                                    ipmi_data_len_t data_len, ipmi_context_t)
172a2d52f12SVijay Khemka {
173a2d52f12SVijay Khemka     uint8_t* req = reinterpret_cast<uint8_t*>(request);
174a2d52f12SVijay Khemka 
175a2d52f12SVijay Khemka     globEna = *req;
176a2d52f12SVijay Khemka     *data_len = 0;
177a2d52f12SVijay Khemka 
178a2d52f12SVijay Khemka     return IPMI_CC_OK;
179a2d52f12SVijay Khemka }
180a2d52f12SVijay Khemka 
181a2d52f12SVijay Khemka //----------------------------------------------------------------------
182a2d52f12SVijay Khemka // Get Global Enables (CMD_APP_GET_GLOBAL_ENABLES)
183a2d52f12SVijay Khemka //----------------------------------------------------------------------
184e39f9393SWilly Tu ipmi_ret_t ipmiAppGetGlobalEnables(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
185a2d52f12SVijay Khemka                                    ipmi_response_t response,
186e39f9393SWilly Tu                                    ipmi_data_len_t data_len, ipmi_context_t)
187a2d52f12SVijay Khemka {
188a2d52f12SVijay Khemka     uint8_t* res = reinterpret_cast<uint8_t*>(response);
189a2d52f12SVijay Khemka 
190a2d52f12SVijay Khemka     *data_len = 1;
191a2d52f12SVijay Khemka     *res++ = globEna;
192a2d52f12SVijay Khemka 
193a2d52f12SVijay Khemka     return IPMI_CC_OK;
194a2d52f12SVijay Khemka }
195a2d52f12SVijay Khemka 
196a2d52f12SVijay Khemka //----------------------------------------------------------------------
197666a4d95SVijay Khemka // Clear Message flags (IPMI/Section 22.3) (CMD_APP_CLEAR_MESSAGE_FLAGS)
198666a4d95SVijay Khemka //----------------------------------------------------------------------
199e39f9393SWilly Tu ipmi_ret_t ipmiAppClearMsgFlags(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
200e39f9393SWilly Tu                                 ipmi_response_t, ipmi_data_len_t data_len,
201e39f9393SWilly Tu                                 ipmi_context_t)
202666a4d95SVijay Khemka {
203666a4d95SVijay Khemka     // Do Nothing and just return success
204666a4d95SVijay Khemka     *data_len = 0;
205666a4d95SVijay Khemka 
206666a4d95SVijay Khemka     return IPMI_CC_OK;
207666a4d95SVijay Khemka }
208666a4d95SVijay Khemka 
209666a4d95SVijay Khemka //----------------------------------------------------------------------
210a2d52f12SVijay Khemka // Get System GUID (CMD_APP_GET_SYS_GUID)
211a2d52f12SVijay Khemka //----------------------------------------------------------------------
2125f8e3435SManikandan Elumalai #if BIC_ENABLED
2135f8e3435SManikandan Elumalai ipmi::RspType<std::vector<uint8_t>>
2145f8e3435SManikandan Elumalai     ipmiAppGetSysGUID(ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
2155f8e3435SManikandan Elumalai 
2165f8e3435SManikandan Elumalai {
2175f8e3435SManikandan Elumalai     std::vector<uint8_t> respData;
2185f8e3435SManikandan Elumalai 
2195f8e3435SManikandan Elumalai     uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
2205f8e3435SManikandan Elumalai 
2215f8e3435SManikandan Elumalai     if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
2225f8e3435SManikandan Elumalai         return ipmi::responseUnspecifiedError();
2235f8e3435SManikandan Elumalai 
2245f8e3435SManikandan Elumalai     return ipmi::responseSuccess(respData);
2255f8e3435SManikandan Elumalai }
2265f8e3435SManikandan Elumalai 
2275f8e3435SManikandan Elumalai #else
228e39f9393SWilly Tu ipmi_ret_t ipmiAppGetSysGUID(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
229e39f9393SWilly Tu                              ipmi_response_t response, ipmi_data_len_t data_len,
230e39f9393SWilly Tu                              ipmi_context_t)
231a2d52f12SVijay Khemka {
232a2d52f12SVijay Khemka     uint8_t* res = reinterpret_cast<uint8_t*>(response);
233a2d52f12SVijay Khemka     if (getSystemGUID(res))
234a2d52f12SVijay Khemka     {
235a2d52f12SVijay Khemka         return IPMI_CC_UNSPECIFIED_ERROR;
236a2d52f12SVijay Khemka     }
237a2d52f12SVijay Khemka     *data_len = GUID_SIZE;
238a2d52f12SVijay Khemka     return IPMI_CC_OK;
239a2d52f12SVijay Khemka }
240a2d52f12SVijay Khemka 
2415f8e3435SManikandan Elumalai #endif
2425f8e3435SManikandan Elumalai 
243666a4d95SVijay Khemka //----------------------------------------------------------------------
244666a4d95SVijay Khemka // Platform specific functions for storing app data
245666a4d95SVijay Khemka //----------------------------------------------------------------------
246666a4d95SVijay Khemka 
247666a4d95SVijay Khemka void flush_app_data()
248666a4d95SVijay Khemka {
249802ccb11SVijay Khemka     std::ofstream file(JSON_APP_DATA_FILE);
250666a4d95SVijay Khemka     file << appData;
251802ccb11SVijay Khemka     file.close();
252666a4d95SVijay Khemka     return;
253666a4d95SVijay Khemka }
254666a4d95SVijay Khemka 
255e9baaff1SBonnie Lo static int platSetSysFWVer(uint8_t* ver, const std::string key)
256666a4d95SVijay Khemka {
257666a4d95SVijay Khemka     std::stringstream ss;
258666a4d95SVijay Khemka     int i;
259666a4d95SVijay Khemka 
260666a4d95SVijay Khemka     /* TODO: implement byte 1: Set selector
261666a4d95SVijay Khemka      * byte 2: encodeing, currently only supported
262666a4d95SVijay Khemka      * ASCII which is value 0, UTF and unicode are
263666a4d95SVijay Khemka      * not supported yet.
264666a4d95SVijay Khemka      */
265666a4d95SVijay Khemka     if (ver[1] & 0x0f)
266666a4d95SVijay Khemka         return -1;
267666a4d95SVijay Khemka 
268666a4d95SVijay Khemka     for (i = 3; i < 3 + ver[2]; i++)
269666a4d95SVijay Khemka     {
270666a4d95SVijay Khemka         ss << (char)ver[i];
271666a4d95SVijay Khemka     }
272666a4d95SVijay Khemka 
273e9baaff1SBonnie Lo     appData[key] = ss.str();
274666a4d95SVijay Khemka     flush_app_data();
275666a4d95SVijay Khemka 
276666a4d95SVijay Khemka     return 0;
277666a4d95SVijay Khemka }
278666a4d95SVijay Khemka 
279e9baaff1SBonnie Lo static int platGetSysFWVer(std::vector<uint8_t>& respData,
280e9baaff1SBonnie Lo                            const std::string key)
281666a4d95SVijay Khemka {
282e9baaff1SBonnie Lo     int len = -1;
283666a4d95SVijay Khemka 
284e9baaff1SBonnie Lo     if (!appData.contains(std::string(key)))
285e9baaff1SBonnie Lo     {
286e9baaff1SBonnie Lo         return -1;
287e9baaff1SBonnie Lo     }
288e9baaff1SBonnie Lo     std::string str = appData[key].get<std::string>();
289e9baaff1SBonnie Lo 
290e9baaff1SBonnie Lo     respData.push_back(0); // byte 1: Set selector not supported
291e9baaff1SBonnie Lo     respData.push_back(0); // byte 2: Only ASCII supported
292666a4d95SVijay Khemka 
293666a4d95SVijay Khemka     len = str.length();
294e9baaff1SBonnie Lo     respData.push_back(len); // byte 3: Size of version
295e9baaff1SBonnie Lo 
296e9baaff1SBonnie Lo     for (auto c : str)
297e9baaff1SBonnie Lo     {
298e9baaff1SBonnie Lo         respData.push_back(c);
299e9baaff1SBonnie Lo     }
300e9baaff1SBonnie Lo 
301e9baaff1SBonnie Lo     // Remaining byte fill to 0
302e9baaff1SBonnie Lo     for (int i = 0; i < SIZE_SYSFW_VER - (len + 3); i++)
303e9baaff1SBonnie Lo     {
304e9baaff1SBonnie Lo         respData.push_back(0);
305e9baaff1SBonnie Lo     }
306666a4d95SVijay Khemka 
307666a4d95SVijay Khemka     return (len + 3);
308666a4d95SVijay Khemka }
309666a4d95SVijay Khemka 
310666a4d95SVijay Khemka //----------------------------------------------------------------------
311666a4d95SVijay Khemka // Set Sys Info Params (IPMI/Sec 22.14a) (CMD_APP_SET_SYS_INFO_PARAMS)
312666a4d95SVijay Khemka //----------------------------------------------------------------------
313e9baaff1SBonnie Lo ipmi::RspType<uint8_t> ipmiAppSetSysInfoParams(ipmi::Context::ptr ctx,
314e9baaff1SBonnie Lo                                                std::vector<uint8_t> req)
315666a4d95SVijay Khemka {
316666a4d95SVijay Khemka     uint8_t param = req[0];
317e9baaff1SBonnie Lo     uint8_t req_len = req.size();
318e9baaff1SBonnie Lo     std::optional<size_t> hostId = findHost(ctx->hostIdx);
319666a4d95SVijay Khemka 
320e9baaff1SBonnie Lo     if (!hostId)
321e9baaff1SBonnie Lo     {
322e9baaff1SBonnie Lo         phosphor::logging::log<phosphor::logging::level::ERR>(
323e9baaff1SBonnie Lo             "Invalid Host Id received");
324e9baaff1SBonnie Lo         return ipmi::responseInvalidCommand();
325e9baaff1SBonnie Lo     }
326666a4d95SVijay Khemka 
327666a4d95SVijay Khemka     switch (param)
328666a4d95SVijay Khemka     {
329666a4d95SVijay Khemka         case SYS_INFO_PARAM_SET_IN_PROG:
330666a4d95SVijay Khemka             sysInfoParams.set_in_prog = req[1];
331666a4d95SVijay Khemka             break;
332666a4d95SVijay Khemka         case SYS_INFO_PARAM_SYSFW_VER:
333e9baaff1SBonnie Lo         {
334666a4d95SVijay Khemka             memcpy(sysInfoParams.sysfw_ver, &req[1], SIZE_SYSFW_VER);
335e9baaff1SBonnie Lo             std::string version_key = KEY_SYSFW_VER + std::to_string(*hostId);
336e9baaff1SBonnie Lo             if (platSetSysFWVer(sysInfoParams.sysfw_ver, version_key))
337e9baaff1SBonnie Lo                 return ipmi::responseSystemInfoParamterNotSupportCommand();
338666a4d95SVijay Khemka             break;
339e9baaff1SBonnie Lo         }
340666a4d95SVijay Khemka         case SYS_INFO_PARAM_SYS_NAME:
341666a4d95SVijay Khemka             memcpy(sysInfoParams.sys_name, &req[1], SIZE_SYS_NAME);
342666a4d95SVijay Khemka             break;
343666a4d95SVijay Khemka         case SYS_INFO_PARAM_PRI_OS_NAME:
344666a4d95SVijay Khemka             memcpy(sysInfoParams.pri_os_name, &req[1], SIZE_OS_NAME);
345666a4d95SVijay Khemka             break;
346666a4d95SVijay Khemka         case SYS_INFO_PARAM_PRESENT_OS_NAME:
347666a4d95SVijay Khemka             memcpy(sysInfoParams.present_os_name, &req[1], SIZE_OS_NAME);
348666a4d95SVijay Khemka             break;
349666a4d95SVijay Khemka         case SYS_INFO_PARAM_PRESENT_OS_VER:
350666a4d95SVijay Khemka             memcpy(sysInfoParams.present_os_ver, &req[1], SIZE_OS_VER);
351666a4d95SVijay Khemka             break;
352666a4d95SVijay Khemka         case SYS_INFO_PARAM_BMC_URL:
353666a4d95SVijay Khemka             memcpy(sysInfoParams.bmc_url, &req[1], SIZE_BMC_URL);
354666a4d95SVijay Khemka             break;
355666a4d95SVijay Khemka         case SYS_INFO_PARAM_OS_HV_URL:
356666a4d95SVijay Khemka             memcpy(sysInfoParams.os_hv_url, &req[1], SIZE_OS_HV_URL);
357666a4d95SVijay Khemka             break;
358666a4d95SVijay Khemka         case SYS_INFO_PARAM_BIOS_CURRENT_BOOT_LIST:
359666a4d95SVijay Khemka             memcpy(sysInfoParams.bios_current_boot_list, &req[1], req_len);
360666a4d95SVijay Khemka             appData[KEY_BIOS_BOOT_LEN] = req_len;
361666a4d95SVijay Khemka             flush_app_data();
362666a4d95SVijay Khemka             break;
363666a4d95SVijay Khemka         case SYS_INFO_PARAM_BIOS_FIXED_BOOT_DEVICE:
364666a4d95SVijay Khemka             if (SIZE_BIOS_FIXED_BOOT_DEVICE != req_len)
365666a4d95SVijay Khemka                 break;
366666a4d95SVijay Khemka             memcpy(sysInfoParams.bios_fixed_boot_device, &req[1],
367666a4d95SVijay Khemka                    SIZE_BIOS_FIXED_BOOT_DEVICE);
368666a4d95SVijay Khemka             break;
369666a4d95SVijay Khemka         case SYS_INFO_PARAM_BIOS_RSTR_DFLT_SETTING:
370666a4d95SVijay Khemka             if (SIZE_BIOS_RSTR_DFLT_SETTING != req_len)
371666a4d95SVijay Khemka                 break;
372666a4d95SVijay Khemka             memcpy(sysInfoParams.bios_rstr_dflt_setting, &req[1],
373666a4d95SVijay Khemka                    SIZE_BIOS_RSTR_DFLT_SETTING);
374666a4d95SVijay Khemka             break;
375666a4d95SVijay Khemka         case SYS_INFO_PARAM_LAST_BOOT_TIME:
376666a4d95SVijay Khemka             if (SIZE_LAST_BOOT_TIME != req_len)
377666a4d95SVijay Khemka                 break;
378666a4d95SVijay Khemka             memcpy(sysInfoParams.last_boot_time, &req[1], SIZE_LAST_BOOT_TIME);
379666a4d95SVijay Khemka             break;
380666a4d95SVijay Khemka         default:
381e9baaff1SBonnie Lo             return ipmi::responseSystemInfoParamterNotSupportCommand();
382666a4d95SVijay Khemka             break;
383666a4d95SVijay Khemka     }
384666a4d95SVijay Khemka 
385e9baaff1SBonnie Lo     return ipmi::responseSuccess();
386666a4d95SVijay Khemka }
387666a4d95SVijay Khemka 
388666a4d95SVijay Khemka //----------------------------------------------------------------------
389666a4d95SVijay Khemka // Get Sys Info Params (IPMI/Sec 22.14b) (CMD_APP_GET_SYS_INFO_PARAMS)
390666a4d95SVijay Khemka //----------------------------------------------------------------------
391e9baaff1SBonnie Lo ipmi::RspType<std::vector<uint8_t>>
392e9baaff1SBonnie Lo     ipmiAppGetSysInfoParams(ipmi::Context::ptr ctx, uint8_t, uint8_t param,
393e9baaff1SBonnie Lo                             uint8_t, uint8_t)
394666a4d95SVijay Khemka {
395e39f9393SWilly Tu     int len;
396e9baaff1SBonnie Lo     std::vector<uint8_t> respData;
397e9baaff1SBonnie Lo     respData.push_back(1); // Parameter revision
398666a4d95SVijay Khemka 
399e9baaff1SBonnie Lo     std::optional<size_t> hostId = findHost(ctx->hostIdx);
400e9baaff1SBonnie Lo 
401e9baaff1SBonnie Lo     if (!hostId)
402e9baaff1SBonnie Lo     {
403e9baaff1SBonnie Lo         phosphor::logging::log<phosphor::logging::level::ERR>(
404e9baaff1SBonnie Lo             "Invalid Host Id received");
405e9baaff1SBonnie Lo         return ipmi::responseInvalidCommand();
406e9baaff1SBonnie Lo     }
407666a4d95SVijay Khemka 
408666a4d95SVijay Khemka     switch (param)
409666a4d95SVijay Khemka     {
410666a4d95SVijay Khemka         case SYS_INFO_PARAM_SET_IN_PROG:
411e9baaff1SBonnie Lo             respData.push_back(sysInfoParams.set_in_prog);
412666a4d95SVijay Khemka             break;
413666a4d95SVijay Khemka         case SYS_INFO_PARAM_SYSFW_VER:
414e9baaff1SBonnie Lo         {
415e9baaff1SBonnie Lo             std::string version_key = KEY_SYSFW_VER + std::to_string(*hostId);
416e9baaff1SBonnie Lo             if ((platGetSysFWVer(respData, version_key)) < 0)
417e9baaff1SBonnie Lo                 return ipmi::responseSystemInfoParamterNotSupportCommand();
418666a4d95SVijay Khemka             break;
419e9baaff1SBonnie Lo         }
420666a4d95SVijay Khemka         case SYS_INFO_PARAM_SYS_NAME:
421e9baaff1SBonnie Lo             respData.insert(respData.end(), std::begin(sysInfoParams.sys_name),
422e9baaff1SBonnie Lo                             std::end(sysInfoParams.sys_name));
423666a4d95SVijay Khemka             break;
424666a4d95SVijay Khemka         case SYS_INFO_PARAM_PRI_OS_NAME:
425e9baaff1SBonnie Lo             respData.insert(respData.end(),
426e9baaff1SBonnie Lo                             std::begin(sysInfoParams.pri_os_name),
427e9baaff1SBonnie Lo                             std::end(sysInfoParams.pri_os_name));
428666a4d95SVijay Khemka             break;
429666a4d95SVijay Khemka         case SYS_INFO_PARAM_PRESENT_OS_NAME:
430e9baaff1SBonnie Lo             respData.insert(respData.end(),
431e9baaff1SBonnie Lo                             std::begin(sysInfoParams.present_os_name),
432e9baaff1SBonnie Lo                             std::end(sysInfoParams.present_os_name));
433666a4d95SVijay Khemka             break;
434666a4d95SVijay Khemka         case SYS_INFO_PARAM_PRESENT_OS_VER:
435e9baaff1SBonnie Lo             respData.insert(respData.end(),
436e9baaff1SBonnie Lo                             std::begin(sysInfoParams.present_os_ver),
437e9baaff1SBonnie Lo                             std::end(sysInfoParams.present_os_ver));
438666a4d95SVijay Khemka             break;
439666a4d95SVijay Khemka         case SYS_INFO_PARAM_BMC_URL:
440e9baaff1SBonnie Lo             respData.insert(respData.end(), std::begin(sysInfoParams.bmc_url),
441e9baaff1SBonnie Lo                             std::end(sysInfoParams.bmc_url));
442666a4d95SVijay Khemka             break;
443666a4d95SVijay Khemka         case SYS_INFO_PARAM_OS_HV_URL:
444e9baaff1SBonnie Lo             respData.insert(respData.end(), std::begin(sysInfoParams.os_hv_url),
445e9baaff1SBonnie Lo                             std::end(sysInfoParams.os_hv_url));
446666a4d95SVijay Khemka             break;
447666a4d95SVijay Khemka         case SYS_INFO_PARAM_BIOS_CURRENT_BOOT_LIST:
448666a4d95SVijay Khemka             len = appData[KEY_BIOS_BOOT_LEN].get<uint8_t>();
449e9baaff1SBonnie Lo             respData.insert(respData.end(),
450e9baaff1SBonnie Lo                             std::begin(sysInfoParams.bios_current_boot_list),
451e9baaff1SBonnie Lo                             std::begin(sysInfoParams.bios_current_boot_list) +
452e9baaff1SBonnie Lo                                 len);
453666a4d95SVijay Khemka             break;
454666a4d95SVijay Khemka         case SYS_INFO_PARAM_BIOS_FIXED_BOOT_DEVICE:
455e9baaff1SBonnie Lo             respData.insert(respData.end(),
456e9baaff1SBonnie Lo                             std::begin(sysInfoParams.bios_fixed_boot_device),
457e9baaff1SBonnie Lo                             std::end(sysInfoParams.bios_fixed_boot_device));
458666a4d95SVijay Khemka             break;
459666a4d95SVijay Khemka         case SYS_INFO_PARAM_BIOS_RSTR_DFLT_SETTING:
460e9baaff1SBonnie Lo             respData.insert(respData.end(),
461e9baaff1SBonnie Lo                             std::begin(sysInfoParams.bios_rstr_dflt_setting),
462e9baaff1SBonnie Lo                             std::end(sysInfoParams.bios_rstr_dflt_setting));
463666a4d95SVijay Khemka             break;
464666a4d95SVijay Khemka         case SYS_INFO_PARAM_LAST_BOOT_TIME:
465e9baaff1SBonnie Lo             respData.insert(respData.end(),
466e9baaff1SBonnie Lo                             std::begin(sysInfoParams.last_boot_time),
467e9baaff1SBonnie Lo                             std::end(sysInfoParams.last_boot_time));
468666a4d95SVijay Khemka             break;
469666a4d95SVijay Khemka         default:
470e9baaff1SBonnie Lo             return ipmi::responseSystemInfoParamterNotSupportCommand();
471666a4d95SVijay Khemka             break;
472666a4d95SVijay Khemka     }
473e9baaff1SBonnie Lo 
474e9baaff1SBonnie Lo     return ipmi::responseSuccess(respData);
475666a4d95SVijay Khemka }
476666a4d95SVijay Khemka 
477a2d52f12SVijay Khemka void registerAPPFunctions()
478a2d52f12SVijay Khemka {
479666a4d95SVijay Khemka     /* Get App data stored in json file */
480802ccb11SVijay Khemka     std::ifstream file(JSON_APP_DATA_FILE);
481666a4d95SVijay Khemka     if (file)
482802ccb11SVijay Khemka     {
483666a4d95SVijay Khemka         file >> appData;
484802ccb11SVijay Khemka         file.close();
485802ccb11SVijay Khemka     }
486666a4d95SVijay Khemka 
487666a4d95SVijay Khemka     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SELFTEST_RESULTS, NULL,
488666a4d95SVijay Khemka                          ipmiAppGetSTResults,
489666a4d95SVijay Khemka                          PRIVILEGE_USER); // Get Self Test Results
490666a4d95SVijay Khemka     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_MFR_TEST_ON, NULL,
491666a4d95SVijay Khemka                          ipmiAppMfrTestOn,
492666a4d95SVijay Khemka                          PRIVILEGE_USER); // Manufacturing Test On
493a2d52f12SVijay Khemka     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_SET_GLOBAL_ENABLES, NULL,
494a2d52f12SVijay Khemka                          ipmiAppSetGlobalEnables,
495666a4d95SVijay Khemka                          PRIVILEGE_USER); // Set Global Enables
496a2d52f12SVijay Khemka     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_GLOBAL_ENABLES, NULL,
497a2d52f12SVijay Khemka                          ipmiAppGetGlobalEnables,
498a2d52f12SVijay Khemka                          PRIVILEGE_USER); // Get Global Enables
499666a4d95SVijay Khemka     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_CLEAR_MESSAGE_FLAGS, NULL,
500666a4d95SVijay Khemka                          ipmiAppClearMsgFlags,
501666a4d95SVijay Khemka                          PRIVILEGE_USER); // Clear Message flags
5025f8e3435SManikandan Elumalai #if BIC_ENABLED
5035f8e3435SManikandan Elumalai     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
5045f8e3435SManikandan Elumalai                           ipmi::app::cmdGetSystemGuid, ipmi::Privilege::User,
5055f8e3435SManikandan Elumalai                           ipmiAppGetSysGUID);
5065f8e3435SManikandan Elumalai #else
507a2d52f12SVijay Khemka     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SYS_GUID, NULL,
508a2d52f12SVijay Khemka                          ipmiAppGetSysGUID,
509a2d52f12SVijay Khemka                          PRIVILEGE_USER); // Get System GUID
5105f8e3435SManikandan Elumalai #endif
511e9baaff1SBonnie Lo     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
512e9baaff1SBonnie Lo                           ipmi::app::cmdSetSystemInfoParameters,
513e9baaff1SBonnie Lo                           ipmi::Privilege::User, ipmiAppSetSysInfoParams);
514e9baaff1SBonnie Lo 
515e9baaff1SBonnie Lo     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
516e9baaff1SBonnie Lo                           ipmi::app::cmdGetSystemInfoParameters,
517e9baaff1SBonnie Lo                           ipmi::Privilege::User, ipmiAppGetSysInfoParams);
518a2d52f12SVijay Khemka     return;
519a2d52f12SVijay Khemka }
520a2d52f12SVijay Khemka 
521a2d52f12SVijay Khemka } // namespace ipmi
522