[Silabs] Window-app refactor (#27390)

* Window-app refactor.

* Fix WiFi build

* Restyled by whitespace

* Restyled by clang-format

* Fixed misspell in WindowManager.cpp

* Removed obsolete data model usage for Silabs Window App

---------

Co-authored-by: jepenven-silabs <jean-francois.penven@silabs.com>
Co-authored-by: Jean-Francois Penven <67962328+jepenven-silabs@users.noreply.github.com>
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn
index 2d8ec86..7983d16 100644
--- a/examples/platform/silabs/SiWx917/BUILD.gn
+++ b/examples/platform/silabs/SiWx917/BUILD.gn
@@ -247,16 +247,13 @@
     "${wifi_sdk_dir}/ethernetif.cpp",
     "${wifi_sdk_dir}/lwip_netif.cpp",
     "${wifi_sdk_dir}/wfx_notify.cpp",
+    "BaseApplication.cpp",
     "SiWx917/rsi_if.c",
     "SiWx917/wfx_rsi_host.c",
     "init_ccpPlatform.cpp",
     "matter_config.cpp",
   ]
 
-  if (use_base_app) {
-    sources += [ "BaseApplication.cpp" ]
-  }
-
   if (chip_enable_pw_rpc || chip_build_libshell) {
     sources += [ "uart.cpp" ]
   }
diff --git a/examples/platform/silabs/args.gni b/examples/platform/silabs/args.gni
index 47d4cbb..ff53170 100644
--- a/examples/platform/silabs/args.gni
+++ b/examples/platform/silabs/args.gni
@@ -22,5 +22,4 @@
 
 declare_args() {
   app_data_model = ""
-  use_base_app = true
 }
diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn
index 4a7119d..6d08c1d 100644
--- a/examples/platform/silabs/efr32/BUILD.gn
+++ b/examples/platform/silabs/efr32/BUILD.gn
@@ -280,14 +280,11 @@
     "${silabs_common_plat_dir}/heap_4_silabs.c",
     "${silabs_common_plat_dir}/silabs_utils.cpp",
     "${silabs_common_plat_dir}/syscalls_stubs.cpp",
+    "BaseApplication.cpp",
     "init_efrPlatform.cpp",
     "matter_config.cpp",
   ]
 
-  if (use_base_app) {
-    sources += [ "BaseApplication.cpp" ]
-  }
-
   if (chip_enable_pw_rpc || chip_build_libshell || enable_openthread_cli) {
     sources += [ "uart.cpp" ]
   }
diff --git a/examples/window-app/silabs/BUILD.gn b/examples/window-app/silabs/BUILD.gn
index 3536280..e5c33fd 100644
--- a/examples/window-app/silabs/BUILD.gn
+++ b/examples/window-app/silabs/BUILD.gn
@@ -18,9 +18,17 @@
 import("//build_overrides/pigweed.gni")
 
 import("${build_root}/config/defaults.gni")
+import("${efr32_sdk_build_root}/silabs_executable.gni")
+
+import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
 import("${chip_root}/src/platform/device.gni")
 import("${chip_root}/third_party/silabs/silabs_board.gni")
-import("${efr32_sdk_build_root}/silabs_executable.gni")
+
+if (chip_enable_pw_rpc) {
+  import("//build_overrides/pigweed.gni")
+  import("$dir_pw_build/target_types.gni")
+}
+
 assert(current_os == "freertos")
 
 project_dir = "${chip_root}/examples/window-app"
@@ -106,10 +114,10 @@
   defines = []
 
   sources = [
-    "${project_dir}/common/src/WindowApp.cpp",
-    "${project_dir}/common/src/ZclCallbacks.cpp",
-    "src/WindowAppImpl.cpp",
-    "src/main.cpp",
+    "${examples_common_plat_dir}/main.cpp",
+    "src/AppTask.cpp",
+    "src/WindowManager.cpp",
+    "src/ZclCallbacks.cpp",
   ]
 
   if (!disable_lcd) {
diff --git a/examples/window-app/silabs/SiWx917/.gn b/examples/window-app/silabs/SiWx917/.gn
deleted file mode 100644
index 0adefc6..0000000
--- a/examples/window-app/silabs/SiWx917/.gn
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2020 Project CHIP Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import("//build_overrides/build.gni")
-
-# The location of the build configuration file.
-buildconfig = "${build_root}/config/BUILDCONFIG.gn"
-
-# CHIP uses angle bracket includes.
-check_system_includes = true
-
-default_args = {
-  target_cpu = "arm"
-  target_os = "freertos"
-  import("//args.gni")
-}
diff --git a/examples/window-app/silabs/SiWx917/BUILD.gn b/examples/window-app/silabs/SiWx917/BUILD.gn
deleted file mode 100644
index 0d6c06b..0000000
--- a/examples/window-app/silabs/SiWx917/BUILD.gn
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (c) 2020 Project CHIP Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import("//build_overrides/build.gni")
-import("//build_overrides/chip.gni")
-import("//build_overrides/efr32_sdk.gni")
-import("//build_overrides/pigweed.gni")
-
-import("${build_root}/config/defaults.gni")
-import("${chip_root}/src/platform/device.gni")
-import("${efr32_sdk_build_root}/SiWx917_sdk.gni")
-import("${efr32_sdk_build_root}/silabs_executable.gni")
-
-assert(current_os == "freertos")
-
-project_dir = "${chip_root}/examples/window-app"
-efr32_project_dir = "${project_dir}/silabs/SiWx917"
-examples_plat_dir = "${chip_root}/examples/platform/silabs/SiWx917"
-examples_common_plat_dir = "${chip_root}/examples/platform/silabs"
-import("${examples_plat_dir}/args.gni")
-
-declare_args() {
-  # Dump memory usage at link time.
-  chip_print_memory_usage = false
-}
-
-siwx917_sdk("sdk") {
-  sources = [
-    "${efr32_project_dir}/include/CHIPProjectConfig.h",
-    "${examples_plat_dir}/FreeRTOSConfig.h",
-  ]
-
-  include_dirs = [
-    "${chip_root}/src/platform/silabs/SiWx917",
-    "${efr32_project_dir}/include",
-    "${examples_plat_dir}",
-    "${chip_root}/src/lib",
-    "${examples_common_plat_dir}",
-  ]
-}
-
-silabs_executable("window_app") {
-  output_name = "chip-siwx917-window-example.out"
-  output_dir = root_out_dir
-  include_dirs = [
-    "include",
-    "${project_dir}/common/include",
-  ]
-  defines = []
-
-  sources = [
-    "${project_dir}/common/src/WindowApp.cpp",
-    "${project_dir}/common/src/ZclCallbacks.cpp",
-    "src/WindowAppImpl.cpp",
-    "src/main.cpp",
-  ]
-
-  if (!disable_lcd) {
-    sources += [ "src/LcdPainter.cpp" ]
-  }
-
-  deps = [
-    ":sdk",
-    "${examples_plat_dir}:siwx917-common",
-    app_data_model,
-  ]
-
-  ldscript = "${examples_plat_dir}/ldscripts/${silabs_family}.ld"
-
-  inputs = [ ldscript ]
-
-  ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ]
-
-  if (chip_print_memory_usage) {
-    ldflags += [
-      "-Wl,--print-memory-usage",
-      "-fstack-usage",
-    ]
-  }
-
-  # WiFi Settings
-  if (chip_enable_wifi) {
-    ldflags += [
-      "-Wl,--defsym",
-      "-Wl,SILABS_WIFI=1",
-    ]
-  }
-}
-
-group("siwx917") {
-  deps = [ ":window_app" ]
-}
-
-group("default") {
-  deps = [ ":siwx917" ]
-}
diff --git a/examples/window-app/silabs/SiWx917/README.md b/examples/window-app/silabs/SiWx917/README.md
deleted file mode 100644
index a68345a..0000000
--- a/examples/window-app/silabs/SiWx917/README.md
+++ /dev/null
@@ -1,166 +0,0 @@
-# Matter SiWx917 Window Covering Example
-
-An example showing the use of CHIP on the Silicon Labs SiWx917 SoC device.
-
-<hr>
-
--   [Matter SiWx917 Window Covering Example](#matter-siwx917-window-covering-example)
-    -   [Introduction](#introduction)
-    -   [Building](#building)
-    -   [Flashing the Application](#flashing-the-application)
-    -   [Viewing Logging Output](#viewing-logging-output)
-    -   [Running the Complete Example](#running-the-complete-example)
-        -   [Notes](#notes)
-    -   [Building options](#building-options)
-        -   [Disabling logging](#disabling-logging)
-        -   [Debug build / release build](#debug-build--release-build)
-        -   [Disabling LCD](#disabling-lcd)
-        -   [KVS maximum entry count](#kvs-maximum-entry-count)
-
-<hr>
-
-> **NOTE:** Silicon Laboratories now maintains a public matter GitHub repo with
-> frequent releases thoroughly tested and validated. Developers looking to
-> develop matter products with silabs hardware are encouraged to use our latest
-> release with added tools and documentation.
-> [Silabs Matter Github](https://github.com/SiliconLabs/matter/releases)
-
-## Introduction
-
-The SiWx917 window-covering example provides a baseline demonstration of a
-Window Covering device, built using Matter, the Silicon Labs Gecko SDK, and the
-Silicon Labs WiseMCU SDK. It can be controlled by a Chip controller over a Wi-Fi
-network.
-
-The SiWx917 device can be commissioned over Bluetooth Low Energy where the
-device and the Chip controller will exchange security information with the
-rendezvous procedure. The Wi-Fi Network credentials are provided to the SiWx917
-device which will then join the Wi-Fi network.
-
-If the LCD is enabled, the LCD on the Silabs WSTK shows a QR Code containing the
-needed commissioning information for the BLE connection and starting the
-rendezvous procedure. Once the device is commissioned, the displays shows a
-representation of the window covering state.
-
-The window-covering example is intended to serve both as a means to explore the
-workings of Matter as well as a template for creating real products based on the
-Silicon Labs platform.
-
-## Building
-
--   Download the
-    [Simplicity Commander](https://www.silabs.com/mcu/programming-options)
-    command line tool, and ensure that `commander` is your shell search path.
-    (For Mac OS X, `commander` is located inside
-    `Commander.app/Contents/MacOS/`.)
-
--   Download and install a suitable ARM gcc tool chain:
-    [GNU Arm Embedded Toolchain 9-2019-q4-major](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)
-
--   Install some additional tools(likely already present for CHIP developers):
-
-           # Linux
-           $ sudo apt-get install git ninja-build
-
-           # Mac OS X
-           $ brew install ninja
-
--   Supported hardware:
-
-    -   > For the latest supported hardware please refer to the
-        > [Hardware Requirements](https://github.com/SiliconLabs/matter/blob/latest/docs/silabs/general/HARDWARE_REQUIREMENTS.md)
-        > in the Silicon Labs Matter Github Repo
-
-*   Build the example application:
-
-          cd ~/connectedhomeip
-          ./scripts/examples/gn_efr32_example.sh ./examples/window-app/silabs/SiWx917/ ./out/window-app BRD4325B
-
--   To delete generated executable, libraries and object files use:
-
-          $ cd ~/connectedhomeip
-          $ rm -rf ./out/
-
-<a name="flashing"></a>
-
-## Flashing the Application
-
--   Flashing requires the SiWx917 SoC device to be configured in the Ozone
-    Debugger.
--   Once it's configured, it can be run with the Ozone Debugger by loading the
-    .out file.
-    -   > For detailed instructions, please refer to
-        > [Running the Matter Demo on SiWx917 SoC](https://github.com/SiliconLabs/matter/blob/latest/docs/silabs/wifi/RUN_DEMO_SiWx917_SoC.md)
-        > in the Silicon Labs Matter Github Repo
-
-## Viewing Logging Output
-
-The example application's logging output can be viewed in the Ozone Debugger.
-
-## Running the Complete Example
-
-    You can provision the [chip-tool](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md)
-    and send ZCL commands to the window covering device. For
-    instance, to set the window covering lift by percentage:
-
-    -   > $SSID and $PSK are the SSID and passcode of your Wi-Fi Access Point.
-
-    ```
-    chip-tool pairing ble-wifi 1122 $SSID $PSK 20202021 3840
-
-    chip-tool onoff on 1 1
-
-    chip-tool windowcovering go-to-tilt-percentage 50 0 1 1
-    ```
-
-    To see the supported window covering cluster commands, use:
-
-    ```
-    chip-tool windowcovering
-    ```
-
-### Notes
-
--   Depending on your network settings your router might not provide native IPv6
-    addresses to your devices (Router / PC). If this is the case, you need to
-    add a static IPv6 addresses on both devices and then an IPv6 route to the
-    border router on your PC
-
-          # On PC (Linux) :
-          $ sudo ip addr add dev <Network interface> 2002::1/64
-
-          # Add IPv6 route on PC (Linux)
-          $ sudo ip route add <Router global IPv6prefix>/64 via 2002::2
-
-## Building options
-
-All of Silabs's examples within the Matter repo have all the features enabled by
-default, as to provide the best end user experience. However some of those
-features can easily be toggled on or off. Here is a short list of options :
-
-### Disabling logging
-
-chip_progress_logging, chip_detail_logging, chip_automation_logging
-
-    $ ./scripts/examples/gn_efr32_example.sh ./examples/window-app/silabs/SiWx917 ./out/window-app BRD4325B "chip_detail_logging=false chip_automation_logging=false chip_progress_logging=false"
-
-### Debug build / release build
-
-is_debug
-
-    $ ./scripts/examples/gn_efr32_example.sh ./examples/window-app/silabs/SiWx917 ./out/window-app BRD4325B "is_debug=false"
-
-### Disabling LCD
-
-show_qr_code
-
-    $ ./scripts/examples/gn_efr32_example.sh ./examples/window-app/silabs/SiWx917 ./out/window-app BRD4325B "show_qr_code=false"
-
-### KVS maximum entry count
-
-kvs_max_entries
-
-    Set the maximum Kvs entries that can be stored in NVM (Default 75)
-    Thresholds: 30 <= kvs_max_entries <= 255
-
-    $ ./scripts/examples/gn_efr32_example.sh ./examples/window-app/silabs/SiWx917 ./out/window-app BRD4325B kvs_max_entries=50
diff --git a/examples/window-app/silabs/SiWx917/args.gni b/examples/window-app/silabs/SiWx917/args.gni
deleted file mode 100644
index 7671254..0000000
--- a/examples/window-app/silabs/SiWx917/args.gni
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) 2020 Project CHIP Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import("//build_overrides/chip.gni")
-import("${chip_root}/config/standalone/args.gni")
-import("${chip_root}/src/platform/silabs/args.gni")
-
-silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain")
-
-app_data_model = "${chip_root}/examples/window-app/common:window-common"
-chip_enable_ota_requestor = true
-
-use_base_app = false
diff --git a/examples/window-app/silabs/SiWx917/build_overrides b/examples/window-app/silabs/SiWx917/build_overrides
deleted file mode 120000
index 995884e..0000000
--- a/examples/window-app/silabs/SiWx917/build_overrides
+++ /dev/null
@@ -1 +0,0 @@
-../../../build_overrides
\ No newline at end of file
diff --git a/examples/window-app/silabs/SiWx917/include/AppConfig.h b/examples/window-app/silabs/SiWx917/include/AppConfig.h
deleted file mode 100644
index 19c6432..0000000
--- a/examples/window-app/silabs/SiWx917/include/AppConfig.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- *    Copyright (c) 2020 Project CHIP Authors
- *    Copyright (c) 2019 Google LLC.
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#pragma once
-
-#include "silabs_utils.h"
-
-// ---- Window Example App Config ----
-#define APP_TASK_NAME "APP"
-
-#define LCD_SIZE 128
-#define LCD_MARGIN_SIZE 1
-#define LCD_BORDER_SIZE 2
-#define LCD_FRAME_SIZE (2 * LCD_MARGIN_SIZE + LCD_BORDER_SIZE)
-#define LCD_COVER_SIZE (LCD_SIZE - 2 * LCD_FRAME_SIZE)
-#define LIFT_OPEN_LIMIT 0
-#define LIFT_CLOSED_LIMIT (LCD_COVER_SIZE - 1)
-#define LIFT_DELTA 1000 // 10%
-#define TILT_OPEN_LIMIT 0
-#define TILT_CLOSED_LIMIT (LCD_COVER_SIZE / 10 - 1)
-#define TILT_DELTA 1000 // 10%
-
-#define WINDOW_COVER_COUNT 2
-
-#ifndef WINDOW_COVER_ENDPOINT1
-#define WINDOW_COVER_ENDPOINT1 1
-#endif
-
-#ifndef WINDOW_COVER_ENDPOINT2
-#define WINDOW_COVER_ENDPOINT2 2
-#endif
-
-#ifndef LONG_PRESS_TIMEOUT
-#define LONG_PRESS_TIMEOUT 3000
-#endif
-
-#ifndef COVER_LIFT_TILT_TIMEOUT
-#define COVER_LIFT_TILT_TIMEOUT 500
-#endif
diff --git a/examples/window-app/silabs/SiWx917/include/CHIPProjectConfig.h b/examples/window-app/silabs/SiWx917/include/CHIPProjectConfig.h
deleted file mode 100644
index f1a6927..0000000
--- a/examples/window-app/silabs/SiWx917/include/CHIPProjectConfig.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *
- *    Copyright (c) 2020 Project CHIP Authors
- *    Copyright (c) 2019 Google LLC.
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-/**
- *    @file
- *          Example project configuration file for CHIP.
- *
- *          This is a place to put application or project-specific overrides
- *          to the default configuration values for general CHIP features.
- *
- */
-
-#pragma once
-
-// Use a default pairing code if one hasn't been provisioned in flash.
-#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE
-#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021
-#endif
-
-#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR
-#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00
-#endif
-// For convenience, Chip Security Test Mode can be enabled and the
-// requirement for authentication in various protocols can be disabled.
-//
-//    WARNING: These options make it possible to circumvent basic Chip security functionality,
-//    including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS.
-//
-#define CHIP_CONFIG_SECURITY_TEST_MODE 0
-
-/**
- * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID
- *
- * 0xFFF1: Test vendor.
- */
-#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1
-
-/**
- * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID
- *
- * 0x8009: example window app
- */
-#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8010
-
-/**
- * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
- *
- * Enable support for Chip-over-BLE (CHIPoBLE).
- */
-#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1
-
-/**
- * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER
- *
- * Enables the use of a hard-coded default serial number if none
- * is found in Chip NV storage.
- */
-#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN"
-
-/**
- * CHIP_DEVICE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS
- *
- * Enable recording UTC timestamps.
- */
-#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1
-
-/**
- * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE
- *
- * A size, in bytes, of the individual debug event logging buffer.
- */
-#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512)
-
-/**
- * CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL
- *
- * The interval (in units of 0.625ms) at which the device will send BLE advertisements while
- * in fast advertising mode.
- *
- * 40 (25ms).
- */
-#define CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL 40
-
-/**
- * CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL
- *
- * The interval (in units of 0.625ms) at which the device will send BLE advertisements while
- * in slow advertisement mode.
- *
- * 800 (500ms).
- */
-#define CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL 800
-
-/**
- * CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT
- *
- * The amount of time in miliseconds after which BLE should change his advertisements
- * from fast interval to slow interval.
- *
- * 30000 (30 secondes).
- */
-#define CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT (30 * 1000)
-
-/**
- *  @def CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
- *
- *  @brief
- *    Active retransmit interval, or time to wait before retransmission after
- *    subsequent failures in milliseconds.
- *
- *  This is the default value, that might be adjusted by end device depending on its
- *  needs (e.g. sleeping period) using Service Discovery TXT record CRA key.
- *
- */
-#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32)
-
-#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
diff --git a/examples/window-app/silabs/SiWx917/include/DeviceConfig.h b/examples/window-app/silabs/SiWx917/include/DeviceConfig.h
deleted file mode 100644
index 350fbb4..0000000
--- a/examples/window-app/silabs/SiWx917/include/DeviceConfig.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*

- *

- *    Copyright (c) 2020 Project CHIP Authors

- *    Copyright (c) 2019 Google LLC.

- *    All rights reserved.

- *

- *    Licensed under the Apache License, Version 2.0 (the "License");

- *    you may not use this file except in compliance with the License.

- *    You may obtain a copy of the License at

- *

- *        http://www.apache.org/licenses/LICENSE-2.0

- *

- *    Unless required by applicable law or agreed to in writing, software

- *    distributed under the License is distributed on an "AS IS" BASIS,

- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- *    See the License for the specific language governing permissions and

- *    limitations under the License.

- */

-

-#pragma once

-

-#ifdef SIWX917_USE_COMISSIONABLE_DATA

-

-uint32_t discriminatorValue = 3840;

-uint64_t passcode           = 20202021;

-uint32_t spake2Interation   = 1000;

-char spake2Salt[]           = "U1BBS0UyUCBLZXkgU2FsdA==";

-char spake2Verifier[]       = "uWFwqugDNGiEck/po7KHwwMwwqZgN10XuyBajPGuyzUEV/iree4lOrao5GuwnlQ65CJzbeUB49s31EH+NEkg0JVI5MGCQGMMT/"

-                        "SRPFNRODm3wH/MBiehuFc6FJ/NH6Rmzw==";

-char genSpake2Path[]   = "";

-uint32_t productId     = 32773;

-uint32_t vendorId      = 65521;

-char productName[]     = "silabs_product";

-char vendorName[]      = "silabs_vendor";

-char hwVersionString[] = "1.0";

-uint32_t rotatingId;

-uint32_t commissionableFlow = 1;

-uint8_t rendezvousFlag      = 2;

-

-#endif
\ No newline at end of file
diff --git a/examples/window-app/silabs/SiWx917/include/LcdPainter.h b/examples/window-app/silabs/SiWx917/include/LcdPainter.h
deleted file mode 100644
index 4a30bde..0000000
--- a/examples/window-app/silabs/SiWx917/include/LcdPainter.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- *    Copyright (c) 2019 Google LLC.
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#pragma once
-
-// clang-format off
-#include "app-common/app-common/zap-generated/enums.h"
-#include "app-common/app-common/zap-generated/cluster-enums.h"
-// clang-format on
-
-#include <lcd.h>
-
-#include <stdint.h>
-
-enum class LcdIcon
-{
-    None = 0,
-    One,
-    Two,
-    Lift,
-    Tilt
-};
-
-class PixelPainter
-{
-public:
-    PixelPainter(uint16_t lift, uint16_t tilt);
-    virtual ~PixelPainter()                       = default;
-    virtual uint8_t Color(uint32_t x, uint32_t y) = 0;
-
-protected:
-    uint16_t mLift;
-    uint16_t mTilt;
-};
-
-class CompositePainter : public PixelPainter
-{
-public:
-    CompositePainter(uint16_t lift, uint16_t tilt, PixelPainter * painter1, PixelPainter * painter2, PixelPainter * painter3);
-    uint8_t Color(uint32_t x, uint32_t y);
-
-private:
-    PixelPainter * mPainter1;
-    PixelPainter * mPainter2;
-    PixelPainter * mPainter3;
-};
-
-class FramePainter : public PixelPainter
-{
-    using PixelPainter::PixelPainter;
-    uint8_t Color(uint32_t x, uint32_t y);
-};
-
-class IconPainter : public PixelPainter
-{
-public:
-    IconPainter(uint16_t lift, uint16_t tilt, LcdIcon icon);
-    uint8_t Color(uint32_t x, uint32_t y);
-
-private:
-    uint8_t mIconSize;
-    uint8_t mIconOffset;
-    LcdIcon mIcon;
-};
-
-class VerticalShadePainter : public PixelPainter
-{
-public:
-    using PixelPainter::PixelPainter;
-    uint8_t Color(uint32_t x, uint32_t y);
-};
-
-class HorizontalShadePainter : public PixelPainter
-{
-public:
-    using PixelPainter::PixelPainter;
-    uint8_t Color(uint32_t x, uint32_t y);
-};
-
-class VerticalBlindPainter : public PixelPainter
-{
-public:
-    VerticalBlindPainter(uint16_t lift, uint16_t tilt);
-    uint8_t Color(uint32_t x, uint32_t y);
-
-private:
-    constexpr static uint8_t sBandCount = 12;
-    uint8_t mBandSize;
-};
-
-class LcdPainter
-{
-public:
-    static void Paint(SilabsLCD & lcd, chip::app::Clusters::WindowCovering::Type type, uint16_t lift, uint16_t tilt, LcdIcon icon);
-
-private:
-    static PixelPainter * GetCoverPainter(chip::app::Clusters::WindowCovering::Type type, uint16_t lift, uint16_t tilt);
-};
diff --git a/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h b/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h
deleted file mode 100644
index 827e3b1..0000000
--- a/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *
- *    Copyright (c) 2021 Project CHIP Authors
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#pragma once
-
-#include <FreeRTOS.h>
-
-#include "LEDWidget.h"
-
-#include <WindowApp.h>
-#include <queue.h>
-#include <setup_payload/QRCodeSetupPayloadGenerator.h>
-
-#include <string>
-#include <task.h>
-#include <timers.h>
-#ifdef DISPLAY_ENABLED
-#include <LcdPainter.h>
-#endif
-
-#define SIWx917_BTN0 0
-#define SIWx917_BTN1 1
-
-#define SL_SIMPLE_BUTTON_PRESSED 1U  ///< BUTTON state is pressed
-#define SL_SIMPLE_BUTTON_RELEASED 0U ///< BUTTON state is released
-
-class WindowAppImpl : public WindowApp
-{
-public:
-    static WindowAppImpl sInstance;
-    bool mWindowAppInit = false;
-
-    WindowAppImpl();
-    CHIP_ERROR Init() override;
-    CHIP_ERROR Start() override;
-    void Finish() override;
-    void PostEvent(const WindowApp::Event & event) override;
-    void PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId) override;
-    void OnButtonChange(uint8_t btn, uint8_t btnAction);
-
-protected:
-    struct Timer : public WindowApp::Timer
-    {
-        TimerHandle_t mHandler = nullptr;
-
-        Timer(const char * name, uint32_t timeoutInMs, Callback callback, void * context);
-        void IsrStart();
-        void Start() override;
-        void Stop() override;
-
-    private:
-        static void TimerCallback(TimerHandle_t xTimer);
-    };
-
-    struct Button : public WindowApp::Button
-    {
-        Button(Button::Id id, const char * name);
-    };
-
-    WindowApp::Timer * CreateTimer(const char * name, uint32_t timeoutInMs, WindowApp::Timer::Callback callback,
-                                   void * context) override;
-    WindowApp::Button * CreateButton(WindowApp::Button::Id id, const char * name) override;
-    void ProcessEvents();
-    void DispatchEvent(const WindowApp::Event & event) override;
-    void UpdateLEDs();
-    void UpdateLCD();
-    void OnMainLoop() override;
-
-    static void OnTaskCallback(void * parameter);
-    static void OnIconTimeout(WindowApp::Timer & timer);
-
-private:
-    void DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute);
-    TaskHandle_t mHandle = nullptr;
-    QueueHandle_t mQueue = nullptr;
-
-    LEDWidget mStatusLED;
-    LEDWidget mActionLED;
-
-    // Get QR Code and emulate its content using NFC tag
-    char mQRCodeBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1];
-#ifdef DISPLAY_ENABLED
-    Timer mIconTimer;
-    LcdIcon mIcon = LcdIcon::None;
-#endif
-};
diff --git a/examples/window-app/silabs/SiWx917/src/LcdPainter.cpp b/examples/window-app/silabs/SiWx917/src/LcdPainter.cpp
deleted file mode 100644
index e1a8041..0000000
--- a/examples/window-app/silabs/SiWx917/src/LcdPainter.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *
- *    Copyright (c) 2020 Project CHIP Authors
- *    Copyright (c) 2019 Google LLC.
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <LcdPainter.h>
-
-using namespace chip::app::Clusters::WindowCovering;
-
-constexpr uint32_t sTiltIcon[] = {
-    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xc1ffffc3, 0xc1ffffc3,
-    0xc1ffffc3, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003,
-    0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003,
-    0xc003c003, 0xc003c003, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
-};
-
-constexpr uint32_t sLiftIcon[] = {
-    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0f00003, 0xc0f00003,
-    0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003,
-    0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0ffffc3,
-    0xc0ffffc3, 0xc0ffffc3, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
-};
-
-constexpr uint32_t sOneIcon[] = {
-    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc00fe003, 0xc01fe003, 0xc03fe003,
-    0xc07fe003, 0xc0fbe003, 0xc1f3e003, 0xc3e3e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003,
-    0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc3ffffc3,
-    0xc3ffffc3, 0xc3ffffc3, 0xc3ffffc3, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
-};
-
-constexpr uint32_t sTwoIcon[] = {
-    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc07ffe03, 0xc0ffff03, 0xc1ffff83,
-    0xc3ffffc3, 0xc3f00fc3, 0xc3e007c3, 0xc3e007c3, 0xc00007c3, 0xc00007c3, 0xc0000fc3, 0xc00fff83,
-    0xc03fff03, 0xc07ffe03, 0xc0fc0003, 0xc1f80003, 0xc1f00003, 0xc3e00003, 0xc3e00003, 0xc3ffffc3,
-    0xc3ffffc3, 0xc3ffffc3, 0xc3ffffc3, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
-};
-
-PixelPainter::PixelPainter(uint16_t lift, uint16_t tilt) : mLift(lift), mTilt(tilt) {}
-
-CompositePainter::CompositePainter(uint16_t lift, uint16_t tilt, PixelPainter * painter1, PixelPainter * painter2,
-                                   PixelPainter * painter3) :
-    PixelPainter(lift, tilt),
-    mPainter1(painter1), mPainter2(painter2), mPainter3(painter3)
-{}
-
-uint8_t CompositePainter::Color(uint32_t x, uint32_t y)
-{
-    int8_t pixel = -1;
-    if (mPainter1)
-    {
-        pixel = mPainter1->Color(x, y);
-        if (pixel >= 0)
-        {
-            return pixel;
-        }
-    }
-    if (mPainter2)
-    {
-        pixel = mPainter2->Color(x, y);
-        if (pixel >= 0)
-        {
-            return pixel;
-        }
-    }
-    if (mPainter3)
-    {
-        pixel = mPainter3->Color(x, y);
-        if (pixel >= 0)
-        {
-            return pixel;
-        }
-    }
-    return pixel;
-}
-
-uint8_t FramePainter::Color(uint32_t x, uint32_t y)
-{
-    if (x < LCD_FRAME_SIZE || x >= (LCD_SIZE - LCD_FRAME_SIZE) || y < LCD_FRAME_SIZE || y >= (LCD_SIZE - LCD_FRAME_SIZE))
-    {
-        if (x < LCD_MARGIN_SIZE || x >= (LCD_SIZE - LCD_MARGIN_SIZE) || y < LCD_MARGIN_SIZE || y >= (LCD_SIZE - LCD_MARGIN_SIZE))
-        {
-            return 0;
-        }
-        else
-        {
-            return (x < (LCD_MARGIN_SIZE + LCD_BORDER_SIZE)) || (x >= (LCD_SIZE - LCD_BORDER_SIZE - LCD_MARGIN_SIZE)) ||
-                (y < (LCD_MARGIN_SIZE + LCD_BORDER_SIZE)) || (y >= (LCD_SIZE - LCD_BORDER_SIZE - LCD_MARGIN_SIZE));
-        }
-    }
-    return -1;
-}
-
-IconPainter::IconPainter(uint16_t lift, uint16_t tilt, LcdIcon icon) : PixelPainter(lift, tilt), mIcon(icon)
-{
-    mIconSize   = sizeof(sTiltIcon) / sizeof(uint32_t);
-    mIconOffset = (LCD_SIZE - mIconSize) / 2;
-}
-
-uint8_t IconPainter::Color(uint32_t x, uint32_t y)
-{
-    const uint32_t * icon = nullptr;
-    switch (mIcon)
-    {
-    case LcdIcon::One:
-        icon = sOneIcon;
-        break;
-    case LcdIcon::Two:
-        icon = sTwoIcon;
-        break;
-    case LcdIcon::Lift:
-        icon = sLiftIcon;
-        break;
-    case LcdIcon::Tilt:
-        icon = sTiltIcon;
-        break;
-    default:
-        return -1;
-    }
-    if (x >= mIconOffset && x < (mIconOffset + mIconSize) && y >= mIconOffset && y < (mIconOffset + mIconSize))
-    {
-        uint32_t x0 = x - mIconOffset;
-        uint32_t y0 = y - mIconOffset;
-        return (icon[y0] & (1 << (31 - x0))) > 0;
-    }
-    return -1;
-}
-
-uint8_t VerticalShadePainter::Color(uint32_t x, uint32_t y)
-{
-    return (y % 2) && y < (uint32_t)(LCD_FRAME_SIZE + mLift);
-}
-
-uint8_t HorizontalShadePainter::Color(uint32_t x, uint32_t y)
-{
-    return (x % 2) && x < (uint32_t)(LCD_FRAME_SIZE + mLift);
-}
-
-VerticalBlindPainter::VerticalBlindPainter(uint16_t lift, uint16_t tilt) : PixelPainter(lift, tilt)
-{
-    mBandSize = (LCD_COVER_SIZE / sBandCount);
-}
-
-uint8_t VerticalBlindPainter::Color(uint32_t x, uint32_t y)
-{
-    if (x % 2)
-    {
-        return 0;
-    }
-    else
-    {
-        uint32_t closedCount = (mLift + 1) / mBandSize;
-        uint32_t bandCount   = (y - LCD_FRAME_SIZE) / mBandSize;
-        // ChipLogProgress(Zcl, "BLIND: ccount:%u, ccount:%u", clusterId);
-        if (bandCount <= closedCount)
-        {
-            return y <= (LCD_FRAME_SIZE + mBandSize * bandCount + mTilt);
-        }
-        else
-        {
-            return 0;
-        }
-    }
-}
-
-PixelPainter * LcdPainter::GetCoverPainter(Type type, uint16_t lift, uint16_t tilt)
-{
-    switch (type)
-    {
-    case Type::kRollerShade:
-    case Type::kRollerShade2Motor:
-    case Type::kRollerShadeExterior:
-    case Type::kRollerShadeExterior2Motor:
-        return new VerticalShadePainter(lift, tilt);
-    case Type::kDrapery:
-    case Type::kAwning:
-        return new HorizontalShadePainter(lift, tilt);
-    case Type::kShutter:
-    case Type::kTiltBlindTiltOnly:
-    case Type::kTiltBlindLiftAndTilt:
-        return new VerticalBlindPainter(lift, tilt);
-    case Type::kProjectorScreen:
-    case Type::kUnknown:
-    default:
-        return new VerticalShadePainter(lift, tilt);
-    }
-
-    return nullptr;
-}
-
-void LcdPainter::Paint(SilabsLCD & lcd, Type type, uint16_t lift, uint16_t tilt, LcdIcon icon)
-{
-    FramePainter framePaint         = FramePainter(lift, tilt);
-    IconPainter iconPaint           = IconPainter(lift, tilt, icon);
-    PixelPainter * coverPaint       = GetCoverPainter(type, lift, tilt);
-    CompositePainter compositePaint = CompositePainter(lift, tilt, &framePaint, &iconPaint, coverPaint);
-    void * context                  = lcd.Context();
-
-    lcd.Clear();
-
-    for (int i = 0; i < LCD_SIZE; i++)
-    {
-        for (int j = 0; j < LCD_SIZE; j++)
-        {
-            if (compositePaint.Color(i, j))
-            {
-                lcd.DrawPixel(context, i, j);
-            }
-        }
-    }
-    lcd.Update();
-    delete coverPaint;
-}
diff --git a/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp b/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp
deleted file mode 100644
index a8a4d3f..0000000
--- a/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- *
- *    Copyright (c) 2021 Project CHIP Authors
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <AppConfig.h>
-#include <WindowAppImpl.h>
-#include <app-common/zap-generated/attributes/Accessors.h>
-#include <app/clusters/window-covering-server/window-covering-server.h>
-#include <app/server/OnboardingCodesUtil.h>
-#include <lib/core/CHIPError.h>
-#include <lib/dnssd/Advertiser.h>
-#include <lib/support/CodeUtils.h>
-#include <platform/CHIPDeviceLayer.h>
-#ifdef QR_CODE_ENABLED
-#include <qrcodegen.h>
-#else
-#include "SilabsDeviceDataProvider.h"
-#include <setup_payload/QRCodeSetupPayloadGenerator.h>
-#include <setup_payload/SetupPayload.h>
-#endif // QR_CODE_ENABLED
-
-extern "C" void sl_button_on_change(uint8_t btn, uint8_t btnAction);
-
-#ifdef SL_WIFI
-#include "wfx_host_events.h"
-#include <app/clusters/network-commissioning/network-commissioning.h>
-#include <platform/silabs/NetworkCommissioningWiFiDriver.h>
-#endif
-
-#ifdef DISPLAY_ENABLED
-#include <LcdPainter.h>
-SilabsLCD slLCD;
-#endif
-
-#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
-
-#define APP_TASK_STACK_SIZE (4096)
-#define APP_TASK_PRIORITY 2
-#define APP_EVENT_QUEUE_SIZE 10
-#define EXAMPLE_VENDOR_ID 0xcafe
-
-#define LCD_ICON_TIMEOUT 1000
-
-using namespace chip::app::Clusters::WindowCovering;
-using namespace chip;
-using namespace ::chip::DeviceLayer;
-#define APP_STATE_LED 0
-#define APP_ACTION_LED 1
-
-#ifdef SL_WIFI
-chip::app::Clusters::NetworkCommissioning::Instance
-    sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(chip::DeviceLayer::NetworkCommissioning::SlWiFiDriver::GetInstance()));
-#endif
-//------------------------------------------------------------------------------
-// Timers
-//------------------------------------------------------------------------------
-
-WindowAppImpl::Timer::Timer(const char * name, uint32_t timeoutInMs, Callback callback, void * context) :
-    WindowApp::Timer(name, timeoutInMs, callback, context)
-{
-    mHandler = xTimerCreate(name,                       // Just a text name, not used by the RTOS kernel
-                            pdMS_TO_TICKS(timeoutInMs), // == default timer period
-                            false,                      // no timer reload (==one-shot)
-                            (void *) this,              // init timer id = app task obj context
-                            TimerCallback               // timer callback handler
-    );
-    if (mHandler == NULL)
-    {
-        SILABS_LOG("Timer create failed");
-        appError(CHIP_ERROR_INTERNAL);
-    }
-}
-
-void WindowAppImpl::Timer::Start()
-{
-    if (xTimerIsTimerActive(mHandler))
-    {
-        Stop();
-    }
-
-    // Timer is not active
-    if (xTimerStart(mHandler, pdMS_TO_TICKS(100)) != pdPASS)
-    {
-        SILABS_LOG("Timer start() failed");
-        appError(CHIP_ERROR_INTERNAL);
-    }
-
-    mIsActive = true;
-}
-
-void WindowAppImpl::Timer::IsrStart()
-{
-    portBASE_TYPE taskWoken = pdFALSE; // For FreeRTOS timer (below).
-    // Start/restart the button debounce timer (Note ISR version of FreeRTOS
-    // api call here).
-    xTimerStartFromISR(mHandler, &taskWoken);
-    if (taskWoken != pdFALSE)
-    {
-        taskYIELD();
-    }
-    mIsActive = true;
-}
-
-void WindowAppImpl::Timer::Stop()
-{
-    mIsActive = false;
-    if (xTimerStop(mHandler, pdMS_TO_TICKS(0)) == pdFAIL)
-    {
-        SILABS_LOG("Timer stop() failed");
-        appError(CHIP_ERROR_INTERNAL);
-    }
-}
-
-void WindowAppImpl::Timer::TimerCallback(TimerHandle_t xTimer)
-{
-    Timer * timer = (Timer *) pvTimerGetTimerID(xTimer);
-    if (timer)
-    {
-        timer->Timeout();
-    }
-}
-
-//------------------------------------------------------------------------------
-// Main Task
-//------------------------------------------------------------------------------
-
-StackType_t sAppStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)];
-StaticTask_t sAppTaskStruct;
-
-uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(WindowApp::Event)];
-StaticQueue_t sAppEventQueueStruct;
-
-WindowAppImpl WindowAppImpl::sInstance;
-
-WindowApp & WindowApp::Instance()
-{
-    return WindowAppImpl::sInstance;
-}
-
-#ifdef DISPLAY_ENABLED
-WindowAppImpl::WindowAppImpl() : mIconTimer("Timer:icon", LCD_ICON_TIMEOUT, OnIconTimeout, this) {}
-#else
-WindowAppImpl::WindowAppImpl() {}
-#endif
-
-void WindowAppImpl::OnTaskCallback(void * parameter)
-{
-#ifdef SL_WIFI
-    /*
-     * Wait for the WiFi to be initialized
-     */
-    SILABS_LOG("APP: Wait WiFi Init");
-    while (!wfx_hw_ready())
-    {
-        vTaskDelay(10);
-    }
-    SILABS_LOG("APP: Done WiFi Init");
-    /* We will init server when we get IP */
-    chip::DeviceLayer::PlatformMgr().LockChipStack();
-    sWiFiNetworkCommissioningInstance.Init();
-    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-    /* added for commissioning with wifi */
-#endif
-
-    sInstance.Run();
-}
-
-void WindowAppImpl::OnIconTimeout(WindowApp::Timer & timer)
-{
-#ifdef DISPLAY_ENABLED
-    sInstance.mIcon = LcdIcon::None;
-    sInstance.UpdateLCD();
-#endif
-}
-
-CHIP_ERROR WindowAppImpl::Init()
-{
-    chip::DeviceLayer::Silabs::GetPlatform().SetButtonsCb(WindowAppImpl::ButtonEventHandler);
-
-    WindowApp::Init();
-
-    // Initialize App Task
-    mHandle = xTaskCreateStatic(OnTaskCallback, APP_TASK_NAME, ArraySize(sAppStack), NULL, 1, sAppStack, &sAppTaskStruct);
-    if (NULL == mHandle)
-    {
-        SILABS_LOG("Failed to allocate app task");
-        return CHIP_ERROR_NO_MEMORY;
-    }
-
-    // Initialize App Queue
-    mQueue = xQueueCreateStatic(APP_EVENT_QUEUE_SIZE, sizeof(WindowApp::Event), sAppEventQueueBuffer, &sAppEventQueueStruct);
-    if (NULL == mQueue)
-    {
-        SILABS_LOG("Failed to allocate app event queue");
-        return CHIP_ERROR_NO_MEMORY;
-    }
-
-    // Initialize LEDs
-
-    mStatusLED.Init(APP_STATE_LED);
-    mActionLED.Init(APP_ACTION_LED);
-
-#ifdef DISPLAY_ENABLED
-    slLCD.Init();
-#endif
-
-#ifndef QR_CODE_ENABLED
-    // Create buffer for QR code that can fit max size and null terminator.
-    char qrCodeBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1];
-    chip::MutableCharSpan QRCode(qrCodeBuffer);
-
-    if (Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider().GetSetupPayload(QRCode) == CHIP_NO_ERROR)
-    {
-        PrintQrCodeURL(QRCode);
-    }
-    else
-    {
-        SILABS_LOG("Getting QR code failed!");
-    }
-#endif // QR_CODE_ENABLED
-
-    mWindowAppInit = true;
-
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR WindowAppImpl::Start()
-{
-    SILABS_LOG("Starting FreeRTOS scheduler");
-    vTaskStartScheduler();
-
-    return CHIP_NO_ERROR;
-}
-
-void WindowAppImpl::Finish()
-{
-    WindowApp::Finish();
-    chip::Platform::MemoryShutdown();
-    // Should never get here.
-    SILABS_LOG("vTaskStartScheduler() failed");
-    appError(CHIP_ERROR_INTERNAL);
-}
-
-void WindowAppImpl::PostEvent(const WindowApp::Event & event)
-{
-    if (mQueue)
-    {
-        BaseType_t status;
-        if (xPortIsInsideInterrupt())
-        {
-            BaseType_t higherPrioTaskWoken = pdFALSE;
-            status                         = xQueueSendFromISR(mQueue, &event, &higherPrioTaskWoken);
-
-#ifdef portYIELD_FROM_ISR
-            portYIELD_FROM_ISR(higherPrioTaskWoken);
-#elif portEND_SWITCHING_ISR // portYIELD_FROM_ISR or portEND_SWITCHING_ISR
-            portEND_SWITCHING_ISR(higherPrioTaskWoken);
-#else                       // portYIELD_FROM_ISR or portEND_SWITCHING_ISR
-#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR"
-#endif // portYIELD_FROM_ISR or portEND_SWITCHING_ISR
-        }
-        else
-        {
-            status = xQueueSend(mQueue, &event, 1);
-        }
-
-        if (!status)
-        {
-            SILABS_LOG("Failed to post event to app task event queue");
-        }
-    }
-}
-
-void WindowAppImpl::PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId)
-{
-    Instance().PostEvent(WindowApp::Event(WindowApp::EventId::AttributeChange, endpoint, attributeId));
-}
-
-void WindowAppImpl::ProcessEvents()
-{
-    WindowApp::Event event = EventId::None;
-
-    BaseType_t received = xQueueReceive(mQueue, &event, pdMS_TO_TICKS(10));
-    while (pdTRUE == received)
-    {
-        DispatchEvent(event);
-        received = xQueueReceive(mQueue, &event, 0);
-    }
-}
-
-WindowApp::Timer * WindowAppImpl::CreateTimer(const char * name, uint32_t timeoutInMs, WindowApp::Timer::Callback callback,
-                                              void * context)
-{
-    return new Timer(name, timeoutInMs, callback, context);
-}
-
-WindowApp::Button * WindowAppImpl::CreateButton(WindowApp::Button::Id id, const char * name)
-{
-    return new Button(id, name);
-}
-
-void WindowAppImpl::DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute)
-{
-    switch (attribute)
-    {
-    /* RO OperationalStatus */
-    case Attributes::OperationalStatus::Id:
-        UpdateLEDs();
-        break;
-    /* RO Type: not supposed to dynamically change -> Cycling Window Covering Demo */
-    case Attributes::Type::Id:
-    /* ============= Positions for Position Aware ============= */
-    case Attributes::CurrentPositionLiftPercent100ths::Id:
-    case Attributes::CurrentPositionTiltPercent100ths::Id:
-        UpdateLCD();
-        break;
-    /* ### ATTRIBUTEs CHANGEs IGNORED ### */
-    /* RO EndProductType: not supposed to dynamically change */
-    case Attributes::EndProductType::Id:
-    /* RO ConfigStatus: set by WC server */
-    case Attributes::ConfigStatus::Id:
-    /* RO SafetyStatus: set by WC server */
-    case Attributes::SafetyStatus::Id:
-    /* RW Mode: User can change */
-    case Attributes::Mode::Id:
-    default:
-        break;
-    }
-}
-
-void WindowAppImpl::DispatchEvent(const WindowApp::Event & event)
-{
-    WindowApp::DispatchEvent(event);
-    switch (event.mId)
-    {
-    case EventId::AttributeChange:
-        DispatchEventAttributeChange(event.mEndpoint, event.mAttributeId);
-        break;
-    case EventId::ResetWarning:
-        SILABS_LOG("Factory Reset Triggered. Release button within %ums to cancel.", LONG_PRESS_TIMEOUT);
-        // Turn off all LEDs before starting blink to make sure blink is
-        // co-ordinated.
-        UpdateLEDs();
-        break;
-    case EventId::ResetCanceled:
-        SILABS_LOG("Factory Reset has been Canceled");
-        UpdateLEDs();
-        break;
-    case EventId::ProvisionedStateChanged:
-        UpdateLEDs();
-        UpdateLCD();
-        break;
-
-    case EventId::WinkOn:
-    case EventId::WinkOff:
-        mState.isWinking = (EventId::WinkOn == event.mId);
-        UpdateLEDs();
-        break;
-    case EventId::ConnectivityStateChanged:
-    case EventId::BLEConnectionsChanged:
-        UpdateLEDs();
-        break;
-#ifdef DISPLAY_ENABLED
-    case EventId::CoverTypeChange:
-        UpdateLCD();
-        break;
-    case EventId::CoverChange:
-        mIconTimer.Start();
-        mIcon = (GetCover().mEndpoint == 1) ? LcdIcon::One : LcdIcon::Two;
-        UpdateLCD();
-        break;
-    case EventId::TiltModeChange:
-        mIconTimer.Start();
-        mIcon = mTiltMode ? LcdIcon::Tilt : LcdIcon::Lift;
-        UpdateLCD();
-        break;
-#endif
-    default:
-        break;
-    }
-}
-
-void WindowAppImpl::UpdateLEDs()
-{
-    Cover & cover = GetCover();
-    if (mResetWarning)
-    {
-
-        mStatusLED.Set(false);
-        mStatusLED.Blink(500);
-
-        mActionLED.Set(false);
-        mActionLED.Blink(500);
-    }
-    else
-    {
-        if (mState.isWinking)
-        {
-
-            mStatusLED.Blink(200, 200);
-        }
-        else
-#if CHIP_ENABLE_OPENTHREAD
-            if (mState.isThreadProvisioned && mState.isThreadEnabled)
-#else
-            if (mState.isWiFiProvisioned && mState.isWiFiEnabled)
-#endif
-
-        {
-
-            mStatusLED.Blink(950, 50);
-        }
-        else if (mState.haveBLEConnections) { mStatusLED.Blink(100, 100); }
-        else { mStatusLED.Blink(50, 950); }
-
-        // Action LED
-        NPercent100ths current;
-        LimitStatus liftLimit = LimitStatus::Intermediate;
-
-        chip::DeviceLayer::PlatformMgr().LockChipStack();
-        Attributes::CurrentPositionLiftPercent100ths::Get(cover.mEndpoint, current);
-        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
-        if (!current.IsNull())
-        {
-            AbsoluteLimits limits = { .open = WC_PERCENT100THS_MIN_OPEN, .closed = WC_PERCENT100THS_MAX_CLOSED };
-            liftLimit             = CheckLimitState(current.Value(), limits);
-        }
-
-        if (OperationalState::Stall != cover.mLiftOpState)
-        {
-
-            mActionLED.Blink(100);
-        }
-        else if (LimitStatus::IsUpOrOpen == liftLimit)
-        {
-
-            mActionLED.Set(true);
-        }
-        else if (LimitStatus::IsDownOrClose == liftLimit)
-        {
-
-            mActionLED.Set(false);
-        }
-        else
-        {
-
-            mActionLED.Blink(1000);
-        }
-    }
-}
-
-void WindowAppImpl::UpdateLCD()
-{
-    // Update LCD
-#ifdef DISPLAY_ENABLED
-#if CHIP_ENABLE_OPENTHREAD
-    if (mState.isThreadProvisioned)
-#else
-    if (mState.isWiFiProvisioned)
-#endif // CHIP_ENABLE_OPENTHREAD
-    {
-        Cover & cover = GetCover();
-        chip::app::DataModel::Nullable<uint16_t> lift;
-        chip::app::DataModel::Nullable<uint16_t> tilt;
-
-        chip::DeviceLayer::PlatformMgr().LockChipStack();
-        Type type = TypeGet(cover.mEndpoint);
-
-        Attributes::CurrentPositionLift::Get(cover.mEndpoint, lift);
-        Attributes::CurrentPositionTilt::Get(cover.mEndpoint, tilt);
-        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
-#ifdef DISPLAY_ENABLED
-        if (!tilt.IsNull() && !lift.IsNull())
-        {
-            LcdPainter::Paint(slLCD, type, lift.Value(), tilt.Value(), mIcon);
-        }
-#endif
-    }
-#ifdef QR_CODE_ENABLED
-    else
-    {
-        chip::MutableCharSpan qrCode(mQRCodeBuffer);
-        if (GetQRCode(qrCode, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)) == CHIP_NO_ERROR)
-        {
-            slLCD.SetQRCode((uint8_t *) qrCode.data(), qrCode.size());
-            slLCD.ShowQRCode(true, true);
-        }
-    }
-#endif // QR_CODE_ENABLED
-#endif // DISPLAY_ENABLED
-}
-
-void WindowAppImpl::OnMainLoop()
-{
-
-    mStatusLED.Animate();
-    mActionLED.Animate();
-}
-
-//------------------------------------------------------------------------------
-// Buttons
-//------------------------------------------------------------------------------
-WindowAppImpl::Button::Button(WindowApp::Button::Id id, const char * name) : WindowApp::Button(id, name) {}
-
-void WindowAppImpl::OnButtonChange(uint8_t Btn, uint8_t btnAction)
-{
-    WindowApp::Button * btn = static_cast<Button *>((Btn == SIWx917_BTN0) ? sInstance.mButtonUp : sInstance.mButtonDown);
-    if (Btn == SIWx917_BTN1)
-    {
-        btn->Press();
-        btn->Release();
-    }
-    else
-    {
-        if (btnAction)
-        {
-            btn->Press();
-        }
-        else
-        {
-            btn->Release();
-        }
-    }
-}
-
-// Silabs button callback from button event ISR
-void sl_button_on_change(uint8_t btn, uint8_t btnAction)
-{
-    WindowAppImpl * app = static_cast<WindowAppImpl *>(&WindowAppImpl::sInstance);
-    if (app->mWindowAppInit)
-    {
-        app->OnButtonChange(btn, btnAction);
-    }
-}
diff --git a/examples/window-app/silabs/SiWx917/src/main.cpp b/examples/window-app/silabs/SiWx917/src/main.cpp
deleted file mode 100644
index 22625fe..0000000
--- a/examples/window-app/silabs/SiWx917/src/main.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- *    Copyright (c) 2020 Project CHIP Authors
- *    Copyright (c) 2019 Google LLC.
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <AppConfig.h>
-#include <WindowApp.h>
-
-#include "init_ccpPlatform.h"
-#include <DeviceInfoProviderImpl.h>
-#include <app/server/Server.h>
-#include <credentials/DeviceAttestationCredsProvider.h>
-#include <matter_config.h>
-#ifdef SILABS_ATTESTATION_CREDENTIALS
-#include <examples/platform/silabs/SilabsDeviceAttestationCreds.h>
-#else
-#include <credentials/examples/DeviceAttestationCredsExample.h>
-#endif
-
-#define BLE_DEV_NAME "Silabs-Window"
-using namespace ::chip::DeviceLayer;
-using namespace ::chip::Credentials;
-
-#define UNUSED_PARAMETER(a) (a = a)
-
-volatile int apperror_cnt;
-static chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
-
-// ================================================================================
-// Main Code
-// ================================================================================
-int main(void)
-{
-    CHIP_ERROR err = CHIP_NO_ERROR;
-
-    init_ccpPlatform();
-    if (SilabsMatterConfig::InitMatter(BLE_DEV_NAME) != CHIP_NO_ERROR)
-        appError(CHIP_ERROR_INTERNAL);
-
-    gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage());
-    chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
-
-    WindowApp & app = WindowApp::Instance();
-
-    SILABS_LOG("Starting App");
-    chip::DeviceLayer::PlatformMgr().LockChipStack();
-    err = app.Init();
-    // Initialize device attestation config
-#ifdef SILABS_ATTESTATION_CREDENTIALS
-    SetDeviceAttestationCredentialsProvider(SILABS::GetSILABSDacProvider());
-#else
-    SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
-#endif
-    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
-    if (err != CHIP_NO_ERROR)
-    {
-        SILABS_LOG("App Init failed");
-        appError(err);
-    }
-
-    err = app.Start();
-    if (err != CHIP_NO_ERROR)
-    {
-        SILABS_LOG("App Start failed");
-        appError(err);
-    }
-
-    app.Finish();
-    return err.AsInteger();
-}
diff --git a/examples/window-app/silabs/SiWx917/third_party/connectedhomeip b/examples/window-app/silabs/SiWx917/third_party/connectedhomeip
deleted file mode 120000
index 5930783..0000000
--- a/examples/window-app/silabs/SiWx917/third_party/connectedhomeip
+++ /dev/null
@@ -1 +0,0 @@
-../../../../..
\ No newline at end of file
diff --git a/examples/window-app/silabs/args.gni b/examples/window-app/silabs/args.gni
index e79d590..6cf67ac 100644
--- a/examples/window-app/silabs/args.gni
+++ b/examples/window-app/silabs/args.gni
@@ -23,5 +23,3 @@
 chip_enable_openthread = true
 openthread_external_platform =
     "${chip_root}/third_party/openthread/platforms/efr32:libopenthread-efr32"
-
-use_base_app = false
diff --git a/examples/window-app/silabs/build_for_wifi_args.gni b/examples/window-app/silabs/build_for_wifi_args.gni
index 2619458..afe39bf 100644
--- a/examples/window-app/silabs/build_for_wifi_args.gni
+++ b/examples/window-app/silabs/build_for_wifi_args.gni
@@ -19,4 +19,3 @@
 
 chip_enable_ota_requestor = true
 app_data_model = "${chip_root}/examples/window-app/common:window-common"
-use_base_app = false
diff --git a/examples/window-app/silabs/include/AppConfig.h b/examples/window-app/silabs/include/AppConfig.h
index 19c6432..fce020a 100644
--- a/examples/window-app/silabs/include/AppConfig.h
+++ b/examples/window-app/silabs/include/AppConfig.h
@@ -24,6 +24,8 @@
 // ---- Window Example App Config ----
 #define APP_TASK_NAME "APP"
 
+#define BLE_DEV_NAME "SiLabs-Window"
+
 #define LCD_SIZE 128
 #define LCD_MARGIN_SIZE 1
 #define LCD_BORDER_SIZE 2
diff --git a/examples/window-app/silabs/include/AppEvent.h b/examples/window-app/silabs/include/AppEvent.h
new file mode 100644
index 0000000..6ed767d
--- /dev/null
+++ b/examples/window-app/silabs/include/AppEvent.h
@@ -0,0 +1,88 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+struct AppEvent;
+typedef void (*EventHandler)(AppEvent *);
+
+#include <app/clusters/window-covering-server/window-covering-server.h>
+#include <lib/core/CHIPError.h>
+
+using namespace chip::app::Clusters::WindowCovering;
+
+struct AppEvent
+{
+    enum AppEventTypes
+    {
+        kEventType_Button = 0,
+        kEventType_Timer,
+        kEventType_Light,
+        kEventType_Install,
+        kEventType_ButtonDown,
+        kEventType_ButtonUp,
+
+        kEventType_None,
+        kEventType_Reset,
+        kEventType_ResetPressed,
+        kEventType_ResetWarning,
+        kEventType_ResetCanceled,
+        // Button events
+        kEventType_UpPressed,
+        kEventType_UpReleased,
+        kEventType_DownPressed,
+        kEventType_DownReleased,
+        // Cover events
+        kEventType_CoverChange,
+        kEventType_CoverTypeChange,
+        kEventType_TiltModeChange,
+
+        // Cover Attribute update events
+        kEventType_AttributeChange,
+
+        // Provisioning events
+        kEventType_ProvisionedStateChanged,
+        kEventType_ConnectivityStateChanged,
+        kEventType_BLEConnectionsChanged,
+        kEventType_WinkOff,
+        kEventType_WinkOn,
+    };
+
+    uint16_t Type;
+    chip::EndpointId mEndpoint = 0;
+    chip::AttributeId mAttributeId;
+
+    union
+    {
+        struct
+        {
+            uint8_t Action;
+        } ButtonEvent;
+        struct
+        {
+            void * Context;
+        } TimerEvent;
+
+        struct
+        {
+            void * Context;
+        } WindowEvent;
+    };
+
+    EventHandler Handler;
+};
diff --git a/examples/window-app/silabs/include/AppTask.h b/examples/window-app/silabs/include/AppTask.h
new file mode 100644
index 0000000..bd05d30
--- /dev/null
+++ b/examples/window-app/silabs/include/AppTask.h
@@ -0,0 +1,68 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    Copyright (c) 2019 Google LLC.
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+/**********************************************************
+ * Includes
+ *********************************************************/
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "BaseApplication.h"
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+#include <ble/BLEEndPoint.h>
+#include <lib/core/CHIPError.h>
+#include <platform/CHIPDeviceLayer.h>
+
+/**********************************************************
+ * AppTask Declaration
+ *********************************************************/
+
+class AppTask : public BaseApplication
+{
+
+public:
+    AppTask() = default;
+
+    static AppTask & GetAppTask() { return sAppTask; }
+
+    /**
+     * @brief AppTask task main loop function
+     *
+     * @param pvParameter FreeRTOS task parameter
+     */
+    static void AppTaskMain(void * pvParameter);
+
+    CHIP_ERROR StartAppTask();
+
+    static void ButtonEventHandler(uint8_t button, uint8_t btnAction);
+
+private:
+    static AppTask sAppTask;
+
+    /**
+     * @brief AppTask initialisation function
+     *
+     * @return CHIP_ERROR
+     */
+    CHIP_ERROR Init();
+};
diff --git a/examples/window-app/silabs/include/WindowAppImpl.h b/examples/window-app/silabs/include/WindowAppImpl.h
deleted file mode 100644
index 8cc1b14..0000000
--- a/examples/window-app/silabs/include/WindowAppImpl.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- *
- *    Copyright (c) 2021 Project CHIP Authors
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#pragma once
-
-#include <FreeRTOS.h>
-
-#include "LEDWidget.h"
-
-#include <WindowApp.h>
-#include <queue.h>
-#include <setup_payload/QRCodeSetupPayloadGenerator.h>
-#include <string>
-#include <task.h>
-#include <timers.h>
-#ifdef DISPLAY_ENABLED
-#include <LcdPainter.h>
-#endif
-
-class WindowAppImpl : public WindowApp
-{
-public:
-    static WindowAppImpl sInstance;
-
-    WindowAppImpl();
-    CHIP_ERROR Init() override;
-    CHIP_ERROR Start() override;
-    void Finish() override;
-    void PostEvent(const WindowApp::Event & event) override;
-    void PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId) override;
-    static void ButtonEventHandler(uint8_t button, uint8_t btnAction);
-    void OnButtonChange(uint8_t button, uint8_t btnAction);
-
-protected:
-    struct Timer : public WindowApp::Timer
-    {
-        TimerHandle_t mHandler = nullptr;
-
-        Timer(const char * name, uint32_t timeoutInMs, Callback callback, void * context);
-        void IsrStart();
-        void Start() override;
-        void Stop() override;
-
-    private:
-        static void TimerCallback(TimerHandle_t xTimer);
-    };
-
-    struct Button : public WindowApp::Button
-    {
-        Button(Button::Id id, const char * name);
-    };
-
-    WindowApp::Timer * CreateTimer(const char * name, uint32_t timeoutInMs, WindowApp::Timer::Callback callback,
-                                   void * context) override;
-    WindowApp::Button * CreateButton(WindowApp::Button::Id id, const char * name) override;
-    void ProcessEvents();
-    void DispatchEvent(const WindowApp::Event & event) override;
-    void UpdateLEDs();
-    void UpdateLCD();
-    void OnMainLoop() override;
-
-    static void OnTaskCallback(void * parameter);
-    static void OnIconTimeout(WindowApp::Timer & timer);
-
-private:
-    void DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute);
-    TaskHandle_t mHandle = nullptr;
-    QueueHandle_t mQueue = nullptr;
-
-    LEDWidget mStatusLED;
-    LEDWidget mActionLED;
-
-    // Get QR Code and emulate its content using NFC tag
-    char mQRCodeBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1];
-#ifdef DISPLAY_ENABLED
-    Timer mIconTimer;
-    LcdIcon mIcon = LcdIcon::None;
-#endif
-};
diff --git a/examples/window-app/silabs/include/WindowManager.h b/examples/window-app/silabs/include/WindowManager.h
new file mode 100644
index 0000000..0249ddc
--- /dev/null
+++ b/examples/window-app/silabs/include/WindowManager.h
@@ -0,0 +1,168 @@
+/*
+ *
+ *    Copyright (c) 2021 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <app/clusters/window-covering-server/window-covering-server.h>
+#include <lib/core/CHIPError.h>
+
+#include "AppEvent.h"
+
+#include "LEDWidget.h"
+#include <FreeRTOS.h>
+#include <string>
+#include <task.h>
+#include <timers.h>
+#ifdef DISPLAY_ENABLED
+#include <LcdPainter.h>
+#endif
+
+using namespace chip::app::Clusters::WindowCovering;
+
+class WindowManager
+{
+public:
+    static WindowManager sWindow;
+    struct Timer
+    {
+        typedef void (*Callback)(Timer & timer);
+
+        Timer(uint32_t timeoutInMs, Callback callback, void * context);
+
+        void Start();
+        void Stop();
+        void Timeout();
+
+        Callback mCallback = nullptr;
+        void * mContext    = nullptr;
+        bool mIsActive     = false;
+
+        TimerHandle_t mHandler = nullptr;
+
+    private:
+        static void TimerCallback(TimerHandle_t xTimer);
+    };
+
+    struct Cover
+    {
+        void Init(chip::EndpointId endpoint);
+
+        void LiftUpdate(bool newTarget);
+        void LiftGoToTarget() { LiftUpdate(true); }
+        void LiftContinueToTarget() { LiftUpdate(false); }
+        void LiftStepToward(OperationalState direction);
+        void LiftSchedulePositionSet(chip::Percent100ths position) { SchedulePositionSet(position, false); }
+        void LiftScheduleOperationalStateSet(OperationalState opState) { ScheduleOperationalStateSet(opState, false); }
+
+        void TiltUpdate(bool newTarget);
+        void TiltGoToTarget() { TiltUpdate(true); }
+        void TiltContinueToTarget() { TiltUpdate(false); }
+        void TiltStepToward(OperationalState direction);
+        void TiltSchedulePositionSet(chip::Percent100ths position) { SchedulePositionSet(position, true); }
+        void TiltScheduleOperationalStateSet(OperationalState opState) { ScheduleOperationalStateSet(opState, true); }
+
+        void UpdateTargetPosition(OperationalState direction, bool isTilt);
+
+        Type CycleType();
+
+        static void OnLiftTimeout(Timer & timer);
+        static void OnTiltTimeout(Timer & timer);
+
+        chip::EndpointId mEndpoint = 0;
+
+        Timer * mLiftTimer = nullptr;
+        Timer * mTiltTimer = nullptr;
+
+        OperationalState mLiftOpState = OperationalState::Stall;
+        OperationalState mTiltOpState = OperationalState::Stall;
+
+        struct CoverWorkData
+        {
+            chip::EndpointId mEndpointId;
+            bool isTilt;
+
+            union
+            {
+                chip::Percent100ths percent100ths;
+                OperationalState opState;
+            };
+        };
+
+        void SchedulePositionSet(chip::Percent100ths position, bool isTilt);
+        static void CallbackPositionSet(intptr_t arg);
+        void ScheduleOperationalStateSet(OperationalState opState, bool isTilt);
+        static void CallbackOperationalStateSet(intptr_t arg);
+    };
+
+    static WindowManager & Instance();
+
+    WindowManager();
+
+    CHIP_ERROR Init();
+    void PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId);
+
+    static void ButtonEventHandler(uint8_t button, uint8_t btnAction);
+    void UpdateLEDs();
+    void UpdateLCD();
+
+    static void GeneralEventHandler(AppEvent * aEvent);
+
+    static void OnIconTimeout(WindowManager::Timer & timer);
+
+protected:
+    struct StateFlags
+    {
+#if CHIP_ENABLE_OPENTHREAD
+        bool isThreadProvisioned = false;
+        bool isThreadEnabled     = false;
+#else
+        bool isWiFiProvisioned = false;
+        bool isWiFiEnabled     = false;
+#endif
+        bool haveBLEConnections = false;
+        bool isWinking          = false;
+    };
+
+    Cover & GetCover();
+    Cover * GetCover(chip::EndpointId endpoint);
+
+    static void OnLongPressTimeout(Timer & timer);
+
+    Timer * mLongPressTimer = nullptr;
+    StateFlags mState;
+    bool mTiltMode       = false;
+    bool mUpPressed      = false;
+    bool mDownPressed    = false;
+    bool mUpSuppressed   = false;
+    bool mDownSuppressed = false;
+    bool mResetWarning   = false;
+
+private:
+    void HandleLongPress();
+    void DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute);
+
+    Cover mCoverList[WINDOW_COVER_COUNT];
+    uint8_t mCurrentCover = 0;
+
+    LEDWidget mStatusLED;
+    LEDWidget mActionLED;
+
+#ifdef DISPLAY_ENABLED
+    Timer mIconTimer;
+    LcdIcon mIcon = LcdIcon::None;
+#endif
+};
diff --git a/examples/window-app/silabs/openthread.gni b/examples/window-app/silabs/openthread.gni
index 94e0605..ffe5dc7 100644
--- a/examples/window-app/silabs/openthread.gni
+++ b/examples/window-app/silabs/openthread.gni
@@ -22,7 +22,5 @@
 chip_enable_ota_requestor = true
 chip_enable_openthread = true
 
-use_base_app = false
-
 openthread_external_platform =
     "${chip_root}/third_party/openthread/platforms/efr32:libopenthread-efr32"
diff --git a/examples/window-app/silabs/src/AppTask.cpp b/examples/window-app/silabs/src/AppTask.cpp
new file mode 100644
index 0000000..9adf137
--- /dev/null
+++ b/examples/window-app/silabs/src/AppTask.cpp
@@ -0,0 +1,141 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    Copyright (c) 2019 Google LLC.
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "AppTask.h"
+#include "AppConfig.h"
+#include "AppEvent.h"
+
+#include "WindowManager.h"
+
+#include "LEDWidget.h"
+
+#include <app/clusters/on-off-server/on-off-server.h>
+#include <app/server/OnboardingCodesUtil.h>
+#include <app/server/Server.h>
+#include <app/util/attribute-storage.h>
+
+#include <assert.h>
+
+#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
+
+#include <setup_payload/QRCodeSetupPayloadGenerator.h>
+#include <setup_payload/SetupPayload.h>
+
+#include <lib/support/CodeUtils.h>
+
+#if !defined(BRD2704A)
+#define LIGHT_LED 1
+#else
+#define LIGHT_LED 0
+#endif
+
+using namespace chip;
+using namespace ::chip::DeviceLayer;
+using namespace ::chip::DeviceLayer::Silabs;
+
+namespace {
+LEDWidget sLightLED;
+}
+
+using namespace chip::TLV;
+using namespace ::chip::DeviceLayer;
+
+AppTask AppTask::sAppTask;
+
+CHIP_ERROR AppTask::Init()
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    chip::DeviceLayer::Silabs::GetPlatform().SetButtonsCb(WindowManager::ButtonEventHandler);
+
+#ifdef DISPLAY_ENABLED
+    GetLCD().Init((uint8_t *) "Window-App");
+#endif
+
+    err = BaseApplication::Init();
+    if (err != CHIP_NO_ERROR)
+    {
+        SILABS_LOG("BaseApplication::Init() failed");
+        appError(err);
+    }
+
+    err = WindowManager::sWindow.Init();
+
+    if (err != CHIP_NO_ERROR)
+    {
+        SILABS_LOG("WindowMgr::Init() failed");
+        appError(err);
+    }
+
+    sLightLED.Init(LIGHT_LED);
+
+// Update the LCD with the Stored value. Show QR Code if not provisioned
+#ifdef DISPLAY_ENABLED
+
+#ifdef QR_CODE_ENABLED
+#ifdef SL_WIFI
+    if (!ConnectivityMgr().IsWiFiStationProvisioned())
+#else
+    if (!ConnectivityMgr().IsThreadProvisioned())
+#endif /* !SL_WIFI */
+    {
+        GetLCD().ShowQRCode(true, true);
+    }
+#endif // QR_CODE_ENABLED
+#endif
+
+    return err;
+}
+
+CHIP_ERROR AppTask::StartAppTask()
+{
+    return BaseApplication::StartAppTask(AppTaskMain);
+}
+
+void AppTask::AppTaskMain(void * pvParameter)
+{
+
+    AppEvent event;
+    QueueHandle_t sAppEventQueue = *(static_cast<QueueHandle_t *>(pvParameter));
+
+    CHIP_ERROR err = sAppTask.Init();
+    if (err != CHIP_NO_ERROR)
+    {
+        SILABS_LOG("AppTask.Init() failed");
+        appError(err);
+    }
+
+#if !(defined(CHIP_DEVICE_CONFIG_ENABLE_SED) && CHIP_DEVICE_CONFIG_ENABLE_SED)
+    sAppTask.StartStatusLEDTimer();
+#endif
+
+    SILABS_LOG("App Task started");
+
+    WindowManager::sWindow.UpdateLEDs();
+    WindowManager::sWindow.UpdateLCD();
+
+    while (true)
+    {
+        BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY);
+        while (eventReceived == pdTRUE)
+        {
+            sAppTask.DispatchEvent(&event);
+            eventReceived = xQueueReceive(sAppEventQueue, &event, 0);
+        }
+    }
+}
diff --git a/examples/window-app/silabs/src/WindowAppImpl.cpp b/examples/window-app/silabs/src/WindowAppImpl.cpp
deleted file mode 100644
index c4e4821..0000000
--- a/examples/window-app/silabs/src/WindowAppImpl.cpp
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- *
- *    Copyright (c) 2021 Project CHIP Authors
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <AppConfig.h>
-#include <WindowAppImpl.h>
-#include <app-common/zap-generated/attributes/Accessors.h>
-#include <app/clusters/window-covering-server/window-covering-server.h>
-#include <app/server/OnboardingCodesUtil.h>
-#include <lib/core/CHIPError.h>
-#include <lib/dnssd/Advertiser.h>
-#include <lib/support/CodeUtils.h>
-#include <platform/CHIPDeviceLayer.h>
-#ifdef QR_CODE_ENABLED
-#include <qrcodegen.h>
-#else
-#include "SilabsDeviceDataProvider.h"
-#include <setup_payload/QRCodeSetupPayloadGenerator.h>
-#include <setup_payload/SetupPayload.h>
-#endif // QR_CODE_ENABLED
-
-#include <sl_system_kernel.h>
-
-#ifdef SL_WIFI
-#include "wfx_host_events.h"
-#include <app/clusters/network-commissioning/network-commissioning.h>
-#include <platform/silabs/NetworkCommissioningWiFiDriver.h>
-#endif
-
-#ifdef DISPLAY_ENABLED
-#include <LcdPainter.h>
-SilabsLCD slLCD;
-#endif
-
-#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
-
-#define APP_TASK_STACK_SIZE (4096)
-#define APP_TASK_PRIORITY 2
-#define APP_EVENT_QUEUE_SIZE 10
-#define EXAMPLE_VENDOR_ID 0xcafe
-
-#define LCD_ICON_TIMEOUT 1000
-
-using namespace chip::app::Clusters::WindowCovering;
-using namespace chip;
-using namespace ::chip::DeviceLayer;
-using namespace ::chip::DeviceLayer::Silabs;
-#define APP_STATE_LED 0
-#define APP_ACTION_LED 1
-
-#ifdef SL_WIFI
-chip::app::Clusters::NetworkCommissioning::Instance
-    sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(chip::DeviceLayer::NetworkCommissioning::SlWiFiDriver::GetInstance()));
-#endif
-//------------------------------------------------------------------------------
-// Timers
-//------------------------------------------------------------------------------
-
-WindowAppImpl::Timer::Timer(const char * name, uint32_t timeoutInMs, Callback callback, void * context) :
-    WindowApp::Timer(name, timeoutInMs, callback, context)
-{
-    mHandler = xTimerCreate(name,                       // Just a text name, not used by the RTOS kernel
-                            pdMS_TO_TICKS(timeoutInMs), // == default timer period (mS)
-                            false,                      // no timer reload (==one-shot)
-                            (void *) this,              // init timer id = app task obj context
-                            TimerCallback               // timer callback handler
-    );
-    if (mHandler == NULL)
-    {
-        SILABS_LOG("Timer create failed");
-        appError(CHIP_ERROR_INTERNAL);
-    }
-}
-
-void WindowAppImpl::Timer::Start()
-{
-    if (xTimerIsTimerActive(mHandler))
-    {
-        Stop();
-    }
-
-    // Timer is not active
-    if (xTimerStart(mHandler, pdMS_TO_TICKS(100)) != pdPASS)
-    {
-        SILABS_LOG("Timer start() failed");
-        appError(CHIP_ERROR_INTERNAL);
-    }
-
-    mIsActive = true;
-}
-
-void WindowAppImpl::Timer::IsrStart()
-{
-    portBASE_TYPE taskWoken = pdFALSE; // For FreeRTOS timer (below).
-    // Start/restart the button debounce timer (Note ISR version of FreeRTOS
-    // api call here).
-    xTimerStartFromISR(mHandler, &taskWoken);
-    if (taskWoken != pdFALSE)
-    {
-        taskYIELD();
-    }
-    mIsActive = true;
-}
-
-void WindowAppImpl::Timer::Stop()
-{
-    mIsActive = false;
-    if (xTimerStop(mHandler, pdMS_TO_TICKS(0)) == pdFAIL)
-    {
-        SILABS_LOG("Timer stop() failed");
-        appError(CHIP_ERROR_INTERNAL);
-    }
-}
-
-void WindowAppImpl::Timer::TimerCallback(TimerHandle_t xTimer)
-{
-    Timer * timer = (Timer *) pvTimerGetTimerID(xTimer);
-    if (timer)
-    {
-        timer->Timeout();
-    }
-}
-
-//------------------------------------------------------------------------------
-// Main Task
-//------------------------------------------------------------------------------
-
-StackType_t sAppStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)];
-StaticTask_t sAppTaskStruct;
-
-uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(WindowApp::Event)];
-StaticQueue_t sAppEventQueueStruct;
-
-WindowAppImpl WindowAppImpl::sInstance;
-
-WindowApp & WindowApp::Instance()
-{
-    return WindowAppImpl::sInstance;
-}
-
-#ifdef DISPLAY_ENABLED
-WindowAppImpl::WindowAppImpl() : mIconTimer("Timer:icon", LCD_ICON_TIMEOUT, OnIconTimeout, this) {}
-#else
-WindowAppImpl::WindowAppImpl() {}
-#endif
-
-void WindowAppImpl::OnTaskCallback(void * parameter)
-{
-#ifdef SL_WIFI
-    /*
-     * Wait for the WiFi to be initialized
-     */
-    SILABS_LOG("APP: Wait WiFi Init");
-    while (!wfx_hw_ready())
-    {
-        vTaskDelay(10);
-    }
-    SILABS_LOG("APP: Done WiFi Init");
-    /* We will init server when we get IP */
-    chip::DeviceLayer::PlatformMgr().LockChipStack();
-    sWiFiNetworkCommissioningInstance.Init();
-    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-    /* added for commisioning with wifi */
-#endif
-
-    sInstance.Run();
-}
-
-void WindowAppImpl::OnIconTimeout(WindowApp::Timer & timer)
-{
-#ifdef DISPLAY_ENABLED
-    sInstance.mIcon = LcdIcon::None;
-    sInstance.UpdateLCD();
-#endif
-}
-
-CHIP_ERROR WindowAppImpl::Init()
-{
-    chip::DeviceLayer::Silabs::GetPlatform().SetButtonsCb(WindowAppImpl::ButtonEventHandler);
-
-    WindowApp::Init();
-
-    // Initialize App Task
-    mHandle = xTaskCreateStatic(OnTaskCallback, APP_TASK_NAME, ArraySize(sAppStack), NULL, 1, sAppStack, &sAppTaskStruct);
-    if (NULL == mHandle)
-    {
-        SILABS_LOG("Failed to allocate app task");
-        return CHIP_ERROR_NO_MEMORY;
-    }
-
-    // Initialize App Queue
-    mQueue = xQueueCreateStatic(APP_EVENT_QUEUE_SIZE, sizeof(WindowApp::Event), sAppEventQueueBuffer, &sAppEventQueueStruct);
-    if (NULL == mQueue)
-    {
-        SILABS_LOG("Failed to allocate app event queue");
-        return CHIP_ERROR_NO_MEMORY;
-    }
-
-    // Initialize LEDs
-    LEDWidget::InitGpio();
-    mStatusLED.Init(APP_STATE_LED);
-    mActionLED.Init(APP_ACTION_LED);
-
-#ifdef DISPLAY_ENABLED
-    slLCD.Init();
-#endif
-
-#ifndef QR_CODE_ENABLED
-    // Create buffer for QR code that can fit max size and null terminator.
-    char qrCodeBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1];
-    chip::MutableCharSpan QRCode(qrCodeBuffer);
-
-    if (Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider().GetSetupPayload(QRCode) == CHIP_NO_ERROR)
-    {
-        PrintQrCodeURL(QRCode);
-    }
-    else
-    {
-        SILABS_LOG("Getting QR code failed!");
-    }
-#endif // QR_CODE_ENABLED
-
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR WindowAppImpl::Start()
-{
-    SILABS_LOG("Starting FreeRTOS scheduler");
-    sl_system_kernel_start();
-
-    return CHIP_NO_ERROR;
-}
-
-void WindowAppImpl::Finish()
-{
-    WindowApp::Finish();
-    chip::Platform::MemoryShutdown();
-    // Should never get here.
-    SILABS_LOG("vTaskStartScheduler() failed");
-    appError(CHIP_ERROR_INTERNAL);
-}
-
-void WindowAppImpl::PostEvent(const WindowApp::Event & event)
-{
-    if (mQueue)
-    {
-        BaseType_t status;
-        if (xPortIsInsideInterrupt())
-        {
-            BaseType_t higherPrioTaskWoken = pdFALSE;
-            status                         = xQueueSendFromISR(mQueue, &event, &higherPrioTaskWoken);
-
-#ifdef portYIELD_FROM_ISR
-            portYIELD_FROM_ISR(higherPrioTaskWoken);
-#elif portEND_SWITCHING_ISR // portYIELD_FROM_ISR or portEND_SWITCHING_ISR
-            portEND_SWITCHING_ISR(higherPrioTaskWoken);
-#else                       // portYIELD_FROM_ISR or portEND_SWITCHING_ISR
-#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR"
-#endif // portYIELD_FROM_ISR or portEND_SWITCHING_ISR
-        }
-        else
-        {
-            status = xQueueSend(mQueue, &event, 1);
-        }
-
-        if (!status)
-        {
-            SILABS_LOG("Failed to post event to app task event queue");
-        }
-    }
-}
-
-void WindowAppImpl::PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId)
-{
-    Instance().PostEvent(WindowApp::Event(WindowApp::EventId::AttributeChange, endpoint, attributeId));
-}
-
-void WindowAppImpl::ProcessEvents()
-{
-    WindowApp::Event event = EventId::None;
-
-    BaseType_t received = xQueueReceive(mQueue, &event, pdMS_TO_TICKS(10));
-    while (pdTRUE == received)
-    {
-        DispatchEvent(event);
-        received = xQueueReceive(mQueue, &event, 0);
-    }
-}
-
-WindowApp::Timer * WindowAppImpl::CreateTimer(const char * name, uint32_t timeoutInMs, WindowApp::Timer::Callback callback,
-                                              void * context)
-{
-    return new Timer(name, timeoutInMs, callback, context);
-}
-
-WindowApp::Button * WindowAppImpl::CreateButton(WindowApp::Button::Id id, const char * name)
-{
-    return new Button(id, name);
-}
-
-void WindowAppImpl::DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute)
-{
-    switch (attribute)
-    {
-    /* RO OperationalStatus */
-    case Attributes::OperationalStatus::Id:
-        UpdateLEDs();
-        break;
-    /* RO Type: not supposed to dynamically change -> Cycling Window Covering Demo */
-    case Attributes::Type::Id:
-    /* ============= Positions for Position Aware ============= */
-    case Attributes::CurrentPositionLiftPercent100ths::Id:
-    case Attributes::CurrentPositionTiltPercent100ths::Id:
-        UpdateLCD();
-        break;
-    /* ### ATTRIBUTEs CHANGEs IGNORED ### */
-    /* RO EndProductType: not supposed to dynamically change */
-    case Attributes::EndProductType::Id:
-    /* RO ConfigStatus: set by WC server */
-    case Attributes::ConfigStatus::Id:
-    /* RO SafetyStatus: set by WC server */
-    case Attributes::SafetyStatus::Id:
-    /* RW Mode: User can change */
-    case Attributes::Mode::Id:
-    default:
-        break;
-    }
-}
-
-void WindowAppImpl::DispatchEvent(const WindowApp::Event & event)
-{
-    WindowApp::DispatchEvent(event);
-    switch (event.mId)
-    {
-    case EventId::AttributeChange:
-        DispatchEventAttributeChange(event.mEndpoint, event.mAttributeId);
-        break;
-    case EventId::ResetWarning:
-        SILABS_LOG("Factory Reset Triggered. Release button within %ums to cancel.", LONG_PRESS_TIMEOUT);
-        // Turn off all LEDs before starting blink to make sure blink is
-        // co-ordinated.
-        UpdateLEDs();
-        break;
-    case EventId::ResetCanceled:
-        SILABS_LOG("Factory Reset has been Canceled");
-        UpdateLEDs();
-        break;
-    case EventId::ProvisionedStateChanged:
-        UpdateLEDs();
-        UpdateLCD();
-        break;
-
-    case EventId::WinkOn:
-    case EventId::WinkOff:
-        mState.isWinking = (EventId::WinkOn == event.mId);
-        UpdateLEDs();
-        break;
-    case EventId::ConnectivityStateChanged:
-    case EventId::BLEConnectionsChanged:
-        UpdateLEDs();
-        break;
-#ifdef DISPLAY_ENABLED
-    case EventId::CoverTypeChange:
-        UpdateLCD();
-        break;
-    case EventId::CoverChange:
-        mIconTimer.Start();
-        mIcon = (GetCover().mEndpoint == 1) ? LcdIcon::One : LcdIcon::Two;
-        UpdateLCD();
-        break;
-    case EventId::TiltModeChange:
-        mIconTimer.Start();
-        mIcon = mTiltMode ? LcdIcon::Tilt : LcdIcon::Lift;
-        UpdateLCD();
-        break;
-#endif
-    default:
-        break;
-    }
-}
-
-void WindowAppImpl::UpdateLEDs()
-{
-    Cover & cover = GetCover();
-    if (mResetWarning)
-    {
-        mStatusLED.Set(false);
-        mStatusLED.Blink(500);
-
-        mActionLED.Set(false);
-        mActionLED.Blink(500);
-    }
-    else
-    {
-        if (mState.isWinking)
-        {
-            mStatusLED.Blink(200, 200);
-        }
-        else
-#if CHIP_ENABLE_OPENTHREAD
-            if (mState.isThreadProvisioned && mState.isThreadEnabled)
-#else
-            if (mState.isWiFiProvisioned && mState.isWiFiEnabled)
-#endif
-
-        {
-
-            mStatusLED.Blink(950, 50);
-        }
-        else if (mState.haveBLEConnections) { mStatusLED.Blink(100, 100); }
-        else { mStatusLED.Blink(50, 950); }
-
-        // Action LED
-        NPercent100ths current;
-        LimitStatus liftLimit = LimitStatus::Intermediate;
-
-        chip::DeviceLayer::PlatformMgr().LockChipStack();
-        Attributes::CurrentPositionLiftPercent100ths::Get(cover.mEndpoint, current);
-        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
-        if (!current.IsNull())
-        {
-            AbsoluteLimits limits = { .open = WC_PERCENT100THS_MIN_OPEN, .closed = WC_PERCENT100THS_MAX_CLOSED };
-            liftLimit             = CheckLimitState(current.Value(), limits);
-        }
-
-        if (OperationalState::Stall != cover.mLiftOpState)
-        {
-
-            mActionLED.Blink(100);
-        }
-        else if (LimitStatus::IsUpOrOpen == liftLimit)
-        {
-
-            mActionLED.Set(true);
-        }
-        else if (LimitStatus::IsDownOrClose == liftLimit)
-        {
-
-            mActionLED.Set(false);
-        }
-        else
-        {
-
-            mActionLED.Blink(1000);
-        }
-    }
-}
-
-void WindowAppImpl::UpdateLCD()
-{
-    // Update LCD
-#ifdef DISPLAY_ENABLED
-#if CHIP_ENABLE_OPENTHREAD
-    if (mState.isThreadProvisioned)
-#else
-    if (mState.isWiFiProvisioned)
-#endif // CHIP_ENABLE_OPENTHREAD
-    {
-        Cover & cover = GetCover();
-        chip::app::DataModel::Nullable<uint16_t> lift;
-        chip::app::DataModel::Nullable<uint16_t> tilt;
-
-        chip::DeviceLayer::PlatformMgr().LockChipStack();
-        Type type = TypeGet(cover.mEndpoint);
-
-        Attributes::CurrentPositionLift::Get(cover.mEndpoint, lift);
-        Attributes::CurrentPositionTilt::Get(cover.mEndpoint, tilt);
-        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
-#ifdef DISPLAY_ENABLED
-        if (!tilt.IsNull() && !lift.IsNull())
-        {
-            LcdPainter::Paint(slLCD, type, lift.Value(), tilt.Value(), mIcon);
-        }
-#endif
-    }
-#ifdef QR_CODE_ENABLED
-    else
-    {
-        chip::MutableCharSpan qrCode(mQRCodeBuffer);
-        if (GetQRCode(qrCode, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)) == CHIP_NO_ERROR)
-        {
-            slLCD.SetQRCode((uint8_t *) qrCode.data(), qrCode.size());
-            slLCD.ShowQRCode(true, true);
-        }
-    }
-#endif // QR_CODE_ENABLED
-#endif // DISPLAY_ENABLED
-}
-
-void WindowAppImpl::OnMainLoop()
-{
-
-    mStatusLED.Animate();
-    mActionLED.Animate();
-}
-
-//------------------------------------------------------------------------------
-// Buttons
-//------------------------------------------------------------------------------
-WindowAppImpl::Button::Button(WindowApp::Button::Id id, const char * name) : WindowApp::Button(id, name) {}
-
-void WindowAppImpl::OnButtonChange(uint8_t button, uint8_t btnAction)
-{
-    WindowApp::Button * btn = static_cast<Button *>((button == 0) ? sInstance.mButtonUp : sInstance.mButtonDown);
-
-    if (btnAction == static_cast<uint8_t>(SilabsPlatform::ButtonAction::ButtonPressed))
-    {
-        btn->Press();
-    }
-    else
-    {
-        btn->Release();
-    }
-}
-
-// Silabs button callback from button event ISR
-void WindowAppImpl::ButtonEventHandler(uint8_t button, uint8_t btnAction)
-{
-    WindowAppImpl * app = static_cast<WindowAppImpl *>(&WindowAppImpl::sInstance);
-    app->OnButtonChange(button, btnAction);
-}
diff --git a/examples/window-app/silabs/src/WindowManager.cpp b/examples/window-app/silabs/src/WindowManager.cpp
new file mode 100644
index 0000000..c6687ab
--- /dev/null
+++ b/examples/window-app/silabs/src/WindowManager.cpp
@@ -0,0 +1,884 @@
+/*
+ *
+ *    Copyright (c) 2021 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "AppEvent.h"
+#include "AppTask.h"
+#include <AppConfig.h>
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <app/server/Server.h>
+#include <app/util/af.h>
+
+#include <lib/support/CodeUtils.h>
+#include <platform/CHIPDeviceLayer.h>
+
+#include <WindowManager.h>
+
+#include <app/clusters/window-covering-server/window-covering-server.h>
+#include <app/server/OnboardingCodesUtil.h>
+#include <lib/core/CHIPError.h>
+#include <lib/dnssd/Advertiser.h>
+#include <lib/support/CodeUtils.h>
+#include <platform/CHIPDeviceLayer.h>
+
+#ifdef SL_WIFI
+#include "wfx_host_events.h"
+#include <app/clusters/network-commissioning/network-commissioning.h>
+#include <platform/silabs/NetworkCommissioningWiFiDriver.h>
+#endif
+
+#ifdef DISPLAY_ENABLED
+#include <LcdPainter.h>
+SilabsLCD slLCD;
+#endif
+
+#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
+
+#define LCD_ICON_TIMEOUT 1000
+
+using namespace chip::app::Clusters::WindowCovering;
+using namespace chip;
+using namespace ::chip::DeviceLayer;
+using namespace ::chip::DeviceLayer::Silabs;
+#define APP_STATE_LED 0
+#define APP_ACTION_LED 1
+
+using namespace ::chip::Credentials;
+using namespace ::chip::DeviceLayer;
+using namespace chip::app::Clusters::WindowCovering;
+
+WindowManager WindowManager::sWindow;
+
+AppEvent CreateNewEvent(AppEvent::AppEventTypes type)
+{
+    AppEvent aEvent;
+    aEvent.Type                = type;
+    aEvent.Handler             = WindowManager::GeneralEventHandler;
+    WindowManager * window     = static_cast<WindowManager *>(&WindowManager::sWindow);
+    aEvent.WindowEvent.Context = window;
+    return aEvent;
+}
+
+inline void OnTriggerEffectCompleted(chip::System::Layer * systemLayer, void * appState)
+{
+    AppEvent event = CreateNewEvent(AppEvent::kEventType_WinkOff);
+    AppTask::GetAppTask().PostEvent(&event);
+}
+
+void WindowManager::Timer::Start()
+{
+    if (xTimerIsTimerActive(mHandler))
+    {
+        Stop();
+    }
+
+    // Timer is not active
+    if (xTimerStart(mHandler, pdMS_TO_TICKS(100)) != pdPASS)
+    {
+        SILABS_LOG("Timer start() failed");
+        appError(CHIP_ERROR_INTERNAL);
+    }
+
+    mIsActive = true;
+}
+
+void WindowManager::Timer::Timeout()
+{
+    mIsActive = false;
+    if (mCallback)
+    {
+        mCallback(*this);
+    }
+}
+
+WindowManager::Cover & WindowManager::GetCover()
+{
+    return mCoverList[mCurrentCover];
+}
+
+WindowManager::Cover * WindowManager::GetCover(chip::EndpointId endpoint)
+{
+    for (uint16_t i = 0; i < WINDOW_COVER_COUNT; ++i)
+    {
+        if (mCoverList[i].mEndpoint == endpoint)
+        {
+            return &mCoverList[i];
+        }
+    }
+    return nullptr;
+}
+
+void WindowManager::DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute)
+{
+    Cover * cover = GetCover(endpoint);
+    chip::BitMask<Mode> mode;
+    chip::BitMask<ConfigStatus> configStatus;
+    chip::BitMask<OperationalStatus> opStatus;
+
+    if (nullptr == cover)
+    {
+        ChipLogProgress(Zcl, "Ep[%u] not supported AttributeId=%u\n", endpoint, (unsigned int) attribute);
+        return;
+    }
+
+    switch (attribute)
+    {
+    /* For a device supporting Position Awareness : Changing the Target triggers motions on the real or simulated device */
+    case Attributes::TargetPositionLiftPercent100ths::Id:
+        cover->LiftGoToTarget();
+        break;
+    /* For a device supporting Position Awareness : Changing the Target triggers motions on the real or simulated device */
+    case Attributes::TargetPositionTiltPercent100ths::Id:
+        cover->TiltGoToTarget();
+        break;
+    /* RO OperationalStatus */
+    case Attributes::OperationalStatus::Id:
+        chip::DeviceLayer::PlatformMgr().LockChipStack();
+        opStatus = OperationalStatusGet(endpoint);
+        OperationalStatusPrint(opStatus);
+        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+        UpdateLEDs();
+        break;
+    /* RW Mode */
+    case Attributes::Mode::Id:
+        chip::DeviceLayer::PlatformMgr().LockChipStack();
+        mode = ModeGet(endpoint);
+        ModePrint(mode);
+        ModeSet(endpoint, mode); // refilter mode if needed
+        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+        break;
+    /* RO ConfigStatus: set by WC server */
+    case Attributes::ConfigStatus::Id:
+        chip::DeviceLayer::PlatformMgr().LockChipStack();
+        configStatus = ConfigStatusGet(endpoint);
+        ConfigStatusPrint(configStatus);
+        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+        break;
+    /* ### ATTRIBUTEs CHANGEs IGNORED ### */
+    /* RO Type: not supposed to dynamically change */
+    case Attributes::Type::Id:
+    /* RO EndProductType: not supposed to dynamically change */
+    case Attributes::EndProductType::Id:
+    /* RO SafetyStatus: set by WC server */
+    case Attributes::SafetyStatus::Id:
+    /* ============= Positions for Position Aware ============= */
+    case Attributes::CurrentPositionLiftPercent100ths::Id:
+    case Attributes::CurrentPositionTiltPercent100ths::Id:
+        UpdateLCD();
+        break;
+    default:
+        break;
+    }
+}
+
+void WindowManager::HandleLongPress()
+{
+
+    AppEvent event;
+    event.Handler             = GeneralEventHandler;
+    WindowManager * window    = static_cast<WindowManager *>(&WindowManager::sWindow);
+    event.WindowEvent.Context = window;
+
+    if (mUpPressed && mDownPressed)
+    {
+        // Long press both buttons: Cycle between window coverings
+        mUpSuppressed = mDownSuppressed = true;
+        mCurrentCover                   = mCurrentCover < WINDOW_COVER_COUNT - 1 ? mCurrentCover + 1 : 0;
+        event.Type                      = AppEvent::kEventType_CoverChange;
+        AppTask::GetAppTask().PostEvent(&event);
+    }
+    else if (mUpPressed)
+    {
+        mUpSuppressed = true;
+        if (mResetWarning)
+        {
+            // Double long press button up: Reset now, you were warned!
+            event.Type = AppEvent::kEventType_Reset;
+            AppTask::GetAppTask().PostEvent(&event);
+        }
+        else
+        {
+            // Long press button up: Reset warning!
+            event.Type = AppEvent::kEventType_ResetWarning;
+            AppTask::GetAppTask().PostEvent(&event);
+        }
+    }
+    else if (mDownPressed)
+    {
+        // Long press button down: Cycle between covering types
+        mDownSuppressed = true;
+        Type type       = GetCover().CycleType();
+        mTiltMode       = mTiltMode && (Type::kTiltBlindLiftAndTilt == type);
+    }
+}
+
+void WindowManager::OnLongPressTimeout(WindowManager::Timer & timer)
+{
+    WindowManager * app = static_cast<WindowManager *>(timer.mContext);
+    if (app)
+    {
+        app->HandleLongPress();
+    }
+}
+
+void WindowManager::Cover::Init(chip::EndpointId endpoint)
+{
+    mEndpoint  = endpoint;
+    mLiftTimer = new Timer(COVER_LIFT_TILT_TIMEOUT, OnLiftTimeout, this);
+    mTiltTimer = new Timer(COVER_LIFT_TILT_TIMEOUT, OnTiltTimeout, this);
+
+    // Preset Lift attributes
+    Attributes::InstalledOpenLimitLift::Set(endpoint, LIFT_OPEN_LIMIT);
+    Attributes::InstalledClosedLimitLift::Set(endpoint, LIFT_CLOSED_LIMIT);
+
+    // Preset Tilt attributes
+    Attributes::InstalledOpenLimitTilt::Set(endpoint, TILT_OPEN_LIMIT);
+    Attributes::InstalledClosedLimitTilt::Set(endpoint, TILT_CLOSED_LIMIT);
+
+    // Note: All Current Positions are preset via Zap config and kept across reboot via NVM: no need to init them
+
+    // Attribute: Id  0 Type
+    TypeSet(endpoint, Type::kTiltBlindLiftAndTilt);
+
+    // Attribute: Id  7 ConfigStatus
+    chip::BitMask<ConfigStatus> configStatus = ConfigStatusGet(endpoint);
+    configStatus.Set(ConfigStatus::kLiftEncoderControlled);
+    configStatus.Set(ConfigStatus::kTiltEncoderControlled);
+    ConfigStatusSet(endpoint, configStatus);
+
+    chip::app::Clusters::WindowCovering::ConfigStatusUpdateFeatures(endpoint);
+
+    // Attribute: Id 13 EndProductType
+    EndProductTypeSet(endpoint, EndProductType::kInteriorBlind);
+
+    // Attribute: Id 24 Mode
+    chip::BitMask<Mode> mode;
+    mode.Clear(Mode::kMotorDirectionReversed);
+    mode.Clear(Mode::kMaintenanceMode);
+    mode.Clear(Mode::kCalibrationMode);
+    mode.Set(Mode::kLedFeedback);
+
+    /* Mode also update ConfigStatus accordingly */
+    ModeSet(endpoint, mode);
+
+    // Attribute: Id 27 SafetyStatus (Optional)
+    chip::BitFlags<SafetyStatus> safetyStatus(0x00); // 0 is no issues;
+}
+
+void WindowManager::Cover::LiftStepToward(OperationalState direction)
+{
+    EmberAfStatus status;
+    chip::Percent100ths percent100ths;
+    NPercent100ths current;
+
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+    status = Attributes::CurrentPositionLiftPercent100ths::Get(mEndpoint, current);
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    if ((status == EMBER_ZCL_STATUS_SUCCESS) && !current.IsNull())
+    {
+        percent100ths = ComputePercent100thsStep(direction, current.Value(), LIFT_DELTA);
+    }
+    else
+    {
+        percent100ths = WC_PERCENT100THS_MIDDLE; // set at middle by default
+    }
+
+    LiftSchedulePositionSet(percent100ths);
+}
+
+void WindowManager::Cover::LiftUpdate(bool newTarget)
+{
+    NPercent100ths current, target;
+
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+
+    Attributes::TargetPositionLiftPercent100ths::Get(mEndpoint, target);
+    Attributes::CurrentPositionLiftPercent100ths::Get(mEndpoint, current);
+
+    OperationalState opState = ComputeOperationalState(target, current);
+
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    /* If Triggered by a TARGET update */
+    if (newTarget)
+    {
+        mLiftTimer->Stop(); // Cancel previous motion if any
+        mLiftOpState = opState;
+    }
+
+    if (mLiftOpState == opState)
+    {
+        /* Actuator still need to move, not reached/crossed Target yet */
+        LiftStepToward(mLiftOpState);
+    }
+    else /* CURRENT reached TARGET or crossed it */
+    {
+        /* Actuator finalize the movement AND CURRENT Must be equal to TARGET at the end */
+        if (!target.IsNull())
+            LiftSchedulePositionSet(target.Value());
+
+        mLiftOpState = OperationalState::Stall;
+    }
+
+    LiftScheduleOperationalStateSet(mLiftOpState);
+
+    if ((OperationalState::Stall != mLiftOpState) && mLiftTimer)
+    {
+        mLiftTimer->Start();
+    }
+}
+
+void WindowManager::Cover::TiltStepToward(OperationalState direction)
+{
+    EmberAfStatus status;
+    chip::Percent100ths percent100ths;
+    NPercent100ths current;
+
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+    status = Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, current);
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    if ((status == EMBER_ZCL_STATUS_SUCCESS) && !current.IsNull())
+    {
+        percent100ths = ComputePercent100thsStep(direction, current.Value(), TILT_DELTA);
+    }
+    else
+    {
+        percent100ths = WC_PERCENT100THS_MIDDLE; // set at middle by default
+    }
+
+    TiltSchedulePositionSet(percent100ths);
+}
+
+void WindowManager::Cover::TiltUpdate(bool newTarget)
+{
+    NPercent100ths current, target;
+
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+
+    Attributes::TargetPositionTiltPercent100ths::Get(mEndpoint, target);
+    Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, current);
+
+    OperationalState opState = ComputeOperationalState(target, current);
+
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    /* If Triggered by a TARGET update */
+    if (newTarget)
+    {
+        mTiltTimer->Stop(); // Cancel previous motion if any
+        mTiltOpState = opState;
+    }
+
+    if (mTiltOpState == opState)
+    {
+        /* Actuator still need to move, not reached/crossed Target yet */
+        TiltStepToward(mTiltOpState);
+    }
+    else /* CURRENT reached TARGET or crossed it */
+    {
+        /* Actuator finalize the movement AND CURRENT Must be equal to TARGET at the end */
+        if (!target.IsNull())
+            TiltSchedulePositionSet(target.Value());
+
+        mTiltOpState = OperationalState::Stall;
+    }
+
+    TiltScheduleOperationalStateSet(mTiltOpState);
+
+    if ((OperationalState::Stall != mTiltOpState) && mTiltTimer)
+    {
+        mTiltTimer->Start();
+    }
+}
+
+void WindowManager::Cover::UpdateTargetPosition(OperationalState direction, bool isTilt)
+{
+    EmberAfStatus status;
+    NPercent100ths current;
+    chip::Percent100ths target;
+
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+
+    if (isTilt)
+    {
+        status = Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, current);
+        if ((status == EMBER_ZCL_STATUS_SUCCESS) && !current.IsNull())
+        {
+            target = ComputePercent100thsStep(direction, current.Value(), TILT_DELTA);
+            (void) Attributes::TargetPositionTiltPercent100ths::Set(mEndpoint, target);
+        }
+    }
+    else
+    {
+        status = Attributes::CurrentPositionLiftPercent100ths::Get(mEndpoint, current);
+        if ((status == EMBER_ZCL_STATUS_SUCCESS) && !current.IsNull())
+        {
+            target = ComputePercent100thsStep(direction, current.Value(), LIFT_DELTA);
+            (void) Attributes::TargetPositionLiftPercent100ths::Set(mEndpoint, target);
+        }
+    }
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+}
+
+Type WindowManager::Cover::CycleType()
+{
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+    Type type = TypeGet(mEndpoint);
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    switch (type)
+    {
+    case Type::kRollerShade:
+        type = Type::kDrapery;
+        // tilt = false;
+        break;
+    case Type::kDrapery:
+        type = Type::kTiltBlindLiftAndTilt;
+        break;
+    case Type::kTiltBlindLiftAndTilt:
+        type = Type::kRollerShade;
+        // tilt = false;
+        break;
+    default:
+        type = Type::kTiltBlindLiftAndTilt;
+    }
+
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+    TypeSet(mEndpoint, type);
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    return type;
+}
+
+void WindowManager::Cover::OnLiftTimeout(WindowManager::Timer & timer)
+{
+    WindowManager::Cover * cover = static_cast<WindowManager::Cover *>(timer.mContext);
+    if (cover)
+    {
+        cover->LiftContinueToTarget();
+    }
+}
+
+void WindowManager::Cover::OnTiltTimeout(WindowManager::Timer & timer)
+{
+    WindowManager::Cover * cover = static_cast<WindowManager::Cover *>(timer.mContext);
+    if (cover)
+    {
+        cover->TiltContinueToTarget();
+    }
+}
+
+void WindowManager::Cover::SchedulePositionSet(chip::Percent100ths position, bool isTilt)
+{
+    CoverWorkData * data = chip::Platform::New<CoverWorkData>();
+    VerifyOrReturn(data != nullptr, ChipLogProgress(Zcl, "Cover::SchedulePositionSet - Out of Memory for WorkData"));
+
+    data->mEndpointId   = mEndpoint;
+    data->percent100ths = position;
+    data->isTilt        = isTilt;
+
+    chip::DeviceLayer::PlatformMgr().ScheduleWork(CallbackPositionSet, reinterpret_cast<intptr_t>(data));
+}
+
+void WindowManager::Cover::CallbackPositionSet(intptr_t arg)
+{
+    NPercent100ths position;
+    WindowManager::Cover::CoverWorkData * data = reinterpret_cast<WindowManager::Cover::CoverWorkData *>(arg);
+    position.SetNonNull(data->percent100ths);
+
+    if (data->isTilt)
+        TiltPositionSet(data->mEndpointId, position);
+    else
+        LiftPositionSet(data->mEndpointId, position);
+
+    chip::Platform::Delete(data);
+}
+
+void WindowManager::Cover::ScheduleOperationalStateSet(OperationalState opState, bool isTilt)
+{
+    CoverWorkData * data = chip::Platform::New<CoverWorkData>();
+    VerifyOrReturn(data != nullptr, ChipLogProgress(Zcl, "Cover::OperationalStatusSet - Out of Memory for WorkData"));
+
+    data->mEndpointId = mEndpoint;
+    data->opState     = opState;
+    data->isTilt      = isTilt;
+
+    chip::DeviceLayer::PlatformMgr().ScheduleWork(CallbackOperationalStateSet, reinterpret_cast<intptr_t>(data));
+}
+
+void WindowManager::Cover::CallbackOperationalStateSet(intptr_t arg)
+{
+    WindowManager::Cover::CoverWorkData * data = reinterpret_cast<WindowManager::Cover::CoverWorkData *>(arg);
+
+    OperationalStateSet(data->mEndpointId, data->isTilt ? OperationalStatus::kTilt : OperationalStatus::kLift, data->opState);
+
+    chip::Platform::Delete(data);
+}
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+
+WindowManager::Timer::Timer(uint32_t timeoutInMs, Callback callback, void * context) : mCallback(callback), mContext(context)
+{
+    mHandler = xTimerCreate("",                         // Just a text name, not used by the RTOS kernel
+                            pdMS_TO_TICKS(timeoutInMs), // == default timer period (mS)
+                            false,                      // no timer reload (==one-shot)
+                            (void *) this,              // init timer id = app task obj context
+                            TimerCallback               // timer callback handler
+    );
+    if (mHandler == NULL)
+    {
+        SILABS_LOG("Timer create failed");
+        appError(CHIP_ERROR_INTERNAL);
+    }
+}
+
+void WindowManager::Timer::Stop()
+{
+    mIsActive = false;
+    if (xTimerStop(mHandler, pdMS_TO_TICKS(0)) == pdFAIL)
+    {
+        SILABS_LOG("Timer stop() failed");
+        appError(CHIP_ERROR_INTERNAL);
+    }
+}
+
+void WindowManager::Timer::TimerCallback(TimerHandle_t xTimer)
+{
+    Timer * timer = (Timer *) pvTimerGetTimerID(xTimer);
+    if (timer)
+    {
+        timer->Timeout();
+    }
+}
+
+WindowManager & WindowManager::Instance()
+{
+    return WindowManager::sWindow;
+}
+
+#ifdef DISPLAY_ENABLED
+WindowManager::WindowManager() : mIconTimer(LCD_ICON_TIMEOUT, OnIconTimeout, this) {}
+#else
+WindowManager::WindowManager() {}
+#endif
+
+void WindowManager::OnIconTimeout(WindowManager::Timer & timer)
+{
+#ifdef DISPLAY_ENABLED
+    sWindow.mIcon = LcdIcon::None;
+    sWindow.UpdateLCD();
+#endif
+}
+
+CHIP_ERROR WindowManager::Init()
+{
+    chip::DeviceLayer::PlatformMgr().LockChipStack();
+
+    ConfigurationMgr().LogDeviceConfig();
+
+    // Timers
+    mLongPressTimer = new Timer(LONG_PRESS_TIMEOUT, OnLongPressTimeout, this);
+
+    // Coverings
+    mCoverList[0].Init(WINDOW_COVER_ENDPOINT1);
+    mCoverList[1].Init(WINDOW_COVER_ENDPOINT2);
+
+    // Initialize LEDs
+    LEDWidget::InitGpio();
+    mStatusLED.Init(APP_STATE_LED);
+    mActionLED.Init(APP_ACTION_LED);
+
+#ifdef DISPLAY_ENABLED
+    slLCD.Init();
+#endif
+
+    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+    return CHIP_NO_ERROR;
+}
+
+void WindowManager::PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId)
+{
+    AppEvent event     = CreateNewEvent(AppEvent::kEventType_AttributeChange);
+    event.mEndpoint    = endpoint;
+    event.mAttributeId = attributeId;
+    AppTask::GetAppTask().PostEvent(&event);
+}
+
+void WindowManager::UpdateLEDs()
+{
+    Cover & cover = GetCover();
+    if (mResetWarning)
+    {
+        mStatusLED.Set(false);
+        mStatusLED.Blink(500);
+
+        mActionLED.Set(false);
+        mActionLED.Blink(500);
+    }
+    else
+    {
+        if (mState.isWinking)
+        {
+            mStatusLED.Blink(200, 200);
+        }
+        else
+#if CHIP_ENABLE_OPENTHREAD
+            if (mState.isThreadProvisioned && mState.isThreadEnabled)
+#else
+            if (mState.isWiFiProvisioned && mState.isWiFiEnabled)
+#endif
+
+        {
+
+            mStatusLED.Blink(950, 50);
+        }
+        else if (mState.haveBLEConnections)
+        {
+            mStatusLED.Blink(100, 100);
+        }
+        else
+        {
+            mStatusLED.Blink(50, 950);
+        }
+
+        // Action LED
+        NPercent100ths current;
+        LimitStatus liftLimit = LimitStatus::Intermediate;
+
+        chip::DeviceLayer::PlatformMgr().LockChipStack();
+        Attributes::CurrentPositionLiftPercent100ths::Get(cover.mEndpoint, current);
+        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+        if (!current.IsNull())
+        {
+            AbsoluteLimits limits = { .open = WC_PERCENT100THS_MIN_OPEN, .closed = WC_PERCENT100THS_MAX_CLOSED };
+            liftLimit             = CheckLimitState(current.Value(), limits);
+        }
+
+        if (OperationalState::Stall != cover.mLiftOpState)
+        {
+
+            mActionLED.Blink(100);
+        }
+        else if (LimitStatus::IsUpOrOpen == liftLimit)
+        {
+
+            mActionLED.Set(true);
+        }
+        else if (LimitStatus::IsDownOrClose == liftLimit)
+        {
+
+            mActionLED.Set(false);
+        }
+        else
+        {
+
+            mActionLED.Blink(1000);
+        }
+    }
+}
+
+void WindowManager::UpdateLCD()
+{
+    // Update LCD
+#ifdef DISPLAY_ENABLED
+#if CHIP_ENABLE_OPENTHREAD
+    if (mState.isThreadProvisioned)
+#else
+    if (mState.isWiFiProvisioned)
+#endif // CHIP_ENABLE_OPENTHREAD
+    {
+        Cover & cover = GetCover();
+        chip::app::DataModel::Nullable<uint16_t> lift;
+        chip::app::DataModel::Nullable<uint16_t> tilt;
+
+        chip::DeviceLayer::PlatformMgr().LockChipStack();
+        Type type = TypeGet(cover.mEndpoint);
+
+        Attributes::CurrentPositionLift::Get(cover.mEndpoint, lift);
+        Attributes::CurrentPositionTilt::Get(cover.mEndpoint, tilt);
+        chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+#ifdef DISPLAY_ENABLED
+        if (!tilt.IsNull() && !lift.IsNull())
+        {
+            LcdPainter::Paint(slLCD, type, lift.Value(), tilt.Value(), mIcon);
+        }
+#endif
+    }
+#endif // DISPLAY_ENABLED
+}
+
+// Silabs button callback from button event ISR
+void WindowManager::ButtonEventHandler(uint8_t button, uint8_t btnAction)
+{
+    AppEvent event;
+
+    if (btnAction == static_cast<uint8_t>(SilabsPlatform::ButtonAction::ButtonPressed))
+    {
+        event = CreateNewEvent(button ? AppEvent::kEventType_DownPressed : AppEvent::kEventType_UpPressed);
+    }
+    else
+    {
+        event = CreateNewEvent(button ? AppEvent::kEventType_DownReleased : AppEvent::kEventType_UpReleased);
+    }
+
+    AppTask::GetAppTask().PostEvent(&event);
+}
+
+void WindowManager::GeneralEventHandler(AppEvent * aEvent)
+{
+    WindowManager * window = static_cast<WindowManager *>(aEvent->WindowEvent.Context);
+
+    switch (aEvent->Type)
+    {
+    case AppEvent::kEventType_ResetWarning:
+        window->mResetWarning = true;
+        if (window->mLongPressTimer)
+        {
+            window->mLongPressTimer->Start();
+        }
+        SILABS_LOG("Factory Reset Triggered. Release button within %ums to cancel.", LONG_PRESS_TIMEOUT);
+        // Turn off all LEDs before starting blink to make sure blink is
+        // co-ordinated.
+        window->UpdateLEDs();
+        break;
+
+    case AppEvent::kEventType_ResetCanceled:
+        window->mResetWarning = false;
+        SILABS_LOG("Factory Reset has been Canceled");
+        window->UpdateLEDs();
+        break;
+
+    case AppEvent::kEventType_Reset:
+        chip::Server::GetInstance().ScheduleFactoryReset();
+        break;
+
+    case AppEvent::kEventType_UpPressed:
+        window->mUpPressed = true;
+        if (window->mLongPressTimer)
+        {
+            window->mLongPressTimer->Start();
+        }
+        break;
+
+    case AppEvent::kEventType_UpReleased:
+        window->mUpPressed = false;
+        if (window->mLongPressTimer)
+        {
+            window->mLongPressTimer->Stop();
+        }
+        if (window->mResetWarning)
+        {
+            aEvent->Type = AppEvent::kEventType_ResetCanceled;
+            AppTask::GetAppTask().PostEvent(aEvent);
+        }
+        if (window->mUpSuppressed)
+        {
+            window->mUpSuppressed = false;
+        }
+        else if (window->mDownPressed)
+        {
+            window->mTiltMode     = !(window->mTiltMode);
+            window->mUpSuppressed = window->mDownSuppressed = true;
+            aEvent->Type                                    = AppEvent::kEventType_TiltModeChange;
+            AppTask::GetAppTask().PostEvent(aEvent);
+        }
+        else
+        {
+            window->GetCover().UpdateTargetPosition(OperationalState::MovingUpOrOpen, window->mTiltMode);
+        }
+        break;
+
+    case AppEvent::kEventType_DownPressed:
+        window->mDownPressed = true;
+        if (window->mLongPressTimer)
+        {
+            window->mLongPressTimer->Start();
+        }
+        break;
+
+    case AppEvent::kEventType_DownReleased:
+        window->mDownPressed = false;
+        if (window->mLongPressTimer)
+        {
+            window->mLongPressTimer->Stop();
+        }
+        if (window->mResetWarning)
+        {
+            aEvent->Type = AppEvent::kEventType_ResetCanceled;
+            AppTask::GetAppTask().PostEvent(aEvent);
+        }
+        if (window->mDownSuppressed)
+        {
+            window->mDownSuppressed = false;
+        }
+        else if (window->mUpPressed)
+        {
+            window->mTiltMode     = !(window->mTiltMode);
+            window->mUpSuppressed = window->mDownSuppressed = true;
+            aEvent->Type                                    = AppEvent::kEventType_TiltModeChange;
+        }
+        else
+        {
+            window->GetCover().UpdateTargetPosition(OperationalState::MovingDownOrClose, window->mTiltMode);
+        }
+        break;
+    case AppEvent::kEventType_AttributeChange:
+        window->DispatchEventAttributeChange(aEvent->mEndpoint, aEvent->mAttributeId);
+        break;
+
+    case AppEvent::kEventType_ProvisionedStateChanged:
+        window->UpdateLEDs();
+        window->UpdateLCD();
+        break;
+
+    case AppEvent::kEventType_WinkOn:
+    case AppEvent::kEventType_WinkOff:
+        window->mState.isWinking = (AppEvent::kEventType_WinkOn == aEvent->Type);
+        window->UpdateLEDs();
+        break;
+
+    case AppEvent::kEventType_ConnectivityStateChanged:
+    case AppEvent::kEventType_BLEConnectionsChanged:
+        window->UpdateLEDs();
+        break;
+
+#ifdef DISPLAY_ENABLED
+    case AppEvent::kEventType_CoverTypeChange:
+        window->UpdateLCD();
+        break;
+    case AppEvent::kEventType_CoverChange:
+        window->mIconTimer.Start();
+        window->mIcon = (window->GetCover().mEndpoint == 1) ? LcdIcon::One : LcdIcon::Two;
+        window->UpdateLCD();
+        break;
+    case AppEvent::kEventType_TiltModeChange:
+        window->mIconTimer.Start();
+        window->mIcon = window->mTiltMode ? LcdIcon::Tilt : LcdIcon::Lift;
+        window->UpdateLCD();
+        break;
+#endif
+
+    default:
+        break;
+    }
+}
diff --git a/examples/window-app/silabs/src/ZclCallbacks.cpp b/examples/window-app/silabs/src/ZclCallbacks.cpp
new file mode 100644
index 0000000..4e2a688
--- /dev/null
+++ b/examples/window-app/silabs/src/ZclCallbacks.cpp
@@ -0,0 +1,58 @@
+/*
+ *
+ *    Copyright (c) 2021 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ *   This file implements the handler for data model messages.
+ */
+
+#include <AppConfig.h>
+#include <WindowManager.h>
+
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <app-common/zap-generated/callback.h>
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app-common/zap-generated/ids/Attributes.h>
+#include <app-common/zap-generated/ids/Clusters.h>
+#include <app/CommandHandler.h>
+#include <app/ConcreteAttributePath.h>
+#include <app/ConcreteCommandPath.h>
+#include <app/clusters/window-covering-server/window-covering-server.h>
+#include <app/util/af.h>
+
+using namespace ::chip;
+using namespace ::chip::app::Clusters::WindowCovering;
+
+void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
+                                       uint8_t * value)
+{
+    switch (attributePath.mClusterId)
+    {
+    case app::Clusters::Identify::Id:
+        ChipLogProgress(Zcl, "Identify cluster ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
+                        ChipLogValueMEI(attributePath.mAttributeId), type, *value, size);
+        break;
+    default:
+        break;
+    }
+}
+
+/* Forwards all attributes changes */
+void MatterWindowCoveringClusterServerAttributeChangedCallback(const app::ConcreteAttributePath & attributePath)
+{
+    WindowManager::Instance().PostAttributeChange(attributePath.mEndpointId, attributePath.mAttributeId);
+}
diff --git a/examples/window-app/silabs/src/main.cpp b/examples/window-app/silabs/src/main.cpp
deleted file mode 100644
index f575ffe..0000000
--- a/examples/window-app/silabs/src/main.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *
- *    Copyright (c) 2020 Project CHIP Authors
- *    Copyright (c) 2019 Google LLC.
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <AppConfig.h>
-#include <WindowApp.h>
-
-#include "init_efrPlatform.h"
-#include "sl_system_kernel.h"
-#include <DeviceInfoProviderImpl.h>
-#include <app/server/Server.h>
-#include <credentials/DeviceAttestationCredsProvider.h>
-#include <matter_config.h>
-#ifdef SILABS_ATTESTATION_CREDENTIALS
-#include <examples/platform/silabs/SilabsDeviceAttestationCreds.h>
-#else
-#include <credentials/examples/DeviceAttestationCredsExample.h>
-#endif
-
-#define BLE_DEV_NAME "Silabs-Window"
-using namespace ::chip::DeviceLayer;
-using namespace ::chip::Credentials;
-
-#define UNUSED_PARAMETER(a) (a = a)
-
-volatile int apperror_cnt;
-static chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
-
-// ================================================================================
-// Main Code
-// ================================================================================
-int main(void)
-{
-    CHIP_ERROR err = CHIP_NO_ERROR;
-
-    init_efrPlatform();
-    if (SilabsMatterConfig::InitMatter(BLE_DEV_NAME) != CHIP_NO_ERROR)
-        appError(CHIP_ERROR_INTERNAL);
-
-    gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage());
-    chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
-
-    WindowApp & app = WindowApp::Instance();
-
-    SILABS_LOG("Starting App");
-    chip::DeviceLayer::PlatformMgr().LockChipStack();
-    err = app.Init();
-    // Initialize device attestation config
-#ifdef SILABS_ATTESTATION_CREDENTIALS
-    SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider());
-#else
-    SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
-#endif
-    chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
-    if (err != CHIP_NO_ERROR)
-    {
-        SILABS_LOG("App Init failed");
-        appError(err);
-    }
-
-    err = app.Start();
-    if (err != CHIP_NO_ERROR)
-    {
-        SILABS_LOG("App Start failed");
-        appError(err);
-    }
-
-    app.Finish();
-    return err.AsInteger();
-}