blob: b46698414a97458f56bf7a29e48be591cef58f61 [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 Dixit1e5c81e2024-05-03 07:54:00 -050033 "EID", 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),
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +093040 std::bind_front(&InventoryManager::queryDeviceIdentifiers, this));
Tom Joseph75356c12021-06-20 03:52:40 -070041 if (rc)
42 {
Riya Dixit49cfb132023-03-02 04:26:53 -060043 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050044 "Failed to send query device identifiers request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050045 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070046 }
47 }
48}
49
50void InventoryManager::queryDeviceIdentifiers(mctp_eid_t eid,
51 const pldm_msg* response,
52 size_t respMsgLen)
53{
54 if (response == nullptr || !respMsgLen)
55 {
Riya Dixit76f2c602024-03-28 07:34:12 -050056 error(
57 "No response received for query device identifiers for endpoint ID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050058 "EID", eid);
Tom Joseph75356c12021-06-20 03:52:40 -070059 return;
60 }
61
62 uint8_t completionCode = PLDM_SUCCESS;
63 uint32_t deviceIdentifiersLen = 0;
64 uint8_t descriptorCount = 0;
65 uint8_t* descriptorPtr = nullptr;
66
67 auto rc = decode_query_device_identifiers_resp(
68 response, respMsgLen, &completionCode, &deviceIdentifiersLen,
69 &descriptorCount, &descriptorPtr);
70 if (rc)
71 {
Riya Dixit49cfb132023-03-02 04:26:53 -060072 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050073 "Failed to decode query device identifiers response for endpoint ID '{EID}' and descriptor count '{DESCRIPTOR_COUNT}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050074 "EID", eid, "DESCRIPTOR_COUNT", descriptorCount, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070075 return;
76 }
77
78 if (completionCode)
79 {
Riya Dixit49cfb132023-03-02 04:26:53 -060080 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050081 "Failed to query device identifiers response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050082 "EID", eid, "CC", completionCode);
Tom Joseph75356c12021-06-20 03:52:40 -070083 return;
84 }
85
86 Descriptors descriptors{};
87 while (descriptorCount-- && (deviceIdentifiersLen > 0))
88 {
89 uint16_t descriptorType = 0;
90 variable_field descriptorData{};
91
92 rc = decode_descriptor_type_length_value(
93 descriptorPtr, deviceIdentifiersLen, &descriptorType,
94 &descriptorData);
95 if (rc)
96 {
Riya Dixit49cfb132023-03-02 04:26:53 -060097 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050098 "Failed to decode descriptor type {TYPE}, length {LENGTH} and value for endpoint ID '{EID}', response code '{RC}'",
99 "TYPE", descriptorType, "LENGTH", deviceIdentifiersLen, "EID",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500100 eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700101 return;
102 }
103
104 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
105 {
106 std::vector<uint8_t> descData(
107 descriptorData.ptr, descriptorData.ptr + descriptorData.length);
108 descriptors.emplace(descriptorType, std::move(descData));
109 }
110 else
111 {
112 uint8_t descriptorTitleStrType = 0;
113 variable_field descriptorTitleStr{};
114 variable_field vendorDefinedDescriptorData{};
115
116 rc = decode_vendor_defined_descriptor_value(
117 descriptorData.ptr, descriptorData.length,
118 &descriptorTitleStrType, &descriptorTitleStr,
119 &vendorDefinedDescriptorData);
120 if (rc)
121 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600122 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500123 "Failed to decode vendor-defined descriptor value for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500124 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700125 return;
126 }
127
128 auto vendorDefinedDescriptorTitleStr =
129 utils::toString(descriptorTitleStr);
130 std::vector<uint8_t> vendorDescData(
131 vendorDefinedDescriptorData.ptr,
132 vendorDefinedDescriptorData.ptr +
133 vendorDefinedDescriptorData.length);
134 descriptors.emplace(descriptorType,
135 std::make_tuple(vendorDefinedDescriptorTitleStr,
136 vendorDescData));
137 }
138 auto nextDescriptorOffset =
139 sizeof(pldm_descriptor_tlv().descriptor_type) +
140 sizeof(pldm_descriptor_tlv().descriptor_length) +
141 descriptorData.length;
142 descriptorPtr += nextDescriptorOffset;
143 deviceIdentifiersLen -= nextDescriptorOffset;
144 }
145
146 descriptorMap.emplace(eid, std::move(descriptors));
147
148 // Send GetFirmwareParameters request
149 sendGetFirmwareParametersRequest(eid);
150}
151
152void InventoryManager::sendGetFirmwareParametersRequest(mctp_eid_t eid)
153{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930154 auto instanceId = instanceIdDb.next(eid);
Tom Joseph75356c12021-06-20 03:52:40 -0700155 Request requestMsg(sizeof(pldm_msg_hdr) +
156 PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
157 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
158 auto rc = encode_get_firmware_parameters_req(
159 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
160 if (rc)
161 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930162 instanceIdDb.free(eid, instanceId);
Riya Dixit76f2c602024-03-28 07:34:12 -0500163 error(
164 "Failed to encode get firmware parameters req for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500165 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700166 return;
167 }
168
169 rc = handler.registerRequest(
170 eid, instanceId, PLDM_FWUP, PLDM_GET_FIRMWARE_PARAMETERS,
171 std::move(requestMsg),
Andrew Jefferyc14fb4b2024-07-25 22:13:09 +0930172 std::bind_front(&InventoryManager::getFirmwareParameters, this));
Tom Joseph75356c12021-06-20 03:52:40 -0700173 if (rc)
174 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600175 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500176 "Failed to send get firmware parameters request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500177 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700178 }
179}
180
181void InventoryManager::getFirmwareParameters(mctp_eid_t eid,
182 const pldm_msg* response,
183 size_t respMsgLen)
184{
185 if (response == nullptr || !respMsgLen)
186 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500187 error(
188 "No response received for get firmware parameters for endpoint ID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500189 "EID", eid);
Tom Joseph75356c12021-06-20 03:52:40 -0700190 descriptorMap.erase(eid);
191 return;
192 }
193
194 pldm_get_firmware_parameters_resp fwParams{};
195 variable_field activeCompImageSetVerStr{};
196 variable_field pendingCompImageSetVerStr{};
197 variable_field compParamTable{};
198
199 auto rc = decode_get_firmware_parameters_resp(
200 response, respMsgLen, &fwParams, &activeCompImageSetVerStr,
201 &pendingCompImageSetVerStr, &compParamTable);
202 if (rc)
203 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600204 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500205 "Failed to decode get firmware parameters response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500206 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700207 return;
208 }
209
210 if (fwParams.completion_code)
211 {
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500212 auto fw_param_cc = fwParams.completion_code;
Riya Dixit49cfb132023-03-02 04:26:53 -0600213 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500214 "Failed to get firmware parameters response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500215 "EID", eid, "CC", fw_param_cc);
Tom Joseph75356c12021-06-20 03:52:40 -0700216 return;
217 }
218
219 auto compParamPtr = compParamTable.ptr;
220 auto compParamTableLen = compParamTable.length;
221 pldm_component_parameter_entry compEntry{};
222 variable_field activeCompVerStr{};
223 variable_field pendingCompVerStr{};
224
225 ComponentInfo componentInfo{};
226 while (fwParams.comp_count-- && (compParamTableLen > 0))
227 {
228 auto rc = decode_get_firmware_parameters_resp_comp_entry(
229 compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
230 &pendingCompVerStr);
231 if (rc)
232 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600233 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500234 "Failed to decode component parameter table entry for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500235 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700236 return;
237 }
238
239 auto compClassification = compEntry.comp_classification;
240 auto compIdentifier = compEntry.comp_identifier;
241 componentInfo.emplace(
242 std::make_pair(compClassification, compIdentifier),
243 compEntry.comp_classification_index);
244 compParamPtr += sizeof(pldm_component_parameter_entry) +
245 activeCompVerStr.length + pendingCompVerStr.length;
246 compParamTableLen -= sizeof(pldm_component_parameter_entry) +
247 activeCompVerStr.length + pendingCompVerStr.length;
248 }
249 componentInfoMap.emplace(eid, std::move(componentInfo));
250}
251
252} // namespace fw_update
253
Riya Dixit49cfb132023-03-02 04:26:53 -0600254} // namespace pldm