blob: 805d0ec1aef341e513841982b7ababc3b7c04b92 [file] [log] [blame]
Pavithra Barithayaa410c652021-07-22 01:32:47 -05001#include "fru_oem_ibm.hpp"
2
3#include <phosphor-logging/lg2.hpp>
4
5#include <ranges>
6
7PHOSPHOR_LOG2_USING;
8
9namespace pldm
10{
11namespace responder
12{
13namespace oem_ibm_fru
14{
15
16void pldm::responder::oem_ibm_fru::Handler::setIBMFruHandler(
17 pldm::responder::fru::Handler* handler)
18{
19 fruHandler = handler;
20}
21
22int pldm::responder::oem_ibm_fru::Handler::processOEMFRUTable(
23 const std::vector<uint8_t>& fruData)
24{
25 uint8_t dataSize = 0;
26 const uint8_t* data = fruData.data();
27
28 while (dataSize < fruData.size())
29 {
30 auto record =
31 reinterpret_cast<const pldm_fru_record_data_format*>(data);
32 if (!record)
33 {
34 return PLDM_ERROR_INVALID_DATA;
35 }
36
37 auto& entityAssociationMap = getAssociateEntityMap();
38 uint16_t fruRSI = le16toh(record->record_set_id);
39
40 dataSize += sizeof(pldm_fru_record_data_format) -
41 sizeof(pldm_fru_record_tlv);
42 data += dataSize;
43
44 for ([[maybe_unused]] const auto& i :
45 std::views::iota(0, (int)record->num_fru_fields))
46 {
47 auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(data);
48 if (!tlv)
49 {
50 return PLDM_ERROR_INVALID_DATA;
51 }
52
53 if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_PCIE_CONFIG_SPACE_DATA)
54 {
55 auto pcieData =
56 reinterpret_cast<const PcieConfigSpaceData*>(tlv->value);
57
58 if (!pcieData)
59 {
60 return PLDM_ERROR_INVALID_DATA;
61 }
62 auto vendorId = std::to_string(htole16(pcieData->vendorId));
63 auto deviceId = std::to_string(htole16(pcieData->deviceId));
64 auto revisionId = std::to_string(pcieData->revisionId);
65
66 std::stringstream ss;
67
68 for (const auto& ele : pcieData->classCode)
69 {
70 ss << std::setfill('0') << std::setw(2) << std::hex << ele;
71 }
72 std::string classCode = ss.str();
73
74 auto subSystemVendorId =
75 std::to_string(htole16(pcieData->subSystemVendorId));
76 auto subSystemId =
77 std::to_string(htole16(pcieData->subSystemId));
78
79 updateDBusProperty(fruRSI, entityAssociationMap, vendorId,
80 deviceId, revisionId, classCode,
81 subSystemVendorId, subSystemId);
82 }
83 // length of tlv is removed from the structure pldm_fru_record_tlv
84 // and the new tlv length is added back.
85 dataSize += sizeof(pldm_fru_record_tlv) - sizeof(uint8_t) +
86 tlv->length;
87 data += dataSize;
88 }
89 }
90
91 return PLDM_SUCCESS;
92}
93
94void Handler::updateDBusProperty(
95 uint16_t fruRSI, const AssociatedEntityMap& fruAssociationMap,
96 const std::string& vendorId, const std::string& deviceId,
97 const std::string& revisionId, const std::string& classCode,
98 const std::string& subSystemVendorId, const std::string& subSystemId)
99{
100 uint16_t entityType{};
101 uint16_t entityInstanceNum{};
102 uint16_t containerId{};
103 uint16_t terminusHandle{};
104 const pldm_pdr_record* record{};
105
106 record = pldm_pdr_fru_record_set_find_by_rsi(
107 pdrRepo, fruRSI, &terminusHandle, &entityType, &entityInstanceNum,
108 &containerId);
109
110 if (record)
111 {
112 for (const auto& [key, value] : fruAssociationMap)
113 {
114 if (entityInstanceNum == value.entity_instance_num &&
115 entityType == value.entity_type &&
116 containerId == value.entity_container_id)
117 {
118 dbus_map_update(key, "Function0VendorId", vendorId);
119 dbus_map_update(key, "Function0DeviceId", deviceId);
120 dbus_map_update(key, "Function0RevisionId", revisionId);
121 dbus_map_update(key, "Function0ClassCode", classCode);
122 dbus_map_update(key, "Function0SubsystemVendorId",
123 subSystemVendorId);
124 dbus_map_update(key, "Function0SubsystemId", subSystemId);
125 }
126 }
127 }
128}
129
130void Handler::dbus_map_update(const std::string& adapterObjPath,
131 const std::string& propertyName,
132 const std::string& propValue)
133{
134 pldm::utils::PropertyValue value = propValue;
135 pldm::utils::DBusMapping dbusMapping;
136 dbusMapping.objectPath = adapterObjPath;
137 dbusMapping.interface = "xyz.openbmc_project.Inventory.Item.PCIeDevice";
138 dbusMapping.propertyName = propertyName;
139 dbusMapping.propertyType = "string";
140 try
141 {
142 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
143 }
144 catch (const std::exception& e)
145 {
146 error("Failed to set '{PROPERTY}' property: {ERROR}", "PROPERTY",
147 propertyName, "ERROR", e);
148 }
149}
150} // namespace oem_ibm_fru
151} // namespace responder
152} // namespace pldm