Skip to content
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
121 changes: 4 additions & 117 deletions slc/apps/air_quality_sensor_app/thread/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,123 +102,10 @@ This sample app works out of the box with no additional configuration required.

## Extending Base App Implementation

### CustomerAppTask

To implement custom app behavior you can override any Silicon Labs implemented API in the CustomerAppTask file. This example provides `CustomerAppTask.h` and `CustomerAppTask.cpp` for that purpose. The base implementation and the full set of overridable `*Impl()` APIs are supplied by the build system in `AppTask.cpp` and `AppTaskImpl.h` under `autogen/`. Any `*Impl()` you do not override keeps the Silicon Labs default behavior.

### How to Override APIs

`CustomerAppTask` derives from the base AppTask through the Curiously Recurring
Template Pattern (CRTP). You override only the `*Impl()` methods you need, the
base declares one `*Impl()` per overridable API. Steps:

1. Find the method to override in the base API (see
[Override API reference](#override-api-reference) below).
2. Declare the same method signature in `CustomerAppTask` in your
`CustomerAppTask.h` under `private:`. Match the base `*Impl()` signature
exactly — note that `*Impl()` overrides are **non-static instance methods**
even when the public dispatcher (e.g. `ButtonEventHandler`) is `static`.
3. Implement the method in `CustomerAppTask.cpp`.
4. Build. The CRTP layer automatically routes each call to your `*Impl()` if
present, otherwise to the Silicon Labs default.

### DataModelCallbacks and CustomerAppTask

What used to live in `DataModelCallbacks.cpp` now lives in `AppTask.cpp`. The
Matter SDK's `MatterPostAttributeChangeCallback` is implemented in
`examples/platform/silabs/BaseApplication.cpp` and forwards to
`AppTask::DMPostAttributeChangeCallback` (defined in `AppTask.cpp`), which you
can customize via `DMPostAttributeChangeCallbackImpl()` in `CustomerAppTask`.

Forwarding into `AppTask` still goes through CRTP as in
[How to Override APIs](#how-to-override-apis).

- **Methods that already exist in the AppTask** — Customize them by overriding
the matching `*Impl()` method in `CustomerAppTask`. Do not edit the
`AppTask.cpp` for app-specific behavior.

- **New custom data model methods** — Add them in `CustomerAppTask` directly.
Do not add new application logic in autogenerated sources; those edits will
not survive regeneration or project upgrades.

### Sample Implementation

The following shows a minimal example `CustomerAppTask` that overrides
`AppInitImpl()` and `ButtonEventHandlerImpl()`.

**CustomerAppTask.h**

```cpp
#pragma once
#include "AppTaskImpl.h"

/** Minimal AppTaskImpl-derived class. Override only the *Impl() methods you need **/
class CustomerAppTask : public AppTaskImpl<CustomerAppTask>
{
public:
static CustomerAppTask & GetAppTask() { return sAppTask; }

private:
friend class AppTaskImpl<CustomerAppTask>;
CHIP_ERROR AppInitImpl();
void ButtonEventHandlerImpl(uint8_t button, uint8_t btnAction);
static CustomerAppTask sAppTask;
};
```

**CustomerAppTask.cpp**

```cpp
#include "CustomerAppTask.h"
#include "AppTask.h"
#include "AppEvent.h"
#include <platform/CHIPDeviceLayer.h>
#include <platform/silabs/platformAbstraction/SilabsPlatform.h>

#define APP_FUNCTION_BUTTON 0

CustomerAppTask CustomerAppTask::sAppTask;

AppTask & AppTask::GetAppTask()
{
return CustomerAppTask::GetAppTask();
}

CHIP_ERROR CustomerAppTask::AppInitImpl()
{
SILABS_LOG("CustomerAppTask: custom implementation (AppInitImpl)");
CHIP_ERROR err = AppTask::AppInit();
if (err == CHIP_NO_ERROR)
{
// Override the SDK default button handler registered in AppTask::AppInit().
chip::DeviceLayer::Silabs::GetPlatform().SetButtonsCb(CustomerAppTask::ButtonEventHandler);
}
return err;
}

void CustomerAppTask::ButtonEventHandlerImpl(uint8_t button, uint8_t btnAction)
{
SILABS_LOG("CustomerAppTask: custom implementation (ButtonEventHandlerImpl)");
AppEvent aEvent = {};
aEvent.Type = AppEvent::kEventType_Button;
aEvent.ButtonEvent.Action = btnAction;

if (button == APP_FUNCTION_BUTTON)
{
aEvent.Handler = BaseApplication::ButtonHandler;
AppTask::GetAppTask().PostEvent(&aEvent);
}
}
```

### Override API Reference

The base API and implementation are generated into your project and live under `autogen/` directory. These files are regenerated on every project upgrade and match your installed SDK version. Use them as the reference for overridable methods and app configuration.

| File | Purpose |
|------|--------|
| `autogen/AppTaskImpl.h` | Declarations of every overridable `*Impl()` method. Copy the signatures you need from here into `CustomerAppTask.h`. |
| `autogen/AppTask.cpp` | Silicon Labs default implementation of AppTask. This is what runs for any `*Impl()` you do not override. Use as reference when customizing behavior. |
See [Extending Base App Implementation](https://docs.silabs.com/matter/2.10.0/matter-api-reference#extending-base-app-implementation)
for how to customize application behavior using `CustomerAppTask` and CRTP `*Impl()` hooks.

Per-example override API references: `autogen/AppTaskImpl.h`, `autogen/AppTask.cpp`.

## Troubleshooting

Expand Down
121 changes: 4 additions & 117 deletions slc/apps/air_quality_sensor_app/wifi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,123 +97,10 @@ This sample app works out of the box with no additional configuration required.

## Extending Base App Implementation

### CustomerAppTask

To implement custom app behavior you can override any Silicon Labs implemented API in the CustomerAppTask file. This example provides `CustomerAppTask.h` and `CustomerAppTask.cpp` for that purpose. The base implementation and the full set of overridable `*Impl()` APIs are supplied by the build system in `AppTask.cpp` and `AppTaskImpl.h` under `autogen/`. Any `*Impl()` you do not override keeps the Silicon Labs default behavior.

### How to Override APIs

`CustomerAppTask` derives from the base AppTask through the Curiously Recurring
Template Pattern (CRTP). You override only the `*Impl()` methods you need, the
base declares one `*Impl()` per overridable API. Steps:

1. Find the method to override in the base API (see
[Override API reference](#override-api-reference) below).
2. Declare the same method signature in `CustomerAppTask` in your
`CustomerAppTask.h` under `private:`. Match the base `*Impl()` signature
exactly — note that `*Impl()` overrides are **non-static instance methods**
even when the public dispatcher (e.g. `ButtonEventHandler`) is `static`.
3. Implement the method in `CustomerAppTask.cpp`.
4. Build. The CRTP layer automatically routes each call to your `*Impl()` if
present, otherwise to the Silicon Labs default.

### DataModelCallbacks and CustomerAppTask

What used to live in `DataModelCallbacks.cpp` now lives in `AppTask.cpp`. The
Matter SDK's `MatterPostAttributeChangeCallback` is implemented in
`examples/platform/silabs/BaseApplication.cpp` and forwards to
`AppTask::DMPostAttributeChangeCallback` (defined in `AppTask.cpp`), which you
can customize via `DMPostAttributeChangeCallbackImpl()` in `CustomerAppTask`.

Forwarding into `AppTask` still goes through CRTP as in
[How to Override APIs](#how-to-override-apis).

- **Methods that already exist in the AppTask** — Customize them by overriding
the matching `*Impl()` method in `CustomerAppTask`. Do not edit the
`AppTask.cpp` for app-specific behavior.

- **New custom data model methods** — Add them in `CustomerAppTask` directly.
Do not add new application logic in autogenerated sources; those edits will
not survive regeneration or project upgrades.

### Sample Implementation

The following shows a minimal example `CustomerAppTask` that overrides
`AppInitImpl()` and `ButtonEventHandlerImpl()`.

**CustomerAppTask.h**

```cpp
#pragma once
#include "AppTaskImpl.h"

/** Minimal AppTaskImpl-derived class. Override only the *Impl() methods you need **/
class CustomerAppTask : public AppTaskImpl<CustomerAppTask>
{
public:
static CustomerAppTask & GetAppTask() { return sAppTask; }

private:
friend class AppTaskImpl<CustomerAppTask>;
CHIP_ERROR AppInitImpl();
void ButtonEventHandlerImpl(uint8_t button, uint8_t btnAction);
static CustomerAppTask sAppTask;
};
```

**CustomerAppTask.cpp**

```cpp
#include "CustomerAppTask.h"
#include "AppTask.h"
#include "AppEvent.h"
#include <platform/CHIPDeviceLayer.h>
#include <platform/silabs/platformAbstraction/SilabsPlatform.h>

#define APP_FUNCTION_BUTTON 0

CustomerAppTask CustomerAppTask::sAppTask;

AppTask & AppTask::GetAppTask()
{
return CustomerAppTask::GetAppTask();
}

CHIP_ERROR CustomerAppTask::AppInitImpl()
{
SILABS_LOG("CustomerAppTask: custom implementation (AppInitImpl)");
CHIP_ERROR err = AppTask::AppInit();
if (err == CHIP_NO_ERROR)
{
// Override the SDK default button handler registered in AppTask::AppInit().
chip::DeviceLayer::Silabs::GetPlatform().SetButtonsCb(CustomerAppTask::ButtonEventHandler);
}
return err;
}

void CustomerAppTask::ButtonEventHandlerImpl(uint8_t button, uint8_t btnAction)
{
SILABS_LOG("CustomerAppTask: custom implementation (ButtonEventHandlerImpl)");
AppEvent aEvent = {};
aEvent.Type = AppEvent::kEventType_Button;
aEvent.ButtonEvent.Action = btnAction;

if (button == APP_FUNCTION_BUTTON)
{
aEvent.Handler = BaseApplication::ButtonHandler;
AppTask::GetAppTask().PostEvent(&aEvent);
}
}
```

### Override API Reference

The base API and implementation are generated into your project and live under `autogen/` directory. These files are regenerated on every project upgrade and match your installed SDK version. Use them as the reference for overridable methods and app configuration.

| File | Purpose |
|------|--------|
| `autogen/AppTaskImpl.h` | Declarations of every overridable `*Impl()` method. Copy the signatures you need from here into `CustomerAppTask.h`. |
| `autogen/AppTask.cpp` | Silicon Labs default implementation of AppTask. This is what runs for any `*Impl()` you do not override. Use as reference when customizing behavior. |
See [Extending Base App Implementation](https://docs.silabs.com/matter/2.10.0/matter-api-reference#extending-base-app-implementation)
for how to customize application behavior using `CustomerAppTask` and CRTP `*Impl()` hooks.

Per-example override API references: `autogen/AppTaskImpl.h`, `autogen/AppTask.cpp`.

## Troubleshooting

Expand Down
45 changes: 21 additions & 24 deletions slc/apps/closure_app/thread/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ The Matter over Thread closure example is a baseline demonstration of a closure
- [Prerequisites/Setup Requirements](#prerequisitessetup-requirements)
- [Steps to Run Demo](#steps-to-run-demo)
- [Extending Base App Implementation](#extending-base-app-implementation)
- [CustomerAppManager](#customerappmanager)
- [How to Override APIs](#how-to-override-apis)
- [DataModelCallbacks and CustomerAppManager](#datamodelcallbacks-and-customerappmanager)
- [Sample Implementation](#sample-implementation)
- [Override API Reference](#override-api-reference)
- [Troubleshooting](#troubleshooting)
- [Resources](#resources)
- [Report Bugs & Get Support](#report-bugs--get-support)
Expand Down Expand Up @@ -108,15 +113,16 @@ This sample app works out of the box with no additional configuration required.

## Extending Base App Implementation

See [Extending Base App Implementation](https://docs.silabs.com/matter/2.10.0/matter-api-reference#extending-base-app-implementation)
for `CustomerAppTask` customization, CRTP `*Impl()` hooks, and data model
callback routing. Per-example AppTask API references:
`autogen/AppTaskImpl.h`, `autogen/AppTask.cpp`.

| Concern | Base | CRTP hook layer | Customer leaf |
| ------- | ---- | --------------- | ------------- |
| Lifecycle / UI / buttons / DM callbacks | `AppTask` | `AppTaskImpl` | `CustomerAppTask` |
| Closure domain logic (motion, latch, panels) | `ClosureManager` | `ClosureManagerImpl` | `CustomerAppManager` |

### CustomerAppTask

To implement custom app behavior you can override any Silicon Labs implemented API in the CustomerAppTask file. This example provides `CustomerAppTask.h` and `CustomerAppTask.cpp` for that purpose. The base implementation and the full set of overridable `*Impl()` APIs are supplied by the build system in `AppTask.cpp` and `AppTaskImpl.h` under `autogen/`. Any `*Impl()` you do not override keeps the Silicon Labs default behavior.

### CustomerAppManager

Closure domain logic lives on `ClosureManager`. The customer leaf is provided as
Expand All @@ -137,29 +143,20 @@ Some `ClosureManager` APIs (`Init`, cluster `On*Command` handlers) are virtual
so shared `closure-common/` code can reach your leaf. Override the matching
`*Impl()` on `CustomerAppManager` — do not override the virtuals directly.

### DataModelCallbacks and CustomerAppTask
### DataModelCallbacks and CustomerAppManager

What used to live in `DataModelCallbacks.cpp` now lives in `AppTask.cpp`. The
Matter SDK's `MatterPostAttributeChangeCallback` is implemented in
`examples/platform/silabs/BaseApplication.cpp` and forwards to
`AppTask::DMPostAttributeChangeCallback` (defined in `AppTask.cpp`), which you
can customize via `DMPostAttributeChangeCallbackImpl()` in `CustomerAppTask`.

Closure-specific cluster attribute-changed callbacks
In addition to the general data model callback routing described in
[Extending Base App Implementation](https://docs.silabs.com/matter/2.10.0/matter-api-reference#datamodelcallbacks-and-customerapptask),
this app forwards closure-specific cluster attribute-changed callbacks
(`MatterClosureControlClusterServerAttributeChangedCallback`,
`MatterClosureDimensionClusterServerAttributeChangedCallback`) are forwarders
in `AppTask.cpp` and dispatch to
`DMClosureControlClusterAttributeChangedCallback` /
`DMClosureDimensionClusterAttributeChangedCallback`, customized via the
matching `*Impl()` hooks on `CustomerAppTask`.
`MatterClosureDimensionClusterServerAttributeChangedCallback`) from `AppTask.cpp`
to `DMClosureControlClusterAttributeChangedCallback` /
`DMClosureDimensionClusterAttributeChangedCallback`, customized via the matching
`*Impl()` hooks on `CustomerAppTask`.

Forwarding into `AppTask` still goes through CRTP as in
[How to Override APIs](#how-to-override-apis).

- **Methods that already exist in the AppTask** — Customize them by overriding
the matching `*Impl()` method in `CustomerAppTask`. Do not edit the
`AppTask.cpp` for app-specific behavior.

- **Methods that already exist in the ClosureManager** — Customize them by
overriding the matching `*Impl()` method in `CustomerAppManager`. Do not
edit `ClosureManager.cpp` for app-specific behavior.
Expand Down Expand Up @@ -277,12 +274,12 @@ chip::Protocols::InteractionModel::Status CustomerAppManager::OnMoveToCommandImp

### Override API Reference

The base API and implementation are generated into your project and live under `autogen/` directory. These files are regenerated on every project upgrade and match your installed SDK version. Use them as the reference for overridable methods and app configuration.
This example has a ClosureManager CRTP chain in addition to the AppTask chain
documented in
[Extending Base App Implementation](https://docs.silabs.com/matter/2.10.0/matter-api-reference/closure-app):

| File | Purpose |
|------|--------|
| `autogen/AppTaskImpl.h` | Declarations of every overridable `*Impl()` method. Copy the signatures you need from here into `CustomerAppTask.h`. |
| `autogen/AppTask.cpp` | Silicon Labs default implementation of AppTask. This is what runs for any `*Impl()` you do not override. Use as reference when customizing behavior. |
| `autogen/ClosureManagerImpl.h` | Declarations of every overridable `*Impl()` method. Copy the signatures you need from here into `CustomerAppManager.h`. |
| `autogen/ClosureManager.cpp` | Silicon Labs default implementation of ClosureManager. This is what runs for any `*Impl()` you do not override. Use as reference when customizing behavior. |

Expand Down
Loading
Loading