blob: 2a2d2d160cfb92f8cfc9adc20db5cf61d390c68d [file] [log] [blame]
Patrick Venturec9508db2018-10-16 17:18:43 -07001#include "writefrudata.hpp"
2
vishwa13555bd2015-11-10 12:10:38 -06003#include <unistd.h>
vishwa13555bd2015-11-10 12:10:38 -06004
George Liu1c629542025-04-03 10:23:47 +08005#include <ipmid/api-types.hpp>
George Liud3b84a72025-08-02 10:23:52 +08006#include <ipmid/handler.hpp>
George Liu98de42a2025-07-30 09:54:21 +08007#include <phosphor-logging/lg2.hpp>
Patrick Venturea8093a22018-10-21 09:07:11 -07008#include <sdbusplus/bus.hpp>
Patrick Venture6cd51352018-10-17 13:26:06 -07009
Patrick Williamscfa96af2023-05-10 07:50:26 -050010#include <cstdio>
11#include <cstring>
12
George Liueed09532025-07-30 10:28:03 +080013void registerNetFnStorageWriteFru() __attribute__((constructor));
vishwa13555bd2015-11-10 12:10:38 -060014
15sd_bus* ipmid_get_sd_bus_connection(void);
16
17///-------------------------------------------------------
18// Called by IPMI netfn router for write fru data command
19//--------------------------------------------------------
George Liud3b84a72025-08-02 10:23:52 +080020ipmi::RspType<uint8_t> ipmiStorageWriteFruData(uint8_t fruId, uint16_t offset,
21 std::vector<uint8_t>& buffer)
vishwa13555bd2015-11-10 12:10:38 -060022{
Jayanth Othayoth883aa422024-12-18 10:33:06 -060023 FILE* fp = nullptr;
Patrick Ventureb25fb9f2018-10-21 12:35:03 -070024 char fruFilename[16] = {0};
George Liud3b84a72025-08-02 10:23:52 +080025 const char* mode = "rb+";
vishwa13555bd2015-11-10 12:10:38 -060026
27 // Maintaining a temporary file to pump the data
George Liud3b84a72025-08-02 10:23:52 +080028 std::sprintf(fruFilename, "%s%02x", "/tmp/ipmifru", fruId);
vishwac93d6d42015-12-16 11:55:16 -060029
George Liu98de42a2025-07-30 09:54:21 +080030 lg2::debug(
31 "IPMI WRITE-FRU-DATA, file name: {FILE}, offset: {OFFSET}, length: {LENGTH}",
George Liud3b84a72025-08-02 10:23:52 +080032 "FILE", fruFilename, "OFFSET", offset, "LENGTH", buffer.size());
vishwa13555bd2015-11-10 12:10:38 -060033
Patrick Ventureb25fb9f2018-10-21 12:35:03 -070034 if (access(fruFilename, F_OK) == -1)
Patrick Venturec9508db2018-10-16 17:18:43 -070035 {
vishwa13555bd2015-11-10 12:10:38 -060036 mode = "wb";
Patrick Venturec9508db2018-10-16 17:18:43 -070037 }
vishwa13555bd2015-11-10 12:10:38 -060038
Jayanth Othayoth883aa422024-12-18 10:33:06 -060039 if ((fp = std::fopen(fruFilename, mode)) != nullptr)
vishwa13555bd2015-11-10 12:10:38 -060040 {
Patrick Venture6cd51352018-10-17 13:26:06 -070041 if (std::fseek(fp, offset, SEEK_SET))
vishwa13555bd2015-11-10 12:10:38 -060042 {
George Liu98de42a2025-07-30 09:54:21 +080043 lg2::error(
44 "Seek into fru file failed, file name: {FILE}, errno: {ERRNO}",
45 "FILE", fruFilename, "ERRNO", errno);
Patrick Venture6cd51352018-10-17 13:26:06 -070046 std::fclose(fp);
George Liud3b84a72025-08-02 10:23:52 +080047
48 return ipmi::responseInvalidFieldRequest();
vishwa13555bd2015-11-10 12:10:38 -060049 }
vishwac93d6d42015-12-16 11:55:16 -060050
George Liud3b84a72025-08-02 10:23:52 +080051 if (std::fwrite(buffer.data(), 1, buffer.size(), fp) != buffer.size())
vishwa13555bd2015-11-10 12:10:38 -060052 {
George Liu98de42a2025-07-30 09:54:21 +080053 lg2::error(
54 "Write into fru file failed, file name: {FILE}, errno: {ERRNO}",
55 "FILE", fruFilename, "ERRNO", errno);
Patrick Venture6cd51352018-10-17 13:26:06 -070056 std::fclose(fp);
George Liud3b84a72025-08-02 10:23:52 +080057
58 return ipmi::responseInvalidFieldRequest();
vishwa13555bd2015-11-10 12:10:38 -060059 }
vishwac93d6d42015-12-16 11:55:16 -060060
Patrick Venture6cd51352018-10-17 13:26:06 -070061 std::fclose(fp);
vishwac93d6d42015-12-16 11:55:16 -060062 }
63 else
vishwa13555bd2015-11-10 12:10:38 -060064 {
George Liu98de42a2025-07-30 09:54:21 +080065 lg2::error("Error trying to write to {FILE}", "FILE", fruFilename);
vishwa13555bd2015-11-10 12:10:38 -060066
George Liud3b84a72025-08-02 10:23:52 +080067 return ipmi::responseInvalidFieldRequest();
68 }
vishwa13555bd2015-11-10 12:10:38 -060069
vishwac93d6d42015-12-16 11:55:16 -060070 // Get the reference to global sd_bus object
Patrick Venturec9508db2018-10-16 17:18:43 -070071 sd_bus* bus_type = ipmid_get_sd_bus_connection();
vishwaf3ca3522015-12-02 10:35:13 -060072
vishwa13555bd2015-11-10 12:10:38 -060073 // We received some bytes. It may be full or partial. Send a valid
74 // FRU file to the inventory controller on DBus for the correct number
Patrick Williams5e8829e2022-07-22 19:26:53 -050075 sdbusplus::bus_t bus{bus_type};
George Liud3b84a72025-08-02 10:23:52 +080076 validateFRUArea(fruId, fruFilename, bus);
vishwa13555bd2015-11-10 12:10:38 -060077
George Liud3b84a72025-08-02 10:23:52 +080078 return ipmi::responseSuccess(buffer.size());
vishwa13555bd2015-11-10 12:10:38 -060079}
80
81//-------------------------------------------------------
82// Registering WRITE FRU DATA command handler with daemon
83//-------------------------------------------------------
George Liueed09532025-07-30 10:28:03 +080084void registerNetFnStorageWriteFru()
vishwa13555bd2015-11-10 12:10:38 -060085{
George Liu98de42a2025-07-30 09:54:21 +080086 lg2::info(
87 "Registering WRITE FRU DATA command handler, netfn:{NETFN}, cmd:{CMD}",
88 "NETFN", lg2::hex, ipmi::netFnStorage, "CMD", lg2::hex,
89 ipmi::storage::cmdWriteFruData);
Patrick Venture6cd51352018-10-17 13:26:06 -070090
George Liud3b84a72025-08-02 10:23:52 +080091 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
92 ipmi::storage::cmdWriteFruData,
93 ipmi::Privilege::Admin, ipmiStorageWriteFruData);
vishwa13555bd2015-11-10 12:10:38 -060094}