blob: c8605f44ba8318695c3ad4e88aaf109c88a3a32b [file] [log] [blame]
Tom Josephef90b0d2021-08-17 07:12:49 -07001#include "device_updater.hpp"
2
3#include "libpldm/firmware_update.h"
4
5#include <functional>
6
7namespace pldm
8{
9
10namespace fw_update
11{
12
13void DeviceUpdater::startFwUpdateFlow()
14{
15 auto instanceId = requester.getInstanceId(eid);
16 // NumberOfComponents
17 const auto& applicableComponents =
18 std::get<ApplicableComponents>(fwDeviceIDRecord);
19 // PackageDataLength
20 const auto& fwDevicePkgData =
21 std::get<FirmwareDevicePackageData>(fwDeviceIDRecord);
22 // ComponentImageSetVersionString
23 const auto& compImageSetVersion =
24 std::get<ComponentImageSetVersion>(fwDeviceIDRecord);
25 variable_field compImgSetVerStrInfo{};
26 compImgSetVerStrInfo.ptr =
27 reinterpret_cast<const uint8_t*>(compImageSetVersion.data());
28 compImgSetVerStrInfo.length =
29 static_cast<uint8_t>(compImageSetVersion.size());
30
31 Request request(sizeof(pldm_msg_hdr) +
32 sizeof(struct pldm_request_update_req) +
33 compImgSetVerStrInfo.length);
34 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
35
36 auto rc = encode_request_update_req(
37 instanceId, maxTransferSize, applicableComponents.size(),
38 PLDM_FWUP_MIN_OUTSTANDING_REQ, fwDevicePkgData.size(),
39 PLDM_STR_TYPE_ASCII, compImgSetVerStrInfo.length, &compImgSetVerStrInfo,
40 requestMsg,
41 sizeof(struct pldm_request_update_req) + compImgSetVerStrInfo.length);
42 if (rc)
43 {
44 requester.markFree(eid, instanceId);
45 std::cerr << "encode_request_update_req failed, EID=" << unsigned(eid)
46 << ", RC=" << rc << "\n";
47 // Handle error scenario
48 }
49
50 rc = handler.registerRequest(
51 eid, instanceId, PLDM_FWUP, PLDM_REQUEST_UPDATE, std::move(request),
52 std::move(std::bind_front(&DeviceUpdater::requestUpdate, this)));
53 if (rc)
54 {
55 std::cerr << "Failed to send RequestUpdate request, EID="
56 << unsigned(eid) << ", RC=" << rc << "\n ";
57 // Handle error scenario
58 }
59}
60
61void DeviceUpdater::requestUpdate(mctp_eid_t eid, const pldm_msg* response,
62 size_t respMsgLen)
63{
64 if (response == nullptr || !respMsgLen)
65 {
66 // Handle error scenario
67 std::cerr << "No response received for RequestUpdate, EID="
68 << unsigned(eid) << "\n";
69 return;
70 }
71
72 uint8_t completionCode = 0;
73 uint16_t fdMetaDataLen = 0;
74 uint8_t fdWillSendPkgData = 0;
75
76 auto rc = decode_request_update_resp(response, respMsgLen, &completionCode,
77 &fdMetaDataLen, &fdWillSendPkgData);
78 if (rc)
79 {
80 std::cerr << "Decoding RequestUpdate response failed, EID="
81 << unsigned(eid) << ", RC=" << rc << "\n";
82 return;
83 }
84 if (completionCode)
85 {
86 std::cerr << "RequestUpdate response failed with error "
87 "completion code, EID="
88 << unsigned(eid) << ", CC=" << unsigned(completionCode)
89 << "\n";
90 return;
91 }
92
93 // Optional fields DeviceMetaData and GetPackageData not handled
94 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
95 event, std::bind(&DeviceUpdater::sendPassCompTableRequest, this,
96 componentIndex));
97}
98
99void DeviceUpdater::sendPassCompTableRequest(size_t offset)
100{
101 pldmRequest.reset();
102
103 auto instanceId = requester.getInstanceId(eid);
104 // TransferFlag
105 const auto& applicableComponents =
106 std::get<ApplicableComponents>(fwDeviceIDRecord);
107 uint8_t transferFlag = 0;
108 if (applicableComponents.size() == 1)
109 {
110 transferFlag = PLDM_START_AND_END;
111 }
112 else if (offset == 0)
113 {
114 transferFlag = PLDM_START;
115 }
116 else if (offset == applicableComponents.size() - 1)
117 {
118 transferFlag = PLDM_END;
119 }
120 else
121 {
122 transferFlag = PLDM_MIDDLE;
123 }
124 const auto& comp = compImageInfos[applicableComponents[offset]];
125 // ComponentClassification
126 CompClassification compClassification = std::get<static_cast<size_t>(
127 ComponentImageInfoPos::CompClassificationPos)>(comp);
128 // ComponentIdentifier
129 CompIdentifier compIdentifier =
130 std::get<static_cast<size_t>(ComponentImageInfoPos::CompIdentifierPos)>(
131 comp);
132 // ComponentClassificationIndex
133 CompClassificationIndex compClassificationIndex{};
134 auto compKey = std::make_pair(compClassification, compIdentifier);
135 if (compInfo.contains(compKey))
136 {
137 auto search = compInfo.find(compKey);
138 compClassificationIndex = search->second;
139 }
140 else
141 {
142 // Handle error scenario
143 }
144 // ComponentComparisonStamp
145 CompComparisonStamp compComparisonStamp = std::get<static_cast<size_t>(
146 ComponentImageInfoPos::CompComparisonStampPos)>(comp);
147 // ComponentVersionString
148 const auto& compVersion =
149 std::get<static_cast<size_t>(ComponentImageInfoPos::CompVersionPos)>(
150 comp);
151 variable_field compVerStrInfo{};
152 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVersion.data());
153 compVerStrInfo.length = static_cast<uint8_t>(compVersion.size());
154
155 Request request(sizeof(pldm_msg_hdr) +
156 sizeof(struct pldm_pass_component_table_req) +
157 compVerStrInfo.length);
158 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
159 auto rc = encode_pass_component_table_req(
160 instanceId, transferFlag, compClassification, compIdentifier,
161 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
162 compVerStrInfo.length, &compVerStrInfo, requestMsg,
163 sizeof(pldm_pass_component_table_req) + compVerStrInfo.length);
164 if (rc)
165 {
166 requester.markFree(eid, instanceId);
167 std::cerr << "encode_pass_component_table_req failed, EID="
168 << unsigned(eid) << ", RC=" << rc << "\n";
169 // Handle error scenario
170 }
171
172 rc = handler.registerRequest(
173 eid, instanceId, PLDM_FWUP, PLDM_PASS_COMPONENT_TABLE,
174 std::move(request),
175 std::move(std::bind_front(&DeviceUpdater::passCompTable, this)));
176 if (rc)
177 {
178 std::cerr << "Failed to send PassComponentTable request, EID="
179 << unsigned(eid) << ", RC=" << rc << "\n ";
180 // Handle error scenario
181 }
182}
183
184void DeviceUpdater::passCompTable(mctp_eid_t eid, const pldm_msg* response,
185 size_t respMsgLen)
186{
187 if (response == nullptr || !respMsgLen)
188 {
189 // Handle error scenario
190 std::cerr << "No response received for PassComponentTable, EID="
191 << unsigned(eid) << "\n";
192 return;
193 }
194
195 uint8_t completionCode = 0;
196 uint8_t compResponse = 0;
197 uint8_t compResponseCode = 0;
198
199 auto rc =
200 decode_pass_component_table_resp(response, respMsgLen, &completionCode,
201 &compResponse, &compResponseCode);
202 if (rc)
203 {
204 // Handle error scenario
205 std::cerr << "Decoding PassComponentTable response failed, EID="
206 << unsigned(eid) << ", RC=" << rc << "\n";
207 return;
208 }
209 if (completionCode)
210 {
211 // Handle error scenario
212 std::cerr << "PassComponentTable response failed with error "
213 "completion code, EID="
214 << unsigned(eid) << ", CC=" << unsigned(completionCode)
215 << "\n";
216 return;
217 }
218 // Handle ComponentResponseCode
219
220 const auto& applicableComponents =
221 std::get<ApplicableComponents>(fwDeviceIDRecord);
222 if (componentIndex == applicableComponents.size() - 1)
223 {
224 componentIndex = 0;
225 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
226 event, std::bind(&DeviceUpdater::sendUpdateComponentRequest, this,
227 componentIndex));
228 }
229 else
230 {
231 componentIndex++;
232 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
233 event, std::bind(&DeviceUpdater::sendPassCompTableRequest, this,
234 componentIndex));
235 }
236}
237
238void DeviceUpdater::sendUpdateComponentRequest(size_t offset)
239{
240 pldmRequest.reset();
241
242 auto instanceId = requester.getInstanceId(eid);
243 const auto& applicableComponents =
244 std::get<ApplicableComponents>(fwDeviceIDRecord);
245 const auto& comp = compImageInfos[applicableComponents[offset]];
246 // ComponentClassification
247 CompClassification compClassification = std::get<static_cast<size_t>(
248 ComponentImageInfoPos::CompClassificationPos)>(comp);
249 // ComponentIdentifier
250 CompIdentifier compIdentifier =
251 std::get<static_cast<size_t>(ComponentImageInfoPos::CompIdentifierPos)>(
252 comp);
253 // ComponentClassificationIndex
254 CompClassificationIndex compClassificationIndex{};
255 auto compKey = std::make_pair(compClassification, compIdentifier);
256 if (compInfo.contains(compKey))
257 {
258 auto search = compInfo.find(compKey);
259 compClassificationIndex = search->second;
260 }
261 else
262 {
263 // Handle error scenario
264 }
265
266 // UpdateOptionFlags
267 bitfield32_t updateOptionFlags;
268 updateOptionFlags.bits.bit0 = std::get<3>(comp)[0];
269 // ComponentVersion
270 const auto& compVersion = std::get<7>(comp);
271 variable_field compVerStrInfo{};
272 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVersion.data());
273 compVerStrInfo.length = static_cast<uint8_t>(compVersion.size());
274
275 Request request(sizeof(pldm_msg_hdr) +
276 sizeof(struct pldm_update_component_req) +
277 compVerStrInfo.length);
278 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
279
280 auto rc = encode_update_component_req(
281 instanceId, compClassification, compIdentifier, compClassificationIndex,
282 std::get<static_cast<size_t>(
283 ComponentImageInfoPos::CompComparisonStampPos)>(comp),
284 std::get<static_cast<size_t>(ComponentImageInfoPos::CompSizePos)>(comp),
285 updateOptionFlags, PLDM_STR_TYPE_ASCII, compVerStrInfo.length,
286 &compVerStrInfo, requestMsg,
287 sizeof(pldm_update_component_req) + compVerStrInfo.length);
288 if (rc)
289 {
290 requester.markFree(eid, instanceId);
291 std::cerr << "encode_update_component_req failed, EID=" << unsigned(eid)
292 << ", RC=" << rc << "\n";
293 // Handle error scenario
294 }
295
296 rc = handler.registerRequest(
297 eid, instanceId, PLDM_FWUP, PLDM_UPDATE_COMPONENT, std::move(request),
298 std::move(std::bind_front(&DeviceUpdater::updateComponent, this)));
299 if (rc)
300 {
301 std::cerr << "Failed to send UpdateComponent request, EID="
302 << unsigned(eid) << ", RC=" << rc << "\n ";
303 // Handle error scenario
304 }
305}
306
307void DeviceUpdater::updateComponent(mctp_eid_t eid, const pldm_msg* response,
308 size_t respMsgLen)
309{
310 if (response == nullptr || !respMsgLen)
311 {
312 // Handle error scenario
313 std::cerr << "No response received for updateComponent, EID="
314 << unsigned(eid) << "\n";
315 return;
316 }
317
318 uint8_t completionCode = 0;
319 uint8_t compCompatibilityResp = 0;
320 uint8_t compCompatibilityRespCode = 0;
321 bitfield32_t updateOptionFlagsEnabled{};
322 uint16_t timeBeforeReqFWData = 0;
323
324 auto rc = decode_update_component_resp(
325 response, respMsgLen, &completionCode, &compCompatibilityResp,
326 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
327 &timeBeforeReqFWData);
328 if (rc)
329 {
330 std::cerr << "Decoding UpdateComponent response failed, EID="
331 << unsigned(eid) << ", RC=" << rc << "\n";
332 return;
333 }
334 if (completionCode)
335 {
336 std::cerr << "UpdateComponent response failed with error "
337 "completion code, EID="
338 << unsigned(eid) << ", CC=" << unsigned(completionCode)
339 << "\n";
340 return;
341 }
342}
343
344Response DeviceUpdater::requestFwData(const pldm_msg* request,
345 size_t payloadLength)
346{
347 uint8_t completionCode = PLDM_SUCCESS;
348 uint32_t offset = 0;
349 uint32_t length = 0;
350 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
351 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
352 auto rc = decode_request_firmware_data_req(request, payloadLength, &offset,
353 &length);
354 if (rc)
355 {
356 std::cerr << "Decoding RequestFirmwareData request failed, EID="
357 << unsigned(eid) << ", RC=" << rc << "\n";
358 rc = encode_request_firmware_data_resp(
359 request->hdr.instance_id, PLDM_ERROR_INVALID_DATA, responseMsg,
360 sizeof(completionCode));
361 if (rc)
362 {
363 std::cerr << "Encoding RequestFirmwareData response failed, EID="
364 << unsigned(eid) << ", RC=" << rc << "\n";
365 }
366 return response;
367 }
368
369 const auto& applicableComponents =
370 std::get<ApplicableComponents>(fwDeviceIDRecord);
371 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
372 auto compOffset = std::get<5>(comp);
373 auto compSize = std::get<6>(comp);
374 std::cerr << "offset = " << unsigned(offset)
375 << ", length = " << unsigned(length) << "\n";
376
377 if (length < PLDM_FWUP_BASELINE_TRANSFER_SIZE || length > maxTransferSize)
378 {
379 rc = encode_request_firmware_data_resp(
380 request->hdr.instance_id, PLDM_FWUP_INVALID_TRANSFER_LENGTH,
381 responseMsg, sizeof(completionCode));
382 if (rc)
383 {
384 std::cerr << "Encoding RequestFirmwareData response failed, EID="
385 << unsigned(eid) << ", RC=" << rc << "\n";
386 }
387 return response;
388 }
389
390 if (offset + length > compSize + PLDM_FWUP_BASELINE_TRANSFER_SIZE)
391 {
392 rc = encode_request_firmware_data_resp(
393 request->hdr.instance_id, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg,
394 sizeof(completionCode));
395 if (rc)
396 {
397 std::cerr << "Encoding RequestFirmwareData response failed, EID="
398 << unsigned(eid) << ", RC=" << rc << "\n";
399 }
400 return response;
401 }
402
403 size_t padBytes = 0;
404 if (offset + length > compSize)
405 {
406 padBytes = offset + length - compSize;
407 }
408
409 response.resize(sizeof(pldm_msg_hdr) + sizeof(completionCode) + length);
410 responseMsg = reinterpret_cast<pldm_msg*>(response.data());
411 package.seekg(compOffset + offset);
412 package.read(reinterpret_cast<char*>(response.data() +
413 sizeof(pldm_msg_hdr) +
414 sizeof(completionCode)),
415 length - padBytes);
416 rc = encode_request_firmware_data_resp(request->hdr.instance_id,
417 completionCode, responseMsg,
418 sizeof(completionCode));
419 if (rc)
420 {
421 std::cerr << "Encoding RequestFirmwareData response failed, EID="
422 << unsigned(eid) << ", RC=" << rc << "\n";
423 return response;
424 }
425
426 return response;
427}
428
429Response DeviceUpdater::transferComplete(const pldm_msg* request,
430 size_t payloadLength)
431{
432 uint8_t completionCode = PLDM_SUCCESS;
433 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
434 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
435
436 uint8_t transferResult = 0;
437 auto rc =
438 decode_transfer_complete_req(request, payloadLength, &transferResult);
439 if (rc)
440 {
441 std::cerr << "Decoding TransferComplete request failed, EID="
442 << unsigned(eid) << ", RC=" << rc << "\n";
443 rc = encode_transfer_complete_resp(request->hdr.instance_id,
444 PLDM_ERROR_INVALID_DATA, responseMsg,
445 sizeof(completionCode));
446 if (rc)
447 {
448 std::cerr << "Encoding TransferComplete response failed, EID="
449 << unsigned(eid) << ", RC=" << rc << "\n";
450 }
451 return response;
452 }
453
454 const auto& applicableComponents =
455 std::get<ApplicableComponents>(fwDeviceIDRecord);
456 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
457 const auto& compVersion = std::get<7>(comp);
458
459 if (transferResult == PLDM_FWUP_TRANSFER_SUCCESS)
460 {
461 std::cout << "Component Transfer complete, EID=" << unsigned(eid)
462 << ", COMPONENT_VERSION=" << compVersion << "\n";
463 }
464 else
465 {
466 std::cerr << "Transfer of the component failed, EID=" << unsigned(eid)
467 << ", COMPONENT_VERSION=" << compVersion
468 << ", TRANSFER_RESULT=" << unsigned(transferResult) << "\n";
469 }
470
471 rc = encode_transfer_complete_resp(request->hdr.instance_id, completionCode,
472 responseMsg, sizeof(completionCode));
473 if (rc)
474 {
475 std::cerr << "Encoding TransferComplete response failed, EID="
476 << unsigned(eid) << ", RC=" << rc << "\n";
477 return response;
478 }
479
480 return response;
481}
482
483Response DeviceUpdater::verifyComplete(const pldm_msg* request,
484 size_t payloadLength)
485{
486 uint8_t completionCode = PLDM_SUCCESS;
487 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
488 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
489
490 uint8_t verifyResult = 0;
491 auto rc = decode_verify_complete_req(request, payloadLength, &verifyResult);
492 if (rc)
493 {
494 std::cerr << "Decoding VerifyComplete request failed, EID="
495 << unsigned(eid) << ", RC=" << rc << "\n";
496 rc = encode_verify_complete_resp(request->hdr.instance_id,
497 PLDM_ERROR_INVALID_DATA, responseMsg,
498 sizeof(completionCode));
499 if (rc)
500 {
501 std::cerr << "Encoding VerifyComplete response failed, EID="
502 << unsigned(eid) << ", RC=" << rc << "\n";
503 }
504 return response;
505 }
506
507 const auto& applicableComponents =
508 std::get<ApplicableComponents>(fwDeviceIDRecord);
509 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
510 const auto& compVersion = std::get<7>(comp);
511
512 if (verifyResult == PLDM_FWUP_VERIFY_SUCCESS)
513 {
514 std::cout << "Component verification complete, EID=" << unsigned(eid)
515 << ", COMPONENT_VERSION=" << compVersion << "\n";
516 }
517 else
518 {
519 std::cerr << "Component verification failed, EID=" << unsigned(eid)
520 << ", COMPONENT_VERSION=" << compVersion
521 << ", VERIFY_RESULT=" << unsigned(verifyResult) << "\n";
522 }
523
524 rc = encode_verify_complete_resp(request->hdr.instance_id, completionCode,
525 responseMsg, sizeof(completionCode));
526 if (rc)
527 {
528 std::cerr << "Encoding VerifyComplete response failed, EID="
529 << unsigned(eid) << ", RC=" << rc << "\n";
530 return response;
531 }
532
533 return response;
534}
535
536Response DeviceUpdater::applyComplete(const pldm_msg* request,
537 size_t payloadLength)
538{
539 uint8_t completionCode = PLDM_SUCCESS;
540 Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
541 auto responseMsg = reinterpret_cast<pldm_msg*>(response.data());
542
543 uint8_t applyResult = 0;
544 bitfield16_t compActivationModification{};
545 auto rc = decode_apply_complete_req(request, payloadLength, &applyResult,
546 &compActivationModification);
547 if (rc)
548 {
549 std::cerr << "Decoding ApplyComplete request failed, EID="
550 << unsigned(eid) << ", RC=" << rc << "\n";
551 rc = encode_apply_complete_resp(request->hdr.instance_id,
552 PLDM_ERROR_INVALID_DATA, responseMsg,
553 sizeof(completionCode));
554 if (rc)
555 {
556 std::cerr << "Encoding ApplyComplete response failed, EID="
557 << unsigned(eid) << ", RC=" << rc << "\n";
558 }
559 return response;
560 }
561
562 const auto& applicableComponents =
563 std::get<ApplicableComponents>(fwDeviceIDRecord);
564 const auto& comp = compImageInfos[applicableComponents[componentIndex]];
565 const auto& compVersion = std::get<7>(comp);
566
567 if (applyResult == PLDM_FWUP_APPLY_SUCCESS ||
568 applyResult == PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD)
569 {
570 std::cout << "Component apply complete, EID=" << unsigned(eid)
571 << ", COMPONENT_VERSION=" << compVersion << "\n";
572 }
573 else
574 {
575 std::cerr << "Component apply failed, EID=" << unsigned(eid)
576 << ", COMPONENT_VERSION=" << compVersion
577 << ", APPLY_RESULT=" << unsigned(applyResult) << "\n";
578 }
579
580 rc = encode_apply_complete_resp(request->hdr.instance_id, completionCode,
581 responseMsg, sizeof(completionCode));
582 if (rc)
583 {
584 std::cerr << "Encoding ApplyComplete response failed, EID="
585 << unsigned(eid) << ", RC=" << rc << "\n";
586 return response;
587 }
588
589 if (componentIndex == applicableComponents.size() - 1)
590 {
591 componentIndex = 0;
592 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
593 event,
594 std::bind(&DeviceUpdater::sendActivateFirmwareRequest, this));
595 }
596 else
597 {
598 componentIndex++;
599 pldmRequest = std::make_unique<sdeventplus::source::Defer>(
600 event, std::bind(&DeviceUpdater::sendUpdateComponentRequest, this,
601 componentIndex));
602 }
603
604 return response;
605}
606
607void DeviceUpdater::sendActivateFirmwareRequest()
608{
609 pldmRequest.reset();
610 auto instanceId = requester.getInstanceId(eid);
611 Request request(sizeof(pldm_msg_hdr) +
612 sizeof(struct pldm_activate_firmware_req));
613 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
614
615 auto rc = encode_activate_firmware_req(
616 instanceId, PLDM_NOT_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
617 sizeof(pldm_activate_firmware_req));
618 if (rc)
619 {
620 requester.markFree(eid, instanceId);
621 std::cerr << "encode_activate_firmware_req failed, EID="
622 << unsigned(eid) << ", RC=" << rc << "\n";
623 }
624
625 rc = handler.registerRequest(
626 eid, instanceId, PLDM_FWUP, PLDM_ACTIVATE_FIRMWARE, std::move(request),
627 std::move(std::bind_front(&DeviceUpdater::activateFirmware, this)));
628 if (rc)
629 {
630 std::cerr << "Failed to send ActivateFirmware request, EID="
631 << unsigned(eid) << ", RC=" << rc << "\n ";
632 }
633}
634
635void DeviceUpdater::activateFirmware(mctp_eid_t eid, const pldm_msg* response,
636 size_t respMsgLen)
637{
638 if (response == nullptr || !respMsgLen)
639 {
640 // Handle error scenario
641 std::cerr << "No response received for ActivateFirmware, EID="
642 << unsigned(eid) << "\n";
643 return;
644 }
645
646 uint8_t completionCode = 0;
647 uint16_t estimatedTimeForActivation = 0;
648
649 auto rc = decode_activate_firmware_resp(
650 response, respMsgLen, &completionCode, &estimatedTimeForActivation);
651 if (rc)
652 {
653 // Handle error scenario
654 std::cerr << "Decoding ActivateFirmware response failed, EID="
655 << unsigned(eid) << ", RC=" << rc << "\n";
656 return;
657 }
658 if (completionCode)
659 {
660 // Handle error scenario
661 std::cerr << "ActivateFirmware response failed with error "
662 "completion code, EID="
663 << unsigned(eid) << ", CC=" << unsigned(completionCode)
664 << "\n";
665 return;
666 }
667}
668
669} // namespace fw_update
670
671} // namespace pldm