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