Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OTA Requestor] Implement the CancelImageUpdate() OTARequestor API #13778

Merged
merged 11 commits into from
Jan 26, 2022
Merged
18 changes: 18 additions & 0 deletions src/app/clusters/ota-requestor/OTARequestor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ void OTARequestor::ConnectToProvider(OnConnectedAction onConnectedAction)
{
VerifyOrReturn(mOtaRequestorDriver != nullptr, ChipLogError(SoftwareUpdate, "OTA requestor driver not set"));
VerifyOrReturn(mServer != nullptr, ChipLogError(SoftwareUpdate, "Server not set"));
VerifyOrReturn(mProviderNodeId != kUndefinedNodeId, ChipLogError(SoftwareUpdate, "Provider Node ID not set"));

FabricInfo * fabricInfo = mServer->GetFabricTable().FindFabricWithIndex(mProviderFabricIndex);
VerifyOrReturn(fabricInfo != nullptr, ChipLogError(SoftwareUpdate, "Cannot find fabric"));
Expand All @@ -284,6 +285,23 @@ void OTARequestor::ConnectToProvider(OnConnectedAction onConnectedAction)
ChipLogError(SoftwareUpdate, "Cannot establish connection to provider: %" CHIP_ERROR_FORMAT, err.Format()));
}

// Application directs the Requestor to cancel image update in progress. All the Requestor state is
selissia marked this conversation as resolved.
Show resolved Hide resolved
// cleared, UpdateState is reset to Idle
void OTARequestor::CancelImageUpdate()
{
mBdxDownloader->EndDownload(CHIP_ERROR_CONNECTION_ABORTED);

// All Provider info should be invalidated
mProviderNodeId = kUndefinedNodeId;
mProviderFabricIndex = kUndefinedFabricIndex;
mProviderEndpointId = kRootEndpointId;

RecordNewUpdateState(OTAUpdateStateEnum::kIdle, OTAChangeReasonEnum::kUnknown);
carol-apple marked this conversation as resolved.
Show resolved Hide resolved

// Notify the platform, it might choose to take additional actions
mOtaRequestorDriver->UpdateCancelled();
}

CHIP_ERROR OTARequestor::GetUpdateProgress(EndpointId endpointId, app::DataModel::Nullable<uint8_t> & progress)
{
VerifyOrReturnError(OtaRequestorServerGetUpdateStateProgress(endpointId, progress) == EMBER_ZCL_STATUS_SUCCESS,
Expand Down
16 changes: 6 additions & 10 deletions src/app/clusters/ota-requestor/OTARequestor.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,9 @@ class OTARequestor : public OTARequestorInterface, public BDXDownloader::StateDe
mProviderEndpointId = endpointId;
}

// Application directs the Requestor to abort the download in progress. All the Requestor state (such
// as the QueryImageResponse content) is preserved
void AbortImageUpdate();

// Application directs the Requestor to abort the download in progress. All the Requestor state is
// cleared, UploadState is reset to Idle
void AbortAndResetState();
// Application directs the Requestor to cancel image update in progress. All the Requestor state is
// cleared, UpdateState is reset to Idle
void CancelImageUpdate() override;

// Application notifies the Requestor on the user consent action, TRUE if consent is given,
// FALSE otherwise
Expand Down Expand Up @@ -275,9 +271,9 @@ class OTARequestor : public OTARequestorInterface, public BDXDownloader::StateDe
static void OnNotifyUpdateAppliedFailure(void * context, CHIP_ERROR error);

OTARequestorDriver * mOtaRequestorDriver = nullptr;
NodeId mProviderNodeId = kUndefinedNodeId;
FabricIndex mProviderFabricIndex = kUndefinedFabricIndex;
EndpointId mProviderEndpointId = kRootEndpointId;
NodeId mProviderNodeId = kUndefinedNodeId; // Only valid for the current update in progress
carol-apple marked this conversation as resolved.
Show resolved Hide resolved
FabricIndex mProviderFabricIndex = kUndefinedFabricIndex; // Only valid for the current update in progress
EndpointId mProviderEndpointId = kRootEndpointId; // Only valid for the current update in progress
uint32_t mOtaStartDelayMs = 0;
CASESessionManager * mCASESessionManager = nullptr;
OnConnectedAction mOnConnectedAction = kQueryImage;
Expand Down
3 changes: 3 additions & 0 deletions src/include/platform/OTARequestorDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class OTARequestorDriver

/// Called when the current software update should be discontinued
virtual void UpdateDiscontinued() = 0;

/// Called when the current software update has been cancelled by the local application
virtual void UpdateCancelled() = 0;
};

} // namespace chip
4 changes: 4 additions & 0 deletions src/include/platform/OTARequestorInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class OTARequestorInterface

// Manually set OTA Provider parameters
virtual void TestModeSetProviderParameters(NodeId nodeId, FabricIndex fabIndex, EndpointId endpointId) = 0;

// Application directs the Requestor to cancel image update in progress. All the Requestor state is
// cleared, UpdateState is reset to Idle
virtual void CancelImageUpdate() = 0;
};

// The instance of the class implementing OTARequestorInterface must be managed through
Expand Down
5 changes: 5 additions & 0 deletions src/platform/GenericOTARequestorDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ void GenericOTARequestorDriver::UpdateDiscontinued()
mImageProcessor->Abort();
}

void GenericOTARequestorDriver::UpdateCancelled()
{
// Platform might choose to schedule a retry here
}

void GenericOTARequestorDriver::ScheduleDelayedAction(UpdateFailureState state, System::Clock::Seconds32 delay,
System::TimerCompleteCallback action)
{
Expand Down
1 change: 1 addition & 0 deletions src/platform/GenericOTARequestorDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class GenericOTARequestorDriver : public OTARequestorDriver
void UpdateConfirmed(System::Clock::Seconds32 delay) override;
void UpdateSuspended(System::Clock::Seconds32 delay) override;
void UpdateDiscontinued() override;
void UpdateCancelled() override;

private:
void ScheduleDelayedAction(UpdateFailureState state, System::Clock::Seconds32 delay, System::TimerCompleteCallback action);
Expand Down
19 changes: 10 additions & 9 deletions src/platform/Linux/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,29 +180,30 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)

CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block)
{
if ((block.data() == nullptr) || block.empty())
if (!IsSpanUsable(block))
{
ReleaseBlock();
return CHIP_NO_ERROR;
}

// Allocate memory for block data if it has not been done yet
if (mBlock.empty())
if (mBlock.size() < block.size())
{
mBlock = MutableByteSpan(static_cast<uint8_t *>(chip::Platform::MemoryAlloc(block.size())), block.size());
if (mBlock.data() == nullptr)
if (!mBlock.empty())
{
ReleaseBlock();
}
uint8_t * mBlock_ptr = static_cast<uint8_t *>(chip::Platform::MemoryAlloc(block.size()));
if (mBlock_ptr == nullptr)
{
return CHIP_ERROR_NO_MEMORY;
}
mBlock = MutableByteSpan(mBlock_ptr, block.size());
}

// Store the actual block data
CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock);
if (err != CHIP_NO_ERROR)
{
ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format());
return err;
}

return CHIP_NO_ERROR;
}

Expand Down