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