blob: 92ceff91b183fb53154f6e25cf1a89a6695fb232 [file] [log] [blame]
Archana Kakanid6b00562024-03-31 17:53:58 -05001#include "file_io_type_pcie.hpp"
2
3#include "libpldm/base.h"
4#include "libpldm/file_io.h"
5
6#include <stdint.h>
7
8#include <phosphor-logging/lg2.hpp>
9
10PHOSPHOR_LOG2_USING;
11
12namespace pldm
13{
14namespace responder
15{
16
17static constexpr auto pciePath = "/var/lib/pldm/pcie-topology/";
18constexpr auto topologyFile = "topology";
19constexpr auto cableInfoFile = "cableinfo";
20
21namespace fs = std::filesystem;
22std::unordered_map<uint16_t, bool> PCIeInfoHandler::receivedFiles;
23
24PCIeInfoHandler::PCIeInfoHandler(uint32_t fileHandle, uint16_t fileType) :
25 FileHandler(fileHandle), infoType(fileType)
26{
27 receivedFiles.emplace(infoType, false);
28}
29
30int PCIeInfoHandler::writeFromMemory(
31 uint32_t offset, uint32_t length, uint64_t address,
32 oem_platform::Handler* /*oemPlatformHandler*/)
33{
34 if (!fs::exists(pciePath))
35 {
36 fs::create_directories(pciePath);
37 fs::permissions(pciePath,
38 fs::perms::others_read | fs::perms::owner_write);
39 }
40
41 fs::path infoFile(fs::path(pciePath) / topologyFile);
42 if (infoType == PLDM_FILE_TYPE_CABLE_INFO)
43 {
44 infoFile = (fs::path(pciePath) / cableInfoFile);
45 }
46
47 try
48 {
49 std::ofstream pcieData(infoFile, std::ios::out | std::ios::binary);
50 auto rc = transferFileData(infoFile, false, offset, length, address);
51 if (rc != PLDM_SUCCESS)
52 {
53 error("TransferFileData failed in PCIeTopology with error {ERROR}",
54 "ERROR", rc);
55 return rc;
56 }
57 return PLDM_SUCCESS;
58 }
59 catch (const std::exception& e)
60 {
61 error("Create/Write data to the File type {TYPE}, failed {ERROR}",
62 "TYPE", (int)infoType, "ERROR", e);
63 return PLDM_ERROR;
64 }
65}
66
67int PCIeInfoHandler::write(const char* buffer, uint32_t, uint32_t& length,
68 oem_platform::Handler* /*oemPlatformHandler*/)
69{
70 fs::path infoFile(fs::path(pciePath) / topologyFile);
71 if (infoType == PLDM_FILE_TYPE_CABLE_INFO)
72 {
73 infoFile = (fs::path(pciePath) / cableInfoFile);
74 }
75
76 try
77 {
78 std::ofstream pcieData(infoFile, std::ios::out | std::ios::binary |
79 std::ios::app);
80
81 if (!buffer)
82 {
83 pcieData.write(buffer, length);
84 }
85 pcieData.close();
86 }
87 catch (const std::exception& e)
88 {
89 error("Create/Write data to the File type {TYPE}, failed {ERROR}",
90 "TYPE", (int)infoType, "ERROR", e);
91 return PLDM_ERROR;
92 }
93
94 return PLDM_SUCCESS;
95}
96
97int PCIeInfoHandler::fileAck(uint8_t /*fileStatus*/)
98{
99 receivedFiles[infoType] = true;
100 try
101 {
102 if (receivedFiles.at(PLDM_FILE_TYPE_CABLE_INFO) &&
103 receivedFiles.at(PLDM_FILE_TYPE_PCIE_TOPOLOGY))
104 {
105 receivedFiles.clear();
106 }
107 }
108 catch (const std::out_of_range& e)
109 {
110 info("Received only one of the topology file");
111 }
112 return PLDM_SUCCESS;
113}
114
115} // namespace responder
116} // namespace pldm