fw-update: Implement RequestFirmwareData timeout (UA_T2)
This commit introduces the UA_T2 timeout mechanism for the
RequestFirmwareData command as specified in the Timing Specification
section of the PLDM Firmware Update Specification. The Update Agent(UA),
which orchestrates firmware updates to devices, will now enforce this
timeout to ensure reliable update processes.
The timeout has a default value of 60 seconds is set according to the
PLDM specification's minimum requirement for UA_T2.
Tests:
- Simulating a timeout by turning off the components during a FW update
```
Decoded fw request data at offset '589824' and length '4096' for endpoint ID 26 and Component index 0
Decoded fw request data at offset '663552' and length '4096' for endpoint ID 18 and Component index 0
Request firmware data timed out. No command received from FD within the expected time of 60s from endpoint ID 26, component index 0
Sending cancel update component request for endpoint ID 26
8c 05 1c
Request firmware data timed out. No command received from FD within the expected time of 60s from endpoint ID 18, component index 0
Sending cancel update component request for endpoint ID 18
8c 05 1c
```
Change-Id: I9d34bffa0a4be81d3e8564994a2ea0ef6f2aecd6
Signed-off-by: P Arun Kumar Reddy <arunpapannagari23@gmail.com>
diff --git a/fw-update/device_updater.cpp b/fw-update/device_updater.cpp
index 14d507b..f61428b 100644
--- a/fw-update/device_updater.cpp
+++ b/fw-update/device_updater.cpp
@@ -377,6 +377,15 @@
}
}
+void DeviceUpdater::createRequestFwDataTimer()
+{
+ reqFwDataTimer = std::make_unique<sdbusplus::Timer>([this]() -> void {
+ componentUpdateStatus[componentIndex] = false;
+ sendCancelUpdateComponentRequest();
+ updateManager->updateDeviceCompletion(eid, false);
+ });
+}
+
Response DeviceUpdater::requestFwData(const pldm_msg* request,
size_t payloadLength)
{
@@ -463,6 +472,27 @@
return response;
}
+ if (!reqFwDataTimer)
+ {
+ if (offset != 0)
+ {
+ warning("First data request is not at offset 0");
+ }
+ createRequestFwDataTimer();
+ }
+
+ if (reqFwDataTimer)
+ {
+ reqFwDataTimer->start(std::chrono::seconds(updateTimeoutSeconds),
+ false);
+ }
+ else
+ {
+ error(
+ "Failed to start timer for handling request firmware data for endpoint ID {EID}",
+ "EID", eid, "RC", rc);
+ }
+
return response;
}
@@ -473,6 +503,12 @@
Response response(sizeof(pldm_msg_hdr) + sizeof(completionCode), 0);
auto responseMsg = new (response.data()) pldm_msg;
+ if (reqFwDataTimer)
+ {
+ reqFwDataTimer->stop();
+ reqFwDataTimer.reset();
+ }
+
uint8_t transferResult = 0;
auto rc =
decode_transfer_complete_req(request, payloadLength, &transferResult);