diff --git a/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.cpp b/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.cpp index fb971ffbdb58a6..ad3d0c814525eb 100644 --- a/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.cpp +++ b/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.cpp @@ -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. @@ -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; +} diff --git a/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.h b/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.h index c219aa5c679f05..d3c00709ea794b 100644 --- a/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.h +++ b/examples/ota-requestor-app/linux/LinuxOTARequestorDriver.h @@ -21,6 +21,8 @@ */ #include "app/clusters/ota-requestor/OTARequestorDriver.h" +namespace chip { + class LinuxOTARequestorDriver : public OTARequestorDriver { @@ -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 diff --git a/examples/ota-requestor-app/linux/README.md b/examples/ota-requestor-app/linux/README.md index 85a57db881da7d..fed5e9462b264f 100644 --- a/examples/ota-requestor-app/linux/README.md +++ b/examples/ota-requestor-app/linux/README.md @@ -30,7 +30,7 @@ In terminal 2: In terminal 3: ``` -./chip-ota-requestor-app -d ${REQUESTOR_LONG_DISCRIMINATOR} -u ${REQUESTOR_UDP_PORT} -i ${PROVIDER_IP_ADDRESS} -n ${PROVIDER_NODE_ID} -q ${DELAY_QUERY_SECONDS} +./chip-ota-requestor-app -d ${REQUESTOR_LONG_DISCRIMINATOR} -u ${REQUESTOR_UDP_PORT} -n ${PROVIDER_NODE_ID} -f ${PROVIDER_FABRIC_INDEX} -q ${DELAY_QUERY_SECONDS} ``` - `{REQUESTOR_LONG_DISCRIMINATOR}` is the long discriminator specified for the @@ -39,7 +39,10 @@ In terminal 3: for secure connections - `${PROVIDER_IP_ADDRESS}` is the IP address of the ota-provider-app that has been resolved manually -- `${PROVIDER_NODE_ID}` is the node ID of the ota-provider-app assigned above +- `${PROVIDER_NODE_ID}` is the node ID of the ota-provider-app; this is a Test + Mode parameter and should not be used in most scenarios +- `${PROVIDER_FABRIC_INDEX}` is the fabric index of the ota-provider-app; this + is a Test Mode parameter and should not be used in most scenarios - `${DELAY_QUERY_SECONDS}` is the amount of time in seconds to wait before initiating secure session establishment and query for software image diff --git a/examples/ota-requestor-app/linux/main.cpp b/examples/ota-requestor-app/linux/main.cpp index 4f38efd37420a2..679bbb8434bb52 100644 --- a/examples/ota-requestor-app/linux/main.cpp +++ b/examples/ota-requestor-app/linux/main.cpp @@ -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; diff --git a/src/app/clusters/ota-requestor/OTARequestor.cpp b/src/app/clusters/ota-requestor/OTARequestor.cpp index d8918c82bd6095..fb85193dfd815d 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.cpp +++ b/src/app/clusters/ota-requestor/OTARequestor.cpp @@ -330,15 +330,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) diff --git a/src/app/clusters/ota-requestor/OTARequestor.h b/src/app/clusters/ota-requestor/OTARequestor.h index 270e80c020187c..4425cfd0eb560c 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.h +++ b/src/app/clusters/ota-requestor/OTARequestor.h @@ -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; } @@ -59,20 +66,34 @@ 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); + + /* Commented out until the API is supported + // Application directs the Requestor to download the image using the suppiled parameter and without + // issuing QueryImage + OTATriggerResult ResumeImageDownload(const BdxDownloadParameters & bdxParameters){ 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 diff --git a/src/app/clusters/ota-requestor/OTARequestorDriver.h b/src/app/clusters/ota-requestor/OTARequestorDriver.h index 098417926d922d..a1bcb6855801e5 100644 --- a/src/app/clusters/ota-requestor/OTARequestorDriver.h +++ b/src/app/clusters/ota-requestor/OTARequestorDriver.h @@ -24,19 +24,84 @@ #pragma once +#include + +namespace chip { + +/* Commented out until the API is supported +// The set of parameters needed for starting a BDX download. +struct BdxDownloadParameters +{ + uint32_t delayedActionTime; // Might not be needed + chip::CharSpan imageURI; + uint32_t softwareVersion; + chip::CharSpan softwareVersionString; // Might not be needed + chip::ByteSpan updateToken; + bool userConsentNeeded; // Might not be needed + chip::ByteSpan metadataForRequestor; // Might not be needed +}; +*/ + +// 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 + + /* Commented out until the API is supported + // 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 diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index f2b60acf39f611..99f50100f5a243 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -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 *