blob: 9cb47171aae55514c437ba2d25e550efa4afc4e6 [file] [log] [blame] [view]
# ota-requestor-app (Linux)
This is a reference application that is both a server for the OTA Requestor
Cluster, as well as a client of the OTA Provider Cluster. It can initiate a
software update with a given OTA Provider node, and download a file.
## Build
Suggest doing the following:
```
scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux out/debug chip_config_network_layer_ble=false
```
## Usage
In addition to the general options available to all Linux applications, the
following command line options are available for the OTA Requestor application.
Note that these options are for testing purposes.
| Command Line Option | Description |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -a, --autoApplyImage | If supplied, apply the image immediately after download. Otherwise, the OTA update is complete after image download. |
| -c, --requestorCanConsent \<true \| false\> | Value for the RequestorCanConsent field in the QueryImage command. If not supplied, the value is determined by the driver. |
| -d, --disableNotifyUpdateApplied | If supplied, disable sending of the NotifyUpdateApplied command. Otherwise, after successfully loading into the updated image, send the NotifyUpdateApplied command. |
| -f, --otaDownloadPath \<file path\> | If supplied, the OTA image is downloaded to the given fully-qualified file-path. Otherwise, the default location for the downloaded image is at /tmp/test.bin |
| -p, --periodicQueryTimeout \<time in seconds\> | The periodic time interval to wait before attempting to query a provider from the default OTA provider list. If none or zero is supplied, the value is determined by the driver. |
| -u, --userConsentState \<granted \| denied \| deferred\> | Represents the current user consent status when the OTA Requestor is acting as a user consent delegate. This value is only applicable if value of the UserConsentNeeded field in the QueryImageResponse is set to true. This value is used for the first attempt to download. For all subsequent queries, the value of granted will be used.<li> granted: Authorize OTA requestor to download an OTA image <li> denied: Forbid OTA requestor to download an OTA image <li> deferred: Defer obtaining user consent |
| -w, --watchdogTimeout \<time in seconds\> | Maximum amount of time allowed for an OTA download before the process is cancelled and state reset to idle. If none or zero is supplied, the value is determined by the driver. |
## Software Image Version
The current software version of the OTA Requestor application is defined by
`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` in
[CHIPProjectConfig.h](https://github.com/project-chip/connectedhomeip/blob/master/config/standalone/CHIPProjectConfig.h).
This value can be confirmed by reading the `SoftwareVersion` attribute of the
Basic Information cluster:
```
out/chip-tool basic read software-version 0x1234567890 0
```
### Validations
On receiving the QueryImageResponse from the OTA Provider application, the OTA
Requestor application will verify that the software version specified in the
`SoftwareVersion` field of the response contains a value newer than the current
running version. If the update supplied does not pass this version check, the
following log message should be expected, indicating the update will not
proceed:
```
[1648233572232] [48462:7613274] CHIP: [SWU] Available update version 1 is <= current version 1, update ignored
```
If the OTA update progresses to downloading, the process will abort if the
software image
[header](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-provider-app/linux#software-image-header)
is missing. The following log messages should be expected:
```
[1648246917398] [71786:7874994] CHIP: [SWU] Image does not contain a valid header
[1648246917399] [71786:7874994] CHIP: [BDX] TransferSession error
```
On booting into the new image, if the running version does not match the version
specified in the QueryImageResponse, the following log message should be
expected:
```
[1648244159295] [58606:7774255] CHIP: [SWU] Failed to confirm image: ../../examples/ota-requestor-app/linux/third_party/connectedhomeip/src/platform/Linux/OTAImageProcessorImpl.cpp:110: CHIP Error 0x00000003: Incorrect state
```
This message serves as a warning that the new image is not expected. However,
the OTA Requestor application will recover gracefully and return to a state
where another OTA update may be initiated.
### Generate Images
To validate booting into a newer OTA Requestor image on the Linux platform, the
following must be performed:
1. Modify `CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` to a value greater than
the current running version
2. [Build](https://github.com/project-chip/connectedhomeip/blob/master/examples/ota-requestor-app/linux/README.md#build)
an OTA Requestor application with the new version
3. Using the executable created in step 2, generate an image with a software
image
[header](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-provider-app/linux#software-image-header)
that matches the version in step 1
4. Use this generated binary when supplying the image file to the OTA Provider
application
5. Launch the original application (an OTA Requestor application generated prior
to step 1) with the command line option `--autoApplyImage`
## Common Instructions
The Linux
[ota-provider-app](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-provider-app/linux)
can be used together with this reference application to test OTA features. Here
are some common instructions for building and commissioning the applications.
### OTA Provider application
#### Build the OTA Provider application
Follow instructions
[here](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-provider-app/linux#build)
#### Run the OTA Provider application
```
out/chip-ota-provider-app --discriminator ${PROVIDER_LONG_DISCRIMINATOR} --secured-device-port ${PROVIDER_UDP_PORT} --KVS ${KVS_STORE_LOCATION} --filepath ${SW_IMAGE_FILE}
```
- `${PROVIDER_LONG_DISCRIMINATOR}` is the long discriminator specified for the
OTA Provider application for commissioning discovery. If none is supplied,
the default is 3840. This must be different from the value used by the OTA
Requestor application.
- `${PROVIDER_UDP_PORT}` is the UDP port that the OTA Provider application
listens on for secure connections. If none is supplied, the default is 5540.
This must be different from the value used by the OTA Requestor application.
- `${KVS_STORE_LOCATION}` is a location where the KVS items will be stored. If
none is supplied, the default is /tmp/chip_kvs. This must be different from
the value used by the OTA Requestor application.
- `${SW_IMAGE_FILE}` is the file representing a software image to be served.
This file must include a header as defined in the specification.
#### Commission the OTA Provider application
```
out/chip-tool pairing onnetwork-long ${PROVIDER_NODE_ID} 20202021 ${PROVIDER_LONG_DISCRIMINATOR}
```
- `${PROVIDER_NODE_ID}` is the node id to assign to the OTA Provider
application running
- `${PROVIDER_LONG_DISCRIMINATOR}` is the long discriminator of the OTA
Provider application running
### OTA Requestor application
#### Build the OTA Requestor application
Follow instructions
[here](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-requestor-app/linux#build)
#### Run the OTA Requestor application:
```
out/chip-ota-requestor-app --discriminator ${REQUESTOR_LONG_DISCRIMINATOR} --secured-device-port ${REQUESTOR_UDP_PORT} --KVS ${KVS_STORE_LOCATION} --periodicQueryTimeout ${TIME_IN_SECONDS} --autoApplyImage
```
- `${REQUESTOR_LONG_DISCRIMINATOR}` is the long discriminator specified for
the OTA Requestor application for commissioning discovery. If none is
supplied, the default is 3840. This must be different from the value used by
the OTA Provider application.
- `${REQUESTOR_UDP_PORT}` is the UDP port that the OTA Requestor application
listens on for secure connections. If none is supplied, the default is 5540.
This must be different from the value used by the OTA Provider application.
- `${KVS_STORE_LOCATION}` is a location where the KVS items will be stored. If
none is supplied, the default is /tmp/chip_kvs. This must be different from
the value used by the OTA Provider application.
- `${TIME_IN_SECONDS}` is the periodic timeout for querying providers in the
default OTA provider list. If none or zero is supplied the timeout is set to
every 24 hours.
- `--autoApplyImage` is supplied to indicate the image should be immediately
applied after download. If not supplied, the OTA update is complete after
image download.
#### Commission the OTA Requestor application
```
out/chip-tool pairing onnetwork-long ${REQUESTOR_NODE_ID} 20202021 ${REQUESTOR_LONG_DISCRIMINATOR}
```
- `${REQUESTOR_NODE_ID}` is the node id to assign to the OTA Requestor
application running
- `${REQUESTOR_LONG_DISCRIMINATOR}` is the long discriminator of the OTA
Requestor application running
## Examples
There are two methods for this reference application to connect to a device
running OTA Provider server and download a software image.
If the ACL entry on the provider has not been properly installed, the QueryImage
command will be denied. Logs similar to the following may be observed on the OTA
Provider application:
```
[1648244658368] [59686:7786439] CHIP: [DMG] AccessControl: checking f=1 a=c s=0x000000000000FACE t= c=0x0000_0029 e=0 p=o
[1648244658368] [59686:7786439] CHIP: [DMG] AccessControl: denied
```
If this is encountered, follow instructions
[here](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-provider-app/linux#access-control-requirements)
to install. Note that this only needs to be performed once. There is no need to
write this ACL entry again unless the KVS store has been removed.
### Trigger using AnnounceOTAProvider Command
When the `AnnounceOTAProvider` command is received, it will trigger a QueryImage
command to the provider specified in the command and start the OTA process.
#### In terminal 1:
**Build the OTA Provider application**
```
scripts/examples/gn_build_example.sh examples/ota-provider-app/linux/ out chip_config_network_layer_ble=false
```
**Run the OTA Provider application**
```
out/chip-ota-provider-app --discriminator 22 --secured-device-port 5565 --KVS /tmp/chip_kvs_provider --filepath /tmp/ota-image.bin
```
#### In terminal 2:
**Build the OTA Requestor application**
```
scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux/ out chip_config_network_layer_ble=false
```
**Run the OTA Requestor application**
```
out/chip-ota-requestor-app --discriminator 18 --secured-device-port 5560 --KVS /tmp/chip_kvs_requestor
```
#### In terminal 3:
**Commission the OTA Provider application**
```
out/chip-tool pairing onnetwork-long 0xDEADBEEF 20202021 22
```
**Commission the OTA Requestor application**
```
out/chip-tool pairing onnetwork-long 0x1234567890 20202021 18
```
**Issue the AnnounceOTAProvider command**
```
out/chip-tool otasoftwareupdaterequestor announce-otaprovider 0xDEADBEEF 0 0 0 0x1234567890 0
```
The OTA Requestor application with node ID 0x1234567890 will process this
command and send a QueryImage command to the OTA Provider with node ID
`0xDEADBEEF`, as specified in the `AnnounceOTAProvider` command.
### Trigger using DefaultOTAProviders attribute
If one or more provider locations have been written to the `DefaultOTAProviders`
attribute, this can be used to trigger a QueryImage command to a provider in the
attribute and start the OTA process.
#### In terminal 1:
**Build the OTA Provider application**
```
scripts/examples/gn_build_example.sh examples/ota-provider-app/linux/ out chip_config_network_layer_ble=false
```
**Run the OTA Provider application**
```
out/chip-ota-provider-app --discriminator 22 --secured-device-port 5565 --KVS /tmp/chip_kvs_provider --filepath /tmp/ota-image.bin
```
#### In terminal 2:
**Build the OTA Requestor application**
```
scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux/ out chip_config_network_layer_ble=false
```
**Run the OTA Requestor application**
```
out/chip-ota-requestor-app --discriminator 18 --secured-device-port 5560 --KVS /tmp/chip_kvs_requestor --periodicQueryTimeout 60 --otaDownloadPath /tmp/test.bin
```
#### In terminal 3:
**Commission the OTA Provider application**
```
out/chip-tool pairing onnetwork-long 0xDEADBEEF 20202021 22
```
**Commission the OTA Requestor application**
```
out/chip-tool pairing onnetwork-long 0x1234567890 20202021 18
```
**Write to the DefaultOTAProviders attribute**
```
out/chip-tool otasoftwareupdaterequestor write default-ota-providers '[{"providerNodeID": 3735928559, "endpoint": 0}]' 0x1234567890 0
```
Every 60 seconds from when the OTA Requestor application has launched, the OTA
Requestor application with node ID 0x1234567890 will send a QueryImage command
to the OTA Provider with node ID `0xDEADBEEF`, as specified in the
`DefaultOTAProviders` attribute.
## DefaultOTAProviders attribute
The `DefaultOTAProviders` attribute represents a list of `ProviderLocation`
structs. Each entry in this list is a default OTA Provider per fabric. There can
not be more than one entry containing the same fabric.
To add more than one entry to the `DefaultOTAProviders` attribute, the OTA
Requestor app must be commissioned into multiple fabrics. At least one OTA
Provider app should be commissioned into each corresponding fabric that the OTA
Requestor app had been commissioned into.
The following example has two OTA Provider apps, each commissioned into a
different fabric (alpha and beta) and one OTA Requestor app commissioned into
both alpha and beta fabrics.
### In terminal 1:
**Build the OTA Provider application**
```
scripts/examples/gn_build_example.sh examples/ota-provider-app/linux/ out chip_config_network_layer_ble=false
```
**Run the first OTA Provider application**
```
out/chip-ota-provider-app --discriminator 22 --secured-device-port 5565 --KVS /tmp/chip_kvs_provider --filepath /tmp/ota-image.bin
```
### In terminal 2:
**Run the second OTA Provider application**
```
out/chip-ota-provider-app --discriminator 23 --secured-device-port 5566 --KVS /tmp/chip_kvs_provider2 --filepath /tmp/ota-image2.bin
```
### In terminal 3:
**Build the OTA Requestor application**
```
scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux/ out chip_config_network_layer_ble=false
```
**Run the OTA Requestor application**
```
out/chip-ota-requestor-app --discriminator 18 --secured-device-port 5560 --KVS /tmp/chip_kvs_requestor --periodicQueryTimeout 10
```
### In terminal 4:
**Commission the first OTA Provider into the first fabric (alpha)**
```
out/chip-tool pairing onnetwork-long 0xC0FFEE 20202021 22
```
**Commission the second OTA Provider into the second fabric (beta)**
```
out/chip-tool pairing onnetwork-long 0xB0BA 20202021 23 --commissioner-name beta
```
**Commission the OTA Requestor application into the first fabric (alpha)**
```
out/chip-tool pairing onnetwork-long 0xDEB 20202021 18
```
**Open Basic Commissioning Window for the OTA Requestor application**
```
out/chip-tool administratorcommissioning open-basic-commissioning-window 600 0xDEB 0 --timedInteractionTimeoutMs 600
```
**Commission the OTA Requestor application into the second fabric (beta)**
```
out/chip-tool pairing onnetwork-long 0xB0B 20202021 18 --commissioner-name beta
```
**Write/Read DefaultOTAProviders on the first fabric (alpha)**
```
out/chip-tool otasoftwareupdaterequestor write default-ota-providers '[{"providerNodeID": 12648430, "endpoint": 0}]' 0xDEB 0
out/chip-tool otasoftwareupdaterequestor read default-ota-providers 0xDEB 0
```
**Write/Read DefaultOTAProviders on second fabric (beta)**
```
out/chip-tool otasoftwareupdaterequestor write default-ota-providers '[{"providerNodeID": 45242, "endpoint": 0}]' 0xB0B 0 --commissioner-name beta
out/chip-tool otasoftwareupdaterequestor read default-ota-providers 0xB0B 0 --commissioner-name beta
```
**Write ACL for the first OTA Provider application**
```
out/chip-tool accesscontrol write acl '[{"privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"privilege": 3, "authMode": 2, "subjects": null, "targets": [{"cluster": 41, "endpoint": null, "deviceType": null}]}]' 0xC0FFEE 0
```
**Write ACL for the second OTA Provider application**
```
out/chip-tool accesscontrol write acl '[{"privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"privilege": 3, "authMode": 2, "subjects": null, "targets": [{"cluster": 41, "endpoint": null, "deviceType": null}]}]' 0xB0BA 0 --commissioner-name beta
```
NOTE: For all operations, specify which fabric to use by passing in
`--commissioner-name`. The supported values are alpha, beta, and gamma. By
default, if none is supplied, alpha is used.