blob: 49b6326ebaa166761d8da9757907d413e78ef571 [file] [log] [blame]
Tom Josephef90b0d2021-08-17 07:12:49 -07001#include "device_updater.hpp"
2
Tom Joseph4d8d5772021-08-17 07:35:05 -07003#include "activation.hpp"
4#include "update_manager.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 Josephef90b0d2021-08-17 07:12:49 -070010#include <functional>
11
Riya Dixit49cfb132023-03-02 04:26:53 -060012PHOSPHOR_LOG2_USING;
13
Tom Josephef90b0d2021-08-17 07:12:49 -070014namespace pldm
15{
16
17namespace fw_update
18{
19
20void DeviceUpdater::startFwUpdateFlow()
21{
Andrew Jefferya330b2f2023-05-04 14:55:37 +093022 auto instanceId = updateManager->instanceIdDb.next(eid);
Tom Josephef90b0d2021-08-17 07:12:49 -070023 // NumberOfComponents
24 const auto& applicableComponents =
25 std::get<ApplicableComponents>(fwDeviceIDRecord);
26 // PackageDataLength
27 const auto& fwDevicePkgData =
28 std::get<FirmwareDevicePackageData>(fwDeviceIDRecord);
29 // ComponentImageSetVersionString
30 const auto& compImageSetVersion =
31 std::get<ComponentImageSetVersion>(fwDeviceIDRecord);
32 variable_field compImgSetVerStrInfo{};
33 compImgSetVerStrInfo.ptr =
34 reinterpret_cast<const uint8_t*>(compImageSetVersion.data());
35 compImgSetVerStrInfo.length =
36 static_cast<uint8_t>(compImageSetVersion.size());
37
38 Request request(sizeof(pldm_msg_hdr) +
39 sizeof(struct pldm_request_update_req) +
40 compImgSetVerStrInfo.length);
41 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
42
43 auto rc = encode_request_update_req(
44 instanceId, maxTransferSize, applicableComponents.size(),
45 PLDM_FWUP_MIN_OUTSTANDING_REQ, fwDevicePkgData.size(),
46 PLDM_STR_TYPE_ASCII, compImgSetVerStrInfo.length, &compImgSetVerStrInfo,
47 requestMsg,
48 sizeof(struct pldm_request_update_req) + compImgSetVerStrInfo.length);
49 if (rc)
50 {
Tom Josephef90b0d2021-08-17 07:12:49 -070051 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -050052 updateManager->instanceIdDb.free(eid, instanceId);
53 error(
54 "Failed to encode request update request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050055 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -070056 }
57
Tom Josephb7e083e2021-10-26 15:10:03 +053058 rc = updateManager->handler.registerRequest(
Tom Josephef90b0d2021-08-17 07:12:49 -070059 eid, instanceId, PLDM_FWUP, PLDM_REQUEST_UPDATE, std::move(request),
60 std::move(std::bind_front(&DeviceUpdater::requestUpdate, this)));
61 if (rc)
62 {
Tom Josephef90b0d2021-08-17 07:12:49 -070063 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -050064 error(
65 "Failed to send request update for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050066 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -070067 }
68}
69
70void DeviceUpdater::requestUpdate(mctp_eid_t eid, const pldm_msg* response,
71 size_t respMsgLen)
72{
73 if (response == nullptr || !respMsgLen)
74 {
75 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -050076 error("No response received for request update for endpoint ID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050077 "EID", eid);
Tom Josephef90b0d2021-08-17 07:12:49 -070078 return;
79 }
80
81 uint8_t completionCode = 0;
82 uint16_t fdMetaDataLen = 0;
83 uint8_t fdWillSendPkgData = 0;
84
85 auto rc = decode_request_update_resp(response, respMsgLen, &completionCode,
86 &fdMetaDataLen, &fdWillSendPkgData);
87 if (rc)
88 {
Riya Dixit76f2c602024-03-28 07:34:12 -050089 error(
90 "Failed to decode request update response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050091 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -070092 return;
93 }
94 if (completionCode)
95 {
Riya Dixit49cfb132023-03-02 04:26:53 -060096 error(
Riya Dixit76f2c602024-03-28 07:34:12 -050097 "Failure in request update response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050098 "EID", eid, "CC", completionCode);
Tom Josephef90b0d2021-08-17 07:12:49 -070099 return;
100 }
101
102 // Optional fields DeviceMetaData and GetPackageData not handled
103 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
Tom Josephb7e083e2021-10-26 15:10:03 +0530104 updateManager->event,
105 std::bind(&DeviceUpdater::sendPassCompTableRequest, this,
106 componentIndex));
Tom Josephef90b0d2021-08-17 07:12:49 -0700107}
108
109void DeviceUpdater::sendPassCompTableRequest(size_t offset)
110{
111 pldmRequest.reset();
112
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930113 auto instanceId = updateManager->instanceIdDb.next(eid);
Tom Josephef90b0d2021-08-17 07:12:49 -0700114 // TransferFlag
115 const auto& applicableComponents =
116 std::get<ApplicableComponents>(fwDeviceIDRecord);
117 uint8_t transferFlag = 0;
118 if (applicableComponents.size() == 1)
119 {
120 transferFlag = PLDM_START_AND_END;
121 }
122 else if (offset == 0)
123 {
124 transferFlag = PLDM_START;
125 }
126 else if (offset == applicableComponents.size() - 1)
127 {
128 transferFlag = PLDM_END;
129 }
130 else
131 {
132 transferFlag = PLDM_MIDDLE;
133 }
134 const auto& comp = compImageInfos[applicableComponents[offset]];
135 // ComponentClassification
136 CompClassification compClassification = std::get<static_cast<size_t>(
137 ComponentImageInfoPos::CompClassificationPos)>(comp);
138 // ComponentIdentifier
139 CompIdentifier compIdentifier =
140 std::get<static_cast<size_t>(ComponentImageInfoPos::CompIdentifierPos)>(
141 comp);
142 // ComponentClassificationIndex
143 CompClassificationIndex compClassificationIndex{};
144 auto compKey = std::make_pair(compClassification, compIdentifier);
145 if (compInfo.contains(compKey))
146 {
147 auto search = compInfo.find(compKey);
148 compClassificationIndex = search->second;
149 }
150 else
151 {
152 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500153 error(
154 "Failed to find component classification '{CLASSIFICATION}' and identifier '{IDENTIFIER}'",
155 "CLASSIFICATION", compClassification, "IDENTIFIER", compIdentifier);
Tom Josephef90b0d2021-08-17 07:12:49 -0700156 }
157 // ComponentComparisonStamp
158 CompComparisonStamp compComparisonStamp = std::get<static_cast<size_t>(
159 ComponentImageInfoPos::CompComparisonStampPos)>(comp);
160 // ComponentVersionString
161 const auto& compVersion =
162 std::get<static_cast<size_t>(ComponentImageInfoPos::CompVersionPos)>(
163 comp);
164 variable_field compVerStrInfo{};
165 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVersion.data());
166 compVerStrInfo.length = static_cast<uint8_t>(compVersion.size());
167
168 Request request(sizeof(pldm_msg_hdr) +
169 sizeof(struct pldm_pass_component_table_req) +
170 compVerStrInfo.length);
171 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
172 auto rc = encode_pass_component_table_req(
173 instanceId, transferFlag, compClassification, compIdentifier,
174 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
175 compVerStrInfo.length, &compVerStrInfo, requestMsg,
176 sizeof(pldm_pass_component_table_req) + compVerStrInfo.length);
177 if (rc)
178 {
Tom Josephef90b0d2021-08-17 07:12:49 -0700179 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500180 updateManager->instanceIdDb.free(eid, instanceId);
181 error(
182 "Failed to encode pass component table req for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500183 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700184 }
185
Tom Josephb7e083e2021-10-26 15:10:03 +0530186 rc = updateManager->handler.registerRequest(
Tom Josephef90b0d2021-08-17 07:12:49 -0700187 eid, instanceId, PLDM_FWUP, PLDM_PASS_COMPONENT_TABLE,
188 std::move(request),
189 std::move(std::bind_front(&DeviceUpdater::passCompTable, this)));
190 if (rc)
191 {
Tom Josephef90b0d2021-08-17 07:12:49 -0700192 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500193 error(
194 "Failed to send pass component table request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500195 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700196 }
197}
198
199void DeviceUpdater::passCompTable(mctp_eid_t eid, const pldm_msg* response,
200 size_t respMsgLen)
201{
202 if (response == nullptr || !respMsgLen)
203 {
204 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500205 error(
206 "No response received for pass component table for endpoint ID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500207 "EID", eid);
Tom Josephef90b0d2021-08-17 07:12:49 -0700208 return;
209 }
210
211 uint8_t completionCode = 0;
212 uint8_t compResponse = 0;
213 uint8_t compResponseCode = 0;
214
Patrick Williams6da4f912023-05-10 07:50:53 -0500215 auto rc = decode_pass_component_table_resp(response, respMsgLen,
216 &completionCode, &compResponse,
217 &compResponseCode);
Tom Josephef90b0d2021-08-17 07:12:49 -0700218 if (rc)
219 {
220 // Handle error scenario
Riya Dixit49cfb132023-03-02 04:26:53 -0600221 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500222 "Failed to decode pass component table response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500223 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700224 return;
225 }
226 if (completionCode)
227 {
228 // Handle error scenario
Riya Dixit49cfb132023-03-02 04:26:53 -0600229 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500230 "Failed to pass component table response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500231 "EID", eid, "CC", completionCode);
Tom Josephef90b0d2021-08-17 07:12:49 -0700232 return;
233 }
234 // Handle ComponentResponseCode
235
236 const auto& applicableComponents =
237 std::get<ApplicableComponents>(fwDeviceIDRecord);
238 if (componentIndex == applicableComponents.size() - 1)
239 {
240 componentIndex = 0;
241 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
Tom Josephb7e083e2021-10-26 15:10:03 +0530242 updateManager->event,
243 std::bind(&DeviceUpdater::sendUpdateComponentRequest, this,
244 componentIndex));
Tom Josephef90b0d2021-08-17 07:12:49 -0700245 }
246 else
247 {
248 componentIndex++;
249 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
Tom Josephb7e083e2021-10-26 15:10:03 +0530250 updateManager->event,
251 std::bind(&DeviceUpdater::sendPassCompTableRequest, this,
252 componentIndex));
Tom Josephef90b0d2021-08-17 07:12:49 -0700253 }
254}
255
256void DeviceUpdater::sendUpdateComponentRequest(size_t offset)
257{
258 pldmRequest.reset();
259
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930260 auto instanceId = updateManager->instanceIdDb.next(eid);
Tom Josephef90b0d2021-08-17 07:12:49 -0700261 const auto& applicableComponents =
262 std::get<ApplicableComponents>(fwDeviceIDRecord);
263 const auto& comp = compImageInfos[applicableComponents[offset]];
264 // ComponentClassification
265 CompClassification compClassification = std::get<static_cast<size_t>(
266 ComponentImageInfoPos::CompClassificationPos)>(comp);
267 // ComponentIdentifier
268 CompIdentifier compIdentifier =
269 std::get<static_cast<size_t>(ComponentImageInfoPos::CompIdentifierPos)>(
270 comp);
271 // ComponentClassificationIndex
272 CompClassificationIndex compClassificationIndex{};
273 auto compKey = std::make_pair(compClassification, compIdentifier);
274 if (compInfo.contains(compKey))
275 {
276 auto search = compInfo.find(compKey);
277 compClassificationIndex = search->second;
278 }
279 else
280 {
281 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500282 error(
283 "Failed to find component classification '{CLASSIFICATION}' and identifier '{IDENTIFIER}'",
284 "CLASSIFICATION", compClassification, "IDENTIFIER", compIdentifier);
Tom Josephef90b0d2021-08-17 07:12:49 -0700285 }
286
287 // UpdateOptionFlags
288 bitfield32_t updateOptionFlags;
289 updateOptionFlags.bits.bit0 = std::get<3>(comp)[0];
290 // ComponentVersion
291 const auto& compVersion = std::get<7>(comp);
292 variable_field compVerStrInfo{};
293 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVersion.data());
294 compVerStrInfo.length = static_cast<uint8_t>(compVersion.size());
295
296 Request request(sizeof(pldm_msg_hdr) +
297 sizeof(struct pldm_update_component_req) +
298 compVerStrInfo.length);
299 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
300
301 auto rc = encode_update_component_req(
302 instanceId, compClassification, compIdentifier, compClassificationIndex,
303 std::get<static_cast<size_t>(
304 ComponentImageInfoPos::CompComparisonStampPos)>(comp),
305 std::get<static_cast<size_t>(ComponentImageInfoPos::CompSizePos)>(comp),
306 updateOptionFlags, PLDM_STR_TYPE_ASCII, compVerStrInfo.length,
307 &compVerStrInfo, requestMsg,
308 sizeof(pldm_update_component_req) + compVerStrInfo.length);
309 if (rc)
310 {
Tom Josephef90b0d2021-08-17 07:12:49 -0700311 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500312 updateManager->instanceIdDb.free(eid, instanceId);
313 error(
314 "Failed to encode update component req for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500315 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700316 }
317
Tom Josephb7e083e2021-10-26 15:10:03 +0530318 rc = updateManager->handler.registerRequest(
Tom Josephef90b0d2021-08-17 07:12:49 -0700319 eid, instanceId, PLDM_FWUP, PLDM_UPDATE_COMPONENT, std::move(request),
320 std::move(std::bind_front(&DeviceUpdater::updateComponent, this)));
321 if (rc)
322 {
Tom Josephef90b0d2021-08-17 07:12:49 -0700323 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500324 error(
325 "Failed to send update request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500326 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700327 }
328}
329
330void DeviceUpdater::updateComponent(mctp_eid_t eid, const pldm_msg* response,
331 size_t respMsgLen)
332{
333 if (response == nullptr || !respMsgLen)
334 {
335 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500336 error(
337 "No response received for update component with endpoint ID {EID}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500338 "EID", eid);
Tom Josephef90b0d2021-08-17 07:12:49 -0700339 return;
340 }
341
342 uint8_t completionCode = 0;
343 uint8_t compCompatibilityResp = 0;
344 uint8_t compCompatibilityRespCode = 0;
345 bitfield32_t updateOptionFlagsEnabled{};
346 uint16_t timeBeforeReqFWData = 0;
347
348 auto rc = decode_update_component_resp(
349 response, respMsgLen, &completionCode, &compCompatibilityResp,
350 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
351 &timeBeforeReqFWData);
352 if (rc)
353 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500354 error(
355 "Failed to decode update request response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500356 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700357 return;
358 }
359 if (completionCode)
360 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600361 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500362 "Failed to update request response for endpoint ID '{EID}', completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500363 "EID", eid, "CC", completionCode);
Tom Josephef90b0d2021-08-17 07:12:49 -0700364 return;
365 }
366}
367
368Response DeviceUpdater::requestFwData(const pldm_msg* request,
369 size_t payloadLength)
370{
371 uint8_t completionCode = PLDM_SUCCESS;
372 uint32_t offset = 0;
373 uint32_t length = 0;
374 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
375 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
376 auto rc = decode_request_firmware_data_req(request, payloadLength, &offset,
377 &length);
378 if (rc)
379 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600380 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500381 "Failed to decode request firmware date request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500382 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700383 rc = encode_request_firmware_data_resp(
384 request->hdr.instance_id, PLDM_ERROR_INVALID_DATA, responseMsg,
385 sizeof(completionCode));
386 if (rc)
387 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600388 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500389 "Failed to encode request firmware date response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500390 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700391 }
392 return response;
393 }
394
395 const auto& applicableComponents =
396 std::get<ApplicableComponents>(fwDeviceIDRecord);
397 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
398 auto compOffset = std::get<5>(comp);
399 auto compSize = std::get<6>(comp);
Riya Dixit76f2c602024-03-28 07:34:12 -0500400 info("Decoded fw request data at offset '{OFFSET}' and length '{LENGTH}' ",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500401 "OFFSET", offset, "LENGTH", length);
Tom Josephef90b0d2021-08-17 07:12:49 -0700402 if (length < PLDM_FWUP_BASELINE_TRANSFER_SIZE || length > maxTransferSize)
403 {
404 rc = encode_request_firmware_data_resp(
405 request->hdr.instance_id, PLDM_FWUP_INVALID_TRANSFER_LENGTH,
406 responseMsg, sizeof(completionCode));
407 if (rc)
408 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600409 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500410 "Failed to encode request firmware date response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500411 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700412 }
413 return response;
414 }
415
416 if (offset + length > compSize + PLDM_FWUP_BASELINE_TRANSFER_SIZE)
417 {
418 rc = encode_request_firmware_data_resp(
419 request->hdr.instance_id, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg,
420 sizeof(completionCode));
421 if (rc)
422 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600423 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500424 "Failed to encode request firmware date response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500425 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700426 }
427 return response;
428 }
429
430 size_t padBytes = 0;
431 if (offset + length > compSize)
432 {
433 padBytes = offset + length - compSize;
434 }
435
436 response.resize(sizeof(pldm_msg_hdr) + sizeof(completionCode) + length);
437 responseMsg = reinterpret_cast<pldm_msg*>(response.data());
438 package.seekg(compOffset + offset);
439 package.read(reinterpret_cast<char*>(response.data() +
440 sizeof(pldm_msg_hdr) +
441 sizeof(completionCode)),
442 length - padBytes);
443 rc = encode_request_firmware_data_resp(request->hdr.instance_id,
444 completionCode, responseMsg,
445 sizeof(completionCode));
446 if (rc)
447 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600448 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500449 "Failed to encode request firmware date response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500450 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700451 return response;
452 }
453
454 return response;
455}
456
457Response DeviceUpdater::transferComplete(const pldm_msg* request,
458 size_t payloadLength)
459{
460 uint8_t completionCode = PLDM_SUCCESS;
461 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
462 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
463
464 uint8_t transferResult = 0;
Patrick Williams6da4f912023-05-10 07:50:53 -0500465 auto rc = decode_transfer_complete_req(request, payloadLength,
466 &transferResult);
Tom Josephef90b0d2021-08-17 07:12:49 -0700467 if (rc)
468 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500469 error(
470 "Failed to decode TransferComplete request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500471 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700472 rc = encode_transfer_complete_resp(request->hdr.instance_id,
473 PLDM_ERROR_INVALID_DATA, responseMsg,
474 sizeof(completionCode));
475 if (rc)
476 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600477 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500478 "Failed to encode TransferComplete response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500479 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700480 }
481 return response;
482 }
483
484 const auto& applicableComponents =
485 std::get<ApplicableComponents>(fwDeviceIDRecord);
486 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
487 const auto& compVersion = std::get<7>(comp);
488
489 if (transferResult == PLDM_FWUP_TRANSFER_SUCCESS)
490 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600491 info(
Riya Dixit76f2c602024-03-28 07:34:12 -0500492 "Component endpoint ID '{EID}' and version '{COMPONENT_VERSION}' transfer complete.",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500493 "EID", eid, "COMPONENT_VERSION", compVersion);
Tom Josephef90b0d2021-08-17 07:12:49 -0700494 }
495 else
496 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600497 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500498 "Failure in transfer of the component endpoint ID '{EID}' and version '{COMPONENT_VERSION}' with transfer result - {RESULT}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500499 "EID", eid, "COMPONENT_VERSION", compVersion, "RESULT",
500 transferResult);
Tom Josephef90b0d2021-08-17 07:12:49 -0700501 }
502
503 rc = encode_transfer_complete_resp(request->hdr.instance_id, completionCode,
504 responseMsg, sizeof(completionCode));
505 if (rc)
506 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500507 error(
508 "Failed to encode transfer complete response of endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500509 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700510 return response;
511 }
512
513 return response;
514}
515
516Response DeviceUpdater::verifyComplete(const pldm_msg* request,
517 size_t payloadLength)
518{
519 uint8_t completionCode = PLDM_SUCCESS;
520 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
521 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
522
523 uint8_t verifyResult = 0;
524 auto rc = decode_verify_complete_req(request, payloadLength, &verifyResult);
525 if (rc)
526 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500527 error(
528 "Failed to decode verify complete request of endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500529 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700530 rc = encode_verify_complete_resp(request->hdr.instance_id,
531 PLDM_ERROR_INVALID_DATA, responseMsg,
532 sizeof(completionCode));
533 if (rc)
534 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600535 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500536 "Failed to encode verify complete response of endpoint ID '{EID}', response code '{RC}'.",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500537 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700538 }
539 return response;
540 }
541
542 const auto& applicableComponents =
543 std::get<ApplicableComponents>(fwDeviceIDRecord);
544 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
545 const auto& compVersion = std::get<7>(comp);
546
547 if (verifyResult == PLDM_FWUP_VERIFY_SUCCESS)
548 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600549 info(
Riya Dixit76f2c602024-03-28 07:34:12 -0500550 "Component endpoint ID '{EID}' and version '{COMPONENT_VERSION}' verification complete.",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500551 "EID", eid, "COMPONENT_VERSION", compVersion);
Tom Josephef90b0d2021-08-17 07:12:49 -0700552 }
553 else
554 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600555 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500556 "Failed to verify component endpoint ID '{EID}' and version '{COMPONENT_VERSION}' with transfer result - '{RESULT}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500557 "EID", eid, "COMPONENT_VERSION", compVersion, "RESULT",
558 verifyResult);
Tom Josephef90b0d2021-08-17 07:12:49 -0700559 }
560
561 rc = encode_verify_complete_resp(request->hdr.instance_id, completionCode,
562 responseMsg, sizeof(completionCode));
563 if (rc)
564 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500565 error(
566 "Failed to encode verify complete response for endpoint ID '{EID}', response code - {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500567 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700568 return response;
569 }
570
571 return response;
572}
573
574Response DeviceUpdater::applyComplete(const pldm_msg* request,
575 size_t payloadLength)
576{
577 uint8_t completionCode = PLDM_SUCCESS;
578 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
579 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
580
581 uint8_t applyResult = 0;
582 bitfield16_t compActivationModification{};
583 auto rc = decode_apply_complete_req(request, payloadLength, &applyResult,
584 &compActivationModification);
585 if (rc)
586 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500587 error(
588 "Failed to decode apply complete request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500589 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700590 rc = encode_apply_complete_resp(request->hdr.instance_id,
591 PLDM_ERROR_INVALID_DATA, responseMsg,
592 sizeof(completionCode));
593 if (rc)
594 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600595 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500596 "Failed to encode apply complete response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500597 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700598 }
599 return response;
600 }
601
602 const auto& applicableComponents =
603 std::get<ApplicableComponents>(fwDeviceIDRecord);
604 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
605 const auto& compVersion = std::get<7>(comp);
606
607 if (applyResult == PLDM_FWUP_APPLY_SUCCESS ||
608 applyResult == PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD)
609 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600610 info(
Riya Dixit76f2c602024-03-28 07:34:12 -0500611 "Component endpoint ID '{EID}' with '{COMPONENT_VERSION}' apply complete.",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500612 "EID", eid, "COMPONENT_VERSION", compVersion);
Tom Joseph4d8d5772021-08-17 07:35:05 -0700613 updateManager->updateActivationProgress();
Tom Josephef90b0d2021-08-17 07:12:49 -0700614 }
615 else
616 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600617 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500618 "Failed to apply component endpoint ID '{EID}' and version '{COMPONENT_VERSION}', error - {ERROR}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500619 "EID", eid, "COMPONENT_VERSION", compVersion, "ERROR", applyResult);
Tom Josephef90b0d2021-08-17 07:12:49 -0700620 }
621
622 rc = encode_apply_complete_resp(request->hdr.instance_id, completionCode,
623 responseMsg, sizeof(completionCode));
624 if (rc)
625 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500626 error(
627 "Failed to encode apply complete response for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500628 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700629 return response;
630 }
631
632 if (componentIndex == applicableComponents.size() - 1)
633 {
634 componentIndex = 0;
635 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
Tom Josephb7e083e2021-10-26 15:10:03 +0530636 updateManager->event,
Tom Josephef90b0d2021-08-17 07:12:49 -0700637 std::bind(&DeviceUpdater::sendActivateFirmwareRequest, this));
638 }
639 else
640 {
641 componentIndex++;
642 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
Tom Josephb7e083e2021-10-26 15:10:03 +0530643 updateManager->event,
644 std::bind(&DeviceUpdater::sendUpdateComponentRequest, this,
645 componentIndex));
Tom Josephef90b0d2021-08-17 07:12:49 -0700646 }
647
648 return response;
649}
650
651void DeviceUpdater::sendActivateFirmwareRequest()
652{
653 pldmRequest.reset();
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930654 auto instanceId = updateManager->instanceIdDb.next(eid);
Tom Josephef90b0d2021-08-17 07:12:49 -0700655 Request request(sizeof(pldm_msg_hdr) +
656 sizeof(struct pldm_activate_firmware_req));
657 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
658
659 auto rc = encode_activate_firmware_req(
660 instanceId, PLDM_NOT_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
661 sizeof(pldm_activate_firmware_req));
662 if (rc)
663 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930664 updateManager->instanceIdDb.free(eid, instanceId);
Riya Dixit76f2c602024-03-28 07:34:12 -0500665 error(
666 "Failed to encode activate firmware req for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500667 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700668 }
669
Tom Josephb7e083e2021-10-26 15:10:03 +0530670 rc = updateManager->handler.registerRequest(
Tom Josephef90b0d2021-08-17 07:12:49 -0700671 eid, instanceId, PLDM_FWUP, PLDM_ACTIVATE_FIRMWARE, std::move(request),
672 std::move(std::bind_front(&DeviceUpdater::activateFirmware, this)));
673 if (rc)
674 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500675 error(
676 "Failed to send activate firmware request for endpoint ID '{EID}', response code '{RC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500677 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700678 }
679}
680
681void DeviceUpdater::activateFirmware(mctp_eid_t eid, const pldm_msg* response,
682 size_t respMsgLen)
683{
684 if (response == nullptr || !respMsgLen)
685 {
686 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500687 error(
688 "No response received for activate firmware for endpoint ID '{EID}'",
689 "EID", eid);
Tom Josephef90b0d2021-08-17 07:12:49 -0700690 return;
691 }
692
693 uint8_t completionCode = 0;
694 uint16_t estimatedTimeForActivation = 0;
695
696 auto rc = decode_activate_firmware_resp(
697 response, respMsgLen, &completionCode, &estimatedTimeForActivation);
698 if (rc)
699 {
700 // Handle error scenario
Riya Dixit76f2c602024-03-28 07:34:12 -0500701 error(
702 "Failed to decode activate firmware response for endpoint ID '{EID}', response code '{RC}'",
703 "EID", eid, "RC", rc);
Tom Josephef90b0d2021-08-17 07:12:49 -0700704 return;
705 }
706 if (completionCode)
707 {
708 // Handle error scenario
Riya Dixit49cfb132023-03-02 04:26:53 -0600709 error(
Riya Dixit76f2c602024-03-28 07:34:12 -0500710 "Failed to activate firmware response for endpoint ID '{EID}', completion code '{CC}'",
711 "EID", eid, "CC", completionCode);
Tom Josephef90b0d2021-08-17 07:12:49 -0700712 return;
713 }
Tom Joseph4d8d5772021-08-17 07:35:05 -0700714
715 updateManager->updateDeviceCompletion(eid, true);
Tom Josephef90b0d2021-08-17 07:12:49 -0700716}
717
718} // namespace fw_update
719
Patrick Williams6da4f912023-05-10 07:50:53 -0500720} // namespace pldm