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

Update OTA Requestor Server cluster attributes #13484

Merged
merged 2 commits into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,12 +543,10 @@ static void InitOTARequestor(void)
{
#if CONFIG_ENABLE_OTA_REQUESTOR
SetRequestorInstance(&gRequestorCore);
gRequestorCore.SetServerInstance(&Server::GetInstance());
gRequestorCore.SetOtaRequestorDriver(&gRequestorUser);
gRequestorCore.Init(&Server::GetInstance(), &gRequestorUser, &gDownloader);
gImageProcessor.SetOTADownloader(&gDownloader);
gDownloader.SetImageProcessorDelegate(&gImageProcessor);
gRequestorUser.Init(&gRequestorCore, &gImageProcessor);
gRequestorCore.SetBDXDownloader(&gDownloader);
#endif
}

Expand Down
4 changes: 1 addition & 3 deletions examples/lighting-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,7 @@ void AppTask::InitOTARequestor()
sOTAImageProcessor.SetOTADownloader(&sBDXDownloader);
sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor);
sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor);
sOTARequestor.SetOtaRequestorDriver(&sOTARequestorDriver);
sOTARequestor.SetBDXDownloader(&sBDXDownloader);
sOTARequestor.SetServerInstance(&chip::Server::GetInstance());
sOTARequestor.Init(&chip::Server::GetInstance(), &sOTARequestorDriver, &sBDXDownloader);
chip::SetRequestorInstance(&sOTARequestor);
#endif
}
Expand Down
9 changes: 1 addition & 8 deletions examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,7 @@ CHIP_ERROR AppTask::Init()
// Initialize and interconnect the Requestor and Image Processor objects -- START
SetRequestorInstance(&gRequestorCore);

// Set server instance used for session establishment
chip::Server * server = &(chip::Server::GetInstance());
gRequestorCore.SetServerInstance(server);

// Connect the Requestor and Requestor Driver objects
gRequestorCore.SetOtaRequestorDriver(&gRequestorUser);
gRequestorCore.Init(&(chip::Server::GetInstance()), &gRequestorUser, &gDownloader);
gRequestorUser.Init(&gRequestorCore, &gImageProcessor);

// WARNING: this is probably not realistic to know such details of the image or to even have an OTADownloader instantiated at
Expand All @@ -143,8 +138,6 @@ CHIP_ERROR AppTask::Init()

// Connect the gDownloader and Image Processor objects
gDownloader.SetImageProcessorDelegate(&gImageProcessor);

gRequestorCore.SetBDXDownloader(&gDownloader);
// Initialize and interconnect the Requestor and Image Processor objects -- END

// QR code will be used with CHIP Tool
Expand Down
9 changes: 1 addition & 8 deletions examples/ota-requestor-app/efr32/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,7 @@ int main(void)
// Initialize and interconnect the Requestor and Image Processor objects -- START
SetRequestorInstance(&gRequestorCore);

// Set server instance used for session establishment
chip::Server * server = &(chip::Server::GetInstance());
gRequestorCore.SetServerInstance(server);

// Connect the Requestor and Requestor Driver objects
gRequestorCore.SetOtaRequestorDriver(&gRequestorUser);
gRequestorCore.Init(&(chip::Server::GetInstance()), &gRequestorUser, &gDownloader);

OTAImageProcessorParams ipParams;
ipParams.imageFile = CharSpan("test.txt");
Expand All @@ -186,8 +181,6 @@ int main(void)

// Connect the Downloader and Image Processor objects
gDownloader.SetImageProcessorDelegate(&gImageProcessor);

gRequestorCore.SetBDXDownloader(&gDownloader);
// Initialize and interconnect the Requestor and Image Processor objects -- END

EFR32_LOG("Starting Platform Manager Event Loop");
Expand Down
8 changes: 1 addition & 7 deletions examples/ota-requestor-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,8 @@ extern "C" void app_main()

ESPInitConsole();
SetRequestorInstance(&gRequestorCore);

Server * server = &(Server::GetInstance());
gRequestorCore.SetServerInstance(server);
gRequestorCore.SetOtaRequestorDriver(&gRequestorUser);

gRequestorCore.Init(&(Server::GetInstance()), &gRequestorUser, &gDownloader);
gImageProcessor.SetOTADownloader(&gDownloader);
gDownloader.SetImageProcessorDelegate(&gImageProcessor);
gRequestorUser.Init(&gRequestorCore, &gImageProcessor);

gRequestorCore.SetBDXDownloader(&gDownloader);
}
48 changes: 23 additions & 25 deletions examples/ota-requestor-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,27 @@ HelpOptions helpOptions("ota-requestor-app", "Usage: ota-requestor-app [options]

OptionSet * allOptions[] = { &cmdLineOptions, &helpOptions, nullptr };

static void InitOTARequestor(void)
{
// Set the global instance of the OTA requestor core component
SetRequestorInstance(&gRequestorCore);

gRequestorCore.Init(&(chip::Server::GetInstance()), &gRequestorUser, &gDownloader);
gRequestorUser.Init(&gRequestorCore, &gImageProcessor);

// WARNING: this is probably not realistic to know such details of the image or to even have an OTADownloader instantiated at
// the beginning of program execution. We're using hardcoded values here for now since this is a reference application.
// TODO: instatiate and initialize these values when QueryImageResponse tells us an image is available
// TODO: add API for OTARequestor to pass QueryImageResponse info to the application to use for OTADownloader init
OTAImageProcessorParams ipParams;
ipParams.imageFile = CharSpan("test.txt");
gImageProcessor.SetOTAImageProcessorParams(ipParams);
gImageProcessor.SetOTADownloader(&gDownloader);

// Set the image processor instance used for handling image being downloaded
gDownloader.SetImageProcessorDelegate(&gImageProcessor);
}

bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue)
{
bool retval = true;
Expand Down Expand Up @@ -192,31 +213,8 @@ int main(int argc, char * argv[])
// Initialize device attestation config
SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());

// Initialize and interconnect the Requestor and Image Processor objects -- START
SetRequestorInstance(&gRequestorCore);

// Set server instance used for session establishment
chip::Server * server = &(chip::Server::GetInstance());
gRequestorCore.SetServerInstance(server);

// Connect the Requestor and Requestor Driver objects
gRequestorCore.SetOtaRequestorDriver(&gRequestorUser);
gRequestorUser.Init(&gRequestorCore, &gImageProcessor);

// WARNING: this is probably not realistic to know such details of the image or to even have an OTADownloader instantiated at
// the beginning of program execution. We're using hardcoded values here for now since this is a reference application.
// TODO: instatiate and initialize these values when QueryImageResponse tells us an image is available
// TODO: add API for OTARequestor to pass QueryImageResponse info to the application to use for OTADownloader init
OTAImageProcessorParams ipParams;
ipParams.imageFile = CharSpan("test.txt");
gImageProcessor.SetOTAImageProcessorParams(ipParams);
gImageProcessor.SetOTADownloader(&gDownloader);

// Connect the Downloader and Image Processor objects
gDownloader.SetImageProcessorDelegate(&gImageProcessor);

gRequestorCore.SetBDXDownloader(&gDownloader);
// Initialize and interconnect the Requestor and Image Processor objects -- END
// Initialize all OTA download components
InitOTARequestor();

// Test Mode operation: If a delay is provided, QueryImage after the timer expires
if (delayQueryTimeInSec > 0)
Expand Down
3 changes: 1 addition & 2 deletions src/app/clusters/ota-requestor/BDXDownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,13 @@ CHIP_ERROR BDXDownloader::HandleBdxEvent(const chip::bdx::TransferSession::Outpu
{
// BDX transfer is not complete until BlockAckEOF has been sent
SetState(State::kComplete);

// TODO: how/when to reset the BDXDownloader to be ready to handle another download
}
break;
}
case TransferSession::OutputEventType::kBlockReceived: {
chip::ByteSpan blockData(outEvent.blockdata.Data, outEvent.blockdata.Length);
ReturnErrorOnFailure(mImageProcessor->ProcessBlock(blockData));
mStateDelegate->OnUpdateProgressChanged(mImageProcessor->GetPercentComplete());

// TODO: this will cause problems if Finalize() is not guaranteed to do its work after ProcessBlock().
if (outEvent.blockdata.IsEof)
Expand Down
5 changes: 4 additions & 1 deletion src/app/clusters/ota-requestor/BDXDownloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ class BDXDownloader : public chip::OTADownloader
class StateDelegate
{
public:
// Handle download state change
virtual void OnDownloadStateChanged(State state) = 0;
virtual ~StateDelegate() = default;
// Handle update progress change
virtual void OnUpdateProgressChanged(uint8_t percent) = 0;
virtual ~StateDelegate() = default;
};

// To be called when there is an incoming message to handle (of any protocol type)
Expand Down
61 changes: 45 additions & 16 deletions src/app/clusters/ota-requestor/OTARequestor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
* OTA Requestor logic is contained in this class.
*/

#include <app-common/zap-generated/attributes/Accessors.h>
#include <lib/core/CHIPEncoding.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/OTAImageProcessor.h>
Expand Down Expand Up @@ -88,6 +87,17 @@ static void LogApplyUpdateResponse(const ApplyUpdateResponse::DecodableType & re
ChipLogDetail(SoftwareUpdate, " delayedActionTime: %" PRIu32 " seconds", response.delayedActionTime);
}

static void SetUpdateStateAttribute(OTAUpdateStateEnum state)
{
OtaRequestorServerSetUpdateState(state);

// The UpdateStateProgress attribute only applies to the querying state
if (state != OTAUpdateStateEnum::kQuerying)
{
OtaRequestorServerSetUpdateStateProgress(0);
}
}

void StartDelayTimerHandler(System::Layer * systemLayer, void * appState)
{
VerifyOrReturn(appState != nullptr);
Expand Down Expand Up @@ -135,13 +145,16 @@ void OTARequestor::OnQueryImageResponse(void * context, const QueryImageResponse
case OTAQueryStatus::kBusy:
requestorCore->mOtaRequestorDriver->UpdateNotFound(UpdateNotFoundReason::Busy,
System::Clock::Seconds32(response.delayedActionTime.ValueOr(0)));
SetUpdateStateAttribute(OTAUpdateStateEnum::kDelayedOnQuery);
break;
case OTAQueryStatus::kNotAvailable:
requestorCore->mOtaRequestorDriver->UpdateNotFound(UpdateNotFoundReason::NotAvailable,
System::Clock::Seconds32(response.delayedActionTime.ValueOr(0)));
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
break;
default:
requestorCore->mOtaRequestorDriver->HandleError(OTAUpdateStateEnum::kQuerying, CHIP_ERROR_BAD_REQUEST);
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
break;
}
}
Expand All @@ -153,6 +166,7 @@ void OTARequestor::OnQueryImageFailure(void * context, EmberAfStatus status)

ChipLogDetail(SoftwareUpdate, "QueryImage failure response %" PRIu8, status);
requestorCore->mOtaRequestorDriver->HandleError(OTAUpdateStateEnum::kQuerying, CHIP_ERROR_BAD_REQUEST);
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
}

void OTARequestor::OnApplyUpdateResponse(void * context, const ApplyUpdateResponse::DecodableType & response)
Expand All @@ -169,9 +183,11 @@ void OTARequestor::OnApplyUpdateResponse(void * context, const ApplyUpdateRespon
break;
case OTAApplyUpdateAction::kAwaitNextAction:
requestorCore->mOtaRequestorDriver->UpdateSuspended(System::Clock::Seconds32(response.delayedActionTime));
SetUpdateStateAttribute(OTAUpdateStateEnum::kDelayedOnApply);
break;
case OTAApplyUpdateAction::kDiscontinue:
requestorCore->mOtaRequestorDriver->UpdateDiscontinued();
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
break;
}
}
Expand All @@ -183,6 +199,7 @@ void OTARequestor::OnApplyUpdateFailure(void * context, EmberAfStatus status)

ChipLogDetail(SoftwareUpdate, "ApplyUpdate failure response %" PRIu8, status);
requestorCore->mOtaRequestorDriver->HandleError(OTAUpdateStateEnum::kApplying, CHIP_ERROR_BAD_REQUEST);
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
}

EmberAfStatus OTARequestor::HandleAnnounceOTAProvider(app::CommandHandler * commandObj,
Expand Down Expand Up @@ -271,8 +288,10 @@ void OTARequestor::OnConnected(void * context, OperationalDeviceProxy * devicePr
{
ChipLogError(SoftwareUpdate, "Failed to send QueryImage command: %" CHIP_ERROR_FORMAT, err.Format());
requestorCore->mOtaRequestorDriver->HandleError(OTAUpdateStateEnum::kQuerying, err);
return;
}

SetUpdateStateAttribute(OTAUpdateStateEnum::kQuerying);
break;
}
case kStartBDX: {
Expand All @@ -282,8 +301,11 @@ void OTARequestor::OnConnected(void * context, OperationalDeviceProxy * devicePr
{
ChipLogError(SoftwareUpdate, "Failed to start download: %" CHIP_ERROR_FORMAT, err.Format());
requestorCore->mOtaRequestorDriver->HandleError(OTAUpdateStateEnum::kDownloading, err);
carol-apple marked this conversation as resolved.
Show resolved Hide resolved
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
return;
}

SetUpdateStateAttribute(OTAUpdateStateEnum::kDownloading);
break;
}
case kApplyUpdate: {
Expand All @@ -293,30 +315,18 @@ void OTARequestor::OnConnected(void * context, OperationalDeviceProxy * devicePr
{
ChipLogError(SoftwareUpdate, "Failed to send ApplyUpdate command: %" CHIP_ERROR_FORMAT, err.Format());
requestorCore->mOtaRequestorDriver->HandleError(OTAUpdateStateEnum::kApplying, err);
SetUpdateStateAttribute(OTAUpdateStateEnum::kIdle);
return;
carol-apple marked this conversation as resolved.
Show resolved Hide resolved
}

SetUpdateStateAttribute(OTAUpdateStateEnum::kApplying);
break;
}
default:
break;
}
}

OTARequestorInterface::OTATriggerResult OTARequestor::TriggerImmediateQuery()
{

if (mProviderNodeId != kUndefinedNodeId)
{
ConnectToProvider(kQueryImage);
return kTriggerSuccessful;
}
else
{
ChipLogError(SoftwareUpdate, "No OTA Providers available");
return kNoProviderKnown;
}
}

// Called whenever FindOrEstablishSession fails
void OTARequestor::OnConnectionFailure(void * context, PeerId peerId, CHIP_ERROR error)
{
Expand All @@ -342,6 +352,20 @@ void OTARequestor::OnConnectionFailure(void * context, PeerId peerId, CHIP_ERROR
}
}

OTARequestorInterface::OTATriggerResult OTARequestor::TriggerImmediateQuery()
carol-apple marked this conversation as resolved.
Show resolved Hide resolved
{
if (mProviderNodeId != kUndefinedNodeId)
{
ConnectToProvider(kQueryImage);
return kTriggerSuccessful;
}
else
{
ChipLogError(SoftwareUpdate, "No OTA Providers available");
return kNoProviderKnown;
}
}

void OTARequestor::DownloadUpdate()
{
ConnectToProvider(kStartBDX);
Expand Down Expand Up @@ -369,6 +393,11 @@ void OTARequestor::OnDownloadStateChanged(OTADownloader::State state)
}
}

void OTARequestor::OnUpdateProgressChanged(uint8_t percent)
{
OtaRequestorServerSetUpdateStateProgress(percent);
}

CHIP_ERROR OTARequestor::SendQueryImageRequest(OperationalDeviceProxy & deviceProxy)
{
constexpr OTADownloadProtocol kProtocolsSupported[] = { OTADownloadProtocol::kBDXSynchronous };
Expand Down
Loading