# Matter All-Devices App for Zephyr

The All-Devices App is a Matter application for Zephyr. It uses the Matter
code-driven data model and can contain one or more device types. The enabled
device types are selected at build time. The default device is an on/off light.

## Setup

### 1. Install GN

Matter's build uses GN. Either download a binary from
https://chrome-infra-packages.appspot.com/p/gn/gn and put it in your `PATH`, or
build it from source:

```sh
git clone https://gn.googlesource.com/gn ~/gn
cd ~/gn
python3 build/gen.py
ninja -C out gn
install -m 755 out/gn /usr/local/bin
```

### 2. Set up Zephyr

Follow the generic Zephyr setup:

https://docs.zephyrproject.org/latest/develop/getting_started/index.html

### 3. Add Matter to the West workspace

Matter ships a `zephyr/module.yml` at its repository root, so it is a Zephyr
module: add it to the manifest of your west workspace and Zephyr registers it as
the module `connectedhomeip` and builds it.

Create `~/zephyrproject/zephyr/submanifests/matter.yaml`:

```yaml
manifest:
    projects:
        - name: matter
          url: https://github.com/project-chip/connectedhomeip
          revision: master
          path: modules/lib/matter
          submodules:
              - path: third_party/editline/repo
              - path: third_party/jsoncpp/repo
              - path: third_party/nlassert/repo
              - path: third_party/nlio/repo
              - path: third_party/uriparser/repo
              - path: third_party/pigweed/repo
```

```sh
west update
```

### 4. Stub `pigweed_environment.gni`

`build_overrides/pigweed_environment.gni` is generated by Matter's own
`scripts/activate.sh`/`bootstrap.sh`. That bootstrap is never run in the
Zephyr/west-only workflow. As a workaround, create a minimal stub manually:

```sh
echo > ~/zephyrproject/modules/lib/matter/build_overrides/pigweed_environment.gni
```

## Build

Within the west workspace, build the app with West and sysbuild:

```sh
west build -p always -b xg26_rb4118a --sysbuild \
	modules/lib/matter/examples/all-devices-app/zephyr \
	-d build/all-devices-zephyr-xg26 -- -DUSE_CCACHE=0
```

Flash the resulting images with:

```sh
west flash -d build/all-devices-zephyr-xg26
```

The app supports MCUboot through Zephyr sysbuild. For debugging, use
`west debug`. Use `west attach` when debugging an image that is already signed.

OTA is supported through the Matter OTA Requestor and the Zephyr platform OTA
integration.

## Build Profiles

`prj.conf` is applied by default. Select another profile with `FILE_SUFFIX`:

```sh
# Debug profile
west build ... -- -DFILE_SUFFIX=debug

# Release profile
west build ... -- -DFILE_SUFFIX=release
```

## Device Selection

Device types are Kconfig options (`CONFIG_ALL_DEVICES_DEVICE_*`, see
`Kconfig.devices`). Pick them in `menuconfig` under "Matter device types", or in
a `.conf` file:

```
CONFIG_ALL_DEVICES_DEVICE_ON_OFF_LIGHT=y
CONFIG_ALL_DEVICES_DEVICE_OCCUPANCY_SENSOR=y
```

The CMake variable still overrides Kconfig when set:

```sh
west build ... -- \
	-DALL_DEVICES_ENABLED_DEVICES="on-off-light;occupancy-sensor"
```

An empty list (`-DALL_DEVICES_ENABLED_DEVICES=""`, or no device selected in
Kconfig) enables every device type.

## Factory Reset

Press and hold button 0 for 5 seconds to factory reset the device. Button 0 is
defined as `sw0` in a board overlay.

## Custom AppTask

`AppTaskBase<Derived>` uses CRTP: `Run()` dispatches each init step through the
final type, so a product replaces a step by declaring a method of the same name.
Layers can stack (generic -> vendor -> product) as long as the chain ends in a
non-template `AppTask`.

```cpp
#include "AppTaskBase.h"

namespace chip::app::AllDevices {

template <class Derived>
class MyAppTask : public AppTaskBase<Derived>
{
public:
    CHIP_ERROR InitCredentials(); // replaces the generic step
};

class AppTask final : public MyAppTask<AppTask>
{
};

} // namespace chip::app::AllDevices
```

Point `APP_TASK_IMPL_HEADER` at that header:

```sh
west build ... -- -DAPP_TASK_IMPL_HEADER=MyAppTask.h
```

Call `AppTaskBase<Derived>::Step()` to also run the generic behavior.
