OTA Requestor

This is an implementation of the Matter OTA Requestor functionality that can be used by Matter applications for OTA software updates

Design Overview

There are various components defined to support OTA software updates. The Matter SDK supplies the default implementation to all components. If so desired, a custom implementation may be used to replace the default implementation.

OTARequestorInterface

This is an interface for processing the core requestor logic. This includes sending commands to the OTA Provider cluster as well as handling the responses for those commands. This component also maintains the server attributes for the OTA Requestor cluster.

DefaultOTARequestor class is the default implementation of this interface. Any custom implementation should reside under examples/platform/<platform-name>.

OTARequestorDriver

This is an interface for using/driving the OTARequestorInterface. This component determines the next action to take based on the current status returned by OTARequestorInterface. For instance, after OTARequestorInterface receives a QueryImageResponse that an update is available, it informs OTARequestorDriver which then decides whether it is ready to immediately start the download or to wait on some conditions.

DefaultOTARequestorDriver class is the default implementation of this interface. Any custom implementation should reside under examples/platform/<platform-name>.

Please note the following implementation choices in the default implementation:

  • Upon being notified that an update is available, the image is unconditionally downloaded
  • Upon being notified that the provider is busy, a max number of retries is attempted before the next provider in the default OTA provider list (if one exists) is attempted
  • Upon being notified that an update is not available, querying of the next provider in the default OTA Provider list (if one exists) is attempted
  • Upon being notified that an update has been downloaded, the request to apply the image is immediately sent to the provider
  • Upon being notified that the update may proceed after download, the image is unconditionally applied via the OTAImageProcessorInterface
  • Upon being notified that the update should be discontinued after download, the entire process is aborted
  • Upon a first time boot into a newly applied image, if the image can be confirmed, the provider is immediately notified of the update being applied successfully
  • If an existing OTA update is already in progress, any new attempts to query will be denied
  • A periodic query is attempted every 24 hours, unless overridden
  • The periodic query timer starts whenever OTARequestorInterface is in the idle state

OTAImageProcessorInterface

This is a platform-agnostic interface for processing downloaded chunks of OTA image data. The data could be raw image data meant for flash or metadata. This component should interact with the OTADownloader to drive the download process.

Each platform should provide an implementation of this interface which should reside under src/platform/<platform-name>.

OTADownloader

This is an interface for image download functionality over a particular protocol. Each DownloadProtocolEnum supported should provide an implementation of this interface.

BDXDownloader class is an implementation of this interface for the BDX protocol.

OTARequestorStorage

This is an interface for storing/loading persistent data related to OTA.

DefaultOTARequestorStorage class is the default implementation of this interface. Any custom implementation should reside under examples/platform/<platform-name>.

Steps for including the OTA Requestor functionality in a Matter application

  • Enable Server for the OTA Software Update Requestor cluster in the application zap file
  • Enable Client for the OTA Software Update Provider cluster in the application zap file
  • Implement OTA Requestor components:
    • Use the DefaultOTARequestor class or implement a class derived from OTARequestorInterface
    • Use the DefaultOTARequestorDriver class or implement a class derived from OTARequestorDriver
    • Use the BDXDownloader class or implement a class derived from OTADownloader
    • Implement a class derived from OTAImageProcessorInterface
    • Use the DefaultOTARequestorStorage class or implement a class derived from OTARequestorStorage
  • If using the default implementation of the interfaces defined above, explicitly list all the source files in src/app/clusters/ota-requestor in the application make/build file. For example: src/app/chip_data_model.gni. Otherwise, list the source files where the component implementation reside.
  • Explicitly list all the OTA platform specific files in src/platform. For example: src/platform/Linux/BUILD.gn
  • Instantiate and initialize each component in the application. For example, in an application which uses the default implementation on the Linux platform:
    • Create an instance of the DefaultOTARequestor class
    • Create an instance of the DefaultOTARequestorDriver class
    • Create an instance of the OTAImageProcessorImpl class from src/platform/Linux/OTAImageProcessorImpl.h
    • Create an instance of the BDXDownloader class
    • Create an instance of the DefaultOTARequestorStorage class
    • Register the instance of DefaultOTARequestor through SetRequestorInstance()
    • Initialize the instance of DefaultOTARequestorStorage through DefaultOTARequestorStorage::Init
    • Connect the instances of DefaultOTARequestorStorage, DefaultOTARequestorDriver, and BDXDownloader with the instance of DefaultOTARequestor through DefaultOTARequestor::Init()
    • Connect the instances of DefaultOTARequestor and OTAImageProcessorImpl with the instance of DefaultOTARequestorDriver through DefaultOTARequestorDriver::Init(). It is important that this is performed after DefaultOTARequestor::Init as there are dependencies that DefaultOTARequestor already has access to DefaultOTARequestorDriver by the time this initialization occurs.
    • Connect the instance of BDXDownloader with the instance of OTAImageProcessorImpl through OTAImageProcessorImpl::SetOTADownloader
    • Connect the instance of OTAImageProcessorImpl with the instance of BDXDownloader through OTADownloader::SetImageProcessorDelegate
  • See examples/ota-requestor-app/linux/main.cpp for an example of the initialization code above