blob: b8f86ea684bc907ed449df689a68440ac9605d60 [file] [log] [blame]
Tom Joseph75356c12021-06-20 03:52:40 -07001#include "inventory_manager.hpp"
2
Tom Joseph75356c12021-06-20 03:52:40 -07003#include "common/utils.hpp"
4#include "xyz/openbmc_project/Software/Version/server.hpp"
5
George Liuc453e162022-12-21 17:16:23 +08006#include <libpldm/firmware_update.h>
7
Riya Dixit49cfb132023-03-02 04:26:53 -06008#include <phosphor-logging/lg2.hpp>
9
Tom Joseph75356c12021-06-20 03:52:40 -070010#include <functional>
11
Riya Dixit49cfb132023-03-02 04:26:53 -060012PHOSPHOR_LOG2_USING;
13
Tom Joseph75356c12021-06-20 03:52:40 -070014namespace pldm
15{
Tom Joseph75356c12021-06-20 03:52:40 -070016namespace fw_update
17{
Tom Joseph75356c12021-06-20 03:52:40 -070018void InventoryManager::discoverFDs(const std::vector<mctp_eid_t>& eids)
19{
20 for (const auto& eid : eids)
21 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093022 auto instanceId = instanceIdDb.next(eid);
Tom Joseph75356c12021-06-20 03:52:40 -070023 Request requestMsg(sizeof(pldm_msg_hdr) +
24 PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES);
25 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
26 auto rc = encode_query_device_identifiers_req(
27 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, request);
28 if (rc)
29 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093030 instanceIdDb.free(eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -060031 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050032 "Failed to encode query device identifiers req for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -060033 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070034 continue;
35 }
36
37 rc = handler.registerRequest(
38 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DEVICE_IDENTIFIERS,
39 std::move(requestMsg),
40 std::move(std::bind_front(&InventoryManager::queryDeviceIdentifiers,
41 this)));
42 if (rc)
43 {
Riya Dixit49cfb132023-03-02 04:26:53 -060044 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050045 "Failed to send query device identifiers request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -060046 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070047 }
48 }
49}
50
51void InventoryManager::queryDeviceIdentifiers(mctp_eid_t eid,
52 const pldm_msg* response,
53 size_t respMsgLen)
54{
55 if (response == nullptr || !respMsgLen)
56 {
Riya Dixit76f2c602024-03-28 07:34:12 -050057 error(
58 "No response received for query device identifiers for endpoint ID '{EID}'",
59 "EID", unsigned(eid));
Tom Joseph75356c12021-06-20 03:52:40 -070060 return;
61 }
62
63 uint8_t completionCode = PLDM_SUCCESS;
64 uint32_t deviceIdentifiersLen = 0;
65 uint8_t descriptorCount = 0;
66 uint8_t* descriptorPtr = nullptr;
67
68 auto rc = decode_query_device_identifiers_resp(
69 response, respMsgLen, &completionCode, &deviceIdentifiersLen,
70 &descriptorCount, &descriptorPtr);
71 if (rc)
72 {
Riya Dixit49cfb132023-03-02 04:26:53 -060073 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050074 "Failed to decode query device identifiers response for endpoint ID '{EID}' and descriptor count '{DESCRIPTOR_COUNT}', response code '{RC}'",
75 "EID", unsigned(eid), "DESCRIPTOR_COUNT", descriptorCount, "RC",
76 rc);
Tom Joseph75356c12021-06-20 03:52:40 -070077 return;
78 }
79
80 if (completionCode)
81 {
Riya Dixit49cfb132023-03-02 04:26:53 -060082 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050083 "Failed to query device identifiers response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -060084 "EID", unsigned(eid), "CC", unsigned(completionCode));
Tom Joseph75356c12021-06-20 03:52:40 -070085 return;
86 }
87
88 Descriptors descriptors{};
89 while (descriptorCount-- && (deviceIdentifiersLen > 0))
90 {
91 uint16_t descriptorType = 0;
92 variable_field descriptorData{};
93
94 rc = decode_descriptor_type_length_value(
95 descriptorPtr, deviceIdentifiersLen, &descriptorType,
96 &descriptorData);
97 if (rc)
98 {
Riya Dixit49cfb132023-03-02 04:26:53 -060099 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500100 "Failed to decode descriptor type {TYPE}, length {LENGTH} and value for endpoint ID '{EID}', response code '{RC}'",
101 "TYPE", descriptorType, "LENGTH", deviceIdentifiersLen, "EID",
102 unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700103 return;
104 }
105
106 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
107 {
108 std::vector<uint8_t> descData(
109 descriptorData.ptr, descriptorData.ptr + descriptorData.length);
110 descriptors.emplace(descriptorType, std::move(descData));
111 }
112 else
113 {
114 uint8_t descriptorTitleStrType = 0;
115 variable_field descriptorTitleStr{};
116 variable_field vendorDefinedDescriptorData{};
117
118 rc = decode_vendor_defined_descriptor_value(
119 descriptorData.ptr, descriptorData.length,
120 &descriptorTitleStrType, &descriptorTitleStr,
121 &vendorDefinedDescriptorData);
122 if (rc)
123 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600124 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500125 "Failed to decode vendor-defined descriptor value for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -0600126 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700127 return;
128 }
129
130 auto vendorDefinedDescriptorTitleStr =
131 utils::toString(descriptorTitleStr);
132 std::vector<uint8_t> vendorDescData(
133 vendorDefinedDescriptorData.ptr,
134 vendorDefinedDescriptorData.ptr +
135 vendorDefinedDescriptorData.length);
136 descriptors.emplace(descriptorType,
137 std::make_tuple(vendorDefinedDescriptorTitleStr,
138 vendorDescData));
139 }
140 auto nextDescriptorOffset =
141 sizeof(pldm_descriptor_tlv().descriptor_type) +
142 sizeof(pldm_descriptor_tlv().descriptor_length) +
143 descriptorData.length;
144 descriptorPtr += nextDescriptorOffset;
145 deviceIdentifiersLen -= nextDescriptorOffset;
146 }
147
148 descriptorMap.emplace(eid, std::move(descriptors));
149
150 // Send GetFirmwareParameters request
151 sendGetFirmwareParametersRequest(eid);
152}
153
154void InventoryManager::sendGetFirmwareParametersRequest(mctp_eid_t eid)
155{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930156 auto instanceId = instanceIdDb.next(eid);
Tom Joseph75356c12021-06-20 03:52:40 -0700157 Request requestMsg(sizeof(pldm_msg_hdr) +
158 PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
159 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
160 auto rc = encode_get_firmware_parameters_req(
161 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
162 if (rc)
163 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930164 instanceIdDb.free(eid, instanceId);
Riya Dixit76f2c602024-03-28 07:34:12 -0500165 error(
166 "Failed to encode get firmware parameters req for endpoint ID '{EID}', response code '{RC}'",
167 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700168 return;
169 }
170
171 rc = handler.registerRequest(
172 eid, instanceId, PLDM_FWUP, PLDM_GET_FIRMWARE_PARAMETERS,
173 std::move(requestMsg),
174 std::move(
175 std::bind_front(&InventoryManager::getFirmwareParameters, this)));
176 if (rc)
177 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600178 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500179 "Failed to send get firmware parameters request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -0600180 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700181 }
182}
183
184void InventoryManager::getFirmwareParameters(mctp_eid_t eid,
185 const pldm_msg* response,
186 size_t respMsgLen)
187{
188 if (response == nullptr || !respMsgLen)
189 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500190 error(
191 "No response received for get firmware parameters for endpoint ID '{EID}'",
192 "EID", unsigned(eid));
Tom Joseph75356c12021-06-20 03:52:40 -0700193 descriptorMap.erase(eid);
194 return;
195 }
196
197 pldm_get_firmware_parameters_resp fwParams{};
198 variable_field activeCompImageSetVerStr{};
199 variable_field pendingCompImageSetVerStr{};
200 variable_field compParamTable{};
201
202 auto rc = decode_get_firmware_parameters_resp(
203 response, respMsgLen, &fwParams, &activeCompImageSetVerStr,
204 &pendingCompImageSetVerStr, &compParamTable);
205 if (rc)
206 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600207 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500208 "Failed to decode get firmware parameters response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -0600209 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700210 return;
211 }
212
213 if (fwParams.completion_code)
214 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600215 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500216 "Failed to get firmware parameters response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -0600217 "EID", unsigned(eid), "CC", unsigned(fwParams.completion_code));
Tom Joseph75356c12021-06-20 03:52:40 -0700218 return;
219 }
220
221 auto compParamPtr = compParamTable.ptr;
222 auto compParamTableLen = compParamTable.length;
223 pldm_component_parameter_entry compEntry{};
224 variable_field activeCompVerStr{};
225 variable_field pendingCompVerStr{};
226
227 ComponentInfo componentInfo{};
228 while (fwParams.comp_count-- && (compParamTableLen > 0))
229 {
230 auto rc = decode_get_firmware_parameters_resp_comp_entry(
231 compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
232 &pendingCompVerStr);
233 if (rc)
234 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600235 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500236 "Failed to decode component parameter table entry for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -0600237 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700238 return;
239 }
240
241 auto compClassification = compEntry.comp_classification;
242 auto compIdentifier = compEntry.comp_identifier;
243 componentInfo.emplace(
244 std::make_pair(compClassification, compIdentifier),
245 compEntry.comp_classification_index);
246 compParamPtr += sizeof(pldm_component_parameter_entry) +
247 activeCompVerStr.length + pendingCompVerStr.length;
248 compParamTableLen -= sizeof(pldm_component_parameter_entry) +
249 activeCompVerStr.length + pendingCompVerStr.length;
250 }
251 componentInfoMap.emplace(eid, std::move(componentInfo));
252}
253
254} // namespace fw_update
255
Riya Dixit49cfb132023-03-02 04:26:53 -0600256} // namespace pldm