Skip to content

Commit

Permalink
Clean up the code that sends the query image response from the provider
Browse files Browse the repository at this point in the history
  • Loading branch information
nivi-apple committed Feb 9, 2023
1 parent d6bb8c2 commit 07667b2
Showing 1 changed file with 72 additions and 71 deletions.
143 changes: 72 additions & 71 deletions src/darwin/Framework/CHIP/MTROTAProviderDelegateBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -608,81 +608,82 @@ bool GetPeerNodeInfo(CommandHandler * commandHandler, const ConcreteCommandPath
__block CommandHandler::Handle handle(commandObj);
__block ConcreteCommandPath cachedCommandPath(commandPath.mEndpointId, commandPath.mClusterId, commandPath.mCommandId);

auto completionHandler = ^(
MTROTASoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data, NSError * _Nullable error) {
[controller
asyncDispatchToMatterQueue:^() {
assertChipStackLockedByCurrentThread();

CommandHandler * handler = EnsureValidState(handle, cachedCommandPath, "QueryImage", data, error);
VerifyOrReturn(handler != nullptr);

ChipLogDetail(Controller, "QueryImage: application responded with: %s",
[[data description] cStringUsingEncoding:NSUTF8StringEncoding]);

Commands::QueryImageResponse::Type response;
ConvertFromQueryImageResponseParms(data, response);

auto hasUpdate = [data.status isEqual:@(MTROtaSoftwareUpdateProviderOTAQueryStatusUpdateAvailable)];
auto isBDXProtocolSupported = [commandParams.protocolsSupported
containsObject:@(MTROtaSoftwareUpdateProviderOTADownloadProtocolBDXSynchronous)];
auto completionHandler
= ^(MTROTASoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data, NSError * _Nullable error) {
[controller
asyncDispatchToMatterQueue:^() {
assertChipStackLockedByCurrentThread();

if (hasUpdate && isBDXProtocolSupported) {
auto fabricIndex = handler->GetSubjectDescriptor().fabricIndex;
auto nodeId = handler->GetSubjectDescriptor().subject;
CHIP_ERROR err = gOtaSender.PrepareForTransfer(fabricIndex, nodeId);
if (CHIP_NO_ERROR != err) {
LogErrorOnFailure(err);
if (err == CHIP_ERROR_BUSY) {
Commands::QueryImageResponse::Type busyResponse;
busyResponse.status = static_cast<OTAQueryStatus>(MTROTASoftwareUpdateProviderOTAQueryStatusBusy);
busyResponse.delayedActionTime.SetValue(response.delayedActionTime.ValueOr(kDelayedActionTimeSeconds));
handler->AddResponse(cachedCommandPath, busyResponse);
handle.Release();
return;
}
handler->AddStatus(cachedCommandPath, Protocols::InteractionModel::Status::Failure);
handle.Release();
gOtaSender.ResetState();
return;
}
auto targetNodeId
= handler->GetExchangeContext()->GetSessionHandle()->AsSecureSession()->GetLocalScopedNodeId();
CommandHandler * handler = EnsureValidState(handle, cachedCommandPath, "QueryImage", data, error);
VerifyOrReturn(handler != nullptr);

char uriBuffer[kMaxBDXURILen];
MutableCharSpan uri(uriBuffer);
err = bdx::MakeURI(targetNodeId.GetNodeId(), AsCharSpan(data.imageURI), uri);
if (CHIP_NO_ERROR != err) {
LogErrorOnFailure(err);
handler->AddStatus(cachedCommandPath, Protocols::InteractionModel::Status::Failure);
handle.Release();
gOtaSender.ResetState();
return;
}
ChipLogDetail(Controller, "QueryImage: application responded with: %s",
[[data description] cStringUsingEncoding:NSUTF8StringEncoding]);

response.imageURI.SetValue(uri);
handler->AddResponse(cachedCommandPath, response);
handle.Release();
return;
}
if (!hasUpdate) {
// Send whatever error response our delegate decided on.
handler->AddResponse(cachedCommandPath, response);
} else {
// We must have isBDXProtocolSupported false. Send the corresponding error status.
Commands::QueryImageResponse::Type protocolNotSupportedResponse;
protocolNotSupportedResponse.status
= static_cast<OTAQueryStatus>(MTROTASoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported);
handler->AddResponse(cachedCommandPath, protocolNotSupportedResponse);
}
handle.Release();
gOtaSender.ResetState();
}
Commands::QueryImageResponse::Type response;

// If BDX protocol is not supported, send a response with status - Protocol Not supported
if (![commandParams.protocolsSupported
containsObject:@(MTROtaSoftwareUpdateProviderOTADownloadProtocolBDXSynchronous)]) {
response.status
= static_cast<OTAQueryStatus>(MTROTASoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported);
} else if ([data.status isEqual:@(MTROtaSoftwareUpdateProviderOTAQueryStatusUpdateAvailable)]) {
ConvertFromQueryImageResponseParms(data, response);

// If there is an update available, return a response with status - Available and image uri set in the
// response
auto fabricIndex = handler->GetSubjectDescriptor().fabricIndex;
auto nodeId = handler->GetSubjectDescriptor().subject;
CHIP_ERROR err = gOtaSender.PrepareForTransfer(fabricIndex, nodeId);
if (CHIP_NO_ERROR != err) {
LogErrorOnFailure(err);

// Handle busy error separately as we have a query image response status that maps to busy
if (err == CHIP_ERROR_BUSY) {
response.status = static_cast<OTAQueryStatus>(MTROTASoftwareUpdateProviderOTAQueryStatusBusy);
if (!response.delayedActionTime.HasValue()) {
response.delayedActionTime.SetValue(kDelayedActionTimeSeconds);
}
} else {
handler->AddStatus(cachedCommandPath, StatusIB(err).mStatus);
handle.Release();
gOtaSender.ResetState();
return;
}
}
auto targetNodeId
= handler->GetExchangeContext()->GetSessionHandle()->AsSecureSession()->GetLocalScopedNodeId();

char uriBuffer[kMaxBDXURILen];
MutableCharSpan uri(uriBuffer);
err = bdx::MakeURI(targetNodeId.GetNodeId(), AsCharSpan(data.imageURI), uri);
if (CHIP_NO_ERROR != err) {
LogErrorOnFailure(err);
handler->AddStatus(cachedCommandPath, StatusIB(err).mStatus);
handle.Release();
gOtaSender.ResetState();
return;
}

response.imageURI.SetValue(uri);
handler->AddResponse(cachedCommandPath, response);
handle.Release();
} else {
response.status = static_cast<OTAQueryStatus>([data.status intValue]);
}
handler->AddResponse(cachedCommandPath, response);
handle.Release();

errorHandler:^(NSError *) {
// Not much we can do here
}];
};
// Do not reset state if we have an update available or are returning busy (since we are currently in a BDX
// session)
if (response.status != OTAQueryStatus::kBusy && response.status != OTAQueryStatus::kUpdateAvailable) {
gOtaSender.ResetState();
}
}
errorHandler:^(NSError *) {
// Not much we can do here
}];
};

auto strongDelegate = mDelegate;
dispatch_async(mDelegateNotificationQueue, ^{
Expand Down

0 comments on commit 07667b2

Please sign in to comment.