diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml
index 7bef8b9552f252..3c709c3354aa0b 100644
--- a/.github/workflows/examples-infineon.yaml
+++ b/.github/workflows/examples-infineon.yaml
@@ -26,7 +26,7 @@ concurrency:
jobs:
infineon:
name: Infineon examples building
- timeout-minutes: 30
+ timeout-minutes: 60
runs-on: ubuntu-latest
if: github.actor != 'restyled-io[bot]'
@@ -72,7 +72,14 @@ jobs:
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
p6 default all-clusters-app \
out/infineon-p6-all-clusters/chip-p6-clusters-example.out
-
+ - name: Build lighting-app example
+ timeout-minutes: 10
+ run: |
+ scripts/run_in_build_env.sh \
+ "scripts/build/build_examples.py --no-log-timestamps --target 'infineon-p6-light' build"
+ .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
+ p6 default light-app \
+ out/infineon-p6-light/chip-p6-lighting-example.out
- name: Uploading Size Reports
uses: actions/upload-artifact@v2
if: ${{ !env.ACT }}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index a7a102d81514e2..ce4fecb97314ee 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -246,6 +246,7 @@
"esp32-m5stack-all-clusters-rpc-ipv6only",
"infineon-p6-all-clusters",
"infineon-p6-lock",
+ "infineon-p6-light",
"linux-arm64-all-clusters",
"linux-arm64-all-clusters-ipv6only",
"linux-arm64-chip-tool",
diff --git a/examples/all-clusters-app/p6/src/main.cpp b/examples/all-clusters-app/p6/src/main.cpp
index 68446f6ecf05ab..a943c132dc3620 100644
--- a/examples/all-clusters-app/p6/src/main.cpp
+++ b/examples/all-clusters-app/p6/src/main.cpp
@@ -89,7 +89,14 @@ int main(void)
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- CHIP_ERROR ret = PlatformMgr().InitChipStack();
+ CHIP_ERROR ret = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
+ if (ret != CHIP_NO_ERROR)
+ {
+ P6_LOG("PersistedStorage::KeyValueStoreMgrImpl().Init() failed");
+ appError(ret);
+ }
+
+ ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
{
P6_LOG("PlatformMgr().InitChipStack() failed");
diff --git a/examples/lighting-app/p6/.gn b/examples/lighting-app/p6/.gn
new file mode 100644
index 00000000000000..81cec9d11a421b
--- /dev/null
+++ b/examples/lighting-app/p6/.gn
@@ -0,0 +1,28 @@
+# 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.
+
+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/lighting-app/p6/BUILD.gn b/examples/lighting-app/p6/BUILD.gn
new file mode 100644
index 00000000000000..6af9db2bffd8b8
--- /dev/null
+++ b/examples/lighting-app/p6/BUILD.gn
@@ -0,0 +1,109 @@
+# 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.
+
+import("//build_overrides/build.gni")
+import("//build_overrides/chip.gni")
+import("//build_overrides/p6.gni")
+
+import("${build_root}/config/defaults.gni")
+import("${p6_sdk_build_root}/p6_executable.gni")
+import("${p6_sdk_build_root}/p6_sdk.gni")
+
+assert(current_os == "freertos")
+
+p6_project_dir = "${chip_root}/examples/lighting-app/p6"
+examples_plat_dir = "${chip_root}/examples/platform/p6"
+
+declare_args() {
+ # Dump memory usage at link time.
+ chip_print_memory_usage = false
+
+ # PIN code for PASE session establishment.
+ setup_pin_code = 20202021
+
+ # Monitor & log memory usage at runtime.
+ enable_heap_monitoring = false
+}
+
+p6_sdk_sources("lighting_app_sdk_sources") {
+ include_dirs = [
+ "${chip_root}/src/platform/P6",
+ "${p6_project_dir}/include",
+ "${examples_plat_dir}",
+ ]
+
+ defines = [
+ "BOARD_ID=${p6_board}",
+ "P6_LOG_ENABLED=1",
+ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setup_pin_code}",
+ ]
+
+ sources = [ "${p6_project_dir}/include/CHIPProjectConfig.h" ]
+
+ public_configs = [ "${chip_root}/third_party/p6:p6_sdk_config" ]
+}
+
+p6_executable("lighting_app") {
+ include_dirs = []
+ defines = []
+ output_name = "chip-p6-lighting-example.out"
+
+ sources = [
+ "${examples_plat_dir}/LEDWidget.cpp",
+ "${examples_plat_dir}/init_p6Platform.cpp",
+ "src/AppTask.cpp",
+ "src/ButtonHandler.cpp",
+ "src/LightingManager.cpp",
+ "src/ZclCallbacks.cpp",
+ "src/main.cpp",
+ ]
+
+ deps = [
+ ":lighting_app_sdk_sources",
+ "${chip_root}/examples/common/QRCode",
+ "${chip_root}/examples/lighting-app/lighting-common",
+ "${chip_root}/src/lib",
+ "${chip_root}/src/setup_payload",
+ ]
+
+ include_dirs += [
+ "include",
+ "${examples_plat_dir}",
+ "${p6_project_dir}/include",
+ ]
+
+ defines = []
+
+ if (enable_heap_monitoring) {
+ sources += [ "${examples_plat_dir}/MemMonitoring.cpp" ]
+ defines += [ "HEAP_MONITORING" ]
+ }
+
+ if (chip_print_memory_usage) {
+ ldflags += [
+ "-Wl,--print-memory-usage",
+ "-fstack-usage",
+ ]
+ }
+
+ output_dir = root_out_dir
+}
+
+group("p6") {
+ deps = [ ":lighting_app" ]
+}
+
+group("default") {
+ deps = [ ":p6" ]
+}
diff --git a/examples/lighting-app/p6/README.md b/examples/lighting-app/p6/README.md
new file mode 100644
index 00000000000000..3ef67d0988b81f
--- /dev/null
+++ b/examples/lighting-app/p6/README.md
@@ -0,0 +1,156 @@
+#CHIP P6 Lighting Example
+
+An example showing the use of Matter on the Infineon CY8CKIT-062S2-43012 board.
+
+
+
+- [Matter P6 Lighting Example](#chip-p6-Lighting-example)
+ - [Introduction](#introduction)
+ - [Building](#building)
+ - [Flashing the Application](#flashing-the-application)
+ - [Commissioning and cluster control](#commissioning-and-cluster-control)
+ - [Setting up Python Controller](#setting-up-python-controller)
+ - [Commissioning over BLE](#commissioning-over-ble)
+ - [Notes](#notes)
+ - [Cluster control](#cluster-control)
+
+
+
+
+
+## Introduction
+
+The P6 lighting example provides a baseline demonstration of a Light control
+device, built using Matter and the Infineon Modustoolbox SDK. It can be
+controlled by Matter controller over Wi-Fi network.
+
+The P6 device can be commissioned over Bluetooth Low Energy where the device and
+the Matter controller will exchange security information with the Rendezvous
+procedure. Wi-Fi Network credentials are then provided to the P6 device which
+will then join the network.
+
+
+
+## Building
+
+- [Modustoolbox Software](https://www.cypress.com/products/modustoolbox)
+
+ Refer to `integrations/docker/images/chip-build-infineon/Dockerfile` or
+ `scripts/examples/gn_p6_example.sh` for downloading the Software and related
+ tools.
+
+- Install some additional tools (likely already present for Matter
+ developers): \$ sudo apt install gcc g++ clang ninja-build python
+ python3-venv libssl-dev libavahi-client-dev libglib2.0-dev git cmake
+ python3-pip
+
+- Supported hardware:
+ [CY8CKIT-062S2-43012](https://www.cypress.com/CY8CKIT-062S2-43012)
+
+* Build the example application:
+
+ $ ./scripts/examples/gn_p6_example.sh ./examples/lighting-app/p6 out/lighting_app_p6
+
+- To delete generated executable, libraries and object files use:
+
+ $ cd ~/connectedhomeip
+ $ rm -rf out/
+
+
+
+## Flashing the Application
+
+- Put CY8CKIT-062S2-43012 board on KitProg3 CMSIS-DAP Mode by pressing the
+ `MODE SELECT` button. `KITPROG3 STATUS` LED is ON confirms board is in
+ proper mode.
+
+- On the command line:
+
+ $ cd ~/connectedhomeip
+ $ python3 out/lighting_app_p6/chip-p6-lock-example.flash.py
+
+
+
+## Commissioning and cluster control
+
+Commissioning can be carried out using BLE.
+
+
+
+### Setting up Python Controller
+
+Once P6 is up and running, we need to set up a device controller on Raspberry Pi
+4 to perform commissioning and cluster control.
+
+- Set up python controller.
+
+ $ cd {path-to-connectedhomeip}
+ $ ./scripts/build_python.sh -m platform
+
+- Execute the controller.
+
+ $ source ./out/python_env/bin/activate
+ $ chip-device-ctrl
+
+
+
+### Commissioning over BLE
+
+- Establish the secure session over BLE.
+
+ - chip-device-ctrl > ble-scan
+ - chip-device-ctrl > connect -ble 3840 20202021 1234
+
+ Parameters:
+ 1. Discriminator: 3840
+ 2. Setup-pin-code: 20202021
+ 3. Node ID: Optional.
+ If not passed in this command, then it is auto-generated by the controller and
+ displayed in the output of connect.
+ The same value should be used in the next commands.
+ We have chosen a random node ID which is 1234.
+
+- Add credentials of the Wi-Fi network you want the P6 to connect to, using
+ the `AddWiFiNetwork` command and then enable the P6 to connect to it using
+ `EnableWiFiNetwork` command. In this example, we have used `WIFI_SSID` and
+ `WIFI_PASSWORD` as the SSID and passphrase respectively.
+
+ - chip-device-ctrl > zcl NetworkCommissioning AddWiFiNetwork 1234 0 0 ssid=str:WIFI_SSID credentials=str:WIFI_PASSWORD breadcrumb=0 timeoutMs=1000
+
+ - chip-device-ctrl > zcl NetworkCommissioning EnableNetwork 1234 0 0 networkID=str:WIFI_SSID breadcrumb=0 timeoutMs=1000
+
+- Close the BLE connection to P6, as it is not required hereafter.
+
+ - chip-device-ctrl > close-ble
+
+- Resolve DNS-SD name and update address of the node in the device controller.
+
+ - chip-device-ctrl > resolve 0 1234
+
+
+
+#### Notes
+
+Raspberry Pi 4 BLE connection issues can be avoided by running the following
+commands. These power cycle the BlueTooth hardware and disable BR/EDR mode.
+
+ $ sudo btmgmt -i hci0 power off
+ $ sudo btmgmt -i hci0 bredr off
+ $ sudo btmgmt -i hci0 power on
+
+
+
+### Cluster control
+
+- After successful commissioning, use the OnOff cluster command to toggle
+ device between On or Off states.
+
+ `chip-device-ctrl > zcl OnOff Off 1234 1 0`
+
+ `chip-device-ctrl > zcl OnOff On 1234 1 0`
+
+- Cluster OnOff can also be done using the `USER_BTN1` button on the board.
+ This button is configured with `APP_LIGHT_BUTTON` in `include/AppConfig.h`.
+ Press `USER_BTN1` on the board to toggle between Light ON and OFF states.
+ Light ON and OFF can be observed with 'LED9' on the board. This LED is
+ configured with `LIGHT_STATE_LED` in `include/AppConfig.h`.
diff --git a/examples/lighting-app/p6/args.gni b/examples/lighting-app/p6/args.gni
new file mode 100644
index 00000000000000..f239efee01e5da
--- /dev/null
+++ b/examples/lighting-app/p6/args.gni
@@ -0,0 +1,20 @@
+# 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.
+
+import("//build_overrides/chip.gni")
+import("//build_overrides/pigweed.gni")
+import("${chip_root}/src/platform/P6/args.gni")
+
+p6_target_project =
+ get_label_info(":lighting_app_sdk_sources", "label_no_toolchain")
diff --git a/examples/lighting-app/p6/build_overrides b/examples/lighting-app/p6/build_overrides
new file mode 120000
index 00000000000000..e578e73312ebd1
--- /dev/null
+++ b/examples/lighting-app/p6/build_overrides
@@ -0,0 +1 @@
+../../build_overrides
\ No newline at end of file
diff --git a/examples/lighting-app/p6/include/AppConfig.h b/examples/lighting-app/p6/include/AppConfig.h
new file mode 100644
index 00000000000000..5ed6edd44bd594
--- /dev/null
+++ b/examples/lighting-app/p6/include/AppConfig.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright (c) 2021 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 "cybsp.h"
+#include "cyhal.h"
+
+// ---- Lighting Example App Config ----
+
+#define APP_TASK_NAME "APP"
+
+#define APP_LIGHT_BUTTON_IDX 0
+#define APP_FUNCTION_BUTTON_IDX 1
+
+#define APP_LIGHT_BUTTON CYBSP_USER_BTN1
+#define APP_FUNCTION_BUTTON CYBSP_USER_BTN2
+#define APP_BUTTON_DEBOUNCE_PERIOD_MS 50
+
+#define APP_BUTTON_PRESSED 0
+#define APP_BUTTON_RELEASED 1
+
+#define SYSTEM_STATE_LED CYBSP_USER_LED1
+#define LIGHT_LED CYBSP_USER_LED2
+
+// Time it takes in ms for the simulated actuator to move from one
+// state to another.
+#define ACTUATOR_MOVEMENT_PERIOS_MS 2000
+
+// ---- Thread Polling Config ----
+#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100
+#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000
+
+// P6 Logging
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void appError(int err);
+void P6Log(const char * aFormat, ...);
+#define P6_LOG(...) P6Log(__VA_ARGS__)
+
+#ifdef __cplusplus
+}
+
+#include
+void appError(CHIP_ERROR error);
+#endif
diff --git a/examples/lighting-app/p6/include/AppEvent.h b/examples/lighting-app/p6/include/AppEvent.h
new file mode 100644
index 00000000000000..1191e379982d52
--- /dev/null
+++ b/examples/lighting-app/p6/include/AppEvent.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ * Copyright (c) 2018 Nest Labs, Inc.
+ * 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 *);
+
+struct AppEvent
+{
+ enum AppEventTypes
+ {
+ kEventType_Button = 0,
+ kEventType_Timer,
+ kEventType_Light,
+ kEventType_Install,
+ };
+
+ uint16_t Type;
+
+ union
+ {
+ struct
+ {
+ uint8_t ButtonIdx;
+ uint8_t Action;
+ } ButtonEvent;
+ struct
+ {
+ void * Context;
+ } TimerEvent;
+ struct
+ {
+ uint8_t Action;
+ int32_t Actor;
+ } LightEvent;
+ };
+
+ EventHandler Handler;
+};
diff --git a/examples/lighting-app/p6/include/AppTask.h b/examples/lighting-app/p6/include/AppTask.h
new file mode 100644
index 00000000000000..c7f9a23f48a495
--- /dev/null
+++ b/examples/lighting-app/p6/include/AppTask.h
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright (c) 2021 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
+#include
+
+#include "AppEvent.h"
+#include "LightingManager.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+#include
+#include
+
+// Application-defined error codes in the CHIP_ERROR space.
+#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01)
+#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02)
+#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03)
+#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04)
+#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05)
+#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06)
+
+class AppTask
+{
+
+public:
+ CHIP_ERROR StartAppTask();
+ static void AppTaskMain(void * pvParameter);
+
+ void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction);
+ void PostEvent(const AppEvent * event);
+
+ void ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction);
+
+private:
+ friend AppTask & GetAppTask(void);
+
+ CHIP_ERROR Init();
+
+ static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor);
+ static void ActionCompleted(LightingManager::Action_t aAction);
+
+ void CancelTimer(void);
+
+ void DispatchEvent(AppEvent * event);
+
+ static void FunctionTimerEventHandler(AppEvent * aEvent);
+ static void FunctionHandler(AppEvent * aEvent);
+ static void LightActionEventHandler(AppEvent * aEvent);
+ static void TimerEventHandler(TimerHandle_t xTimer);
+
+ static void UpdateClusterState(void);
+
+ void StartTimer(uint32_t aTimeoutMs);
+
+ enum class Function
+ {
+ kNoneSelected = 0,
+ kSoftwareUpdate = 0,
+ kStartBleAdv = 1,
+ kFactoryReset = 2,
+
+ kInvalid
+ };
+
+ Function mFunction = Function::kNoneSelected;
+ bool mFunctionTimerActive = false;
+ bool mSyncClusterToButtonAction = false;
+
+ static AppTask sAppTask;
+};
+
+inline AppTask & GetAppTask(void)
+{
+ return AppTask::sAppTask;
+}
diff --git a/examples/lighting-app/p6/include/ButtonHandler.h b/examples/lighting-app/p6/include/ButtonHandler.h
new file mode 100644
index 00000000000000..89b40e33477425
--- /dev/null
+++ b/examples/lighting-app/p6/include/ButtonHandler.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 2021 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
+
+#include "FreeRTOS.h"
+#include "cyhal.h"
+#include "timers.h" // provides FreeRTOS timer support
+
+#define GPIO_INTERRUPT_PRIORITY (5)
+
+class ButtonHandler
+{
+public:
+ static void Init(void);
+
+private:
+ static void GpioInit(void);
+ static void lockbuttonIsr(void * handler_arg, cyhal_gpio_event_t event);
+ static void functionbuttonIsr(void * handler_arg, cyhal_gpio_event_t event);
+ static void TimerCallback(TimerHandle_t xTimer);
+};
diff --git a/examples/lighting-app/p6/include/CHIPProjectConfig.h b/examples/lighting-app/p6/include/CHIPProjectConfig.h
new file mode 100644
index 00000000000000..21271e4a31e380
--- /dev/null
+++ b/examples/lighting-app/p6/include/CHIPProjectConfig.h
@@ -0,0 +1,114 @@
+/*
+ *
+ * Copyright (c) 2021 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
+
+/**
+ * CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY
+ *
+ * Enables the use of a hard-coded default Chip device id and credentials if no device id
+ * is found in Chip NV storage.
+ *
+ * This option is for testing only and should be disabled in production releases.
+ */
+#define CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY 34
+
+// 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
+#define CHIP_CONFIG_REQUIRE_AUTH 1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION
+ *
+ * The product revision number assigned to device or product by the device vendor. This
+ * number is scoped to the device product id, and typically corresponds to a revision of the
+ * physical device, a change to its packaging, and/or a change to its marketing presentation.
+ * This value is generally *not* incremented for device software revisions.
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION 1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING
+ *
+ * A string identifying the firmware revision running on the device.
+ * CHIP service currently expects the firmware version to be in the format
+ * {MAJOR_VERSION}.0d{MINOR_VERSION}
+ */
+#ifndef CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING
+#define CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING "0.1ALPHA"
+#endif
+/**
+ * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+ *
+ * Enable support for Chip-over-BLE (CHIPoBLE).
+ */
+#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1
+
+/**
+ * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC
+ *
+ * Enables synchronizing the device's real time clock with a remote Chip Time service
+ * using the Chip Time Sync protocol.
+ */
+#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0
+
+/**
+ * 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_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS
+ *
+ * Enable recording UTC timestamps.
+ */
+#define CHIP_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)
diff --git a/examples/lighting-app/p6/include/LightingManager.h b/examples/lighting-app/p6/include/LightingManager.h
new file mode 100644
index 00000000000000..4cb6fb4647de71
--- /dev/null
+++ b/examples/lighting-app/p6/include/LightingManager.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright (c) 2021 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
+#include
+
+#include "AppEvent.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+
+#include
+
+class LightingManager
+{
+public:
+ enum Action_t
+ {
+ ON_ACTION = 0,
+ OFF_ACTION,
+
+ INVALID_ACTION
+ } Action;
+
+ enum State_t
+ {
+ kState_OffInitiated = 0,
+ kState_OffCompleted,
+ kState_OnInitiated,
+ kState_OnCompleted,
+ } State;
+
+ CHIP_ERROR Init();
+ bool IsLightOn();
+ void EnableAutoTurnOff(bool aOn);
+ void SetAutoTurnOffDuration(uint32_t aDurationInSecs);
+ bool IsActionInProgress();
+ bool InitiateAction(int32_t aActor, Action_t aAction);
+
+ typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor);
+ typedef void (*Callback_fn_completed)(Action_t);
+ void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB);
+
+private:
+ friend LightingManager & LightMgr(void);
+ State_t mState = kState_OnCompleted;
+
+ Callback_fn_initiated mActionInitiated_CB;
+ Callback_fn_completed mActionCompleted_CB;
+
+ bool mAutoTurnOff;
+ uint32_t mAutoTurnOffDuration;
+ bool mAutoTurnOffTimerArmed;
+
+ void CancelTimer(void);
+ void StartTimer(uint32_t aTimeoutMs);
+
+ static void TimerEventHandler(TimerHandle_t xTimer);
+ static void AutoTurnOffTimerEventHandler(AppEvent * aEvent);
+ static void ActuatorMovementTimerEventHandler(AppEvent * aEvent);
+
+ static LightingManager sLight;
+};
+
+inline LightingManager & LightMgr(void)
+{
+ return LightingManager::sLight;
+}
diff --git a/examples/lighting-app/p6/src/AppTask.cpp b/examples/lighting-app/p6/src/AppTask.cpp
new file mode 100644
index 00000000000000..ddfba4aba5fa9c
--- /dev/null
+++ b/examples/lighting-app/p6/src/AppTask.cpp
@@ -0,0 +1,505 @@
+/*
+ *
+ * Copyright (c) 2021 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 "ButtonHandler.h"
+#include "LEDWidget.h"
+#include "qrcodegen.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
+#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
+#define APP_TASK_STACK_SIZE (4096)
+#define APP_TASK_PRIORITY 2
+#define APP_EVENT_QUEUE_SIZE 10
+
+namespace {
+TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer.
+
+TaskHandle_t sAppTaskHandle;
+QueueHandle_t sAppEventQueue;
+
+LEDWidget sStatusLED;
+LEDWidget sLightLED;
+
+bool sIsWiFiStationProvisioned = false;
+bool sIsWiFiStationEnabled = false;
+bool sIsWiFiStationConnected = false;
+bool sHaveBLEConnections = false;
+
+uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(AppEvent)];
+StaticQueue_t sAppEventQueueStruct;
+
+StackType_t appStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)];
+StaticTask_t appTaskStruct;
+} // namespace
+
+using namespace chip::TLV;
+using namespace ::chip::Credentials;
+using namespace ::chip::DeviceLayer;
+
+AppTask AppTask::sAppTask;
+
+CHIP_ERROR AppTask::StartAppTask()
+{
+ sAppEventQueue = xQueueCreateStatic(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent), sAppEventQueueBuffer, &sAppEventQueueStruct);
+ if (sAppEventQueue == NULL)
+ {
+ P6_LOG("Failed to allocate app event queue");
+ appError(APP_ERROR_EVENT_QUEUE_FAILED);
+ }
+
+ // Start App task.
+ sAppTaskHandle = xTaskCreateStatic(AppTaskMain, APP_TASK_NAME, ArraySize(appStack), NULL, 1, appStack, &appTaskStruct);
+ return (sAppTaskHandle == nullptr) ? APP_ERROR_CREATE_TASK_FAILED : CHIP_NO_ERROR;
+}
+
+CHIP_ERROR AppTask::Init()
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ // Register the callback to init the MDNS server when connectivity is available
+ PlatformMgr().AddEventHandler(
+ [](const ChipDeviceEvent * event, intptr_t arg) {
+ // Restart the server whenever an ip address is renewed
+ if (event->Type == DeviceEventType::kInternetConnectivityChange)
+ {
+ if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established ||
+ event->InternetConnectivityChange.IPv6 == kConnectivity_Established)
+ {
+ chip::app::DnssdServer::Instance().StartServer();
+ }
+ }
+ },
+ 0);
+ // Init ZCL Data Model
+ chip::Server::GetInstance().Init();
+
+ // Initialize device attestation config
+ SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
+
+ // Initialise WSTK buttons PB0 and PB1 (including debounce).
+ ButtonHandler::Init();
+
+ // Create FreeRTOS sw timer for Function Selection.
+ sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel
+ 1, // == default timer period (mS)
+ false, // no timer reload (==one-shot)
+ (void *) this, // init timer id = app task obj context
+ TimerEventHandler // timer callback handler
+ );
+ if (sFunctionTimer == NULL)
+ {
+ P6_LOG("funct timer create failed");
+ appError(APP_ERROR_CREATE_TIMER_FAILED);
+ }
+
+ P6_LOG("Current Firmware Version: %s", CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING);
+ err = LightMgr().Init();
+ if (err != CHIP_NO_ERROR)
+ {
+ P6_LOG("LightMgr().Init() failed");
+ appError(err);
+ }
+
+ LightMgr().SetCallbacks(ActionInitiated, ActionCompleted);
+
+ // Initialize LEDs
+ sStatusLED.Init(SYSTEM_STATE_LED);
+ sLightLED.Init(LIGHT_LED);
+ sLightLED.Set(LightMgr().IsLightOn());
+ UpdateClusterState();
+
+ ConfigurationMgr().LogDeviceConfig();
+
+ // Print setup info
+ PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE));
+
+ return err;
+}
+
+void AppTask::AppTaskMain(void * pvParameter)
+{
+ AppEvent event;
+
+ CHIP_ERROR err = sAppTask.Init();
+ if (err != CHIP_NO_ERROR)
+ {
+ P6_LOG("AppTask.Init() failed");
+ appError(err);
+ }
+
+ P6_LOG("App Task started");
+
+ while (true)
+ {
+ BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10));
+ while (eventReceived == pdTRUE)
+ {
+ sAppTask.DispatchEvent(&event);
+ eventReceived = xQueueReceive(sAppEventQueue, &event, 0);
+ }
+
+ // Collect connectivity and configuration state from the CHIP stack. Because
+ // the CHIP event loop is being run in a separate task, the stack must be
+ // locked while these values are queried. However we use a non-blocking
+ // lock request (TryLockCHIPStack()) to avoid blocking other UI activities
+ // when the CHIP task is busy (e.g. with a long crypto operation).
+ if (PlatformMgr().TryLockChipStack())
+ {
+ sIsWiFiStationEnabled = ConnectivityMgr().IsWiFiStationEnabled();
+ sIsWiFiStationConnected = ConnectivityMgr().IsWiFiStationConnected();
+ sIsWiFiStationProvisioned = ConnectivityMgr().IsWiFiStationProvisioned();
+ sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0);
+ PlatformMgr().UnlockChipStack();
+ }
+
+ // Update the status LED if factory reset has not been initiated.
+ //
+ // If system has "full connectivity", keep the LED On constantly.
+ //
+ // If thread and service provisioned, but not attached to the thread network
+ // yet OR no connectivity to the service OR subscriptions are not fully
+ // established THEN blink the LED Off for a short period of time.
+ //
+ // If the system has ble connection(s) uptill the stage above, THEN blink
+ // the LEDs at an even rate of 100ms.
+ //
+ // Otherwise, blink the LED ON for a very short time.
+ if (sAppTask.mFunction != Function::kFactoryReset)
+ {
+ if (sIsWiFiStationEnabled && sIsWiFiStationProvisioned && !sIsWiFiStationConnected)
+ {
+ sStatusLED.Blink(950, 50);
+ }
+ else if (sHaveBLEConnections)
+ {
+ sStatusLED.Blink(100, 100);
+ }
+ else
+ {
+ sStatusLED.Blink(50, 950);
+ }
+ }
+
+ sStatusLED.Animate();
+ sLightLED.Animate();
+ }
+}
+
+void AppTask::LightActionEventHandler(AppEvent * aEvent)
+{
+ bool initiated = false;
+ LightingManager::Action_t action;
+ int32_t actor = 0;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ if (aEvent->Type == AppEvent::kEventType_Light)
+ {
+ action = static_cast(aEvent->LightEvent.Action);
+ actor = aEvent->LightEvent.Actor;
+ }
+ else if (aEvent->Type == AppEvent::kEventType_Button)
+ {
+ if (LightMgr().IsLightOn())
+ {
+ action = LightingManager::OFF_ACTION;
+ }
+ else
+ {
+ action = LightingManager::ON_ACTION;
+ }
+ actor = AppEvent::kEventType_Button;
+ }
+ else
+ {
+ err = APP_ERROR_UNHANDLED_EVENT;
+ }
+
+ if (err == CHIP_NO_ERROR)
+ {
+ initiated = LightMgr().InitiateAction(actor, action);
+
+ if (!initiated)
+ {
+ P6_LOG("Action is already in progress or active.");
+ }
+ }
+}
+
+void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction)
+{
+ if (btnIdx != APP_LIGHT_BUTTON_IDX && btnIdx != APP_FUNCTION_BUTTON_IDX)
+ {
+ return;
+ }
+
+ AppEvent button_event = {};
+ button_event.Type = AppEvent::kEventType_Button;
+ button_event.ButtonEvent.ButtonIdx = btnIdx;
+ button_event.ButtonEvent.Action = btnAction;
+
+ if (btnIdx == APP_LIGHT_BUTTON_IDX)
+ {
+ button_event.Handler = LightActionEventHandler;
+ sAppTask.PostEvent(&button_event);
+ }
+ else if (btnIdx == APP_FUNCTION_BUTTON_IDX)
+ {
+ button_event.Handler = FunctionHandler;
+ sAppTask.PostEvent(&button_event);
+ }
+}
+
+void AppTask::TimerEventHandler(TimerHandle_t xTimer)
+{
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Timer;
+ event.TimerEvent.Context = (void *) xTimer;
+ event.Handler = FunctionTimerEventHandler;
+ sAppTask.PostEvent(&event);
+}
+
+void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
+{
+ if (aEvent->Type != AppEvent::kEventType_Timer)
+ {
+ return;
+ }
+
+ // If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT,
+ // initiate factory reset
+ if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kStartBleAdv)
+ {
+ P6_LOG("Factory Reset Triggered. Release button within %ums to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+
+ // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to
+ // cancel, if required.
+ sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+
+ sAppTask.mFunction = Function::kFactoryReset;
+
+ // Turn off all LEDs before starting blink to make sure blink is
+ // co-ordinated.
+ sStatusLED.Set(false);
+ sLightLED.Set(false);
+
+ sStatusLED.Blink(500);
+ sLightLED.Blink(500);
+ }
+ else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kFactoryReset)
+ {
+ // Actually trigger Factory Reset
+ sAppTask.mFunction = Function::kNoneSelected;
+ ConfigurationMgr().InitiateFactoryReset();
+ }
+}
+
+void AppTask::FunctionHandler(AppEvent * aEvent)
+{
+ // To trigger software update: press the APP_FUNCTION_BUTTON button briefly (<
+ // FACTORY_RESET_TRIGGER_TIMEOUT) To initiate factory reset: press the
+ // APP_FUNCTION_BUTTON for FACTORY_RESET_TRIGGER_TIMEOUT +
+ // FACTORY_RESET_CANCEL_WINDOW_TIMEOUT All LEDs start blinking after
+ // FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated.
+ // To cancel factory reset: release the APP_FUNCTION_BUTTON once all LEDs
+ // start blinking within the FACTORY_RESET_CANCEL_WINDOW_TIMEOUT
+ if (aEvent->ButtonEvent.Action == APP_BUTTON_PRESSED)
+ {
+ if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kNoneSelected)
+ {
+ sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT);
+ sAppTask.mFunction = Function::kStartBleAdv;
+ }
+ }
+ else
+ {
+ // If the button was released before factory reset got initiated, start Thread Network
+ if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kStartBleAdv)
+ {
+ sAppTask.CancelTimer();
+ sAppTask.mFunction = Function::kNoneSelected;
+ }
+ else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kFactoryReset)
+ {
+ // Set Light status LED back to show state of light.
+ sLightLED.Set(LightMgr().IsLightOn());
+
+ sAppTask.CancelTimer();
+
+ // Change the function to none selected since factory reset has been
+ // canceled.
+ sAppTask.mFunction = Function::kNoneSelected;
+
+ P6_LOG("Factory Reset has been Canceled");
+ }
+ }
+}
+
+void AppTask::CancelTimer()
+{
+ if (xTimerStop(sFunctionTimer, 0) == pdFAIL)
+ {
+ P6_LOG("app timer stop() failed");
+ appError(APP_ERROR_STOP_TIMER_FAILED);
+ }
+
+ mFunctionTimerActive = false;
+}
+
+void AppTask::StartTimer(uint32_t aTimeoutInMs)
+{
+ if (xTimerIsTimerActive(sFunctionTimer))
+ {
+ P6_LOG("app timer already started!");
+ CancelTimer();
+ }
+
+ // timer is not active, change its period to required value (== restart).
+ // FreeRTOS- Block for a maximum of 100 ticks if the change period command
+ // cannot immediately be sent to the timer command queue.
+ if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS)
+ {
+ P6_LOG("app timer start() failed");
+ appError(APP_ERROR_START_TIMER_FAILED);
+ }
+
+ mFunctionTimerActive = true;
+}
+
+void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor)
+{
+ // Action initiated, update the light led
+ if (aAction == LightingManager::ON_ACTION)
+ {
+ P6_LOG("Turning light ON");
+ sLightLED.Set(true);
+ }
+ else if (aAction == LightingManager::OFF_ACTION)
+ {
+ P6_LOG("Turning light OFF");
+ sLightLED.Set(false);
+ }
+
+ if (aActor == AppEvent::kEventType_Button)
+ {
+ sAppTask.mSyncClusterToButtonAction = true;
+ }
+}
+
+void AppTask::ActionCompleted(LightingManager::Action_t aAction)
+{
+ // action has been completed bon the light
+ if (aAction == LightingManager::ON_ACTION)
+ {
+ P6_LOG("Light ON");
+ }
+ else if (aAction == LightingManager::OFF_ACTION)
+ {
+ P6_LOG("Light OFF");
+ }
+
+ if (sAppTask.mSyncClusterToButtonAction)
+ {
+ UpdateClusterState();
+ sAppTask.mSyncClusterToButtonAction = false;
+ }
+}
+
+void AppTask::PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction)
+{
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Light;
+ event.LightEvent.Actor = aActor;
+ event.LightEvent.Action = aAction;
+ event.Handler = LightActionEventHandler;
+ PostEvent(&event);
+}
+
+void AppTask::PostEvent(const AppEvent * aEvent)
+{
+ if (sAppEventQueue != NULL)
+ {
+ BaseType_t status;
+ if (xPortIsInsideInterrupt())
+ {
+ BaseType_t higherPrioTaskWoken = pdFALSE;
+ status = xQueueSendFromISR(sAppEventQueue, aEvent, &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(sAppEventQueue, aEvent, 1);
+ }
+
+ if (!status)
+ P6_LOG("Failed to post event to app task event queue");
+ }
+ else
+ {
+ P6_LOG("Event Queue is NULL should never happen");
+ }
+}
+
+void AppTask::DispatchEvent(AppEvent * aEvent)
+{
+ if (aEvent->Handler)
+ {
+ aEvent->Handler(aEvent);
+ }
+ else
+ {
+ P6_LOG("Event received with no handler. Dropping event.");
+ }
+}
+
+void AppTask::UpdateClusterState(void)
+{
+ uint8_t newValue = LightMgr().IsLightOn();
+
+ // write the new on/off value
+ EmberAfStatus status = emberAfWriteAttribute(1, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) &newValue, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ P6_LOG("ERR: updating on/off %x", status);
+ }
+}
diff --git a/examples/lighting-app/p6/src/ButtonHandler.cpp b/examples/lighting-app/p6/src/ButtonHandler.cpp
new file mode 100644
index 00000000000000..729939ba56f1f0
--- /dev/null
+++ b/examples/lighting-app/p6/src/ButtonHandler.cpp
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright (c) 2021 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 "ButtonHandler.h"
+#include "AppConfig.h"
+#include "AppTask.h"
+
+namespace {
+constexpr int kButtonCount = 2;
+
+TimerHandle_t buttonTimers[kButtonCount]; // FreeRTOS timers used for debouncing
+// buttons. Array to hold handles to
+// the created timers.
+
+} // namespace
+
+void ButtonHandler::Init(void)
+{
+ GpioInit();
+ // Create FreeRTOS sw timers for debouncing buttons.
+ for (uint8_t i = 0; i < kButtonCount; i++)
+ {
+ buttonTimers[i] = xTimerCreate("BtnTmr", // Just a text name, not used by the RTOS kernel
+ APP_BUTTON_DEBOUNCE_PERIOD_MS, // timer period
+ false, // no timer reload (==one-shot)
+ (void *) (int) i, // init timer id = button index
+ TimerCallback // timer callback handler (all buttons use
+ // the same timer cn function)
+ );
+ }
+}
+
+void ButtonHandler::GpioInit(void)
+{
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ // Set up button GPIOs to input with pullups.
+ result = cyhal_gpio_init(APP_LIGHT_BUTTON, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ printf(" cyhal_gpio_init failed for APP_LOCK_BUTTON\r\n");
+ }
+ result = cyhal_gpio_init(APP_FUNCTION_BUTTON, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ printf(" cyhal_gpio_init failed for APP_FUNCTION_BUTTON\r\n");
+ }
+ /* Configure GPIO interrupt. */
+ cyhal_gpio_register_callback(APP_LIGHT_BUTTON, lockbuttonIsr, NULL);
+ cyhal_gpio_register_callback(APP_FUNCTION_BUTTON, functionbuttonIsr, NULL);
+ cyhal_gpio_enable_event(APP_LIGHT_BUTTON, CYHAL_GPIO_IRQ_FALL, GPIO_INTERRUPT_PRIORITY, true);
+ cyhal_gpio_enable_event(APP_FUNCTION_BUTTON, CYHAL_GPIO_IRQ_FALL, GPIO_INTERRUPT_PRIORITY, true);
+}
+void ButtonHandler::lockbuttonIsr(void * handler_arg, cyhal_gpio_event_t event)
+{
+ portBASE_TYPE taskWoken = pdFALSE;
+ xTimerStartFromISR(buttonTimers[APP_LIGHT_BUTTON_IDX], &taskWoken);
+}
+
+void ButtonHandler::functionbuttonIsr(void * handler_arg, cyhal_gpio_event_t event)
+{
+ portBASE_TYPE taskWoken = pdFALSE;
+ xTimerStartFromISR(buttonTimers[APP_FUNCTION_BUTTON_IDX], &taskWoken);
+}
+
+void ButtonHandler::TimerCallback(TimerHandle_t xTimer)
+{
+ // Get the button index of the expired timer and call button event helper.
+ uint32_t timerId;
+ uint8_t buttonevent = 0;
+ timerId = (uint32_t) pvTimerGetTimerID(xTimer);
+ if (timerId)
+ {
+ buttonevent = cyhal_gpio_read(APP_FUNCTION_BUTTON);
+ }
+ else
+ {
+ buttonevent = cyhal_gpio_read(APP_LIGHT_BUTTON);
+ }
+ GetAppTask().ButtonEventHandler(timerId, (buttonevent) ? APP_BUTTON_PRESSED : APP_BUTTON_RELEASED);
+}
diff --git a/examples/lighting-app/p6/src/LightingManager.cpp b/examples/lighting-app/p6/src/LightingManager.cpp
new file mode 100644
index 00000000000000..b2db66900c8db6
--- /dev/null
+++ b/examples/lighting-app/p6/src/LightingManager.cpp
@@ -0,0 +1,225 @@
+/*
+ *
+ * Copyright (c) 2021 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 "LightingManager.h"
+
+#include "AppConfig.h"
+#include "AppTask.h"
+#include
+
+LightingManager LightingManager::sLight;
+
+TimerHandle_t sLightTimer;
+
+CHIP_ERROR LightingManager::Init()
+{
+ // Create FreeRTOS sw timer for light timer.
+ sLightTimer = xTimerCreate("lightTmr", // Just a text name, not used by the RTOS kernel
+ 1, // == default timer period (mS)
+ false, // no timer reload (==one-shot)
+ (void *) this, // init timer id = light obj context
+ TimerEventHandler // timer callback handler
+ );
+
+ if (sLightTimer == NULL)
+ {
+ P6_LOG("sLockTimer timer create failed");
+ return APP_ERROR_CREATE_TIMER_FAILED;
+ }
+
+ mState = kState_OffCompleted;
+ mAutoTurnOffTimerArmed = false;
+ mAutoTurnOff = false;
+ mAutoTurnOffDuration = 0;
+
+ return CHIP_NO_ERROR;
+}
+
+void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB)
+{
+ mActionInitiated_CB = aActionInitiated_CB;
+ mActionCompleted_CB = aActionCompleted_CB;
+}
+
+bool LightingManager::IsActionInProgress()
+{
+ return (mState == kState_OffInitiated || mState == kState_OnInitiated);
+}
+
+bool LightingManager::IsLightOn()
+{
+ return (mState == kState_OnCompleted);
+}
+
+void LightingManager::EnableAutoTurnOff(bool aOn)
+{
+ mAutoTurnOff = aOn;
+}
+
+void LightingManager::SetAutoTurnOffDuration(uint32_t aDurationInSecs)
+{
+ mAutoTurnOffDuration = aDurationInSecs;
+}
+
+bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction)
+{
+ bool action_initiated = false;
+ State_t new_state;
+
+ // Initiate Turn On/Off Action only when the previous one is complete.
+ if (mState == kState_OffCompleted && aAction == ON_ACTION)
+ {
+ action_initiated = true;
+
+ new_state = kState_OnInitiated;
+ }
+ else if (mState == kState_OnCompleted && aAction == OFF_ACTION)
+ {
+ action_initiated = true;
+
+ new_state = kState_OffInitiated;
+ }
+
+ if (action_initiated)
+ {
+ if (mAutoTurnOffTimerArmed && new_state == kState_OffInitiated)
+ {
+ // If auto turn off timer has been armed and someone initiates turning off,
+ // cancel the timer and continue as normal.
+ mAutoTurnOffTimerArmed = false;
+
+ CancelTimer();
+ }
+
+ StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS);
+
+ // Since the timer started successfully, update the state and trigger callback
+ mState = new_state;
+
+ if (mActionInitiated_CB)
+ {
+ mActionInitiated_CB(aAction, aActor);
+ }
+ }
+
+ return action_initiated;
+}
+
+void LightingManager::StartTimer(uint32_t aTimeoutMs)
+{
+ if (xTimerIsTimerActive(sLightTimer))
+ {
+ P6_LOG("app timer already started!");
+ CancelTimer();
+ }
+
+ // timer is not active, change its period to required value (== restart).
+ // FreeRTOS- Block for a maximum of 100 ticks if the change period command
+ // cannot immediately be sent to the timer command queue.
+ if (xTimerChangePeriod(sLightTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS)
+ {
+ P6_LOG("sLockTimer timer start() failed");
+ appError(APP_ERROR_START_TIMER_FAILED);
+ }
+}
+
+void LightingManager::CancelTimer(void)
+{
+ if (xTimerStop(sLightTimer, 0) == pdFAIL)
+ {
+ P6_LOG("sLightTimer stop() failed");
+ appError(APP_ERROR_STOP_TIMER_FAILED);
+ }
+}
+
+void LightingManager::TimerEventHandler(TimerHandle_t xTimer)
+{
+ // Get light obj context from timer id.
+ LightingManager * light = static_cast(pvTimerGetTimerID(xTimer));
+
+ // The timer event handler will be called in the context of the timer task
+ // once sLightTimer expires. Post an event to apptask queue with the actual handler
+ // so that the event can be handled in the context of the apptask.
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Timer;
+ event.TimerEvent.Context = light;
+ if (light->mAutoTurnOffTimerArmed)
+ {
+ event.Handler = AutoTurnOffTimerEventHandler;
+ }
+ else
+ {
+ event.Handler = ActuatorMovementTimerEventHandler;
+ }
+ GetAppTask().PostEvent(&event);
+}
+
+void LightingManager::AutoTurnOffTimerEventHandler(AppEvent * aEvent)
+{
+ LightingManager * light = static_cast(aEvent->TimerEvent.Context);
+ int32_t actor = 0;
+
+ // Make sure auto turn off timer is still armed.
+ if (!light->mAutoTurnOffTimerArmed)
+ {
+ return;
+ }
+
+ light->mAutoTurnOffTimerArmed = false;
+
+ P6_LOG("Auto Turn Off has been triggered!");
+
+ light->InitiateAction(actor, OFF_ACTION);
+}
+
+void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
+{
+ Action_t actionCompleted = INVALID_ACTION;
+
+ LightingManager * light = static_cast(aEvent->TimerEvent.Context);
+
+ if (light->mState == kState_OffInitiated)
+ {
+ light->mState = kState_OffCompleted;
+ actionCompleted = OFF_ACTION;
+ }
+ else if (light->mState == kState_OnInitiated)
+ {
+ light->mState = kState_OnCompleted;
+ actionCompleted = ON_ACTION;
+ }
+
+ if (actionCompleted != INVALID_ACTION)
+ {
+ if (light->mActionCompleted_CB)
+ {
+ light->mActionCompleted_CB(actionCompleted);
+ }
+
+ if (light->mAutoTurnOff && actionCompleted == ON_ACTION)
+ {
+ // Start the timer for auto turn off
+ light->StartTimer(light->mAutoTurnOffDuration * 1000);
+
+ light->mAutoTurnOffTimerArmed = true;
+
+ P6_LOG("Auto Turn off enabled. Will be triggered in %u seconds", light->mAutoTurnOffDuration);
+ }
+ }
+}
diff --git a/examples/lighting-app/p6/src/ZclCallbacks.cpp b/examples/lighting-app/p6/src/ZclCallbacks.cpp
new file mode 100644
index 00000000000000..8cb273ce51e3fd
--- /dev/null
+++ b/examples/lighting-app/p6/src/ZclCallbacks.cpp
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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 "LightingManager.h"
+
+#include
+#include
+#include
+#include
+
+using namespace ::chip;
+using namespace ::chip::app::Clusters;
+
+void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type,
+ uint16_t size, uint8_t * value)
+{
+ ClusterId clusterId = attributePath.mClusterId;
+ AttributeId attributeId = attributePath.mAttributeId;
+ ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId));
+
+ if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id)
+ {
+ LightMgr().InitiateAction(AppEvent::kEventType_Light, *value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION);
+ }
+ else if (clusterId == LevelControl::Id)
+ {
+ ChipLogProgress(Zcl,
+ "Level Control attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16 ", length %" PRIu16,
+ ChipLogValueMEI(attributeId), type, *value, size);
+
+ // WIP Apply attribute change to Light
+ }
+ else if (clusterId == ColorControl::Id)
+ {
+ ChipLogProgress(Zcl,
+ "Color Control attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16 ", length %" PRIu16,
+ ChipLogValueMEI(attributeId), type, *value, size);
+
+ // WIP Apply attribute change to Light
+ }
+ else if (clusterId == OnOffSwitchConfiguration::Id)
+ {
+ ChipLogProgress(Zcl,
+ "OnOff Switch Configuration attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16
+ ", length %" PRIu16,
+ ChipLogValueMEI(attributeId), type, *value, size);
+
+ // WIP Apply attribute change to Light
+ }
+ else if (clusterId == Identify::Id)
+ {
+ ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16 ", length %" PRIu16,
+ ChipLogValueMEI(attributeId), type, *value, size);
+ }
+}
+
+/** @brief OnOff Cluster Init
+ *
+ * This function is called when a specific cluster is initialized. It gives the
+ * application an opportunity to take care of cluster initialization procedures.
+ * It is called exactly once for each endpoint where cluster is present.
+ *
+ * @param endpoint Ver.: always
+ *
+ * TODO Issue #3841
+ * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster
+ * attributes to the default value.
+ * The logic here expects something similar to the deprecated Plugins callback
+ * emberAfPluginOnOffClusterServerPostInitCallback.
+ *
+ */
+void emberAfOnOffClusterInitCallback(EndpointId endpoint)
+{
+ // TODO: implement any additional Cluster Server init actions
+}
diff --git a/examples/lighting-app/p6/src/main.cpp b/examples/lighting-app/p6/src/main.cpp
new file mode 100644
index 00000000000000..7d493daff2a25e
--- /dev/null
+++ b/examples/lighting-app/p6/src/main.cpp
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright (c) 2021 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
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "AppConfig.h"
+#include "init_p6Platform.h"
+#include
+
+#ifdef HEAP_MONITORING
+#include "MemMonitoring.h"
+#endif
+
+using namespace ::chip;
+using namespace ::chip::Inet;
+using namespace ::chip::DeviceLayer;
+
+volatile int apperror_cnt;
+// ================================================================================
+// App Error
+//=================================================================================
+void appError(int err)
+{
+ P6_LOG("!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!", err);
+ portDISABLE_INTERRUPTS();
+ while (1)
+ ;
+}
+
+void appError(CHIP_ERROR error)
+{
+ appError(static_cast(error.AsInteger()));
+}
+
+// ================================================================================
+// FreeRTOS Callbacks
+// ================================================================================
+extern "C" void vApplicationIdleHook(void)
+{
+ // FreeRTOS Idle callback
+}
+
+// ================================================================================
+// Main Code
+// ================================================================================
+int main(void)
+{
+ init_p6Platform();
+
+#ifdef HEAP_MONITORING
+ MemMonitoring::startHeapMonitoring();
+#endif
+
+ P6_LOG("==================================================\r\n");
+ P6_LOG("chip-p6-lighting-example starting\r\n");
+ P6_LOG("==================================================\r\n");
+
+ // Init Chip memory management before the stack
+ chip::Platform::MemoryInit();
+
+ CHIP_ERROR ret = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
+ if (ret != CHIP_NO_ERROR)
+ {
+ P6_LOG("PersistedStorage::KeyValueStoreMgrImpl().Init() failed");
+ appError(ret);
+ }
+
+ ret = PlatformMgr().InitChipStack();
+ if (ret != CHIP_NO_ERROR)
+ {
+ P6_LOG("PlatformMgr().InitChipStack() failed");
+ appError(ret);
+ }
+ chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName("P6_LIGHT");
+ P6_LOG("Starting Platform Manager Event Loop");
+ ret = PlatformMgr().StartEventLoopTask();
+ if (ret != CHIP_NO_ERROR)
+ {
+ P6_LOG("PlatformMgr().StartEventLoopTask() failed");
+ appError(ret);
+ }
+ ret = GetAppTask().StartAppTask();
+ if (ret != CHIP_NO_ERROR)
+ {
+ P6_LOG("GetAppTask().Init() failed");
+ appError(ret);
+ }
+ /* Start the FreeRTOS scheduler */
+ vTaskStartScheduler();
+
+ chip::Platform::MemoryShutdown();
+ PlatformMgr().StopEventLoopTask();
+ PlatformMgr().Shutdown();
+
+ // Should never get here.
+ P6_LOG("vTaskStartScheduler() failed");
+ appError(ret);
+}
diff --git a/examples/lighting-app/p6/third_party/connectedhomeip b/examples/lighting-app/p6/third_party/connectedhomeip
new file mode 120000
index 00000000000000..c866b86874994d
--- /dev/null
+++ b/examples/lighting-app/p6/third_party/connectedhomeip
@@ -0,0 +1 @@
+../../../..
\ No newline at end of file
diff --git a/examples/lock-app/p6/include/AppTask.h b/examples/lock-app/p6/include/AppTask.h
index 44718ea75a424a..e4da2aba0aa403 100644
--- a/examples/lock-app/p6/include/AppTask.h
+++ b/examples/lock-app/p6/include/AppTask.h
@@ -80,7 +80,7 @@ class AppTask
kInvalid
};
- Function mFunction = Function::kInvalid;
+ Function mFunction = Function::kNoneSelected;
bool mFunctionTimerActive = false;
bool mSyncClusterToButtonAction = false;
diff --git a/examples/lock-app/p6/include/BoltLockManager.h b/examples/lock-app/p6/include/BoltLockManager.h
index 34aa815af65f13..4c0093b3efd592 100644
--- a/examples/lock-app/p6/include/BoltLockManager.h
+++ b/examples/lock-app/p6/include/BoltLockManager.h
@@ -59,7 +59,7 @@ class BoltLockManager
private:
friend BoltLockManager & BoltLockMgr(void);
- State mState = State::kLockingCompleted;
+ State mState = State::kUnlockingCompleted;
Callback_fn_initiated mActionInitiated_CB;
Callback_fn_completed mActionCompleted_CB;
diff --git a/examples/lock-app/p6/src/BoltLockManager.cpp b/examples/lock-app/p6/src/BoltLockManager.cpp
index 6499a2104d139e..8f7ee9dd5f1fdf 100644
--- a/examples/lock-app/p6/src/BoltLockManager.cpp
+++ b/examples/lock-app/p6/src/BoltLockManager.cpp
@@ -43,7 +43,7 @@ CHIP_ERROR BoltLockManager::Init()
appError(APP_ERROR_CREATE_TIMER_FAILED);
}
- mState = State::kLockingCompleted;
+ mState = State::kUnlockingCompleted;
mAutoLockTimerArmed = false;
mAutoRelock = false;
mAutoLockDuration = 0;
diff --git a/examples/lock-app/p6/src/main.cpp b/examples/lock-app/p6/src/main.cpp
index 6fe0298cad4c34..aceba9a2183528 100644
--- a/examples/lock-app/p6/src/main.cpp
+++ b/examples/lock-app/p6/src/main.cpp
@@ -79,9 +79,15 @@ int main(void)
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- // chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
- CHIP_ERROR ret = PlatformMgr().InitChipStack();
+ CHIP_ERROR ret = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
+ if (ret != CHIP_NO_ERROR)
+ {
+ P6_LOG("PersistedStorage::KeyValueStoreMgrImpl().Init() failed");
+ appError(ret);
+ }
+
+ ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
{
P6_LOG("PlatformMgr().InitChipStack() failed");
diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py
index e013bd23a998a8..7d5adf9c0f593f 100644
--- a/scripts/build/build/targets.py
+++ b/scripts/build/build/targets.py
@@ -229,6 +229,7 @@ def InfineonTargets():
yield target.Extend('p6-lock', board=InfineonBoard.P6BOARD, app=InfineonApp.LOCK)
yield target.Extend('p6-all-clusters', board=InfineonBoard.P6BOARD, app=InfineonApp.ALL_CLUSTERS)
+ yield target.Extend('p6-light', board=InfineonBoard.P6BOARD, app=InfineonApp.LIGHT)
ALL = []
diff --git a/scripts/build/builders/infineon.py b/scripts/build/builders/infineon.py
index 7a737c3dc83b67..3c5f1f828afa37 100644
--- a/scripts/build/builders/infineon.py
+++ b/scripts/build/builders/infineon.py
@@ -20,11 +20,14 @@
class InfineonApp(Enum):
LOCK = auto()
+ LIGHT = auto()
ALL_CLUSTERS = auto()
def ExampleName(self):
if self == InfineonApp.LOCK:
return 'lock-app'
+ elif self == InfineonApp.LIGHT:
+ return 'lighting-app'
elif self == InfineonApp.ALL_CLUSTERS:
return 'all-clusters-app'
else:
@@ -33,6 +36,8 @@ def ExampleName(self):
def AppNamePrefix(self):
if self == InfineonApp.LOCK:
return 'chip-p6-lock-example'
+ elif self == InfineonApp.LIGHT:
+ return 'chip-p6-lighting-example'
elif self == InfineonApp.ALL_CLUSTERS:
return 'chip-p6-clusters-example'
else:
@@ -43,6 +48,8 @@ def FlashBundleName(self):
return 'lock_app.flashbundle.txt'
elif self == InfineonApp.ALL_CLUSTERS:
return 'clusters_app.flashbundle.txt'
+ elif self == InfineonApp.LIGHT:
+ return 'light_app.flashbundle.txt'
else:
raise Exception('Unknown app type: %r' % self)
diff --git a/scripts/build/testdata/all_targets_except_host.txt b/scripts/build/testdata/all_targets_except_host.txt
index ba1c11063b90d2..29b96163e85a39 100644
--- a/scripts/build/testdata/all_targets_except_host.txt
+++ b/scripts/build/testdata/all_targets_except_host.txt
@@ -27,6 +27,7 @@ esp32-m5stack-all-clusters-ipv6only
esp32-m5stack-all-clusters-rpc
esp32-m5stack-all-clusters-rpc-ipv6only
infineon-p6-all-clusters
+infineon-p6-light
infineon-p6-lock
mbed-CY8CPROTO_062_4343W-all-clusters-debug (NOGLOB: Compile only for debugging purpose - https://os.mbed.com/docs/mbed-os/latest/program-setup/build-profiles-and-rules.html)
mbed-CY8CPROTO_062_4343W-all-clusters-develop (NOGLOB: Compile only for debugging purpose - https://os.mbed.com/docs/mbed-os/latest/program-setup/build-profiles-and-rules.html)
diff --git a/scripts/build/testdata/build_all_except_host.txt b/scripts/build/testdata/build_all_except_host.txt
index 734f2b84915638..fcd76ac888f211 100644
--- a/scripts/build/testdata/build_all_except_host.txt
+++ b/scripts/build/testdata/build_all_except_host.txt
@@ -272,6 +272,9 @@ idf.py -C examples/all-clusters-app/esp32 -B {out}/esp32-m5stack-all-clusters-rp
# Generating infineon-p6-all-clusters
gn gen --check --fail-on-unused-args --root={root}/examples/all-clusters-app/p6 '--args=p6_board="CY8CKIT-062S2-43012"' {out}/infineon-p6-all-clusters
+# Generating infineon-p6-light
+gn gen --check --fail-on-unused-args --root={root}/examples/lighting-app/p6 '--args=p6_board="CY8CKIT-062S2-43012"' {out}/infineon-p6-light
+
# Generating infineon-p6-lock
gn gen --check --fail-on-unused-args --root={root}/examples/lock-app/p6 '--args=p6_board="CY8CKIT-062S2-43012"' {out}/infineon-p6-lock
@@ -679,6 +682,9 @@ idf.py -C examples/all-clusters-app/esp32 -B {out}/esp32-m5stack-all-clusters-rp
# Building infineon-p6-all-clusters
ninja -C {out}/infineon-p6-all-clusters
+# Building infineon-p6-light
+ninja -C {out}/infineon-p6-light
+
# Building infineon-p6-lock
ninja -C {out}/infineon-p6-lock
diff --git a/scripts/build/testdata/glob_star_targets_except_host.txt b/scripts/build/testdata/glob_star_targets_except_host.txt
index fce80642e1562a..c14ea7f7f87879 100644
--- a/scripts/build/testdata/glob_star_targets_except_host.txt
+++ b/scripts/build/testdata/glob_star_targets_except_host.txt
@@ -27,6 +27,7 @@ esp32-m5stack-all-clusters-ipv6only
esp32-m5stack-all-clusters-rpc
esp32-m5stack-all-clusters-rpc-ipv6only
infineon-p6-all-clusters
+infineon-p6-light
infineon-p6-lock
mbed-CY8CPROTO_062_4343W-all-clusters-release
mbed-CY8CPROTO_062_4343W-light-release
diff --git a/src/platform/P6/ConfigurationManagerImpl.cpp b/src/platform/P6/ConfigurationManagerImpl.cpp
index 067ca9ab4f749b..ef408fec77decd 100644
--- a/src/platform/P6/ConfigurationManagerImpl.cpp
+++ b/src/platform/P6/ConfigurationManagerImpl.cpp
@@ -46,6 +46,28 @@ CHIP_ERROR ConfigurationManagerImpl::Init()
{
CHIP_ERROR err = CHIP_NO_ERROR;
bool failSafeArmed;
+ uint32_t rebootCount;
+
+ if (P6Config::ConfigValueExists(P6Config::kCounterKey_RebootCount))
+ {
+ err = GetRebootCount(rebootCount);
+ SuccessOrExit(err);
+
+ err = StoreRebootCount(rebootCount + 1);
+ SuccessOrExit(err);
+ }
+ else
+ {
+ // The first boot after factory reset of the Node.
+ err = StoreRebootCount(1);
+ SuccessOrExit(err);
+ }
+
+ if (!P6Config::ConfigValueExists(P6Config::kCounterKey_TotalOperationalHours))
+ {
+ err = StoreTotalOperationalHours(0);
+ SuccessOrExit(err);
+ }
// Initialize the generic implementation base class.
err = Internal::GenericConfigurationManagerImpl::Init();
@@ -58,9 +80,30 @@ CHIP_ERROR ConfigurationManagerImpl::Init()
InitiateFactoryReset();
}
+exit:
return err;
}
+CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount)
+{
+ return ReadConfigValue(P6Config::kCounterKey_RebootCount, rebootCount);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount)
+{
+ return WriteConfigValue(P6Config::kCounterKey_RebootCount, rebootCount);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
+{
+ return ReadConfigValue(P6Config::kCounterKey_TotalOperationalHours, totalOperationalHours);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours)
+{
+ return WriteConfigValue(P6Config::kCounterKey_TotalOperationalHours, totalOperationalHours);
+}
+
CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf)
{
CHIP_ERROR err = CHIP_NO_ERROR;
diff --git a/src/platform/P6/ConfigurationManagerImpl.h b/src/platform/P6/ConfigurationManagerImpl.h
index 8aae8d9227f44c..8da0df2b060579 100644
--- a/src/platform/P6/ConfigurationManagerImpl.h
+++ b/src/platform/P6/ConfigurationManagerImpl.h
@@ -38,6 +38,10 @@ namespace DeviceLayer {
class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl
{
public:
+ CHIP_ERROR GetRebootCount(uint32_t & rebootCount) override;
+ CHIP_ERROR StoreRebootCount(uint32_t rebootCount) override;
+ CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override;
+ CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours) override;
// This returns an instance of this class.
static ConfigurationManagerImpl & GetDefaultInstance();
diff --git a/src/platform/P6/DiagnosticDataProviderImpl.cpp b/src/platform/P6/DiagnosticDataProviderImpl.cpp
index 02593d420e2501..3187f917a11784 100644
--- a/src/platform/P6/DiagnosticDataProviderImpl.cpp
+++ b/src/platform/P6/DiagnosticDataProviderImpl.cpp
@@ -23,9 +23,12 @@
#include
+#include "cyhal_system.h"
+#include
#include
#include
#include
+#include
namespace chip {
namespace DeviceLayer {
@@ -36,5 +39,509 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance()
return sInstance;
}
+CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree)
+{
+ heap_info_t heap;
+ Internal::P6Utils::heap_usage(&heap);
+ currentHeapFree = static_cast(heap.HeapFree);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed)
+{
+ // Calculate the Heap used based on Total heap - Free heap
+ heap_info_t heap;
+ Internal::P6Utils::heap_usage(&heap);
+ currentHeapUsed = static_cast(heap.HeapUsed);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark)
+{
+ heap_info_t heap;
+ Internal::P6Utils::heap_usage(&heap);
+ currentHeapHighWatermark = static_cast(heap.HeapMax);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount)
+{
+ uint32_t count = 0;
+
+ CHIP_ERROR err = ConfigurationMgr().GetRebootCount(count);
+
+ if (err == CHIP_NO_ERROR)
+ {
+ VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ rebootCount = static_cast(count);
+ }
+
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetUpTime(uint64_t & upTime)
+{
+ System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp();
+ System::Clock::Timestamp startTime = PlatformMgrImpl().GetStartTime();
+
+ if (currentTime >= startTime)
+ {
+ upTime = std::chrono::duration_cast(currentTime - startTime).count();
+ return CHIP_NO_ERROR;
+ }
+
+ return CHIP_ERROR_INVALID_TIME;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
+{
+ uint64_t upTime = 0;
+
+ if (GetUpTime(upTime) == CHIP_NO_ERROR)
+ {
+ uint32_t totalHours = 0;
+ if (ConfigurationMgr().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR)
+ {
+ /* uptime is terms of seconds and dividing it by 3600 to calculate
+ * totalOperationalHours in hours.
+ */
+ VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ totalOperationalHours = totalHours + static_cast(upTime / 3600);
+ return CHIP_NO_ERROR;
+ }
+ }
+
+ return CHIP_ERROR_INVALID_TIME;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(uint8_t & bootReason)
+{
+ cyhal_reset_reason_t reset_reason = cyhal_system_get_reset_reason();
+ if (reset_reason == CYHAL_SYSTEM_RESET_NONE)
+ {
+ bootReason = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT;
+ }
+ else if (reset_reason == CYHAL_SYSTEM_RESET_WDT)
+ {
+ bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET;
+ }
+ else if (reset_reason == CYHAL_SYSTEM_RESET_SOFT)
+ {
+ bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET;
+ }
+ else if (reset_reason == CYHAL_SYSTEM_RESET_HIB_WAKEUP)
+ {
+ bootReason = EMBER_ZCL_BOOT_REASON_TYPE_HARDWARE_WATCHDOG_RESET;
+ }
+ else
+ {
+ bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
+ }
+ return CHIP_NO_ERROR;
+}
+
+void DiagnosticDataProviderImpl::UpdateoffPremiseService(bool ipv4service, bool ipv6service)
+{
+ /* Enable/Disable IPv4 Off Premise Services */
+ mipv4_offpremise = ipv4service;
+
+ /* Enable/Disable IPv6 Off Premise Services */
+ mipv6_offpremise = ipv6service;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** netifpp)
+{
+ struct netif * net_interface;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ NetworkInterface * ifp = new NetworkInterface();
+ net_interface = cy_lwip_get_interface(CY_LWIP_STA_NW_INTERFACE);
+ if (net_interface)
+ {
+ /* Update Network Interface list */
+ ifp->name = CharSpan(net_interface->name, strlen(net_interface->name));
+ ifp->fabricConnected = net_interface->flags & NETIF_FLAG_LINK_UP;
+ ifp->type = EMBER_ZCL_INTERFACE_TYPE_WI_FI;
+ ifp->offPremiseServicesReachableIPv4 = mipv4_offpremise;
+ ifp->offPremiseServicesReachableIPv6 = mipv6_offpremise;
+ ifp->hardwareAddress = ByteSpan(net_interface->hwaddr, net_interface->hwaddr_len);
+ }
+ *netifpp = ifp;
+
+ return err;
+}
+
+void DiagnosticDataProviderImpl::ReleaseNetworkInterfaces(NetworkInterface * netifp)
+{
+ while (netifp)
+ {
+ NetworkInterface * del = netifp;
+ netifp = netifp->Next;
+ delete del;
+ }
+}
+
+/* Wi-Fi Diagnostics Cluster Support */
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiBssId(ByteSpan & value)
+{
+ cy_wcm_associated_ap_info_t ap_info;
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ ChipLogError(DeviceLayer, "cy_wcm_get_associated_ap_info\r\n");
+ result = cy_wcm_get_associated_ap_info(&ap_info);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_associated_ap_info failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ memcpy(mWiFiMacAddress, ap_info.BSSID, CY_WCM_MAC_ADDR_LEN);
+ value = ByteSpan(mWiFiMacAddress, CY_WCM_MAC_ADDR_LEN);
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiSecurityType(uint8_t & securityType)
+{
+ cy_wcm_associated_ap_info_t ap_info;
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ result = cy_wcm_get_associated_ap_info(&ap_info);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_associated_ap_info failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ if (ap_info.security == CY_WCM_SECURITY_OPEN)
+ {
+ securityType = EMBER_ZCL_SECURITY_TYPE_NONE;
+ }
+ else if (ap_info.security & WPA3_SECURITY)
+ {
+ securityType = EMBER_ZCL_SECURITY_TYPE_WPA3;
+ }
+ else if (ap_info.security & WPA2_SECURITY)
+ {
+ securityType = EMBER_ZCL_SECURITY_TYPE_WPA2;
+ }
+ else if (ap_info.security & WPA_SECURITY)
+ {
+ securityType = EMBER_ZCL_SECURITY_TYPE_WPA;
+ }
+ else if (ap_info.security & WEP_ENABLED)
+ {
+ securityType = EMBER_ZCL_SECURITY_TYPE_WEP;
+ }
+ else
+ {
+ securityType = EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED;
+ }
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiVersion(uint8_t & wiFiVersion)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ wl_bss_info_t bss_info;
+ whd_security_t security;
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+
+ if (whd_wifi_get_ap_info(whd_ifs[CY_WCM_INTERFACE_TYPE_STA], &bss_info, &security) != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "whd_wifi_get_ap_info failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ /* VHT Capable bit variable is not defined in whd and has to use the reserved bit */
+ if (bss_info.reserved[0])
+ {
+ wiFiVersion = EMBER_ZCL_WI_FI_VERSION_TYPE_802__11AC;
+ }
+ /* HT Capable */
+ else if (bss_info.n_cap)
+ {
+ wiFiVersion = EMBER_ZCL_WI_FI_VERSION_TYPE_802__11N;
+ }
+ /* 11g Capable */
+ else
+ {
+ wiFiVersion = EMBER_ZCL_WI_FI_VERSION_TYPE_802__11G;
+ }
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiChannelNumber(uint16_t & channelNumber)
+{
+ cy_wcm_associated_ap_info_t ap_info;
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ result = cy_wcm_get_associated_ap_info(&ap_info);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_associated_ap_info failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ channelNumber = ap_info.channel;
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiRssi(int8_t & rssi)
+{
+ cy_wcm_associated_ap_info_t ap_info;
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ result = cy_wcm_get_associated_ap_info(&ap_info);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_associated_ap_info failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ rssi = ap_info.signal_strength;
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiBeaconRxCount(uint32_t & beaconRxCount)
+{
+ uint64_t count;
+ ReturnErrorOnFailure(WiFiCounters(WiFiStatsCountType::kWiFiBeaconRxCount, count));
+
+ count -= mBeaconRxCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ beaconRxCount = static_cast(count);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiBeaconLostCount(uint32_t & beaconLostCount)
+{
+ uint64_t count;
+ ReturnErrorOnFailure(WiFiCounters(WiFiStatsCountType::kWiFiBeaconLostCount, count));
+
+ count -= mBeaconLostCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ beaconLostCount = static_cast(count);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiCurrentMaxRate(uint64_t & currentMaxRate)
+{
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ cy_wcm_wlan_statistics_t stats;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ uint64_t count;
+
+ result = cy_wcm_get_wlan_statistics(CY_WCM_INTERFACE_TYPE_STA, &stats);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_wlan_statistics failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ count = stats.tx_bitrate * PHYRATE_KPBS_BYTES_PER_SEC;
+ currentMaxRate = static_cast(count);
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount)
+{
+ uint64_t count;
+ ReturnErrorOnFailure(WiFiCounters(WiFiStatsCountType::kWiFiMulticastPacketRxCount, count));
+
+ count -= mPacketMulticastRxCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ packetMulticastRxCount = static_cast(count);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount)
+{
+ uint64_t count;
+ ReturnErrorOnFailure(WiFiCounters(WiFiStatsCountType::kWiFiMulticastPacketTxCount, count));
+
+ count -= mPacketMulticastTxCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ packetMulticastTxCount = static_cast(count);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount)
+{
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ cy_wcm_wlan_statistics_t stats;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ uint64_t count;
+
+ result = cy_wcm_get_wlan_statistics(CY_WCM_INTERFACE_TYPE_STA, &stats);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_wlan_statistics failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+ count = stats.rx_packets;
+ count -= mPacketUnicastRxCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+
+ packetUnicastRxCount = static_cast(count);
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount)
+{
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ cy_wcm_wlan_statistics_t stats;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ uint64_t count;
+
+ result = cy_wcm_get_wlan_statistics(CY_WCM_INTERFACE_TYPE_STA, &stats);
+ if (result != CY_RSLT_SUCCESS)
+ {
+ ChipLogError(DeviceLayer, "cy_wcm_get_wlan_statistics failed: %d", (int) result);
+ SuccessOrExit(CHIP_ERROR_INTERNAL);
+ }
+
+ count = stats.tx_packets;
+ count -= mPacketUnicastTxCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+
+ packetUnicastTxCount = static_cast(count);
+
+exit:
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiOverrunCount(uint64_t & overrunCount)
+{
+ uint64_t count;
+ ReturnErrorOnFailure(WiFiCounters(WiFiStatsCountType::kWiFiOverrunCount, count));
+
+ count -= mOverrunCount;
+ VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ overrunCount = static_cast(count);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::ResetWiFiNetworkDiagnosticsCounts()
+{
+ uint64_t count;
+ return WiFiCounters(WiFiStatsCountType::kWiFiResetCount, count);
+}
+
+void DiagnosticDataProviderImpl::ReadCounters(WiFiStatsCountType Counttype, uint64_t & count, wl_cnt_ver_30_t * cnt,
+ wl_cnt_ge40mcst_v1_t * cnt_ge40)
+{
+ if ((!cnt) || (!cnt_ge40))
+ {
+ ChipLogError(DeviceLayer, "ReadCounters failed due to NULL Pointers passed");
+ return;
+ }
+ /* Populate count based in the Counttype */
+ switch (Counttype)
+ {
+ case WiFiStatsCountType::kWiFiUnicastPacketRxCount:
+ count = cnt->rxfrag;
+ break;
+ case WiFiStatsCountType::kWiFiUnicastPacketTxCount:
+ count = cnt->txfrag;
+ break;
+ case WiFiStatsCountType::kWiFiMulticastPacketRxCount:
+ count = cnt->rxmulti;
+ break;
+ case WiFiStatsCountType::kWiFiMulticastPacketTxCount:
+ count = cnt->txmulti;
+ break;
+ case WiFiStatsCountType::kWiFiOverrunCount:
+ count = cnt->txnobuf + cnt->rxnobuf;
+ break;
+ case WiFiStatsCountType::kWiFiBeaconLostCount:
+ count = cnt_ge40->missbcn_dbg;
+ break;
+ case WiFiStatsCountType::kWiFiBeaconRxCount:
+ count = cnt_ge40->rxbeaconmbss;
+ break;
+ /* Update below variables during reset counts command so that next count read will be
+ * starting from these values.
+ */
+ case WiFiStatsCountType::kWiFiResetCount:
+ mBeaconRxCount = cnt_ge40->rxbeaconmbss;
+ mBeaconLostCount = cnt_ge40->missbcn_dbg;
+ mPacketMulticastRxCount = cnt->rxmulti;
+ mPacketMulticastTxCount = cnt->txmulti;
+ mPacketUnicastRxCount = cnt->rxfrag;
+ mPacketUnicastTxCount = cnt->txfrag;
+ mOverrunCount = cnt->txnobuf + cnt->rxnobuf;
+ break;
+ default:
+ ChipLogError(DeviceLayer, "ReadCounters type not handled : %d", (int) Counttype);
+ break;
+ }
+}
+void DiagnosticDataProviderImpl::xtlv_buffer_parsing(const uint8_t * tlv_buf, uint16_t buflen, WiFiStatsCountType Counttype,
+ uint64_t & count)
+{
+ wl_cnt_ver_30_t cnt;
+ wl_cnt_ge40mcst_v1_t cnt_ge40;
+
+ /* parse the tlv buffer and populate the cnt and cnt_ge40 buffer with the counter values */
+ Internal::P6Utils::unpack_xtlv_buf(tlv_buf, buflen, &cnt, &cnt_ge40);
+
+ /* Read the counter based on the Counttype passed */
+ ReadCounters(Counttype, count, &cnt, &cnt_ge40);
+ return;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::WiFiCounters(WiFiStatsCountType type, uint64_t & count)
+{
+ whd_buffer_t buffer;
+ whd_buffer_t response;
+ wl_cnt_info_t * wl_cnt_info = NULL;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ /* Read wl counters iovar using WHD APIs */
+ whd_cdc_get_iovar_buffer(whd_ifs[CY_WCM_INTERFACE_TYPE_STA]->whd_driver, &buffer, WLC_IOCTL_MEDLEN, IOVAR_STR_COUNTERS);
+ whd_cdc_send_iovar(whd_ifs[CY_WCM_INTERFACE_TYPE_STA], CDC_GET, buffer, &response);
+ wl_cnt_info =
+ (wl_cnt_info_t *) whd_buffer_get_current_piece_data_pointer(whd_ifs[CY_WCM_INTERFACE_TYPE_STA]->whd_driver, response);
+
+ /* Parse the buffer only for Counter Version 30 */
+ if (wl_cnt_info->version == WL_CNT_VER_30)
+ {
+ /* 43012 board - Process xtlv buffer data to get statistics */
+ uint8_t * cntdata;
+ cntdata = (uint8_t *) malloc(wl_cnt_info->datalen);
+
+ CHK_CNTBUF_DATALEN(wl_cnt_info, WLC_IOCTL_MEDLEN);
+ if (cntdata == NULL)
+ {
+ return CHIP_ERROR_INTERNAL;
+ }
+ /* Allocate the memory for buffer */
+ memcpy(cntdata, wl_cnt_info->data, wl_cnt_info->datalen);
+
+ /* parse the xtlv wl counters data */
+ xtlv_buffer_parsing(cntdata, wl_cnt_info->datalen, type, count);
+
+ /* Free the memory */
+ free(cntdata);
+ }
+ return err;
+}
+
} // namespace DeviceLayer
} // namespace chip
diff --git a/src/platform/P6/DiagnosticDataProviderImpl.h b/src/platform/P6/DiagnosticDataProviderImpl.h
index 731f445fec8671..b15456ebc8351b 100644
--- a/src/platform/P6/DiagnosticDataProviderImpl.h
+++ b/src/platform/P6/DiagnosticDataProviderImpl.h
@@ -22,7 +22,34 @@
#pragma once
+#include
+
+#include "whd.h"
+#include "whd_buffer_api.h"
+#include "whd_network_types.h"
+#include "whd_wifi_api.h"
+#include "whd_wlioctl.h"
+#include
#include
+#include
+
+#define PHYRATE_KPBS_BYTES_PER_SEC 125
+
+/* WiFi Counters */
+enum class WiFiStatsCountType
+{
+ kWiFiBeaconLostCount,
+ kWiFiBeaconRxCount,
+ kWiFiUnicastPacketRxCount,
+ kWiFiUnicastPacketTxCount,
+ kWiFiMulticastPacketRxCount,
+ kWiFiMulticastPacketTxCount,
+ kWiFiOverrunCount,
+ kWiFiResetCount
+};
+
+#define MAX_WHD_INTERFACE (2)
+extern whd_interface_t whd_ifs[MAX_WHD_INTERFACE];
namespace chip {
namespace DeviceLayer {
@@ -34,6 +61,56 @@ class DiagnosticDataProviderImpl : public DiagnosticDataProvider
{
public:
static DiagnosticDataProviderImpl & GetDefaultInstance();
+
+ // ===== Methods that implement the PlatformManager abstract interface.
+
+ CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override;
+ CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override;
+ CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override;
+
+ CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override;
+ CHIP_ERROR GetUpTime(uint64_t & upTime) override;
+ CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override;
+ CHIP_ERROR GetBootReason(uint8_t & bootReason) override;
+ CHIP_ERROR GetNetworkInterfaces(NetworkInterface ** netifpp) override;
+ void ReleaseNetworkInterfaces(NetworkInterface * netifp) override;
+
+ CHIP_ERROR GetWiFiBssId(ByteSpan & BssId) override;
+ CHIP_ERROR GetWiFiSecurityType(uint8_t & securityType) override;
+ CHIP_ERROR GetWiFiVersion(uint8_t & wifiVersion) override;
+ CHIP_ERROR GetWiFiChannelNumber(uint16_t & channelNumber) override;
+ CHIP_ERROR GetWiFiRssi(int8_t & rssi) override;
+ CHIP_ERROR GetWiFiBeaconRxCount(uint32_t & beaconRxCount) override;
+ CHIP_ERROR GetWiFiBeaconLostCount(uint32_t & beaconLostCount) override;
+ CHIP_ERROR GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount) override;
+ CHIP_ERROR GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount) override;
+ CHIP_ERROR GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount) override;
+ CHIP_ERROR GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount) override;
+ CHIP_ERROR GetWiFiCurrentMaxRate(uint64_t & currentMaxRate) override;
+ CHIP_ERROR GetWiFiOverrunCount(uint64_t & overrunCount) override;
+ CHIP_ERROR ResetWiFiNetworkDiagnosticsCounts() override;
+ CHIP_ERROR WiFiCounters(WiFiStatsCountType type, uint64_t & count);
+ void xtlv_buffer_parsing(const uint8_t * tlv_buf, uint16_t buflen, WiFiStatsCountType Counttype, uint64_t & count);
+ void ReadCounters(WiFiStatsCountType Counttype, uint64_t & count, wl_cnt_ver_30_t * cnt, wl_cnt_ge40mcst_v1_t * cnt_ge40);
+ /* Function to update ipv4 and ipv6 off premise service capability bit */
+ void UpdateoffPremiseService(bool ipv4service, bool ipv6service);
+ /* These variables will be set to 0 during start up and will be updated when reset-counts
+ * zcl command is received.
+ * These are considered as base for below attributes of WiFi Diagnostics Cluster:
+ * BeaconLostCount, BeaconRxCount, PacketMulticastRxCount, PacketMulticastTxCount,
+ * PacketUnicastRxCount, PacketUnicastTxCount, OverrunCount.
+ * Each attributes read will be difference of WLAN counters minus equivalent variables below.
+ */
+ uint32_t mBeaconRxCount = 0;
+ uint32_t mBeaconLostCount = 0;
+ uint32_t mPacketMulticastRxCount = 0;
+ uint32_t mPacketMulticastTxCount = 0;
+ uint32_t mPacketUnicastRxCount = 0;
+ uint32_t mPacketUnicastTxCount = 0;
+ uint64_t mOverrunCount = 0;
+ uint8_t mWiFiMacAddress[CY_WCM_MAC_ADDR_LEN];
+ bool mipv4_offpremise = false;
+ bool mipv6_offpremise = false;
};
} // namespace DeviceLayer
diff --git a/src/platform/P6/KeyValueStoreManagerImpl.cpp b/src/platform/P6/KeyValueStoreManagerImpl.cpp
index 13b09abc32b4d3..2cbda30f38dd7f 100644
--- a/src/platform/P6/KeyValueStoreManagerImpl.cpp
+++ b/src/platform/P6/KeyValueStoreManagerImpl.cpp
@@ -34,10 +34,12 @@ namespace PersistedStorage {
KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance;
-KeyValueStoreManagerImpl::KeyValueStoreManagerImpl()
+CHIP_ERROR KeyValueStoreManagerImpl::Init()
{
cy_rslt_t result = mtb_key_value_store_init(&kvstore_obj);
init_success = (CY_RSLT_SUCCESS == result) ? true : false;
+
+ return ConvertCyResultToChip(result);
}
CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
diff --git a/src/platform/P6/KeyValueStoreManagerImpl.h b/src/platform/P6/KeyValueStoreManagerImpl.h
index fb8b62c735fc4d..29515f28218c67 100644
--- a/src/platform/P6/KeyValueStoreManagerImpl.h
+++ b/src/platform/P6/KeyValueStoreManagerImpl.h
@@ -37,7 +37,7 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager
friend class KeyValueStoreManager;
public:
- KeyValueStoreManagerImpl();
+ CHIP_ERROR Init();
CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0) const;
CHIP_ERROR _Delete(const char * key);
CHIP_ERROR _Put(const char * key, const void * value, size_t value_size);
diff --git a/src/platform/P6/P6Config.cpp b/src/platform/P6/P6Config.cpp
index 51665960ee91d3..71194b6ac4011f 100644
--- a/src/platform/P6/P6Config.cpp
+++ b/src/platform/P6/P6Config.cpp
@@ -71,6 +71,11 @@ const P6Config::Key P6Config::kConfigKey_LastUsedEpochKeyId = { kConfigNamespace
const P6Config::Key P6Config::kConfigKey_FailSafeArmed = { kConfigNamespace_ChipConfig, "fail-safe-armed" };
const P6Config::Key P6Config::kConfigKey_WiFiStationSecType = { kConfigNamespace_ChipConfig, "sta-sec-type" };
+// Keys stored in the Chip-counters namespace
+const P6Config::Key P6Config::kCounterKey_RebootCount = { kConfigNamespace_ChipCounters, "reboot-count" };
+const P6Config::Key P6Config::kCounterKey_UpTime = { kConfigNamespace_ChipCounters, "up-time" };
+const P6Config::Key P6Config::kCounterKey_TotalOperationalHours = { kConfigNamespace_ChipCounters, "total-hours" };
+
// Prefix used for keys that contain Chip group encryption keys.
const char P6Config::kGroupKeyNamePrefix[] = "gk-";
diff --git a/src/platform/P6/P6Config.h b/src/platform/P6/P6Config.h
index 280a6d7217d2f7..7acfb5e13a5f07 100644
--- a/src/platform/P6/P6Config.h
+++ b/src/platform/P6/P6Config.h
@@ -75,6 +75,9 @@ class P6Config
static const Key kConfigKey_RegulatoryLocation;
static const Key kConfigKey_CountryCode;
static const Key kConfigKey_Breadcrumb;
+ static const Key kCounterKey_RebootCount;
+ static const Key kCounterKey_UpTime;
+ static const Key kCounterKey_TotalOperationalHours;
static const char kGroupKeyNamePrefix[];
diff --git a/src/platform/P6/P6Utils.cpp b/src/platform/P6/P6Utils.cpp
index 578c47b12be065..3e08a3e6becddc 100644
--- a/src/platform/P6/P6Utils.cpp
+++ b/src/platform/P6/P6Utils.cpp
@@ -42,6 +42,7 @@
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
+#include
using namespace ::chip::DeviceLayer::Internal;
using chip::DeviceLayer::Internal::DeviceNetworkInfo;
@@ -675,3 +676,130 @@ CHIP_ERROR P6Utils::ping_init(void)
}
return err;
}
+
+static int xtlv_hdr_size(uint16_t opts, const uint8_t ** data)
+{
+ int len = (int) OFFSETOF(xtlv_t, data); /* nominal */
+ if (opts & XTLV_OPTION_LENU8)
+ {
+ --len;
+ }
+ if (opts & XTLV_OPTION_IDU8)
+ {
+ --len;
+ }
+ return len;
+}
+
+static int xtlv_size_for_data(int dlen, uint16_t opts, const uint8_t ** data)
+{
+ int hsz;
+ hsz = xtlv_hdr_size(opts, data);
+ return ((opts & XTLV_OPTION_ALIGN32) ? ALIGN_SIZE(dlen + hsz, 4) : (dlen + hsz));
+}
+
+static int xtlv_len(const xtlv_t * elt, uint16_t opts)
+{
+ const uint8_t * lenp;
+ int len;
+
+ lenp = (const uint8_t *) &elt->len; /* nominal */
+ if (opts & XTLV_OPTION_IDU8)
+ {
+ --lenp;
+ }
+ if (opts & XTLV_OPTION_LENU8)
+ {
+ len = *lenp;
+ }
+ else
+ {
+ len = _LTOH16_UA(lenp);
+ }
+ return len;
+}
+
+static int xtlv_id(const xtlv_t * elt, uint16_t opts)
+{
+ int id = 0;
+ if (opts & XTLV_OPTION_IDU8)
+ {
+ id = *(const uint8_t *) elt;
+ }
+ else
+ {
+ id = _LTOH16_UA((const uint8_t *) elt);
+ }
+ return id;
+}
+
+static void xtlv_unpack_xtlv(const xtlv_t * xtlv, uint16_t * type, uint16_t * len, const uint8_t ** data, uint16_t opts)
+{
+ if (type)
+ {
+ *type = (uint16_t) xtlv_id(xtlv, opts);
+ }
+ if (len)
+ {
+ *len = (uint16_t) xtlv_len(xtlv, opts);
+ }
+ if (data)
+ {
+ *data = (const uint8_t *) xtlv + xtlv_hdr_size(opts, data);
+ }
+}
+
+void P6Utils::unpack_xtlv_buf(const uint8_t * tlv_buf, uint16_t buflen, wl_cnt_ver_30_t * cnt, wl_cnt_ge40mcst_v1_t * cnt_ge40)
+{
+ uint16_t len;
+ uint16_t type;
+ int size;
+ const xtlv_t * ptlv;
+ int sbuflen = buflen;
+ const uint8_t * data;
+ int hdr_size;
+ hdr_size = xtlv_hdr_size(XTLV_OPTION_ALIGN32, &data);
+ while (sbuflen >= hdr_size)
+ {
+ ptlv = (const xtlv_t *) tlv_buf;
+
+ xtlv_unpack_xtlv(ptlv, &type, &len, &data, XTLV_OPTION_ALIGN32);
+ size = xtlv_size_for_data(len, XTLV_OPTION_ALIGN32, &data);
+
+ sbuflen -= size;
+ if (sbuflen < 0) /* check for buffer overrun */
+ {
+ break;
+ }
+ if (type == 0x100)
+ {
+ memcpy(cnt, (wl_cnt_ver_30_t *) data, sizeof(wl_cnt_ver_30_t));
+ }
+ if (type == 0x400)
+ {
+ memcpy(cnt_ge40, (wl_cnt_ge40mcst_v1_t *) data, sizeof(wl_cnt_ge40mcst_v1_t));
+ }
+ tlv_buf += size;
+ }
+}
+
+/* Get the Heap total size for P6 Linker file */
+uint32_t get_heap_total()
+{
+ extern uint8_t __HeapBase; /* Symbol exported by the linker. */
+ extern uint8_t __HeapLimit; /* Symbol exported by the linker. */
+
+ uint8_t * heap_base = (uint8_t *) &__HeapBase;
+ uint8_t * heap_limit = (uint8_t *) &__HeapLimit;
+ return (uint32_t)(heap_limit - heap_base);
+}
+
+/* Populate Heap info based on heap total size and Current Heap usage */
+void P6Utils::heap_usage(heap_info_t * heap)
+{
+ struct mallinfo mall_info = mallinfo();
+
+ heap->HeapMax = mall_info.arena;
+ heap->HeapUsed = mall_info.uordblks;
+ heap->HeapFree = get_heap_total() - mall_info.uordblks;
+}
diff --git a/src/platform/P6/P6Utils.h b/src/platform/P6/P6Utils.h
index d7850735c53372..62afdabdc411ec 100644
--- a/src/platform/P6/P6Utils.h
+++ b/src/platform/P6/P6Utils.h
@@ -20,6 +20,7 @@
#pragma once
#include "platform/internal/DeviceNetworkInfo.h"
+#include "whd_wlioctl.h"
#include
#include
@@ -63,6 +64,123 @@ typedef enum
WIFI_IF_STA_AP = CY_WCM_INTERFACE_TYPE_AP_STA,
} wifi_interface_t;
+/** MACSTAT counters for ucode (corerev >= 40) */
+typedef struct
+{
+ /* MAC counters: 32-bit version of d11.h's macstat_t */
+ uint32 txallfrm; /**< total number of frames sent, incl. Data, ACK, RTS, CTS,
+ * Control Management (includes retransmissions)
+ */
+ uint32 txrtsfrm; /**< number of RTS sent out by the MAC */
+ uint32 txctsfrm; /**< number of CTS sent out by the MAC */
+ uint32 txackfrm; /**< number of ACK frames sent out */
+ uint32 txdnlfrm; /**< number of Null-Data transmission generated from template */
+ uint32 txbcnfrm; /**< beacons transmitted */
+ uint32 txfunfl[6]; /**< per-fifo tx underflows */
+ uint32 txampdu; /**< number of AMPDUs transmitted */
+ uint32 txmpdu; /**< number of MPDUs transmitted */
+ uint32 txtplunfl; /**< Template underflows (mac was too slow to transmit ACK/CTS
+ * or BCN)
+ */
+ uint32 txphyerror; /**< Transmit phy error, type of error is reported in tx-status for
+ * driver enqueued frames
+ */
+ uint32 pktengrxducast; /**< unicast frames rxed by the pkteng code */
+ uint32 pktengrxdmcast; /**< multicast frames rxed by the pkteng code */
+ uint32 rxfrmtoolong; /**< Received frame longer than legal limit (2346 bytes) */
+ uint32 rxfrmtooshrt; /**< Received frame did not contain enough bytes for its frame type */
+ uint32 rxanyerr; /**< Any RX error that is not counted by other counters. */
+ uint32 rxbadfcs; /**< number of frames for which the CRC check failed in the MAC */
+ uint32 rxbadplcp; /**< parity check of the PLCP header failed */
+ uint32 rxcrsglitch; /**< PHY was able to correlate the preamble but not the header */
+ uint32 rxstrt; /**< Number of received frames with a good PLCP
+ * (i.e. passing parity check)
+ */
+ uint32 rxdtucastmbss; /**< number of received DATA frames with good FCS and matching RA */
+ uint32 rxmgucastmbss; /**< number of received mgmt frames with good FCS and matching RA */
+ uint32 rxctlucast; /**< number of received CNTRL frames with good FCS and matching RA */
+ uint32 rxrtsucast; /**< number of unicast RTS addressed to the MAC (good FCS) */
+ uint32 rxctsucast; /**< number of unicast CTS addressed to the MAC (good FCS) */
+ uint32 rxackucast; /**< number of ucast ACKS received (good FCS) */
+ uint32 rxdtocast; /**< number of received DATA frames (good FCS and not matching RA) */
+ uint32 rxmgocast; /**< number of received MGMT frames (good FCS and not matching RA) */
+ uint32 rxctlocast; /**< number of received CNTRL frame (good FCS and not matching RA) */
+ uint32 rxrtsocast; /**< number of received RTS not addressed to the MAC */
+ uint32 rxctsocast; /**< number of received CTS not addressed to the MAC */
+ uint32 rxdtmcast; /**< number of RX Data multicast frames received by the MAC */
+ uint32 rxmgmcast; /**< number of RX Management multicast frames received by the MAC */
+ uint32 rxctlmcast; /**< number of RX Control multicast frames received by the MAC
+ * (unlikely to see these)
+ */
+ uint32 rxbeaconmbss; /**< beacons received from member of BSS */
+ uint32 rxdtucastobss; /**< number of unicast frames addressed to the MAC from
+ * other BSS (WDS FRAME)
+ */
+ uint32 rxbeaconobss; /**< beacons received from other BSS */
+ uint32 rxrsptmout; /**< number of response timeouts for transmitted frames
+ * expecting a response
+ */
+ uint32 bcntxcancl; /**< transmit beacons canceled due to receipt of beacon (IBSS) */
+ uint32 rxnodelim; /**< number of no valid delimiter detected by ampdu parser */
+ uint32 rxf0ovfl; /**< number of receive fifo 0 overflows */
+ uint32 rxf1ovfl; /**< number of receive fifo 1 overflows */
+ uint32 rxhlovfl; /**< number of length / header fifo overflows */
+ uint32 missbcn_dbg; /**< number of beacon missed to receive */
+ uint32 pmqovfl; /**< number of PMQ overflows */
+ uint32 rxcgprqfrm; /**< number of received Probe requests that made it into
+ * the PRQ fifo
+ */
+ uint32 rxcgprsqovfl; /**< Rx Probe Request Que overflow in the AP */
+ uint32 txcgprsfail; /**< Tx Probe Response Fail. AP sent probe response but did
+ * not get ACK
+ */
+ uint32 txcgprssuc; /**< Tx Probe Response Success (ACK was received) */
+ uint32 prs_timeout; /**< number of probe requests that were dropped from the PRQ
+ * fifo because a probe response could not be sent out within
+ * the time limit defined in M_PRS_MAXTIME
+ */
+ uint32 txrtsfail; /**< number of rts transmission failure that reach retry limit */
+ uint32 txucast; /**< number of unicast tx expecting response other than cts/cwcts */
+ uint32 txinrtstxop; /**< number of data frame transmissions during rts txop */
+ uint32 rxback; /**< blockack rxcnt */
+ uint32 txback; /**< blockack txcnt */
+ uint32 bphy_rxcrsglitch; /**< PHY count of bphy glitches */
+ uint32 rxdrop20s; /**< drop secondary cnt */
+ uint32 rxtoolate; /**< receive too late */
+ uint32 bphy_badplcp; /**< number of bad PLCP reception on BPHY rate */
+ /* XXX: All counter variables have to be of uint32. */
+} wl_cnt_ge40mcst_v1_t;
+
+typedef struct xtlv
+{
+ uint16_t id;
+ uint16_t len;
+ uint8_t data[1];
+} xtlv_t;
+
+#define WL_CNT_VER_30 (30)
+
+/* XTLV Format parsing for wl counters support */
+#define XTLV_OPTION_ALIGN32 0x0001 /* 32bit alignment of type.len.data */
+#define XTLV_OPTION_IDU8 0x0002 /* shorter id */
+#define XTLV_OPTION_LENU8 0x0004 /* shorted length */
+#define OFFSETOF(type, member) ((uintptr_t) & ((type *) 0)->member)
+#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8))
+
+#define CHK_CNTBUF_DATALEN(cntbuf, ioctl_buflen) \
+ do \
+ { \
+ if (((wl_cnt_info_t *) cntbuf)->datalen + OFFSETOF(wl_cnt_info_t, data) > ioctl_buflen) \
+ printf("%s: IOVAR buffer short!\n", __FUNCTION__); \
+ } while (0)
+
+typedef struct heap_info
+{
+ size_t HeapMax;
+ size_t HeapUsed;
+ size_t HeapFree;
+} heap_info_t;
+
namespace chip {
namespace DeviceLayer {
namespace Internal {
@@ -98,6 +216,8 @@ class P6Utils
const cy_wcm_passphrase_t * password, cy_wcm_security_t security = CY_WCM_SECURITY_OPEN);
static CHIP_ERROR OnIPAddressAvailable(void);
static CHIP_ERROR ping_init(void);
+ static void unpack_xtlv_buf(const uint8_t * tlv_buf, uint16_t buflen, wl_cnt_ver_30_t * cnt, wl_cnt_ge40mcst_v1_t * cnt_ge40);
+ static void heap_usage(heap_info_t * heap);
};
} // namespace Internal
diff --git a/src/platform/P6/PlatformManagerImpl.cpp b/src/platform/P6/PlatformManagerImpl.cpp
index 24272b1dae6b89..0ff0ce3a29f6c1 100644
--- a/src/platform/P6/PlatformManagerImpl.cpp
+++ b/src/platform/P6/PlatformManagerImpl.cpp
@@ -50,6 +50,8 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
err = Internal::InitLwIPCoreLock();
SuccessOrExit(err);
+ mStartTime = System::SystemClock().GetMonotonicTimestamp();
+
// Call _InitChipStack() on the generic implementation base class
// to finish the initialization process.
err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack();
@@ -64,5 +66,30 @@ CHIP_ERROR PlatformManagerImpl::InitLwIPCoreLock(void)
return Internal::InitLwIPCoreLock();
}
+CHIP_ERROR PlatformManagerImpl::_Shutdown()
+{
+ uint64_t upTime = 0;
+
+ if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
+ {
+ uint32_t totalOperationalHours = 0;
+
+ if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
+ {
+ ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast(upTime / 3600));
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
+ }
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
+ }
+
+ return Internal::GenericPlatformManagerImpl_FreeRTOS::_Shutdown();
+}
+
} // namespace DeviceLayer
} // namespace chip
diff --git a/src/platform/P6/PlatformManagerImpl.h b/src/platform/P6/PlatformManagerImpl.h
index 8f3559bd80b3d4..f7c56ac435097c 100644
--- a/src/platform/P6/PlatformManagerImpl.h
+++ b/src/platform/P6/PlatformManagerImpl.h
@@ -49,17 +49,21 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener
// ===== Platform-specific members that may be accessed directly by the application.
CHIP_ERROR InitLwIPCoreLock(void);
+ System::Clock::Timestamp GetStartTime() { return mStartTime; }
private:
// ===== Methods that implement the PlatformManager abstract interface.
CHIP_ERROR _InitChipStack(void);
+ CHIP_ERROR _Shutdown();
// ===== Members for internal use by the following friends.
friend PlatformManager & PlatformMgr(void);
friend PlatformManagerImpl & PlatformMgrImpl(void);
+ System::Clock::Timestamp mStartTime = System::Clock::kZero;
+
static PlatformManagerImpl sInstance;
};