Skip to content

Commit

Permalink
[OTA Requestor] Implement the CancelImageUpdate() OTARequestor API (p…
Browse files Browse the repository at this point in the history
…roject-chip#13778)

* Implement the CancelImageUpdate() OTARequestor API

* Restyled by clang-format

* Add CancelImageUpdate() to OTARequestorInterface

* Add the override modifier

* Add UpdateCancelled() API to OTARequestorDriver

* Restyled by clang-format

* Fix a bug in SetBlock() where varied block size will kill the download

Issue: project-chip#13393

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
selissia and restyled-commits authored Jan 26, 2022
1 parent 12db26d commit 3a1a5b0
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 19 deletions.
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
// 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);

// 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
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

0 comments on commit 3a1a5b0

Please sign in to comment.