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] Add various Requestor API declarations #12755

Merged
merged 10 commits into from
Dec 10, 2021
7 changes: 7 additions & 0 deletions examples/ota-requestor-app/linux/LinuxOTARequestorDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "LinuxOTARequestorDriver.h"

using namespace chip;

// A call into the application logic to give it a chance to allow or stop the Requestor
// from proceeding with actual image download. Returning TRUE will allow the download
// to proceed, returning FALSE will abort the download process.
Expand All @@ -32,3 +34,8 @@ bool LinuxOTARequestorDriver::CheckImageDownloadAllowed()

// Notify the application that the download is complete and the image can be applied
void LinuxOTARequestorDriver::ImageDownloadComplete() {}

UserConsentAction LinuxOTARequestorDriver::RequestUserConsent()
{
return ImmediateYes;
}
8 changes: 8 additions & 0 deletions examples/ota-requestor-app/linux/LinuxOTARequestorDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*/
#include "app/clusters/ota-requestor/OTARequestorDriver.h"

namespace chip {

class LinuxOTARequestorDriver : public OTARequestorDriver
{

Expand All @@ -34,5 +36,11 @@ class LinuxOTARequestorDriver : public OTARequestorDriver
// Notify the application that the download is complete and the image can be applied
void ImageDownloadComplete();

// Application is directed to complete user consent: either return ImmediateYes/ImmediateNo
// without blocking or return Requested and call OTARequestor::OnUserConsent() later.
virtual UserConsentAction RequestUserConsent();

// Virtual functions from OTARequestorDriver -- end
};

} // namespace chip
1 change: 1 addition & 0 deletions examples/ota-requestor-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ using chip::VendorId;
using chip::Callback::Callback;
using chip::System::Layer;
using chip::Transport::PeerAddress;
using namespace chip;
using namespace chip::ArgParser;
using namespace chip::Messaging;
using namespace chip::app::Clusters::OtaSoftwareUpdateProvider::Commands;
Expand Down
20 changes: 15 additions & 5 deletions src/app/clusters/ota-requestor/OTARequestor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,25 @@ void OTARequestor::OnConnected(void * context, OperationalDeviceProxy * devicePr
}
}

// Called whenever FindOrEstablishSession fails
void OTARequestor::OnConnectionFailure(void * context, NodeId deviceId, CHIP_ERROR error)
OTARequestor::OTATriggerResult OTARequestor::TriggerImmediateQuery()
{
ChipLogError(SoftwareUpdate, "Failed to connect to node 0x%" PRIX64 ": %" CHIP_ERROR_FORMAT, deviceId, error.Format());

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

void OTARequestor::TriggerImmediateQuery()
// Called whenever FindOrEstablishSession fails
void OTARequestor::OnConnectionFailure(void * context, NodeId deviceId, CHIP_ERROR error)
{
ConnectToProvider(kQueryImage);
ChipLogError(SoftwareUpdate, "Failed to connect to node 0x%" PRIX64 ": %" CHIP_ERROR_FORMAT, deviceId, error.Format());
}

CHIP_ERROR OTARequestor::BuildQueryImageRequest(QueryImageRequest & request)
Expand Down
32 changes: 27 additions & 5 deletions src/app/clusters/ota-requestor/OTARequestor.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,16 @@ class OTARequestor : public OTARequestorInterface

// Application interface declarations -- start

// Return value for various trigger-type APIs
enum OTATriggerResult
{
kTriggerSuccessful = 0,
kNoProviderKnown = 1
};

// Application directs the Requestor to start the Image Query process
// and download the new image if available
void TriggerImmediateQuery();
OTATriggerResult TriggerImmediateQuery();

// A setter for the delegate class pointer
void SetOtaRequestorDriver(OTARequestorDriver * driver) { mOtaRequestorDriver = driver; }
Expand All @@ -59,20 +66,35 @@ class OTARequestor : public OTARequestorInterface
// The BDXDownloader instance should already have the ImageProcessingDelegate set.
void SetBDXDownloader(chip::BDXDownloader * downloader) { mBdxDownloader = downloader; }

// Application directs the Requestor to abort any processing related to
// the image update
// 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 notifies the Requestor on the user consent action, TRUE if consent is given,
// FALSE otherwise
void OnUserConsent(bool result);
selissia marked this conversation as resolved.
Show resolved Hide resolved

// Application directs the Requestor to download the image using the suppiled parameter and without
// issuing QueryImage
OTATriggerResult ResumeImageDownload(const BdxDownloadParameters & bdxParameters)
selissia marked this conversation as resolved.
Show resolved Hide resolved
{ /* NOT IMPLEMENTED YET */
return kTriggerSuccessful;
}

// Application interface declarations -- end

// Virtual functions from OTARequestorInterface start
// Virtual functions from OTARequestorInterface -- start

// Handler for the AnnounceOTAProvider command
EmberAfStatus HandleAnnounceOTAProvider(
app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
const app::Clusters::OtaSoftwareUpdateRequestor::Commands::AnnounceOtaProvider::DecodableType & commandData);

// Virtual functions from OTARequestorInterface -- end

/**
* Called to set the server instance which used to get access to the system resources necessary to open CASE sessions and drive
* BDX transfers
Expand Down
61 changes: 61 additions & 0 deletions src/app/clusters/ota-requestor/OTARequestorDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,80 @@

#pragma once

#include <protocols/bdx/BdxMessages.h>

namespace chip {

// The set of parameters needed for starting a BDX download.
struct BdxDownloadParameters
{
uint32_t delayedActionTime;
chip::CharSpan imageURI;
uint32_t softwareVersion;
chip::CharSpan softwareVersionString;
chip::ByteSpan updateToken;
bool userConsentNeeded;
chip::ByteSpan metadataForRequestor;
};
selissia marked this conversation as resolved.
Show resolved Hide resolved

// Possible values for the UpdateState attribute
enum UpdateStateEnum
{
Unknown = 0,
Idle = 1,
Querying = 2,
DelayedOnQuery = 3,
Downloading = 4,
Applying = 5,
DelayedOnApply = 6,
RollingBack = 7,
DelayedOnUserConsent = 8,
};

// Return type for RequestUserConsent()
enum UserConsentAction
{
ImmediateYes = 1,
ImmediateNo = 2,
Requested = 3,
};

// Interface class to abstract the OTA-related business logic. Each application
// must implement this interface. All calls must be non-blocking unless stated otherwise
class OTARequestorDriver
{
public:
// Mandatory methods, applications are required to implement these

// A call into the application logic to give it a chance to allow or stop the Requestor
// from proceeding with actual image download. Returning TRUE will allow the download
// to proceed, returning FALSE will abort the download process.
virtual bool CheckImageDownloadAllowed() = 0;

// Application is directed to complete user consent: either return ImmediateYes/ImmediateNo
// without blocking or return Requested and call OTARequestor::OnUserConsent() later.
virtual UserConsentAction RequestUserConsent() = 0;

// Notify the application that the download is complete and the image can be applied
virtual void ImageDownloadComplete() = 0;

// Optional methods, applications may choose to implement these

// This method informs the application of the BDX download parameters. This info can be used
// later on for diecting the Requestor to resume an interrupted download
virtual void PostBdxDownloadParameters(const BdxDownloadParameters & bdxParameters){};

// Return maximum supported download block size
virtual uint16_t GetMaxDownloadBlockSize() { return 1024; }

// Get Version of the last downloaded image, return CHIP_ERROR_NOT_FOUND if none exists
virtual CHIP_ERROR GetLastDownloadedImageVersion(uint32_t & out_version) { return CHIP_ERROR_NOT_FOUND; }

// Notify application of a change in the UpdateState attribute
virtual void NotifyUpdateStateChange(chip::UpdateStateEnum state){};

// Destructor
virtual ~OTARequestorDriver() = default;
};

} // namespace chip
9 changes: 9 additions & 0 deletions src/lib/core/CHIPError.h
Original file line number Diff line number Diff line change
Expand Up @@ -2332,6 +2332,15 @@ using CHIP_ERROR = ::chip::ChipError;
* the required elements
*/
#define CHIP_ERROR_IM_MALFORMED_DATA_VERSION_FILTER_IB CHIP_CORE_ERROR(0xd7)

/**
* @def CHIP_ERROR_NOT_FOUND
*
* @brief
* The item referenced in the function call was not found
*/
#define CHIP_ERROR_NOT_FOUND CHIP_CORE_ERROR(0xd8)

/**
* @def CHIP_ERROR_INVALID_SCHEME_PREFIX
*
Expand Down