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] Update README for OTA Requestor application #15064

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ DEDEDEDE
deepnote
DelayedActionTime
delayedActionTimeSec
delayQuery
demangle
deployable
depottools
Expand Down Expand Up @@ -828,6 +829,7 @@ protobuf
protos
Prover
providerNodeId
providerFabricIndex
PRs
PSCAN
PSK
Expand Down Expand Up @@ -889,6 +891,7 @@ req
Requestor
Requestor's
Requestors
RequestorCanConsent
responder
retargeting
reusability
Expand Down
161 changes: 94 additions & 67 deletions examples/ota-requestor-app/linux/README.md
Original file line number Diff line number Diff line change
@@ -1,108 +1,135 @@
# 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 should initiate a
Software Update with a given OTA Provider node, and download a file.
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.

## Building

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 order to use this reference application to connect to a device running OTA
Provider server and download a software image, these commands should be called
in the following order:
In addition to the general options available to all Linux applications, the
following command line options are available for the OTA Requestor application.

| Directory | Description |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -n/--providerNodeId <node ID> | Node ID of the OTA Provider to connect to (hex format) <br> This assumes that you've already commissioned the OTA Provider node with chip-tool |
| -f/--providerFabricIndex <fabric index> | Fabric index of the OTA Provider to connect to. If none is specified, default value is 1. <br> This assumes that you've already commissioned the OTA Provider node with chip-tool |
| -q/--delayQuery <Time in seconds> | From boot up, the amount of time to wait before triggering the QueryImage command. If none or zero is supplied, QueryImage will not be triggered automatically. |
| -c/--requestorCanConsent | If supplied, the RequestorCanConsent field of the QueryImage command is set to true. Otherwise, the value is determined by the driver. |

In terminal 1:
## Software Image Header

All Matter software images must contain a header as defined in section 11.21.1
of the specification. The
[ota_image_tool](https://github.com/project-chip/connectedhomeip/blob/master/src/app/ota_image_tool.py)
is available for generating the required header on a software image. Any
software images that the OTA Requestor application receives must contain the
required header. If the header is missing, the software download will not
succeed.

## Example

One way to use this reference application to connect to a device running OTA
Provider server and download a software image is to issue an AnnounceOTAProvider
command. This will trigger a QueryImage command and start the OTA process. To
test using this method, the following steps should be followed:

### In terminal 1:

**Build the OTA Provider application**

Follow instructions
[here](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-provider-app/linux#building)

**Run the OTA Provider application**

```
./chip-ota-provider-app -f ${SW_IMAGE_FILE}
./chip-ota-provider-app --discriminator ${REQUESTOR_LONG_DISCRIMINATOR} --secured-device-port ${REQUESTOR_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.

In terminal 2:
### In terminal 2:

```
./chip-tool pairing onnetwork ${NODE_ID_TO_ASSIGN_PROVIDER} 20202021
```
**Build the OTA Requestor application**

- `${NODE_ID_TO_ASSIGN_PROVIDER}` is the node id to assign to the
ota-provider-app running in terminal 1.
Follow instructions
[here](https://github.com/project-chip/connectedhomeip/tree/master/examples/ota-requestor-app/linux#building)

In terminal 3:
**Run the OTA Requestor application:**

```
./chip-ota-requestor-app -d ${REQUESTOR_LONG_DISCRIMINATOR} -u ${REQUESTOR_UDP_PORT} -n ${PROVIDER_NODE_ID} -f ${PROVIDER_FABRIC_INDEX} -q ${DELAY_QUERY_SECONDS}
./chip-ota-requestor-app --discriminator ${REQUESTOR_LONG_DISCRIMINATOR} --secured-device-port ${REQUESTOR_UDP_PORT} --KVS ${KVS_STORE_LOCATION}
```

- `{REQUESTOR_LONG_DISCRIMINATOR}` is the long discriminator specified for the
ota-requestor-app for commissioning discovery
- `{REQUESTOR_UDP_PORT}` is the UDP port that the ota-requestor-app listens on
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; 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

In terminal 2:
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.

```
./chip-tool pairing onnetwork-long ${NODE_ID_TO_ASSIGN_REQUESTOR} 20202021 ${REQUESTOR_LONG_DISCRIMINATOR}
```
### In terminal 3:

- `${NODE_ID_TO_ASSIGN_REQUESTOR}` is the node id to assign to the
ota-requestor-app running in terminal 3
- `${REQUESTOR_LONG_DISCRIMINATOR}` is the long discriminator of the
ota-requestor-app specified in terminal 3 above
**Commission the OTA Provider application**

```
./chip-tool otasoftwareupdaterequestor announce-ota-provider ${PROVIDER_NODE_ID} 0 0 0 ${REQUESTOR_NODE_ID} 0
./chip-tool pairing onnetwork-long ${PROVIDER_NODE_ID} 20202021 ${PROVIDER_LONG_DISCRIMINATOR}
```

- `${PROVIDER_NODE_ID}` is the node ID of the ota-provider-app assigned to it
during the pairing step above
- `${REQUESTOR_NODE_ID}` is the node ID of the ota-requestor-app assigned to
it during the pairing step above

## Note

When the Provider, Requestor and chip-tool are run on the same Linux node the
user must issue `rm -r /tmp/chip_*` before starting the Provider and
`rm /tmp/chip_kvs` before starting the Requestor. These commands reset the
shared Key Value Store to a consistent state.
- `${PROVIDER_NODE_ID}` is the node id to assign to the OTA Provider
application running in terminal 1
- `${PROVIDER_LONG_DISCRIMINATOR}` is the long discriminator of the OTA
Provider application specified in terminal 1 above

## Example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove the example?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reworked the example a bit so it's more generic but still gives you plenty of details


Building:
**Commission the OTA Requestor application**

```
scripts/examples/gn_build_example.sh examples/chip-tool out/ chip_config_network_layer_ble=false && scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/debug chip_config_network_layer_ble=false && scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux out/debug chip_config_network_layer_ble=false
./chip-tool pairing onnetwork-long ${REQUESTOR_NODE_ID} 20202021 ${REQUESTOR_LONG_DISCRIMINATOR}
```

Running (in separate terminals as described above):
- `${REQUESTOR_NODE_ID}` is the node id to assign to the OTA Requestor
application running in terminal 2
- `${REQUESTOR_LONG_DISCRIMINATOR}` is the long discriminator of the OTA
Requestor application specified in terminal 2 above

**Issue the AnnounceOTAProvider command**

```
rm -r /tmp/chip_*
./out/debug/chip-ota-provider-app -f /tmp/ota.txt
./out/chip-tool pairing onnetwork 1 20202021
rm /tmp/chip_kvs
./out/debug/chip-ota-requestor-app -u 5560 -d 42
./out/chip-tool pairing onnetwork-long 2 20202021 42
./out/chip-tool otasoftwareupdaterequestor announce-ota-provider 1 0 0 0 2 0
./chip-tool otasoftwareupdaterequestor announce-ota-provider ${PROVIDER_NODE_ID} 0 0 0 ${REQUESTOR_NODE_ID} 0
```

## Current Features / Limitations

### Features
- `${PROVIDER_NODE_ID}` is the OTA Provider application node ID assigned
during the pairing step above
- `${REQUESTOR_NODE_ID}` is the OTA Requestor application node ID assigned
during the pairing step above

- Code for running a full BDX download exists in BDX
- Sends QueryImage command
- Downloads a file over BDX served by an OTA Provider server
- Supports various command line configurations
The OTA Requestor application will process this command and send a QueryImage
command to the OTA Provider

### Limitations
## Limitations

- Stores the downloaded file in the directory this reference app is launched
from
43 changes: 6 additions & 37 deletions examples/ota-requestor-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,19 @@ void OnStartDelayTimerHandler(Layer * systemLayer, void * appState);

constexpr uint16_t kOptionProviderNodeId = 'n';
constexpr uint16_t kOptionProviderFabricIndex = 'f';
constexpr uint16_t kOptionUdpPort = 'u';
constexpr uint16_t kOptionDiscriminator = 'd';
constexpr uint16_t kOptionDelayQuery = 'q';
constexpr uint16_t kOptionRequestorCanConsent = 'c';

NodeId providerNodeId = 0x0;
FabricIndex providerFabricIndex = 1;
uint16_t requestorSecurePort = 0;
uint16_t setupDiscriminator = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR;
uint16_t delayQueryTimeInSec = 0;
chip::Optional<bool> gRequestorCanConsent;

OptionDef cmdLineOptionsDef[] = {
{ "providerNodeId", chip::ArgParser::kArgumentRequired, kOptionProviderNodeId },
{ "providerFabricIndex", chip::ArgParser::kArgumentRequired, kOptionProviderFabricIndex },
{ "udpPort", chip::ArgParser::kArgumentRequired, kOptionUdpPort },
{ "discriminator", chip::ArgParser::kArgumentRequired, kOptionDiscriminator },
{ "delayQuery", chip::ArgParser::kArgumentRequired, kOptionDelayQuery },
{ "RequestorCanConsent", chip::ArgParser::kNoArgument, kOptionRequestorCanConsent },
{ "requestorCanConsent", chip::ArgParser::kNoArgument, kOptionRequestorCanConsent },
{},
};

Expand All @@ -85,21 +79,14 @@ OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS"
" -f/--providerFabricIndex <fabric index>\n"
" Fabric index of the OTA Provider to connect to. If none is specified, default value is 1.\n\n"
" This assumes that you've already commissioned the OTA Provider node with chip-tool.\n"
" -u/--udpPort <UDP port number>\n"
" UDP Port that the OTA Requestor listens on for secure connections.\n"
" -d/--discriminator <discriminator>\n"
" A 12-bit value used to discern between multiple commissionable CHIP device\n"
" advertisements. If none is specified, default value is 3840.\n"
" -q/--delayQuery <Time in seconds>\n"
" From boot up, the amount of time to wait before triggering the QueryImage\n"
" command. If none or zero is supplied, QueryImage will not be triggered.\n"
" -c/--RequestorCanConsent\n"
" If provided, the RequestorCanConsent field of the QueryImage command is set to true.\n"
" Else, the value is determined by the driver.\n " };
" command. If none or zero is supplied, QueryImage will not be triggered automatically.\n"
" -c/--requestorCanConsent\n"
" If supplied, the RequestorCanConsent field of the QueryImage command is set to true.\n"
" Otherwise, the value is determined by the driver.\n " };

HelpOptions helpOptions("ota-requestor-app", "Usage: ota-requestor-app [options]", "1.0");

OptionSet * allOptions[] = { &cmdLineOptions, &helpOptions, nullptr };
OptionSet * allOptions[] = { &cmdLineOptions, nullptr };

static void InitOTARequestor(void)
{
Expand Down Expand Up @@ -143,24 +130,6 @@ bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier,
retval = false;
}
break;
case kOptionUdpPort:
requestorSecurePort = static_cast<uint16_t>(strtol(aValue, NULL, 0));

if (requestorSecurePort == 0)
{
PrintArgError("%s: Input ERROR: udpPort may not be zero\n", aProgram);
retval = false;
}
break;
case kOptionDiscriminator:
setupDiscriminator = static_cast<uint16_t>(strtol(aValue, NULL, 0));

if (setupDiscriminator > 0xFFF)
{
PrintArgError("%s: Input ERROR: setupDiscriminator value %s is out of range \n", aProgram, aValue);
retval = false;
}
break;
case kOptionDelayQuery:
delayQueryTimeInSec = static_cast<uint16_t>(strtol(aValue, NULL, 0));
break;
Expand Down