| #include "device_updater.hpp" |
| |
| #include "libpldm/firmware_update.h" |
| |
| #include "activation.hpp" |
| #include "update_manager.hpp" |
| |
| #include <functional> |
| |
| namespace pldm |
| { |
| |
| namespace fw_update |
| { |
| |
| void DeviceUpdater::startFwUpdateFlow() |
| { |
| auto instanceId = updateManager->requester.getInstanceId(eid); |
| // NumberOfComponents |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| // PackageDataLength |
| const auto& fwDevicePkgData = |
| std::get<FirmwareDevicePackageData>(fwDeviceIDRecord); |
| // ComponentImageSetVersionString |
| const auto& compImageSetVersion = |
| std::get<ComponentImageSetVersion>(fwDeviceIDRecord); |
| variable_field compImgSetVerStrInfo{}; |
| compImgSetVerStrInfo.ptr = |
| reinterpret_cast<const uint8_t*>(compImageSetVersion.data()); |
| compImgSetVerStrInfo.length = |
| static_cast<uint8_t>(compImageSetVersion.size()); |
| |
| Request request(sizeof(pldm_msg_hdr) + |
| sizeof(struct pldm_request_update_req) + |
| compImgSetVerStrInfo.length); |
| auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); |
| |
| auto rc = encode_request_update_req( |
| instanceId, maxTransferSize, applicableComponents.size(), |
| PLDM_FWUP_MIN_OUTSTANDING_REQ, fwDevicePkgData.size(), |
| PLDM_STR_TYPE_ASCII, compImgSetVerStrInfo.length, &compImgSetVerStrInfo, |
| requestMsg, |
| sizeof(struct pldm_request_update_req) + compImgSetVerStrInfo.length); |
| if (rc) |
| { |
| updateManager->requester.markFree(eid, instanceId); |
| std::cerr << "encode_request_update_req failed, EID=" << unsigned(eid) |
| << ", RC=" << rc << "\n"; |
| // Handle error scenario |
| } |
| |
| rc = updateManager->handler.registerRequest( |
| eid, instanceId, PLDM_FWUP, PLDM_REQUEST_UPDATE, std::move(request), |
| std::move(std::bind_front(&DeviceUpdater::requestUpdate, this))); |
| if (rc) |
| { |
| std::cerr << "Failed to send RequestUpdate request, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n "; |
| // Handle error scenario |
| } |
| } |
| |
| void DeviceUpdater::requestUpdate(mctp_eid_t eid, const pldm_msg* response, |
| size_t respMsgLen) |
| { |
| if (response == nullptr || !respMsgLen) |
| { |
| // Handle error scenario |
| std::cerr << "No response received for RequestUpdate, EID=" |
| << unsigned(eid) << "\n"; |
| return; |
| } |
| |
| uint8_t completionCode = 0; |
| uint16_t fdMetaDataLen = 0; |
| uint8_t fdWillSendPkgData = 0; |
| |
| auto rc = decode_request_update_resp(response, respMsgLen, &completionCode, |
| &fdMetaDataLen, &fdWillSendPkgData); |
| if (rc) |
| { |
| std::cerr << "Decoding RequestUpdate response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return; |
| } |
| if (completionCode) |
| { |
| std::cerr << "RequestUpdate response failed with error " |
| "completion code, EID=" |
| << unsigned(eid) << ", CC=" << unsigned(completionCode) |
| << "\n"; |
| return; |
| } |
| |
| // Optional fields DeviceMetaData and GetPackageData not handled |
| pldmRequest = std::make_unique<sdeventplus::source::Defer>( |
| updateManager->event, |
| std::bind(&DeviceUpdater::sendPassCompTableRequest, this, |
| componentIndex)); |
| } |
| |
| void DeviceUpdater::sendPassCompTableRequest(size_t offset) |
| { |
| pldmRequest.reset(); |
| |
| auto instanceId = updateManager->requester.getInstanceId(eid); |
| // TransferFlag |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| uint8_t transferFlag = 0; |
| if (applicableComponents.size() == 1) |
| { |
| transferFlag = PLDM_START_AND_END; |
| } |
| else if (offset == 0) |
| { |
| transferFlag = PLDM_START; |
| } |
| else if (offset == applicableComponents.size() - 1) |
| { |
| transferFlag = PLDM_END; |
| } |
| else |
| { |
| transferFlag = PLDM_MIDDLE; |
| } |
| const auto& comp = compImageInfos[applicableComponents[offset]]; |
| // ComponentClassification |
| CompClassification compClassification = std::get<static_cast<size_t>( |
| ComponentImageInfoPos::CompClassificationPos)>(comp); |
| // ComponentIdentifier |
| CompIdentifier compIdentifier = |
| std::get<static_cast<size_t>(ComponentImageInfoPos::CompIdentifierPos)>( |
| comp); |
| // ComponentClassificationIndex |
| CompClassificationIndex compClassificationIndex{}; |
| auto compKey = std::make_pair(compClassification, compIdentifier); |
| if (compInfo.contains(compKey)) |
| { |
| auto search = compInfo.find(compKey); |
| compClassificationIndex = search->second; |
| } |
| else |
| { |
| // Handle error scenario |
| } |
| // ComponentComparisonStamp |
| CompComparisonStamp compComparisonStamp = std::get<static_cast<size_t>( |
| ComponentImageInfoPos::CompComparisonStampPos)>(comp); |
| // ComponentVersionString |
| const auto& compVersion = |
| std::get<static_cast<size_t>(ComponentImageInfoPos::CompVersionPos)>( |
| comp); |
| variable_field compVerStrInfo{}; |
| compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVersion.data()); |
| compVerStrInfo.length = static_cast<uint8_t>(compVersion.size()); |
| |
| Request request(sizeof(pldm_msg_hdr) + |
| sizeof(struct pldm_pass_component_table_req) + |
| compVerStrInfo.length); |
| auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); |
| auto rc = encode_pass_component_table_req( |
| instanceId, transferFlag, compClassification, compIdentifier, |
| compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, |
| compVerStrInfo.length, &compVerStrInfo, requestMsg, |
| sizeof(pldm_pass_component_table_req) + compVerStrInfo.length); |
| if (rc) |
| { |
| updateManager->requester.markFree(eid, instanceId); |
| std::cerr << "encode_pass_component_table_req failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| // Handle error scenario |
| } |
| |
| rc = updateManager->handler.registerRequest( |
| eid, instanceId, PLDM_FWUP, PLDM_PASS_COMPONENT_TABLE, |
| std::move(request), |
| std::move(std::bind_front(&DeviceUpdater::passCompTable, this))); |
| if (rc) |
| { |
| std::cerr << "Failed to send PassComponentTable request, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n "; |
| // Handle error scenario |
| } |
| } |
| |
| void DeviceUpdater::passCompTable(mctp_eid_t eid, const pldm_msg* response, |
| size_t respMsgLen) |
| { |
| if (response == nullptr || !respMsgLen) |
| { |
| // Handle error scenario |
| std::cerr << "No response received for PassComponentTable, EID=" |
| << unsigned(eid) << "\n"; |
| return; |
| } |
| |
| uint8_t completionCode = 0; |
| uint8_t compResponse = 0; |
| uint8_t compResponseCode = 0; |
| |
| auto rc = |
| decode_pass_component_table_resp(response, respMsgLen, &completionCode, |
| &compResponse, &compResponseCode); |
| if (rc) |
| { |
| // Handle error scenario |
| std::cerr << "Decoding PassComponentTable response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return; |
| } |
| if (completionCode) |
| { |
| // Handle error scenario |
| std::cerr << "PassComponentTable response failed with error " |
| "completion code, EID=" |
| << unsigned(eid) << ", CC=" << unsigned(completionCode) |
| << "\n"; |
| return; |
| } |
| // Handle ComponentResponseCode |
| |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| if (componentIndex == applicableComponents.size() - 1) |
| { |
| componentIndex = 0; |
| pldmRequest = std::make_unique<sdeventplus::source::Defer>( |
| updateManager->event, |
| std::bind(&DeviceUpdater::sendUpdateComponentRequest, this, |
| componentIndex)); |
| } |
| else |
| { |
| componentIndex++; |
| pldmRequest = std::make_unique<sdeventplus::source::Defer>( |
| updateManager->event, |
| std::bind(&DeviceUpdater::sendPassCompTableRequest, this, |
| componentIndex)); |
| } |
| } |
| |
| void DeviceUpdater::sendUpdateComponentRequest(size_t offset) |
| { |
| pldmRequest.reset(); |
| |
| auto instanceId = updateManager->requester.getInstanceId(eid); |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| const auto& comp = compImageInfos[applicableComponents[offset]]; |
| // ComponentClassification |
| CompClassification compClassification = std::get<static_cast<size_t>( |
| ComponentImageInfoPos::CompClassificationPos)>(comp); |
| // ComponentIdentifier |
| CompIdentifier compIdentifier = |
| std::get<static_cast<size_t>(ComponentImageInfoPos::CompIdentifierPos)>( |
| comp); |
| // ComponentClassificationIndex |
| CompClassificationIndex compClassificationIndex{}; |
| auto compKey = std::make_pair(compClassification, compIdentifier); |
| if (compInfo.contains(compKey)) |
| { |
| auto search = compInfo.find(compKey); |
| compClassificationIndex = search->second; |
| } |
| else |
| { |
| // Handle error scenario |
| } |
| |
| // UpdateOptionFlags |
| bitfield32_t updateOptionFlags; |
| updateOptionFlags.bits.bit0 = std::get<3>(comp)[0]; |
| // ComponentVersion |
| const auto& compVersion = std::get<7>(comp); |
| variable_field compVerStrInfo{}; |
| compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVersion.data()); |
| compVerStrInfo.length = static_cast<uint8_t>(compVersion.size()); |
| |
| Request request(sizeof(pldm_msg_hdr) + |
| sizeof(struct pldm_update_component_req) + |
| compVerStrInfo.length); |
| auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); |
| |
| auto rc = encode_update_component_req( |
| instanceId, compClassification, compIdentifier, compClassificationIndex, |
| std::get<static_cast<size_t>( |
| ComponentImageInfoPos::CompComparisonStampPos)>(comp), |
| std::get<static_cast<size_t>(ComponentImageInfoPos::CompSizePos)>(comp), |
| updateOptionFlags, PLDM_STR_TYPE_ASCII, compVerStrInfo.length, |
| &compVerStrInfo, requestMsg, |
| sizeof(pldm_update_component_req) + compVerStrInfo.length); |
| if (rc) |
| { |
| updateManager->requester.markFree(eid, instanceId); |
| std::cerr << "encode_update_component_req failed, EID=" << unsigned(eid) |
| << ", RC=" << rc << "\n"; |
| // Handle error scenario |
| } |
| |
| rc = updateManager->handler.registerRequest( |
| eid, instanceId, PLDM_FWUP, PLDM_UPDATE_COMPONENT, std::move(request), |
| std::move(std::bind_front(&DeviceUpdater::updateComponent, this))); |
| if (rc) |
| { |
| std::cerr << "Failed to send UpdateComponent request, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n "; |
| // Handle error scenario |
| } |
| } |
| |
| void DeviceUpdater::updateComponent(mctp_eid_t eid, const pldm_msg* response, |
| size_t respMsgLen) |
| { |
| if (response == nullptr || !respMsgLen) |
| { |
| // Handle error scenario |
| std::cerr << "No response received for updateComponent, EID=" |
| << unsigned(eid) << "\n"; |
| return; |
| } |
| |
| uint8_t completionCode = 0; |
| uint8_t compCompatibilityResp = 0; |
| uint8_t compCompatibilityRespCode = 0; |
| bitfield32_t updateOptionFlagsEnabled{}; |
| uint16_t timeBeforeReqFWData = 0; |
| |
| auto rc = decode_update_component_resp( |
| response, respMsgLen, &completionCode, &compCompatibilityResp, |
| &compCompatibilityRespCode, &updateOptionFlagsEnabled, |
| &timeBeforeReqFWData); |
| if (rc) |
| { |
| std::cerr << "Decoding UpdateComponent response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return; |
| } |
| if (completionCode) |
| { |
| std::cerr << "UpdateComponent response failed with error " |
| "completion code, EID=" |
| << unsigned(eid) << ", CC=" << unsigned(completionCode) |
| << "\n"; |
| return; |
| } |
| } |
| |
| Response DeviceUpdater::requestFwData(const pldm_msg* request, |
| size_t payloadLength) |
| { |
| uint8_t completionCode = PLDM_SUCCESS; |
| uint32_t offset = 0; |
| uint32_t length = 0; |
| Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0); |
| auto responseMsg = reinterpret_cast<pldm_msg*>(response.data()); |
| auto rc = decode_request_firmware_data_req(request, payloadLength, &offset, |
| &length); |
| if (rc) |
| { |
| std::cerr << "Decoding RequestFirmwareData request failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| rc = encode_request_firmware_data_resp( |
| request->hdr.instance_id, PLDM_ERROR_INVALID_DATA, responseMsg, |
| sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding RequestFirmwareData response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| return response; |
| } |
| |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| const auto& comp = compImageInfos[applicableComponents[componentIndex]]; |
| auto compOffset = std::get<5>(comp); |
| auto compSize = std::get<6>(comp); |
| std::cerr << "offset = " << unsigned(offset) |
| << ", length = " << unsigned(length) << "\n"; |
| |
| if (length < PLDM_FWUP_BASELINE_TRANSFER_SIZE || length > maxTransferSize) |
| { |
| rc = encode_request_firmware_data_resp( |
| request->hdr.instance_id, PLDM_FWUP_INVALID_TRANSFER_LENGTH, |
| responseMsg, sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding RequestFirmwareData response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| return response; |
| } |
| |
| if (offset + length > compSize + PLDM_FWUP_BASELINE_TRANSFER_SIZE) |
| { |
| rc = encode_request_firmware_data_resp( |
| request->hdr.instance_id, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg, |
| sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding RequestFirmwareData response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| return response; |
| } |
| |
| size_t padBytes = 0; |
| if (offset + length > compSize) |
| { |
| padBytes = offset + length - compSize; |
| } |
| |
| response.resize(sizeof(pldm_msg_hdr) + sizeof(completionCode) + length); |
| responseMsg = reinterpret_cast<pldm_msg*>(response.data()); |
| package.seekg(compOffset + offset); |
| package.read(reinterpret_cast<char*>(response.data() + |
| sizeof(pldm_msg_hdr) + |
| sizeof(completionCode)), |
| length - padBytes); |
| rc = encode_request_firmware_data_resp(request->hdr.instance_id, |
| completionCode, responseMsg, |
| sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding RequestFirmwareData response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return response; |
| } |
| |
| return response; |
| } |
| |
| Response DeviceUpdater::transferComplete(const pldm_msg* request, |
| size_t payloadLength) |
| { |
| uint8_t completionCode = PLDM_SUCCESS; |
| Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0); |
| auto responseMsg = reinterpret_cast<pldm_msg*>(response.data()); |
| |
| uint8_t transferResult = 0; |
| auto rc = |
| decode_transfer_complete_req(request, payloadLength, &transferResult); |
| if (rc) |
| { |
| std::cerr << "Decoding TransferComplete request failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| rc = encode_transfer_complete_resp(request->hdr.instance_id, |
| PLDM_ERROR_INVALID_DATA, responseMsg, |
| sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding TransferComplete response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| return response; |
| } |
| |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| const auto& comp = compImageInfos[applicableComponents[componentIndex]]; |
| const auto& compVersion = std::get<7>(comp); |
| |
| if (transferResult == PLDM_FWUP_TRANSFER_SUCCESS) |
| { |
| std::cout << "Component Transfer complete, EID=" << unsigned(eid) |
| << ", COMPONENT_VERSION=" << compVersion << "\n"; |
| } |
| else |
| { |
| std::cerr << "Transfer of the component failed, EID=" << unsigned(eid) |
| << ", COMPONENT_VERSION=" << compVersion |
| << ", TRANSFER_RESULT=" << unsigned(transferResult) << "\n"; |
| } |
| |
| rc = encode_transfer_complete_resp(request->hdr.instance_id, completionCode, |
| responseMsg, sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding TransferComplete response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return response; |
| } |
| |
| return response; |
| } |
| |
| Response DeviceUpdater::verifyComplete(const pldm_msg* request, |
| size_t payloadLength) |
| { |
| uint8_t completionCode = PLDM_SUCCESS; |
| Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0); |
| auto responseMsg = reinterpret_cast<pldm_msg*>(response.data()); |
| |
| uint8_t verifyResult = 0; |
| auto rc = decode_verify_complete_req(request, payloadLength, &verifyResult); |
| if (rc) |
| { |
| std::cerr << "Decoding VerifyComplete request failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| rc = encode_verify_complete_resp(request->hdr.instance_id, |
| PLDM_ERROR_INVALID_DATA, responseMsg, |
| sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding VerifyComplete response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| return response; |
| } |
| |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| const auto& comp = compImageInfos[applicableComponents[componentIndex]]; |
| const auto& compVersion = std::get<7>(comp); |
| |
| if (verifyResult == PLDM_FWUP_VERIFY_SUCCESS) |
| { |
| std::cout << "Component verification complete, EID=" << unsigned(eid) |
| << ", COMPONENT_VERSION=" << compVersion << "\n"; |
| } |
| else |
| { |
| std::cerr << "Component verification failed, EID=" << unsigned(eid) |
| << ", COMPONENT_VERSION=" << compVersion |
| << ", VERIFY_RESULT=" << unsigned(verifyResult) << "\n"; |
| } |
| |
| rc = encode_verify_complete_resp(request->hdr.instance_id, completionCode, |
| responseMsg, sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding VerifyComplete response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return response; |
| } |
| |
| return response; |
| } |
| |
| Response DeviceUpdater::applyComplete(const pldm_msg* request, |
| size_t payloadLength) |
| { |
| uint8_t completionCode = PLDM_SUCCESS; |
| Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0); |
| auto responseMsg = reinterpret_cast<pldm_msg*>(response.data()); |
| |
| uint8_t applyResult = 0; |
| bitfield16_t compActivationModification{}; |
| auto rc = decode_apply_complete_req(request, payloadLength, &applyResult, |
| &compActivationModification); |
| if (rc) |
| { |
| std::cerr << "Decoding ApplyComplete request failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| rc = encode_apply_complete_resp(request->hdr.instance_id, |
| PLDM_ERROR_INVALID_DATA, responseMsg, |
| sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding ApplyComplete response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| return response; |
| } |
| |
| const auto& applicableComponents = |
| std::get<ApplicableComponents>(fwDeviceIDRecord); |
| const auto& comp = compImageInfos[applicableComponents[componentIndex]]; |
| const auto& compVersion = std::get<7>(comp); |
| |
| if (applyResult == PLDM_FWUP_APPLY_SUCCESS || |
| applyResult == PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD) |
| { |
| std::cout << "Component apply complete, EID=" << unsigned(eid) |
| << ", COMPONENT_VERSION=" << compVersion << "\n"; |
| updateManager->updateActivationProgress(); |
| } |
| else |
| { |
| std::cerr << "Component apply failed, EID=" << unsigned(eid) |
| << ", COMPONENT_VERSION=" << compVersion |
| << ", APPLY_RESULT=" << unsigned(applyResult) << "\n"; |
| } |
| |
| rc = encode_apply_complete_resp(request->hdr.instance_id, completionCode, |
| responseMsg, sizeof(completionCode)); |
| if (rc) |
| { |
| std::cerr << "Encoding ApplyComplete response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return response; |
| } |
| |
| if (componentIndex == applicableComponents.size() - 1) |
| { |
| componentIndex = 0; |
| pldmRequest = std::make_unique<sdeventplus::source::Defer>( |
| updateManager->event, |
| std::bind(&DeviceUpdater::sendActivateFirmwareRequest, this)); |
| } |
| else |
| { |
| componentIndex++; |
| pldmRequest = std::make_unique<sdeventplus::source::Defer>( |
| updateManager->event, |
| std::bind(&DeviceUpdater::sendUpdateComponentRequest, this, |
| componentIndex)); |
| } |
| |
| return response; |
| } |
| |
| void DeviceUpdater::sendActivateFirmwareRequest() |
| { |
| pldmRequest.reset(); |
| auto instanceId = updateManager->requester.getInstanceId(eid); |
| Request request(sizeof(pldm_msg_hdr) + |
| sizeof(struct pldm_activate_firmware_req)); |
| auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); |
| |
| auto rc = encode_activate_firmware_req( |
| instanceId, PLDM_NOT_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, |
| sizeof(pldm_activate_firmware_req)); |
| if (rc) |
| { |
| updateManager->requester.markFree(eid, instanceId); |
| std::cerr << "encode_activate_firmware_req failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| } |
| |
| rc = updateManager->handler.registerRequest( |
| eid, instanceId, PLDM_FWUP, PLDM_ACTIVATE_FIRMWARE, std::move(request), |
| std::move(std::bind_front(&DeviceUpdater::activateFirmware, this))); |
| if (rc) |
| { |
| std::cerr << "Failed to send ActivateFirmware request, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n "; |
| } |
| } |
| |
| void DeviceUpdater::activateFirmware(mctp_eid_t eid, const pldm_msg* response, |
| size_t respMsgLen) |
| { |
| if (response == nullptr || !respMsgLen) |
| { |
| // Handle error scenario |
| std::cerr << "No response received for ActivateFirmware, EID=" |
| << unsigned(eid) << "\n"; |
| return; |
| } |
| |
| uint8_t completionCode = 0; |
| uint16_t estimatedTimeForActivation = 0; |
| |
| auto rc = decode_activate_firmware_resp( |
| response, respMsgLen, &completionCode, &estimatedTimeForActivation); |
| if (rc) |
| { |
| // Handle error scenario |
| std::cerr << "Decoding ActivateFirmware response failed, EID=" |
| << unsigned(eid) << ", RC=" << rc << "\n"; |
| return; |
| } |
| if (completionCode) |
| { |
| // Handle error scenario |
| std::cerr << "ActivateFirmware response failed with error " |
| "completion code, EID=" |
| << unsigned(eid) << ", CC=" << unsigned(completionCode) |
| << "\n"; |
| return; |
| } |
| |
| updateManager->updateDeviceCompletion(eid, true); |
| } |
| |
| } // namespace fw_update |
| |
| } // namespace pldm |