blob: 580165b4dcfdbb989ab58c68b089ea12a185f879 [file] [view]
# Architecture & Design
The `all-devices-app` is a reference application demonstrating the **Code-Driven
Data Model** within the Matter SDK. It implements a runtime-configurable data
model.
This document describes the architectural layers, core classes, and design
principles of the application.
---
## 1. The Code-Driven Data Model
The `all-devices-app` implements the **Code-Driven Data Model**:
- **Dynamic Runtime Registration**: Clusters and endpoints are instantiated as
standard C++ objects and registered with the active data model provider at
runtime using `provider.AddEndpoint(...)` via `CodeDrivenDataModelProvider`.
- **Decoupled Cluster Logic**: Server clusters are implemented by deriving
from `DefaultServerCluster` (or similar code-driven base classes).
Attributes and commands are strongly typed and encapsulated within the
cluster classes.
- **Enhanced Testability**: Because devices and clusters are plain C++
objects, they can be directly instantiated in standalone unit tests without
booting the full Matter network stack.
---
## 2. Platform Separation
The `all-devices-app` enforces platform separation between core logic and target
drivers:
```mermaid
graph TD
A[Platform-Agnostic Core<br>`all-devices-common/`]
B[POSIX Platform<br>`posix/`]
C[ESP32 Platform<br>`esp32/`]
D[SiLabs Platform<br>`silabs/`]
E[Telink Platform<br>`telink/`]
B -->|Instantiates & Overrides| A
C -->|Instantiates & Overrides| A
D -->|Instantiates & Overrides| A
E -->|Instantiates & Overrides| A
```
### Platform-Agnostic Core (`all-devices-common/`)
Contains simulated device behaviors and capability management. This layer
compiles independently of the operating system or hardware drivers. It includes:
- **`devices/`**: Concrete implementations of simulated Matter devices (e.g.,
`OccupancySensor`, `DimmableLight`, `Speaker`).
- **`device-factory/`**: Registry (`DeviceFactory`) responsible for mapping
CLI device names to creation factories.
- **`providers/`**: SDK-level data providers (such as
`AllDevicesExampleDeviceInfoProviderImpl`) that supply node lifecycle
information, storage interfaces, and descriptor details.
### Platform-Specific Target Builds (`posix/`, `esp32/`, `silabs/`, `telink/`)
These directories contain hardware-specific or OS-specific drivers, entrypoint
`main()` functions, and build configurations.
- **Platform Overrides**: Platforms can replace simulated behaviors with
hardware drivers. For example, `DeviceFactoryPlatformOverride.cpp` can
register an LED driver for the `on-off-light` device instead of the
simulated device.
---
## 3. Key Core Classes
### The Device Interface
All devices in the application implement `DeviceInterface` and its core base
class, `SingleEndpointDevice`.
```mermaid
classDiagram
class DeviceInterface {
<<interface>>
+Register(EndpointId endpoint, CodeDrivenDataModelProvider & provider, EndpointId parentId)* CHIP_ERROR
+Unregister(CodeDrivenDataModelProvider & provider)*
+GetEndpointId() EndpointId
+GetParentEndpointId() EndpointId
}
class SingleEndpointDevice {
<<abstract>>
-mEndpointId: EndpointId
-mParentEndpointId: EndpointId
-mDeviceTypeList: Span<DeviceTypeDescriptor>
+Register(EndpointId endpoint, CodeDrivenDataModelProvider & provider, EndpointId parentId) CHIP_ERROR
+Unregister(CodeDrivenDataModelProvider & provider)
+SetEndpointId(EndpointId id)
}
class OccupancySensor {
-mOccupancySensingCluster: OccupancySensingCluster
-mBridgedDeviceBasicInformationCluster: BridgedDeviceBasicInformationCluster
+Register(EndpointId endpoint, CodeDrivenDataModelProvider & provider, EndpointId parentId) CHIP_ERROR
}
DeviceInterface <|-- SingleEndpointDevice
SingleEndpointDevice <|-- OccupancySensor
```
- **`DeviceInterface`**
(`all-devices-common/devices/interface/DeviceInterface.h`): Defines the pure
virtual lifecycle contracts (`Register`, `Unregister`, etc.) required for
registering a block of data model elements into the active server.
- **`SingleEndpointDevice`**
(`all-devices-common/devices/interface/SingleEndpointDevice.h`):
Encapsulates endpoint state, managing its assigned `EndpointId`, its parent
endpoint relationship (for bridges or composite devices), and a list of
`DeviceTypeDescriptor` structures.
- **Concrete Devices** (e.g., `OccupancySensor`): Inherit from
`SingleEndpointDevice`, own one or more concrete strongly-typed cluster
instances (`LazyRegisteredServerCluster`), and bind them to the endpoint
during registration.
### The Device Factory
The `DeviceFactory` singleton acts as the central device creator.
1. When a particular device type is enabled during the build, its static
self-registering factory macro executes at startup.
2. The factory maintains an internal map of string keys (e.g.,
`"occupancy-sensor"`) to creation callbacks.
3. During boot, the application parses command-line device types and calls
`DeviceFactory::CreateDevice(...)` to instantiate the specified runtime
devices.
---
## 4. Design Principles & Best Practices
When maintaining or extending the `all-devices-app` architecture, adhere to the
following guidelines:
1. **Platform-Agnostic Core**: Do not introduce OS-specific APIs, direct POSIX
calls, or global singletons into `all-devices-common/`. If a capability
requires platform integration, define an interface in `all-devices-common/`
and provide the implementation in target directories (`posix/`, `esp32/`,
etc.).
2. **Encapsulate Storage via Providers**: Do not write direct persistent files
from device classes. Use the injected `DeviceInfoProvider` or
`DeviceInstanceInfoProvider` interfaces to handle non-volatile runtime
variables and user settings.
3. **Explicit Lifecycle Management**: Do not rely on RAII or C++ destructor
methods for automated endpoint teardown. Core device type implementations
must use `~Device() override = default;` and manage lifecycle teardown
explicitly by executing `Unregister(provider)`.
4. **Concrete Naming**: Avoid ambiguous umbrella folders or generic utility
names. Use specific operational titles (e.g., `DeviceTypeParser.h`,
`NetworkInfrastructureManager.h`).