Skip to content

Commit

Permalink
[NXP][rw61x][k32w1] Rework reference apps (#35172)
Browse files Browse the repository at this point in the history
* [NXP][third_party] Add new NXP SDK support

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][examples] Update examples to support new NXP SDK

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][src] Update src to support new NXP SDK

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][docs] Update docs to support new NXP SDK

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][scripts] Update scripts to support new NXP SDK

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][workflows] Update rw61x workflow to support new NXP SDK

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][submodules] Update submodules to support new NXP SDK

Signed-off-by: Martin Girardot <[email protected]>

* Restyled by gn

* Restyled by prettier-markdown

* [NXP] Spelling fixes

Signed-off-by: Martin Girardot <[email protected]>

* [NXP][examples][common] Add common README file for contact sensor and lighting app

Add mcxw71/k32w1 specific OTA guide in nxp docs area.

Signed-off-by: marius-alex-tache <[email protected]>

* Restyled by prettier-markdown

* [NXP][rw61x][examples][laundry-washer][thermostat][all-custer-app] Updating path to new nxp_matter_support repo

Signed-off-by: Gatien Chapon <[email protected]>

* [NXP][docs] Update RW61x OTA readme to specify the upgrade type used

Signed-off-by: Dina Benamar <[email protected]>

* [NXP] Doc and spelling fixes

Signed-off-by: Martin Girardot <[email protected]>

* Restyled by gn

* Restyled by prettier-markdown

* Restyled by prettier-markdown

* [NXP][workflows] Update docker image version

Signed-off-by: Martin Girardot <[email protected]>

---------

Signed-off-by: Martin Girardot <[email protected]>
Signed-off-by: marius-alex-tache <[email protected]>
Signed-off-by: Gatien Chapon <[email protected]>
Signed-off-by: Dina Benamar <[email protected]>
Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: marius-alex-tache <[email protected]>
Co-authored-by: Gatien Chapon <[email protected]>
Co-authored-by: Dina Benamar <[email protected]>
  • Loading branch information
5 people authored and pull[bot] committed Sep 20, 2024
1 parent 1678e94 commit 38fe9fe
Show file tree
Hide file tree
Showing 116 changed files with 2,219 additions and 2,812 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/examples-nxp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
if: github.actor != 'restyled-io[bot]'

container:
image: ghcr.io/project-chip/chip-build-rw61x:74
image: ghcr.io/project-chip/chip-build-nxp:74
volumes:
- "/tmp/bloat_reports:/tmp/bloat_reports"
steps:
Expand Down
76 changes: 55 additions & 21 deletions docs/guides/nxp/nxp_manufacturing_flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,24 +247,58 @@ adding the following gn argument `chip_use_plain_dac_key=true`.

Supported platforms:

- RW61X - `src/plaftorm/nxp/rt/rw61x/FactoryDataProviderImpl.h`

For platforms that have a secure subsystem (`SE50`), the DAC private key can be
converted to an encrypted blob. This blob will overwrite the DAC private key in
factory data and will be imported in the `SE50` before to sign, by the factory
data provider instance.

The conversion process shall happen at manufacturing time and should be run one
time only:

- Write factory data binary.
- Build the application with
`chip_with_factory_data=1 chip_convert_dac_private_key=1` set.
- Write the application to the board and let it run.

After the conversion process:

- Make sure the application is built with `chip_with_factory_data=1`, but
without `chip_convert_dac_private_key` arg, since conversion already
happened.
- Write the application to the board.
- RW61X

there are three implementations for factory data protection

- whole factory data protection with AES encryption ( chip_with_factory_data=1
chip_enable_secure_whole_factory_data=true )
`examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp`\
`src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp`

- only dac private key protection ( chip_with_factory_data=1
chip_enable_secure_dac_private_key_storage=true )
`examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp`
\
`src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp`

- whole factory data protection with hard-coded AES key (
chip_with_factory_data=1 )
`examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp`
\
`src/platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.cpp`

for the first one, the whole factory data is encrypted by an AES-256 key, the
AES key can be passed through serial link when in factory production mode, and
will be provisioned into Edge Lock, and the returned AES Key blob (wrapped key)
can be stored in the end of factory data region in TLV format. for the
decryption process, the blob is retrieved and provisioned into Edge Lock and the
whole factory data can be decrypted using the returned key index in Edge Lock.
Compared with only dac private key protection solution, this solution can avoid
tampering with the original factory data.

the factory data should be encrypted by an AES-256 key using "--aes256_key"
option in "generate.py" script file.

it will check whether there is AES key blob in factory data region when in each
initialization, if not, the default AES key is converted and the result is
stored into flash, it run only once.

for the second one, it only protect the dac private key inside the factory data,
the dac private key is retrieved and provisioned into Edge Lock, the returned
key blob replace the previous dac private key, and also update the overall size
and hash, and re-write the factory data. when device is doing matter
commissioning, the blob is retrieved and provisioned into Edge Lock and the
signing can be done using the returned key index in Edge Lock.

the factory data should be plain text for the first programming. it will check
whether there is dac private key blob (base on the size of blob, should be 48)
in factory data when in each initialization, if not, the dac private key is
converted and the result is stored into flash, it run only once.

for the third one, it is a little similar to the first one, the whole factory
data is encrypted by an AES key, but there are two differences:

- the AES key is hard-coded and not provisioned into Edge Lock
- the factory data should be encrypted by AES-128 key using "--aes128_key"
option in "generate.py" script file.
179 changes: 179 additions & 0 deletions docs/guides/nxp/nxp_mcxw71_ota_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# NXP `MCXW71/K32W1` OTA guide

### Convert `srec` into `sb3` file

The OTA image files must be encrypted using Over The Air Programming Tool
([OTAP](https://www.nxp.com/design/microcontrollers-developer-resources/connectivity-tool-suite:CONNECTIVITY-TOOL-SUITE?#downloads)).
Bootloader will load the new OTA image only if it detects that the file was
encrypted with the `OTAP` correct keys.

`.srec` file is input for Over The air Programming (`OTAP`) application
(unencrypted) and it's converted to `.sb3` format (encrypted).

In `OTAP` application

- select OTA protocol => `OTAP` Matter
- Browse File
- follow default options (KW45/K32W148, Preserve NVM)
- image information: will update "Application Core (MCU)" - this will generate
the image only for the CM33 core
- keep other settings at default values

### Generate `ota` file

In order to build an OTA image, use the NXP wrapper over the standard tool
`src/app/ota_image_tool.py`:

- `scripts/tools/nxp/ota/ota_image_tool.py`

The tool can be used to generate an OTA image with the following format:

```
| OTA image header | TLV1 | TLV2 | ... | TLVn |
```

where each TLV is in the form `|tag|length|value|`.

Note that "standard" TLV format is used. Matter TLV format is only used for
factory data TLV value.

Please see more in the
[OTA image tool guide](../../../scripts/tools/nxp/ota/README.md).

Here is an example that generates an OTA image with application update TLV from
an `.sb3` file:

```
./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 2 -vs "2.0" -da sha256 --app-input-file ~/binaries/chip-mcxw71-app.sb3 ~/binaries/chip-mcxw71-app.ota
```

A note regarding OTA image header version (`-vn` option). An application binary
has its own software version (given by
`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION`, which can be overwritten). In
order to have a correct OTA process, the OTA header version should be the same
as the binary embedded software version. A user can set a custom software
version in the gn build args by setting `nxp_software_version` to the wanted
version.

### OTA factory data

A user can update the factory data through OTA, at the same time the application
firmware is updated by enabling the following processor in the `gn args`:

- `chip_enable_ota_factory_data_processor=1` to enable default factory data
update processor (disabled by default).

The OTA image used must be updated to include the new factory data.

[OTA image tool guide](../../../scripts/tools/nxp/ota/README.md).

### Running OTA

The OTA topology used for OTA testing is illustrated in the figure below.
Topology is similar with the one used for Matter Test Events.

![OTA_TOPOLOGY](../../../examples/platform/nxp/mcxw71_k32w1/doc/images/ota_topology.JPG)

The concept for OTA is the next one:

- there is an OTA Provider Application that holds the OTA image. In our case,
this is a Linux application running on an Ubuntu based-system;
- the OTA Requestor functionality is embedded inside the reference
application. It will be used for requesting OTA blocks from the OTA
Provider;
- the controller (a linux application called chip-tool) will be used for
commissioning both the device and the OTA Provider App. The device will be
commissioned using the standard Matter flow (BLE + IEEE 802.15.4) while the
OTA Provider Application will be commissioned using the `onnetwork` option
of `chip-tool`;
- during commissioning, each device is assigned a node id by the chip-tool
(can be specified manually by the user). Using the node id of the device and
of the reference application, chip-tool triggers the OTA transfer by
invoking the `announce-ota-provider` command - basically, the OTA Requestor
is informed of the node id of the OTA Provider Application.

_Computer #1_ can be any system running an Ubuntu distribution. We recommand
using CSA official instructions from
[here](https://groups.csa-iot.org/wg/matter-csg/document/28566), where RPi 4 are
proposed. Also, CSA official instructions document point to the OS/Docker images
that should be used on the RPis. For compatibility reasons, we recommand
compiling chip-tool and OTA Provider applications with the same commit id that
was used for compiling the reference application. Also, please note that there
is a single controller (chip-tool) running on Computer #1 which is used for
commissioning both the device and the OTA Provider Application. If needed,
[these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be
used for connecting the RPis to WiFi.

Build the Linux OTA provider application:

```
user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false
```

Build Linux `chip-tool`:

```
user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/chip-tool out/chip-tool-app
```

Start the OTA Provider Application:

```
user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_*
user@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-mcxw71-app.ota
```

Provision the OTA provider application and assign node id _1_. Also, grant ACL
entries to allow OTA requestors:

```
user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_*
user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing onnetwork 1 20202021
user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' 1 0
```

Provision the device and assign node id _2_:

```
user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing ble-thread 2 hex:<operationalDataset> 20202021 3840
```

Start the OTA process:

```
user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-ota-provider 1 0 0 0 2 0
```

### Known issues

- SRP cache on the openthread border router needs to flushed each time a new
commissioning process is attempted. For this, factory reset the device, then
execute `ot-ctl server disable` followed by `ot-ctl server enable`. After
this step, the commissioning process of the device can start;
- Due to some MDNS issues, the commissioning of the OTA Provider Application
may fail. Please make sure that the SRP cache is disabled
(`ot-ctl srp server disable`) on the openthread border router while
commissioning the OTA Provider Application;
- No other Docker image should be running (e.g.: Docker image needed by Test
Harness) except the OTBR one. A docker image can be killed using the
command:

```
user@computer1:~/connectedhomeip$ : sudo docker kill $container_id
```
- In order to avoid MDNS issues, only one interface should be active at one
time. E.g.: if WiFi is used then disable the Ethernet interface and also
disable multicast on that interface:
```
user@computer1:~/connectedhomeip$ sudo ip link set dev eth0 down
user@computer1:~/connectedhomeip$ sudo ifconfig eth0 -multicast
```
- If OTBR Docker image is used, then the "-B" parameter should point to the
interface used for the backbone.
- If Wi-Fi is used on a RPI4, then a 5Ghz network should be selected.
Otherwise, issues related to BLE-WiFi combo may appear.
Loading

0 comments on commit 38fe9fe

Please sign in to comment.