# 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/`. ### 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/`. 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/`. ### 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/`. ## 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