Patrick Venture | c9508db | 2018-10-16 17:18:43 -0700 | [diff] [blame] | 1 | #include "writefrudata.hpp" |
| 2 | |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 3 | #include <unistd.h> |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 4 | |
George Liu | 1c62954 | 2025-04-03 10:23:47 +0800 | [diff] [blame] | 5 | #include <ipmid/api-types.hpp> |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 6 | #include <ipmid/handler.hpp> |
George Liu | 98de42a | 2025-07-30 09:54:21 +0800 | [diff] [blame] | 7 | #include <phosphor-logging/lg2.hpp> |
Patrick Venture | a8093a2 | 2018-10-21 09:07:11 -0700 | [diff] [blame] | 8 | #include <sdbusplus/bus.hpp> |
Patrick Venture | 6cd5135 | 2018-10-17 13:26:06 -0700 | [diff] [blame] | 9 | |
Patrick Williams | cfa96af | 2023-05-10 07:50:26 -0500 | [diff] [blame] | 10 | #include <cstdio> |
| 11 | #include <cstring> |
| 12 | |
George Liu | eed0953 | 2025-07-30 10:28:03 +0800 | [diff] [blame] | 13 | void registerNetFnStorageWriteFru() __attribute__((constructor)); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 14 | |
| 15 | sd_bus* ipmid_get_sd_bus_connection(void); |
| 16 | |
| 17 | ///------------------------------------------------------- |
| 18 | // Called by IPMI netfn router for write fru data command |
| 19 | //-------------------------------------------------------- |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 20 | ipmi::RspType<uint8_t> ipmiStorageWriteFruData(uint8_t fruId, uint16_t offset, |
| 21 | std::vector<uint8_t>& buffer) |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 22 | { |
Jayanth Othayoth | 883aa42 | 2024-12-18 10:33:06 -0600 | [diff] [blame] | 23 | FILE* fp = nullptr; |
Patrick Venture | b25fb9f | 2018-10-21 12:35:03 -0700 | [diff] [blame] | 24 | char fruFilename[16] = {0}; |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 25 | const char* mode = "rb+"; |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 26 | |
| 27 | // Maintaining a temporary file to pump the data |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 28 | std::sprintf(fruFilename, "%s%02x", "/tmp/ipmifru", fruId); |
vishwa | c93d6d4 | 2015-12-16 11:55:16 -0600 | [diff] [blame] | 29 | |
George Liu | 98de42a | 2025-07-30 09:54:21 +0800 | [diff] [blame] | 30 | lg2::debug( |
| 31 | "IPMI WRITE-FRU-DATA, file name: {FILE}, offset: {OFFSET}, length: {LENGTH}", |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 32 | "FILE", fruFilename, "OFFSET", offset, "LENGTH", buffer.size()); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 33 | |
Patrick Venture | b25fb9f | 2018-10-21 12:35:03 -0700 | [diff] [blame] | 34 | if (access(fruFilename, F_OK) == -1) |
Patrick Venture | c9508db | 2018-10-16 17:18:43 -0700 | [diff] [blame] | 35 | { |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 36 | mode = "wb"; |
Patrick Venture | c9508db | 2018-10-16 17:18:43 -0700 | [diff] [blame] | 37 | } |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 38 | |
Jayanth Othayoth | 883aa42 | 2024-12-18 10:33:06 -0600 | [diff] [blame] | 39 | if ((fp = std::fopen(fruFilename, mode)) != nullptr) |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 40 | { |
Patrick Venture | 6cd5135 | 2018-10-17 13:26:06 -0700 | [diff] [blame] | 41 | if (std::fseek(fp, offset, SEEK_SET)) |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 42 | { |
George Liu | 98de42a | 2025-07-30 09:54:21 +0800 | [diff] [blame] | 43 | lg2::error( |
| 44 | "Seek into fru file failed, file name: {FILE}, errno: {ERRNO}", |
| 45 | "FILE", fruFilename, "ERRNO", errno); |
Patrick Venture | 6cd5135 | 2018-10-17 13:26:06 -0700 | [diff] [blame] | 46 | std::fclose(fp); |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 47 | |
| 48 | return ipmi::responseInvalidFieldRequest(); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 49 | } |
vishwa | c93d6d4 | 2015-12-16 11:55:16 -0600 | [diff] [blame] | 50 | |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 51 | if (std::fwrite(buffer.data(), 1, buffer.size(), fp) != buffer.size()) |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 52 | { |
George Liu | 98de42a | 2025-07-30 09:54:21 +0800 | [diff] [blame] | 53 | lg2::error( |
| 54 | "Write into fru file failed, file name: {FILE}, errno: {ERRNO}", |
| 55 | "FILE", fruFilename, "ERRNO", errno); |
Patrick Venture | 6cd5135 | 2018-10-17 13:26:06 -0700 | [diff] [blame] | 56 | std::fclose(fp); |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 57 | |
| 58 | return ipmi::responseInvalidFieldRequest(); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 59 | } |
vishwa | c93d6d4 | 2015-12-16 11:55:16 -0600 | [diff] [blame] | 60 | |
Patrick Venture | 6cd5135 | 2018-10-17 13:26:06 -0700 | [diff] [blame] | 61 | std::fclose(fp); |
vishwa | c93d6d4 | 2015-12-16 11:55:16 -0600 | [diff] [blame] | 62 | } |
| 63 | else |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 64 | { |
George Liu | 98de42a | 2025-07-30 09:54:21 +0800 | [diff] [blame] | 65 | lg2::error("Error trying to write to {FILE}", "FILE", fruFilename); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 66 | |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 67 | return ipmi::responseInvalidFieldRequest(); |
| 68 | } |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 69 | |
vishwa | c93d6d4 | 2015-12-16 11:55:16 -0600 | [diff] [blame] | 70 | // Get the reference to global sd_bus object |
Patrick Venture | c9508db | 2018-10-16 17:18:43 -0700 | [diff] [blame] | 71 | sd_bus* bus_type = ipmid_get_sd_bus_connection(); |
vishwa | f3ca352 | 2015-12-02 10:35:13 -0600 | [diff] [blame] | 72 | |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 73 | // 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 Williams | 5e8829e | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 75 | sdbusplus::bus_t bus{bus_type}; |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 76 | validateFRUArea(fruId, fruFilename, bus); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 77 | |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 78 | return ipmi::responseSuccess(buffer.size()); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | //------------------------------------------------------- |
| 82 | // Registering WRITE FRU DATA command handler with daemon |
| 83 | //------------------------------------------------------- |
George Liu | eed0953 | 2025-07-30 10:28:03 +0800 | [diff] [blame] | 84 | void registerNetFnStorageWriteFru() |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 85 | { |
George Liu | 98de42a | 2025-07-30 09:54:21 +0800 | [diff] [blame] | 86 | 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 Venture | 6cd5135 | 2018-10-17 13:26:06 -0700 | [diff] [blame] | 90 | |
George Liu | d3b84a7 | 2025-08-02 10:23:52 +0800 | [diff] [blame^] | 91 | ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage, |
| 92 | ipmi::storage::cmdWriteFruData, |
| 93 | ipmi::Privilege::Admin, ipmiStorageWriteFruData); |
vishwa | 13555bd | 2015-11-10 12:10:38 -0600 | [diff] [blame] | 94 | } |