diff --git a/.clang-tidy b/.clang-tidy
index 2fa534bc5d2e77..580234c0fad0a3 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,36 +1,42 @@
---
Checks: >
- readability-else-after-return,
- modernize-use-nullptr,
bugprone-*,
- -bugprone-not-null-terminated-result,
- -bugprone-unused-return-value,
+ modernize-use-bool-literals,
+ modernize-use-nullptr,
+ performance-for-range-copy,
+ readability-const-return-type,
+ readability-else-after-return,
+ readability-redundant-control-flow,
+ readability-redundant-string-cstr,
+ readability-redundant-string-init,
-bugprone-branch-clone,
+ -bugprone-copy-constructor-init,
-bugprone-easily-swappable-parameters,
- -bugprone-reserved-identifier,
- -bugprone-macro-parentheses,
-bugprone-forward-declaration-namespace,
-bugprone-forwarding-reference-overload,
- -bugprone-undelegated-constructor,
-bugprone-implicit-widening-of-multiplication-result,
- -bugprone-narrowing-conversions,
+ -bugprone-macro-parentheses,
-bugprone-misplaced-widening-cast,
- -bugprone-suspicious-include,
+ -bugprone-narrowing-conversions,
+ -bugprone-not-null-terminated-result,
+ -bugprone-reserved-identifier,
-bugprone-signed-char-misuse,
- -bugprone-copy-constructor-init,
+ -bugprone-suspicious-include,
+ -bugprone-undelegated-constructor,
+ -bugprone-unused-return-value,
-clang-analyzer-core.CallAndMessage,
+ -clang-analyzer-core.NonNullParamChecker,
-clang-analyzer-core.NullDereference,
- -clang-analyzer-optin.cplusplus.UninitializedObject,
- -clang-analyzer-optin.performance,
- -clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,
- -clang-analyzer-deadcode.DeadStores,
-clang-analyzer-cplusplus.Move,
- -clang-analyzer-optin.cplusplus.VirtualCall,
- -clang-analyzer-security.insecureAPI.strcpy,
+ -clang-analyzer-deadcode.DeadStores,
-clang-analyzer-nullability.NullablePassedToNonnull,
+ -clang-analyzer-optin.cplusplus.UninitializedObject,
+ -clang-analyzer-optin.cplusplus.VirtualCall,
+ -clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,
+ -clang-analyzer-optin.performance,
-clang-analyzer-optin.performance.Padding,
-clang-analyzer-security.insecureAPI.rand,
- -clang-analyzer-core.NonNullParamChecker,
+ -clang-analyzer-security.insecureAPI.strcpy,
-clang-analyzer-unix.Malloc,
-clang-diagnostic-implicit-int-conversion
WarningsAsErrors: '*'
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index b76094b34ad4b2..cf59391ca0ef32 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -7,4 +7,4 @@ updates:
allow:
- dependency-name: "third_party/pigweed/repo"
- dependency-name: "third_party/mbedtls/repo"
- - dependancy-name: "third_party/openthread/repo"
+ - dependency-name: "third_party/openthread/repo"
diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig
index b377c65c2e222f..e4a0a9f3a1abab 100644
--- a/config/nrfconnect/chip-module/Kconfig
+++ b/config/nrfconnect/chip-module/Kconfig
@@ -284,5 +284,9 @@ config CHIP_CERTIFiCATION_DECLARATION_OTA_IMAGE_ID
endif
+# See config/zephyr/Kconfig for full definition
+config CHIP_FACTORY_RESET_ERASE_NVS
+ bool
+ default y if CHIP_FACTORY_DATA || CHIP_FACTORY_DATA_CUSTOM_BACKEND
endif
diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig
index efa0f7abc2c476..9928bb35b49258 100644
--- a/config/zephyr/Kconfig
+++ b/config/zephyr/Kconfig
@@ -202,6 +202,17 @@ config CHIP_CRYPTO_PSA
Use the backend for the Matter crypto layer that is based on PSA crypto
API instead of the default, based on legacy mbedTLS APIs.
+config CHIP_FACTORY_RESET_ERASE_NVS
+ bool "Erase NVS flash pages on factory reset"
+ depends on SETTINGS_NVS
+ help
+ When factory reset is requested, erase flash pages occupied by non-volatile storage
+ instead of removing Matter-related settings only. This provides a more robust
+ factory reset mechanism and allows to regain the original storage performance if any
+ firmware issue has brought it to an unexpected state. For this reason, it is
+ advisable to set this option if all configuration, including device-specific
+ entries, is supposed to be cleared on a factory reset.
+
config CHIP_MALLOC_SYS_HEAP
bool "Memory allocator based on Zephyr sys_heap"
imply SYS_HEAP_RUNTIME_STATS
diff --git a/docs/guides/nrfconnect_examples_configuration.md b/docs/guides/nrfconnect_examples_configuration.md
index 119852b3929a89..0254d8bb390644 100644
--- a/docs/guides/nrfconnect_examples_configuration.md
+++ b/docs/guides/nrfconnect_examples_configuration.md
@@ -193,6 +193,15 @@ instead of using a QR code, which is the default configuration.
To enable NFC for commissioning and share the onboarding payload in an NFC tag,
set the `CONFIG_CHIP_NFC_COMMISSIONING` option.
+**Factory reset behavior**
+
+By default, the factory reset procedure implemented in the Matter stack removes
+Matter-related settings only. If your application does not depend on any
+device-lifelong data stored in the non-volatile storage, set the
+`CONFIG_CHIP_FACTORY_RESET_ERASE_NVS` option to fully erase the NVS partition at
+the factory reset. This approach is more robust and regains the original NVS
+performance in case it has been polluted with unwanted entries.
+
**Logging**
You can enable logging for both the stack and Zephyr’s
diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
index 840f51d0ad993a..99d72eeea360c9 100644
--- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
+++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
@@ -1530,7 +1530,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 1,
"commands": [
@@ -1582,7 +1582,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -1658,7 +1658,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -1694,7 +1694,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -7710,7 +7710,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -7736,7 +7736,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -9396,7 +9396,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -9422,7 +9422,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -10770,7 +10770,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -10814,7 +10814,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -10850,7 +10850,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -10876,7 +10876,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -14102,7 +14102,7 @@
"name": "Pump Configuration and Control",
"code": 512,
"mfgCode": null,
- "define": "PUMP_CONFIG_CONTROL_CLUSTER",
+ "define": "PUMP_CONFIGURATION_AND_CONTROL_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -14128,7 +14128,7 @@
"name": "Pump Configuration and Control",
"code": 512,
"mfgCode": null,
- "define": "PUMP_CONFIG_CONTROL_CLUSTER",
+ "define": "PUMP_CONFIGURATION_AND_CONTROL_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -15308,7 +15308,7 @@
"name": "Thermostat User Interface Configuration",
"code": 516,
"mfgCode": null,
- "define": "THERMOSTAT_UI_CONFIG_CLUSTER",
+ "define": "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -15334,7 +15334,7 @@
"name": "Thermostat User Interface Configuration",
"code": 516,
"mfgCode": null,
- "define": "THERMOSTAT_UI_CONFIG_CLUSTER",
+ "define": "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -16626,7 +16626,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -16652,7 +16652,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -18314,7 +18314,7 @@
"name": "Content Launcher",
"code": 1290,
"mfgCode": null,
- "define": "CONTENT_LAUNCH_CLUSTER",
+ "define": "CONTENT_LAUNCHER_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -18358,7 +18358,7 @@
"name": "Content Launcher",
"code": 1290,
"mfgCode": null,
- "define": "CONTENT_LAUNCH_CLUSTER",
+ "define": "CONTENT_LAUNCHER_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -24128,7 +24128,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -24154,7 +24154,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
diff --git a/examples/all-clusters-app/all-clusters-common/include/static-supported-modes-manager.h b/examples/all-clusters-app/all-clusters-common/include/static-supported-modes-manager.h
index 2d4f674a65920d..8c9515738fa7da 100644
--- a/examples/all-clusters-app/all-clusters-common/include/static-supported-modes-manager.h
+++ b/examples/all-clusters-app/all-clusters-common/include/static-supported-modes-manager.h
@@ -54,7 +54,7 @@ class StaticSupportedModesManager : public chip::app::Clusters::ModeSelect::Supp
public:
static const StaticSupportedModesManager instance;
- const SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override;
+ SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override;
EmberAfStatus getModeOptionByMode(EndpointId endpointId, uint8_t mode, const ModeOptionStructType ** dataPtr) const override;
diff --git a/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp b/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp
index 8308ab8538de17..c9f118464c27ae 100644
--- a/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp
+++ b/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp
@@ -39,7 +39,7 @@ const StaticSupportedModesManager::EndpointSpanPair
const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager();
-const SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const
+SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const
{
for (auto & endpointSpanPair : supportedOptionsByEndpoints)
{
diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
index 14645f267a43db..871a5f71d6acc0 100644
--- a/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
+++ b/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
@@ -148,7 +148,7 @@ int AppTask::StartAppTask()
if (sAppEventQueue == NULL)
{
PLAT_LOG("Failed to allocate app event queue");
- while (1)
+ while (true)
;
}
@@ -157,7 +157,7 @@ int AppTask::StartAppTask()
pdPASS)
{
PLAT_LOG("Failed to create app task");
- while (1)
+ while (true)
;
}
return ret;
@@ -205,7 +205,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().InitChipStack() failed");
- while (1)
+ while (true)
;
}
@@ -213,7 +213,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ThreadStackMgr().InitThreadStack() failed");
- while (1)
+ while (true)
;
}
@@ -221,7 +221,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed");
- while (1)
+ while (true)
;
}
@@ -229,7 +229,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().StartEventLoopTask() failed");
- while (1)
+ while (true)
;
}
@@ -237,7 +237,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ThreadStackMgr().StartThreadTask() failed");
- while (1)
+ while (true)
;
}
@@ -279,7 +279,7 @@ void AppTask::AppTaskMain(void * pvParameter)
sAppTask.Init();
- while (1)
+ while (true)
{
/* Task pend until we have stuff to do */
if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE)
diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/main/main.cpp b/examples/all-clusters-app/cc13x2x7_26x2x7/main/main.cpp
index cb0641fbc85ee0..8311c8990aa5c6 100644
--- a/examples/all-clusters-app/cc13x2x7_26x2x7/main/main.cpp
+++ b/examples/all-clusters-app/cc13x2x7_26x2x7/main/main.cpp
@@ -52,7 +52,7 @@ uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE;
// ================================================================================
extern "C" void vApplicationStackOverflowHook(void)
{
- while (1)
+ while (true)
{
;
}
@@ -85,13 +85,13 @@ int main(void)
{
// can't log until the kernel is started
// PLAT_LOG("GetAppTask().StartAppTask() failed");
- while (1)
+ while (true)
;
}
vTaskStartScheduler();
// Should never get here.
- while (1)
+ while (true)
;
}
diff --git a/examples/all-clusters-app/infineon/psoc6/src/main.cpp b/examples/all-clusters-app/infineon/psoc6/src/main.cpp
index 84b1961f9a881f..2dc8d6353cc62c 100644
--- a/examples/all-clusters-app/infineon/psoc6/src/main.cpp
+++ b/examples/all-clusters-app/infineon/psoc6/src/main.cpp
@@ -59,7 +59,7 @@ void appError(int err)
{
P6_LOG("!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!", err);
portDISABLE_INTERRUPTS();
- while (1)
+ while (true)
;
}
diff --git a/examples/all-clusters-app/nxp/mw320/main.cpp b/examples/all-clusters-app/nxp/mw320/main.cpp
index df0c1dfe6f4e73..b48daf70826f4e 100644
--- a/examples/all-clusters-app/nxp/mw320/main.cpp
+++ b/examples/all-clusters-app/nxp/mw320/main.cpp
@@ -1027,7 +1027,7 @@ void task_main(void * param)
}
}
- while (1)
+ while (true)
{
/* wait for interface up */
os_thread_sleep(os_msec_to_ticks(5000));
@@ -1131,7 +1131,7 @@ static void rst_args_lt(System::Layer * aSystemLayer, void * aAppState)
void task_test_main(void * param)
{
- while (1)
+ while (true)
{
/* wait for interface up */
os_thread_sleep(os_msec_to_ticks(500));
@@ -1272,7 +1272,11 @@ void ShellCLIMain(void * pvParameter)
strcpy(def_psk, "nxp12345");
}
PRINTF("Connecting to [%s, %s] \r\n", def_ssid, def_psk);
- ConnectivityMgrImpl().ProvisionWiFiNetwork(def_ssid, def_psk);
+
+ // TODO: ConnectivityMgrImpl is the platform implementation of ConnectivityMgr layer.
+ // Application should use the APIs defined src/include/platform to talk to the Matter
+ // platfrom layer, instead of calling into the functions defined in the platform implemenation.
+ // ConnectivityMgrImpl().ProvisionWiFiNetwork(def_ssid, def_psk);
}
// Run CHIP servers
diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap
index 6c11faf288ccdf..5897329987f088 100644
--- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap
+++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap
@@ -1530,7 +1530,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 1,
"commands": [
@@ -1582,7 +1582,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -1658,7 +1658,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -1694,7 +1694,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -7710,7 +7710,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -7736,7 +7736,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -9246,7 +9246,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -9272,7 +9272,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -10620,7 +10620,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -10664,7 +10664,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -10700,7 +10700,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -10726,7 +10726,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -13872,7 +13872,7 @@
"name": "Pump Configuration and Control",
"code": 512,
"mfgCode": null,
- "define": "PUMP_CONFIG_CONTROL_CLUSTER",
+ "define": "PUMP_CONFIGURATION_AND_CONTROL_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -13898,7 +13898,7 @@
"name": "Pump Configuration and Control",
"code": 512,
"mfgCode": null,
- "define": "PUMP_CONFIG_CONTROL_CLUSTER",
+ "define": "PUMP_CONFIGURATION_AND_CONTROL_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -15014,7 +15014,7 @@
"name": "Thermostat User Interface Configuration",
"code": 516,
"mfgCode": null,
- "define": "THERMOSTAT_UI_CONFIG_CLUSTER",
+ "define": "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -15040,7 +15040,7 @@
"name": "Thermostat User Interface Configuration",
"code": 516,
"mfgCode": null,
- "define": "THERMOSTAT_UI_CONFIG_CLUSTER",
+ "define": "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -16332,7 +16332,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -16358,7 +16358,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -18038,7 +18038,7 @@
"name": "Content Launcher",
"code": 1290,
"mfgCode": null,
- "define": "CONTENT_LAUNCH_CLUSTER",
+ "define": "CONTENT_LAUNCHER_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -18082,7 +18082,7 @@
"name": "Content Launcher",
"code": 1290,
"mfgCode": null,
- "define": "CONTENT_LAUNCH_CLUSTER",
+ "define": "CONTENT_LAUNCHER_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
@@ -23904,7 +23904,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -23930,7 +23930,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
diff --git a/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/AppTask.cpp
index 14645f267a43db..871a5f71d6acc0 100644
--- a/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/AppTask.cpp
+++ b/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/AppTask.cpp
@@ -148,7 +148,7 @@ int AppTask::StartAppTask()
if (sAppEventQueue == NULL)
{
PLAT_LOG("Failed to allocate app event queue");
- while (1)
+ while (true)
;
}
@@ -157,7 +157,7 @@ int AppTask::StartAppTask()
pdPASS)
{
PLAT_LOG("Failed to create app task");
- while (1)
+ while (true)
;
}
return ret;
@@ -205,7 +205,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().InitChipStack() failed");
- while (1)
+ while (true)
;
}
@@ -213,7 +213,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ThreadStackMgr().InitThreadStack() failed");
- while (1)
+ while (true)
;
}
@@ -221,7 +221,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed");
- while (1)
+ while (true)
;
}
@@ -229,7 +229,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().StartEventLoopTask() failed");
- while (1)
+ while (true)
;
}
@@ -237,7 +237,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ThreadStackMgr().StartThreadTask() failed");
- while (1)
+ while (true)
;
}
@@ -279,7 +279,7 @@ void AppTask::AppTaskMain(void * pvParameter)
sAppTask.Init();
- while (1)
+ while (true)
{
/* Task pend until we have stuff to do */
if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE)
diff --git a/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/main.cpp b/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/main.cpp
index cb0641fbc85ee0..8311c8990aa5c6 100644
--- a/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/main.cpp
+++ b/examples/all-clusters-minimal-app/cc13x2x7_26x2x7/main/main.cpp
@@ -52,7 +52,7 @@ uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE;
// ================================================================================
extern "C" void vApplicationStackOverflowHook(void)
{
- while (1)
+ while (true)
{
;
}
@@ -85,13 +85,13 @@ int main(void)
{
// can't log until the kernel is started
// PLAT_LOG("GetAppTask().StartAppTask() failed");
- while (1)
+ while (true)
;
}
vTaskStartScheduler();
// Should never get here.
- while (1)
+ while (true)
;
}
diff --git a/examples/all-clusters-minimal-app/infineon/psoc6/src/main.cpp b/examples/all-clusters-minimal-app/infineon/psoc6/src/main.cpp
index a7587170607d28..5ac891ae1816f2 100644
--- a/examples/all-clusters-minimal-app/infineon/psoc6/src/main.cpp
+++ b/examples/all-clusters-minimal-app/infineon/psoc6/src/main.cpp
@@ -59,7 +59,7 @@ void appError(int err)
{
P6_LOG("!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!", err);
portDISABLE_INTERRUPTS();
- while (1)
+ while (true)
;
}
diff --git a/examples/android/CHIPTool/.idea/jarRepositories.xml b/examples/android/CHIPTool/.idea/jarRepositories.xml
index a5f05cd8c87d4a..e34606ccde7a9d 100644
--- a/examples/android/CHIPTool/.idea/jarRepositories.xml
+++ b/examples/android/CHIPTool/.idea/jarRepositories.xml
@@ -21,5 +21,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/android/CHIPTool/app/build.gradle b/examples/android/CHIPTool/app/build.gradle
index e38c8448e9bd8c..118b2884adfee1 100644
--- a/examples/android/CHIPTool/app/build.gradle
+++ b/examples/android/CHIPTool/app/build.gradle
@@ -3,12 +3,12 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
- compileSdkVersion 30
+ compileSdkVersion 31
defaultConfig {
applicationId "com.google.chip.chiptool"
minSdkVersion 24
- targetSdkVersion 30
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
@@ -82,7 +82,6 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
- implementation "com.google.android.gms:play-services-vision:20.1.0"
implementation 'androidx.fragment:fragment:1.3.0-beta01'
implementation "androidx.annotation:annotation:1.1.0"
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
@@ -96,6 +95,13 @@ dependencies {
implementation "androidx.work:work-runtime:2.3.3"
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.jjoe64:graphview:4.2.2'
+
+ implementation 'com.google.mlkit:barcode-scanning:17.0.2'
+ def camerax_version = "1.1.0"
+ implementation "androidx.camera:camera-core:${camerax_version}"
+ implementation "androidx.camera:camera-camera2:${camerax_version}"
+ implementation "androidx.camera:camera-lifecycle:${camerax_version}"
+ implementation "androidx.camera:camera-view:${camerax_version}"
}
repositories {
mavenCentral()
diff --git a/examples/android/CHIPTool/app/src/main/AndroidManifest.xml b/examples/android/CHIPTool/app/src/main/AndroidManifest.xml
index ede1f0980aee60..7a2febcf4c3f76 100644
--- a/examples/android/CHIPTool/app/src/main/AndroidManifest.xml
+++ b/examples/android/CHIPTool/app/src/main/AndroidManifest.xml
@@ -23,6 +23,7 @@
diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/BarcodeFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/BarcodeFragment.kt
index 9392a2425ff658..f701d2ca105117 100644
--- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/BarcodeFragment.kt
+++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/BarcodeFragment.kt
@@ -24,6 +24,7 @@ import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
+import android.util.DisplayMetrics
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@@ -31,34 +32,44 @@ import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
-import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AlertDialog
+import androidx.camera.core.*
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.camera.view.PreviewView
+import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.fragment.app.Fragment
import chip.setuppayload.SetupPayload
import chip.setuppayload.SetupPayloadParser
-import chip.setuppayload.SetupPayloadParser.SetupPayloadException
import chip.setuppayload.SetupPayloadParser.UnrecognizedQrCodeException
-import com.google.android.gms.vision.CameraSource
-import com.google.android.gms.vision.barcode.Barcode
-import com.google.android.gms.vision.barcode.BarcodeDetector
import com.google.chip.chiptool.R
import com.google.chip.chiptool.SelectActionFragment
import com.google.chip.chiptool.util.FragmentUtil
-import java.io.IOException
+import com.google.mlkit.vision.barcode.BarcodeScanner
+import com.google.mlkit.vision.barcode.BarcodeScanning
+import com.google.mlkit.vision.barcode.common.Barcode
+import com.google.mlkit.vision.common.InputImage
import kotlinx.android.synthetic.main.barcode_fragment.view.inputAddressBtn
+import java.util.concurrent.Executors
+import kotlin.math.abs
+import kotlin.math.max
+import kotlin.math.min
/** Launches the camera to scan for QR code. */
-class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListener {
-
- private var cameraSource: CameraSource? = null
- private var cameraSourceView: CameraSourceView? = null
- private var barcodeDetector: BarcodeDetector? = null
- private var cameraStarted = false
+class BarcodeFragment : Fragment() {
+ private lateinit var previewView: PreviewView
private var manualCodeEditText: EditText? = null
private var manualCodeBtn: Button? = null
+ private fun aspectRatio(width: Int, height: Int): Int {
+ val previewRatio = max(width, height).toDouble() / min(width, height)
+ if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
+ return AspectRatio.RATIO_4_3
+ }
+ return AspectRatio.RATIO_16_9
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (!hasCameraPermission()) {
@@ -72,11 +83,10 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.barcode_fragment, container, false).apply {
- cameraSourceView = findViewById(R.id.camera_view)
-
+ previewView = findViewById(R.id.camera_view)
manualCodeEditText = findViewById(R.id.manualCodeEditText)
manualCodeBtn = findViewById(R.id.manualCodeBtn)
-
+ startCamera()
inputAddressBtn.setOnClickListener {
FragmentUtil.getHost(
this@BarcodeFragment,
@@ -86,46 +96,76 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
}
}
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- initializeBarcodeDetectorAndCamera()
- }
+ @SuppressLint("UnsafeOptInUsageError")
+ private fun startCamera() {
+ val cameraProviderFuture = ProcessCameraProvider.getInstance(requireActivity())
+ cameraProviderFuture.addListener({
+ val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
+ val metrics = DisplayMetrics().also { previewView.display?.getRealMetrics(it) }
+ val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
+ // Preview
+ val preview: Preview = Preview.Builder()
+ .setTargetAspectRatio(screenAspectRatio)
+ .setTargetRotation(previewView.display.rotation)
+ .build()
+ preview.setSurfaceProvider(previewView.surfaceProvider)
- @SuppressLint("MissingPermission")
- override fun onResume() {
- super.onResume()
+ // Setup barcode scanner
+ val imageAnalysis = ImageAnalysis.Builder()
+ .setTargetAspectRatio(screenAspectRatio)
+ .setTargetRotation(previewView.display.rotation)
+ .build()
+ val cameraExecutor = Executors.newSingleThreadExecutor()
+ val barcodeScanner: BarcodeScanner = BarcodeScanning.getClient()
+ imageAnalysis.setAnalyzer(cameraExecutor) { imageProxy ->
+ processImageProxy(barcodeScanner, imageProxy)
+ }
+ // Select back camera as a default
+ val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
+ try {
+ // Unbind use cases before rebinding
+ cameraProvider.unbindAll()
- if (hasCameraPermission() && !cameraStarted) {
- startCamera()
- }
- }
+ // Bind use cases to camera
+ cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)
- private fun initializeBarcodeDetectorAndCamera() {
- barcodeDetector?.let { detector ->
- if (!detector.isOperational) {
- showCameraUnavailableAlert()
+ } catch (exc: Exception) {
+ Log.e(TAG, "Use case binding failed", exc)
}
- return
- }
-
- val context = requireContext()
- barcodeDetector = BarcodeDetector.Builder(context).build().apply {
- setProcessor(CHIPBarcodeProcessor(this@BarcodeFragment))
- }
- cameraSource = CameraSource.Builder(context, barcodeDetector)
- .setFacing(CameraSource.CAMERA_FACING_BACK)
- .setAutoFocusEnabled(true)
- .setRequestedFps(30.0f)
- .build()
+ }, ContextCompat.getMainExecutor(requireActivity()))
//workaround: can not use gms to scan the code in China, added a EditText to debug
manualCodeBtn?.setOnClickListener {
- var qrCode = manualCodeEditText?.text.toString()
+ val qrCode = manualCodeEditText?.text.toString()
Log.d(TAG, "Submit Code:$qrCode")
handleInputQrCode(qrCode)
}
}
+ @ExperimentalGetImage
+ private fun processImageProxy(
+ barcodeScanner: BarcodeScanner,
+ imageProxy: ImageProxy
+ ) {
+ val inputImage =
+ InputImage.fromMediaImage(imageProxy.image!!, imageProxy.imageInfo.rotationDegrees)
+
+ barcodeScanner.process(inputImage)
+ .addOnSuccessListener { barcodes ->
+ barcodes.forEach {
+ handleScannedQrCode(it)
+ }
+ }
+ .addOnFailureListener {
+ Log.e(TAG, it.message ?: it.toString())
+ }.addOnCompleteListener {
+ // When the image is from CameraX analysis use case, must call image.close() on received
+ // images when finished using them. Otherwise, new images may not be received or the camera
+ // may stall.
+ imageProxy.close()
+ }
+ }
+
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array,
@@ -146,46 +186,20 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
payload = SetupPayloadParser().parseQrCode(qrCode)
} catch (ex: UnrecognizedQrCodeException) {
Log.e(TAG, "Unrecognized QR Code", ex)
- Toast.makeText(requireContext(), "Unrecognized QR Code : ${ex.message}", Toast.LENGTH_SHORT).show()
- payload = SetupPayload()
- return
- } catch (ex: SetupPayloadException) {
- Log.e(TAG, "Exception ", ex)
- Toast.makeText(requireContext(), "Exception : ${ex.message}", Toast.LENGTH_SHORT).show()
- payload = SetupPayload()
- return
+ Toast.makeText(requireContext(), "Unrecognized QR Code", Toast.LENGTH_SHORT).show()
}
FragmentUtil.getHost(this, Callback::class.java)
?.onCHIPDeviceInfoReceived(CHIPDeviceInfo.fromSetupPayload(payload))
}
- @SuppressLint("MissingPermission")
- override fun handleScannedQrCode(barcode: Barcode) {
+ private fun handleScannedQrCode(barcode: Barcode) {
Handler(Looper.getMainLooper()).post {
- stopCamera()
-
lateinit var payload: SetupPayload
try {
payload = SetupPayloadParser().parseQrCode(barcode.displayValue)
} catch (ex: UnrecognizedQrCodeException) {
Log.e(TAG, "Unrecognized QR Code", ex)
Toast.makeText(requireContext(), "Unrecognized QR Code", Toast.LENGTH_SHORT).show()
-
- // Restart camera view.
- if (hasCameraPermission() && !cameraStarted) {
- startCamera()
- }
- payload = SetupPayload()
- return@post
- } catch (ex: SetupPayloadException) {
- Log.e(TAG, "Exception ", ex)
- Toast.makeText(requireContext(), "Exception : ${ex.message}", Toast.LENGTH_SHORT).show()
-
- // Restart camera view.
- if (hasCameraPermission() && !cameraStarted) {
- startCamera()
- }
- payload = SetupPayload()
return@post
}
FragmentUtil.getHost(this, Callback::class.java)
@@ -193,16 +207,6 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
}
}
- override fun onPause() {
- super.onPause()
- stopCamera()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- cameraSourceView?.release()
- }
-
private fun showCameraPermissionAlert() {
AlertDialog.Builder(requireContext())
.setTitle(R.string.camera_permission_missing_alert_title)
@@ -227,24 +231,9 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
.show()
}
- @RequiresPermission(Manifest.permission.CAMERA)
- private fun startCamera() {
- try {
- cameraSourceView?.start(cameraSource)
- cameraStarted = true
- } catch (e: IOException) {
- Log.e(TAG, "Unable to start camera source.", e)
- }
- }
-
- private fun stopCamera() {
- cameraSourceView?.stop()
- cameraStarted = false
- }
-
private fun hasCameraPermission(): Boolean {
return (PackageManager.PERMISSION_GRANTED
- == checkSelfPermission(requireContext(), Manifest.permission.CAMERA))
+ == checkSelfPermission(requireContext(), Manifest.permission.CAMERA))
}
private fun requestCameraPermission() {
@@ -262,6 +251,10 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
private const val TAG = "BarcodeFragment"
private const val REQUEST_CODE_CAMERA_PERMISSION = 100;
- @JvmStatic fun newInstance() = BarcodeFragment()
+ @JvmStatic
+ fun newInstance() = BarcodeFragment()
+
+ private const val RATIO_4_3_VALUE = 4.0 / 3.0
+ private const val RATIO_16_9_VALUE = 16.0 / 9.0
}
-}
+}
\ No newline at end of file
diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPBarcodeProcessor.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPBarcodeProcessor.kt
deleted file mode 100644
index 5ce5c7c4924dc7..00000000000000
--- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPBarcodeProcessor.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2020 Project CHIP Authors
- * All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.google.chip.chiptool.setuppayloadscanner
-
-import com.google.android.gms.vision.Detector
-import com.google.android.gms.vision.barcode.Barcode
-
-/** Processes the detected [Barcode]s from a Camera scan. */
-class CHIPBarcodeProcessor(
- private val listener: BarcodeDetectionListener
-) : Detector.Processor {
-
- override fun receiveDetections(detections: Detector.Detections) {
- val detectedItems = detections.detectedItems
- if (detectedItems.size() <= 0) {
- return
- }
- val barcode = detectedItems.valueAt(0)
- listener.handleScannedQrCode(barcode)
- }
-
- override fun release() {
-
- }
-
- /** Interface for receiving the detected QR Code from a Camera scan. */
- interface BarcodeDetectionListener {
-
- /** Provides the [Barcode] detected in camera scan to the registered listener. */
- fun handleScannedQrCode(barcode: Barcode)
- }
-}
diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CameraSourceView.java b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CameraSourceView.java
deleted file mode 100644
index 41b4f6bbfd5d64..00000000000000
--- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CameraSourceView.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2020 Project CHIP Authors
- * All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.google.chip.chiptool.setuppayloadscanner;
-
-import android.Manifest;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.ViewGroup;
-import androidx.annotation.RequiresPermission;
-import com.google.android.gms.vision.CameraSource;
-import java.io.IOException;
-
-/** Class that displays the camera view. */
-public class CameraSourceView extends ViewGroup {
-
- private static final String TAG = CameraSourceView.class.getSimpleName();
-
- private SurfaceView surfaceView;
- private boolean startRequested;
- private boolean surfaceAvailable;
- private CameraSource cameraSource;
-
- public CameraSourceView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- surfaceView = new SurfaceView(context);
- surfaceView.getHolder().addCallback(new SurfaceCallback());
- addView(surfaceView);
- }
-
- /**
- * Attempts to start the camera source.
- *
- * @param cameraSource the camera source
- * @throws IOException if the camera doesn't work
- * @throws SecurityException if app doesn't have permission to access camera
- */
- @RequiresPermission(Manifest.permission.CAMERA)
- public void start(CameraSource cameraSource) throws IOException, SecurityException {
- if (cameraSource == null) {
- stop();
- }
-
- this.cameraSource = cameraSource;
-
- if (this.cameraSource != null) {
- startRequested = true;
- startIfReady();
- }
- }
-
- /** Stops the camera source. */
- public void stop() {
- if (cameraSource != null) {
- cameraSource.stop();
- }
- }
-
- /** Releases the camera source. */
- public void release() {
- if (cameraSource != null) {
- cameraSource.release();
- cameraSource = null;
- }
- }
-
- @RequiresPermission(Manifest.permission.CAMERA)
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- final int layoutWidth = right - left;
- final int layoutHeight = bottom - top;
-
- for (int position = 0; position < getChildCount(); ++position) {
- getChildAt(position).layout(0, 0, layoutWidth, layoutHeight);
- }
-
- startIfReady();
- }
-
- @RequiresPermission(Manifest.permission.CAMERA)
- private void startIfReady() {
- try {
- if (startRequested && surfaceAvailable) {
- cameraSource.start(surfaceView.getHolder());
- startRequested = false;
- }
- } catch (SecurityException se) {
- Log.e(TAG, "Do not have permission to start the camera", se);
- } catch (IOException ioe) {
- Log.e(TAG, "Could not start camera source.", ioe);
- }
- }
-
- /** Class to handle surface traits and availability */
- private class SurfaceCallback implements SurfaceHolder.Callback {
-
- @RequiresPermission(Manifest.permission.CAMERA)
- @Override
- public void surfaceCreated(SurfaceHolder surface) {
- surfaceAvailable = true;
- startIfReady();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder surface) {
- surfaceAvailable = false;
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
- }
-}
diff --git a/examples/android/CHIPTool/app/src/main/res/layout/barcode_fragment.xml b/examples/android/CHIPTool/app/src/main/res/layout/barcode_fragment.xml
index 357b402ebeb8bb..b8a23d960c75f3 100644
--- a/examples/android/CHIPTool/app/src/main/res/layout/barcode_fragment.xml
+++ b/examples/android/CHIPTool/app/src/main/res/layout/barcode_fragment.xml
@@ -4,7 +4,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
- SetEndpointId(gCurrentEndpointId);
ret =
diff --git a/examples/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp
index ee545d5619feef..5007ceed7402cc 100644
--- a/examples/bridge-app/linux/main.cpp
+++ b/examples/bridge-app/linux/main.cpp
@@ -216,7 +216,7 @@ DECLARE_DYNAMIC_ATTRIBUTE(ZCL_TEMP_MEASURED_VALUE_ATTRIBUTE_ID, INT16S, 2, 0),
// - Descriptor
// - Bridged Device Basic
DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedTempSensorClusters)
-DECLARE_DYNAMIC_CLUSTER(ZCL_TEMP_MEASUREMENT_CLUSTER_ID, tempSensorAttrs, nullptr, nullptr),
+DECLARE_DYNAMIC_CLUSTER(ZCL_TEMPERATURE_MEASUREMENT_CLUSTER_ID, tempSensorAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER_LIST_END;
@@ -270,7 +270,7 @@ int AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep, const Spanfirst);
+ ShutdownCommissioner(commissioner.first);
}
StopTracing();
diff --git a/examples/chip-tool/commands/common/Command.cpp b/examples/chip-tool/commands/common/Command.cpp
index 6717bcbbc03216..59d678158ed073 100644
--- a/examples/chip-tool/commands/common/Command.cpp
+++ b/examples/chip-tool/commands/common/Command.cpp
@@ -42,9 +42,9 @@ bool Command::InitArguments(int argc, char ** argv)
size_t argvExtraArgsCount = (size_t) argc;
size_t mandatoryArgsCount = 0;
size_t optionalArgsCount = 0;
- for (size_t i = 0; i < mArgs.size(); i++)
+ for (auto & arg : mArgs)
{
- if (mArgs[i].isOptional())
+ if (arg.isOptional())
{
optionalArgsCount++;
}
@@ -877,9 +877,8 @@ void ResetOptionalArg(const Argument & arg)
void Command::ResetArguments()
{
- for (size_t i = 0; i < mArgs.size(); i++)
+ for (const auto & arg : mArgs)
{
- const Argument arg = mArgs[i];
const ArgumentType type = arg.type;
if (arg.isOptional())
{
diff --git a/examples/common/pigweed/protos/attributes_service.proto b/examples/common/pigweed/protos/attributes_service.proto
index 8eff6cb079be42..6f09e9faa7ba9a 100644
--- a/examples/common/pigweed/protos/attributes_service.proto
+++ b/examples/common/pigweed/protos/attributes_service.proto
@@ -78,7 +78,7 @@ enum ClusterType {
ZCL_GROUPS_CLUSTER_ID = 0x0004;
ZCL_SCENES_CLUSTER_ID = 0x0005;
ZCL_ON_OFF_CLUSTER_ID = 0x0006;
- ZCL_ON_OFF_SWITCH_CONFIG_CLUSTER_ID = 0x0007;
+ ZCL_ON_OFF_SWITCH_CONFIGURATION_CLUSTER_ID = 0x0007;
ZCL_LEVEL_CONTROL_CLUSTER_ID = 0x0008;
ZCL_ALARM_CLUSTER_ID = 0x0009;
ZCL_TIME_CLUSTER_ID = 0x000A;
@@ -89,8 +89,8 @@ enum ClusterType {
ZCL_POLL_CONTROL_CLUSTER_ID = 0x0020;
ZCL_ACTIONS_CLUSTER_ID = 0x0025;
ZCL_BASIC_CLUSTER_ID = 0x0028;
- ZCL_OTA_PROVIDER_CLUSTER_ID = 0x0029;
- ZCL_OTA_REQUESTOR_CLUSTER_ID = 0x002A;
+ ZCL_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_ID = 0x0029;
+ ZCL_OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER_ID = 0x002A;
ZCL_UNIT_LOCALIZATION_CLUSTER_ID = 0x002D;
ZCL_POWER_SOURCE_CLUSTER_ID = 0x002F;
ZCL_GENERAL_COMMISSIONING_CLUSTER_ID = 0x0030;
@@ -112,15 +112,15 @@ enum ClusterType {
ZCL_DOOR_LOCK_CLUSTER_ID = 0x0101;
ZCL_WINDOW_COVERING_CLUSTER_ID = 0x0102;
ZCL_BARRIER_CONTROL_CLUSTER_ID = 0x0103;
- ZCL_PUMP_CONFIG_CONTROL_CLUSTER_ID = 0x0200;
+ ZCL_PUMP_CONFIGURATION_AND_CONTROL_CLUSTER_ID = 0x0200;
ZCL_THERMOSTAT_CLUSTER_ID = 0x0201;
ZCL_FAN_CONTROL_CLUSTER_ID = 0x0202;
ZCL_DEHUMID_CONTROL_CLUSTER_ID = 0x0203;
- ZCL_THERMOSTAT_UI_CONFIG_CLUSTER_ID = 0x0204;
+ ZCL_THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER_ID = 0x0204;
ZCL_COLOR_CONTROL_CLUSTER_ID = 0x0300;
ZCL_BALLAST_CONFIGURATION_CLUSTER_ID = 0x0301;
ZCL_ILLUMINANCE_MEASUREMENT_CLUSTER_ID = 0x0400;
- ZCL_TEMP_MEASUREMENT_CLUSTER_ID = 0x0402;
+ ZCL_TEMPERATURE_MEASUREMENT_CLUSTER_ID = 0x0402;
ZCL_PRESSURE_MEASUREMENT_CLUSTER_ID = 0x0403;
ZCL_FLOW_MEASUREMENT_CLUSTER_ID = 0x0404;
ZCL_RELATIVE_HUMIDITY_MEASUREMENT_CLUSTER_ID = 0x0405;
@@ -164,7 +164,7 @@ enum ClusterType {
ZCL_MEDIA_INPUT_CLUSTER_ID = 0x0507;
ZCL_LOW_POWER_CLUSTER_ID = 0x0508;
ZCL_KEYPAD_INPUT_CLUSTER_ID = 0x0509;
- ZCL_CONTENT_LAUNCH_CLUSTER_ID = 0x050A;
+ ZCL_CONTENT_LAUNCHER_CLUSTER_ID = 0x050A;
ZCL_AUDIO_OUTPUT_CLUSTER_ID = 0x050B;
ZCL_APPLICATION_LAUNCHER_CLUSTER_ID = 0x050C;
ZCL_APPLICATION_BASIC_CLUSTER_ID = 0x050D;
diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap
index 7ea8d4598f6a4d..56dd9d1b244863 100644
--- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap
+++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap
@@ -622,7 +622,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -648,7 +648,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -1524,7 +1524,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 1,
"commands": [
@@ -1576,7 +1576,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -1652,7 +1652,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -1688,7 +1688,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
diff --git a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h
index ab6165f474f1ec..c912ec2898181a 100644
--- a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h
+++ b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h
@@ -54,24 +54,26 @@ class ReadAttribute : public ModelCommand {
{
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
MTRReadParams * params = [[MTRReadParams alloc] init];
- params.fabricFiltered = mFabricFiltered.HasValue() ? [NSNumber numberWithBool:mFabricFiltered.Value()] : nil;
+ if (mFabricFiltered.HasValue()) {
+ params.filterByFabric = mFabricFiltered.Value();
+ }
[device
- readAttributeWithEndpointID:[NSNumber numberWithUnsignedShort:endpointId]
- clusterID:[NSNumber numberWithUnsignedInteger:mClusterId]
- attributeID:[NSNumber numberWithUnsignedInteger:mAttributeId]
- params:params
- queue:callbackQueue
- completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) {
- if (error != nil) {
- LogNSError("Error reading attribute", error);
- }
- if (values) {
- for (id item in values) {
- NSLog(@"Response Item: %@", [item description]);
- }
- }
- SetCommandExitStatus(error);
- }];
+ readAttributesWithEndpointID:[NSNumber numberWithUnsignedShort:endpointId]
+ clusterID:[NSNumber numberWithUnsignedInteger:mClusterId]
+ attributeID:[NSNumber numberWithUnsignedInteger:mAttributeId]
+ params:params
+ queue:callbackQueue
+ completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) {
+ if (error != nil) {
+ LogNSError("Error reading attribute", error);
+ }
+ if (values) {
+ for (id item in values) {
+ NSLog(@"Response Item: %@", [item description]);
+ }
+ }
+ SetCommandExitStatus(error);
+ }];
return CHIP_NO_ERROR;
}
@@ -124,16 +126,20 @@ class SubscribeAttribute : public ModelCommand {
{
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
- MTRSubscribeParams * params = [[MTRSubscribeParams alloc] init];
- params.keepPreviousSubscriptions
- = mKeepSubscriptions.HasValue() ? [NSNumber numberWithBool:mKeepSubscriptions.Value()] : nil;
- params.autoResubscribe = mAutoResubscribe.HasValue() ? [NSNumber numberWithBool:mAutoResubscribe.Value()] : nil;
-
- [device subscribeAttributeWithEndpointID:[NSNumber numberWithUnsignedShort:endpointId]
+ MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
+ if (mFabricFiltered.HasValue()) {
+ params.filterByFabric = mFabricFiltered.Value();
+ }
+ if (mKeepSubscriptions.HasValue()) {
+ params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
+ }
+ if (mAutoResubscribe.HasValue()) {
+ params.resubscribeIfLost = mAutoResubscribe.Value();
+ }
+
+ [device subscribeToAttributesWithEndpointID:[NSNumber numberWithUnsignedShort:endpointId]
clusterID:[NSNumber numberWithUnsignedInteger:mClusterId]
attributeID:[NSNumber numberWithUnsignedInteger:mAttributeId]
- minInterval:[NSNumber numberWithUnsignedInteger:mMinInterval]
- maxInterval:[NSNumber numberWithUnsignedInteger:mMaxInterval]
params:params
queue:callbackQueue
reportHandler:^(NSArray *> * _Nullable values, NSError * _Nullable error) {
@@ -192,14 +198,15 @@ class SubscribeEvent : public ModelCommand {
{
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
- MTRSubscribeParams * params = [[MTRSubscribeParams alloc] init];
- params.keepPreviousSubscriptions
- = mKeepSubscriptions.HasValue() ? [NSNumber numberWithBool:mKeepSubscriptions.Value()] : nil;
- params.autoResubscribe = mAutoResubscribe.HasValue() ? [NSNumber numberWithBool:mAutoResubscribe.Value()] : nil;
+ MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
+ if (mKeepSubscriptions.HasValue()) {
+ params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
+ }
+ if (mAutoResubscribe.HasValue()) {
+ params.resubscribeIfLost = mAutoResubscribe.Value();
+ }
[device subscribeWithQueue:callbackQueue
- minInterval:@(mMinInterval)
- maxInterval:@(mMaxInterval)
params:params
attributeCacheContainer:nil
attributeReportHandler:^(NSArray * value) {
diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandStorageDelegate.h b/examples/darwin-framework-tool/commands/common/CHIPCommandStorageDelegate.h
index c2f7ba220e9e50..d5f743d57673c5 100644
--- a/examples/darwin-framework-tool/commands/common/CHIPCommandStorageDelegate.h
+++ b/examples/darwin-framework-tool/commands/common/CHIPCommandStorageDelegate.h
@@ -3,7 +3,7 @@
NS_ASSUME_NONNULL_BEGIN
-@interface CHIPToolPersistentStorageDelegate : NSObject
+@interface CHIPToolPersistentStorageDelegate : NSObject
- (nullable NSData *)storageDataForKey:(NSString *)key;
- (BOOL)setStorageData:(NSData *)value forKey:(NSString *)key;
- (BOOL)removeStorageDataForKey:(NSString *)key;
diff --git a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm
index 3b30e704b67515..ad3966a86b1411 100644
--- a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm
+++ b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm
@@ -39,7 +39,7 @@
}
NSError * error;
- return [MTROTAHeaderParser headerFromData:[NSData dataWithBytes:buffer.data() length:buffer.size()] error:&error];
+ return [MTROTAHeader headerFromData:[NSData dataWithBytes:buffer.data() length:buffer.size()] error:&error];
}
// Parses the JSON filepath and extracts DeviceSoftwareVersionModel parameters
diff --git a/examples/darwin-framework-tool/templates/commands.zapt b/examples/darwin-framework-tool/templates/commands.zapt
index d144f717817dcf..aaf3add5046705 100644
--- a/examples/darwin-framework-tool/templates/commands.zapt
+++ b/examples/darwin-framework-tool/templates/commands.zapt
@@ -90,7 +90,7 @@ private:
{{/chip_cluster_commands}}
{{#chip_server_cluster_attributes}}
-{{#*inline "attribute"}}Attribute{{#if (isStrEqual (asUpperCamelCase parent.name) "Descriptor")}}{{#if (isStrEqual (asUpperCamelCase name) "DeviceTypeList")}}DeviceList{{else}}{{asUpperCamelCase name}}{{/if}}{{else}}{{asUpperCamelCase name}}{{/if}}{{/inline}}
+{{#*inline "attribute"}}Attribute{{asUpperCamelCase name}}{{/inline}}
/*
* Attribute {{asUpperCamelCase name}}
@@ -114,7 +114,9 @@ public:
MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
{{#if_is_fabric_scoped_struct type}}
MTRReadParams * params = [[MTRReadParams alloc] init];
- params.fabricFiltered = mFabricFiltered.HasValue() ? [NSNumber numberWithBool:mFabricFiltered.Value()] : nil;
+ if (mFabricFiltered.HasValue()) {
+ params.filterByFabric = mFabricFiltered.Value();
+ }
{{/if_is_fabric_scoped_struct}}
[cluster readAttribute{{asUpperCamelCase name}}With
{{~#if_is_fabric_scoped_struct type~}}
@@ -216,12 +218,14 @@ public:
ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) ReportAttribute ({{asHex code 8}}) on endpoint %u", endpointId);
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
- MTRSubscribeParams * params = [[MTRSubscribeParams alloc] init];
- params.keepPreviousSubscriptions = mKeepSubscriptions.HasValue() ? [NSNumber numberWithBool:mKeepSubscriptions.Value()] : nil;
- params.fabricFiltered = mFabricFiltered.HasValue() ? [NSNumber numberWithBool:mFabricFiltered.Value()] : nil;
- [cluster subscribe{{>attribute}}WithMinInterval:[NSNumber numberWithUnsignedInt:mMinInterval]
- maxInterval:[NSNumber numberWithUnsignedInt:mMaxInterval]
- params:params
+ MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
+ if (mKeepSubscriptions.HasValue()) {
+ params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
+ }
+ if (mFabricFiltered.HasValue()) {
+ params.filterByFabric = mFabricFiltered.Value();
+ }
+ [cluster subscribe{{>attribute}}WithParams:params
subscriptionEstablished:^(){ mSubscriptionEstablished=YES; }
reportHandler:^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
NSLog(@"{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} response %@", [value description]);
diff --git a/examples/darwin-framework-tool/templates/tests/partials/test_cluster.zapt b/examples/darwin-framework-tool/templates/tests/partials/test_cluster.zapt
index ac98bcb21f1742..4bcd47c9ac1724 100644
--- a/examples/darwin-framework-tool/templates/tests/partials/test_cluster.zapt
+++ b/examples/darwin-framework-tool/templates/tests/partials/test_cluster.zapt
@@ -154,10 +154,8 @@ class {{filename}}: public TestCommandBridge
{{#chip_tests_item_parameters}}
{{asObjectiveCBasicType type}} {{asLowerCamelCase name}}Argument = {{asTypedLiteral definedValue type}};
{{/chip_tests_item_parameters}}
- MTRSubscribeParams * params = [[MTRSubscribeParams alloc] init];
- [cluster subscribeAttribute{{asUpperCamelCase attribute}}WithMinInterval:[NSNumber numberWithUnsignedInt:minIntervalArgument]
- maxInterval:[NSNumber numberWithUnsignedInt:maxIntervalArgument]
- params:params
+ MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(minIntervalArgument) maxInterval:@(maxIntervalArgument)];
+ [cluster subscribeAttribute{{asUpperCamelCase attribute}}WithParams:params
subscriptionEstablished:^{
VerifyOrReturn(testSendCluster{{parent.filename}}_{{waitForReport.index}}_{{asUpperCamelCase waitForReport.command}}_Fulfilled, SetCommandExitStatus(CHIP_ERROR_INCORRECT_STATE));
NextTest();
@@ -168,7 +166,7 @@ class {{filename}}: public TestCommandBridge
{{else if isReadAttribute}}
{{#if_is_fabric_scoped_struct attributeObject.type}}
MTRReadParams * params = [[MTRReadParams alloc] init];
- params.fabricFiltered = [NSNumber numberWithBool:{{fabricFiltered}}];
+ params.filterByFabric = {{fabricFiltered}};
{{/if_is_fabric_scoped_struct}}
[cluster readAttribute{{asUpperCamelCase attribute}}With
{{~#if_is_fabric_scoped_struct attributeObject.type~}}
diff --git a/examples/dynamic-bridge-app/bridge-common/bridge-app.zap b/examples/dynamic-bridge-app/bridge-common/bridge-app.zap
index 703f9caf5da8db..c8ea2b9adc1c19 100644
--- a/examples/dynamic-bridge-app/bridge-common/bridge-app.zap
+++ b/examples/dynamic-bridge-app/bridge-common/bridge-app.zap
@@ -7320,7 +7320,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -7362,7 +7362,7 @@
"name": "Temperature Measurement",
"code": 1026,
"mfgCode": null,
- "define": "TEMP_MEASUREMENT_CLUSTER",
+ "define": "TEMPERATURE_MEASUREMENT_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
diff --git a/examples/dynamic-bridge-app/linux/main.cpp b/examples/dynamic-bridge-app/linux/main.cpp
index d106b9c379b0a7..efb339582e3085 100644
--- a/examples/dynamic-bridge-app/linux/main.cpp
+++ b/examples/dynamic-bridge-app/linux/main.cpp
@@ -204,7 +204,7 @@ int AddDeviceEndpoint(Device * dev)
{
gDevices[index] = dev;
EmberAfStatus ret;
- while (1)
+ while (true)
{
// Todo: Update this to schedule the work rather than use this lock
dev->SetEndpointId(gCurrentEndpointId);
diff --git a/examples/light-switch-app/genio/.gn b/examples/light-switch-app/genio/.gn
new file mode 100644
index 00000000000000..0adefc6ff99c6a
--- /dev/null
+++ b/examples/light-switch-app/genio/.gn
@@ -0,0 +1,27 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+
+# The location of the build configuration file.
+buildconfig = "${build_root}/config/BUILDCONFIG.gn"
+
+# CHIP uses angle bracket includes.
+check_system_includes = true
+
+default_args = {
+ target_cpu = "arm"
+ target_os = "freertos"
+ import("//args.gni")
+}
diff --git a/examples/light-switch-app/genio/BUILD.gn b/examples/light-switch-app/genio/BUILD.gn
new file mode 100644
index 00000000000000..ba3f349a011df5
--- /dev/null
+++ b/examples/light-switch-app/genio/BUILD.gn
@@ -0,0 +1,117 @@
+# Copyright (c) 2022 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/mt793x_sdk.gni")
+import("//build_overrides/pigweed.gni")
+
+import("${build_root}/config/defaults.gni")
+import("${mt793x_sdk_build_root}/mt793x_executable.gni")
+import("${mt793x_sdk_build_root}/mt793x_sdk.gni")
+
+import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
+import("${chip_root}/src/platform/device.gni")
+
+if (chip_enable_pw_rpc) {
+ import("//build_overrides/pigweed.gni")
+ import("$dir_pw_build/target_types.gni")
+}
+
+assert(current_os == "freertos")
+
+mt793x_project_dir = "${chip_root}/examples/light-switch-app/genio"
+mt793x_examples_plat_dir = "${chip_root}/examples/platform/mt793x"
+
+declare_args() {
+ # Dump memory usage at link time.
+ chip_print_memory_usage = true
+
+ # PIN code for PASE session establishment.
+ setupPinCode = 20202021
+ setupDiscriminator = 3840
+}
+
+mt793x_sdk("sdk") {
+ sources = [
+ "${mt793x_project_dir}/include/CHIPProjectConfig.h",
+ "${mt793x_project_dir}/include/FreeRTOSConfig.h",
+ ]
+
+ include_dirs = [
+ "${chip_root}/src/platform/mt793x",
+ "${mt793x_project_dir}/include",
+ "${mt793x_examples_plat_dir}",
+ "${chip_root}/src/lib",
+ ]
+
+ defines = [ "OPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_CONSOLE" ]
+
+ defines += [
+ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}",
+ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}",
+ ]
+}
+
+mt793x_executable("light_switch_app") {
+ output_name = "chip-mt793x-light-switch-app-example.out"
+ include_dirs = [ "include" ]
+ defines = []
+
+ sources = [
+ "src/AppTask.cpp",
+ "src/BindingHandler.cpp",
+ "src/LEDWidget.cpp",
+ "src/ZclCallbacks.cpp",
+ "src/main.cpp",
+ ]
+
+ deps = [
+ ":sdk",
+ "${chip_root}/examples/common/QRCode",
+ "${chip_root}/examples/light-switch-app/light-switch-common",
+ "${chip_root}/examples/providers:device_info_provider",
+ "${chip_root}/src/lib",
+ "${chip_root}/src/setup_payload",
+ "${mt793x_examples_plat_dir}:genio-matter-shell",
+ ]
+
+ if (chip_enable_ota_requestor) {
+ defines += [ "MT793X_OTA_ENABLED" ]
+ sources += [ "${examples_plat_dir}/OTAConfig.cpp" ]
+ }
+
+ ldscript = "mt793x_xip.ld"
+
+ inputs = [ ldscript ]
+
+ ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ]
+
+ if (chip_print_memory_usage) {
+ ldflags += [
+ "-Wl,--print-memory-usage",
+ "-fstack-usage",
+ ]
+ }
+
+ output_dir = root_out_dir
+}
+
+group("mt793x") {
+ deps = [ ":light_switch_app" ]
+}
+
+group("default") {
+ deps = [ ":mt793x" ]
+}
diff --git a/examples/light-switch-app/genio/README.md b/examples/light-switch-app/genio/README.md
new file mode 100644
index 00000000000000..d735915d016956
--- /dev/null
+++ b/examples/light-switch-app/genio/README.md
@@ -0,0 +1,132 @@
+#Matter `Genio` Light Switch Example
+
+An example showing the use of Matter on the MediaTek `Genio` MT793X.
+
+
+
+- [Matter Genio Light Switch Example](#chip-genio-light-switch-example)
+ - [Introduction](#introduction)
+ - [Building](#building)
+ - [Note](#note)
+ - [Flashing the Application](#flashing-the-application)
+ - [Viewing Logging Output](#viewing-logging-output)
+ - [Running the Complete Example](#running-the-complete-example)
+ - [Notes](#notes)
+
+
+
+
+
+## Introduction
+
+The `Genio` (MT793X) light switch example provides a baseline demonstration of a
+on-off light switch device, built using Matter and the MediaTek `Genio` SDK. It
+can be controlled by a Chip controller over Wi-Fi network..
+
+The `Genio` device can be commissioned over Bluetooth Low Energy where the
+device and the Chip controller will exchange security information with the
+Rendez-vous procedure. Network credentials are then provided to the `Genio`
+device which will then join the network.
+
+The light switch example is intended to serve both as a means to explore the
+workings of Matter as well as a template for creating real products based on the
+MediaTek platform.
+
+
+
+## Building
+
+- Following the Linux related descriptions in
+ [Build Matter](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/BUILDING.md)
+ to prepare the build environment.
+
+- Supported hardware:
+
+ `Genio` 130A (MT7931) board:
+
+ - `EK-AI7931LD KIT`
+
+* Build the example application:
+
+ `cd ~/connectedhomeip`
+ `./scripts/examples/gn_genio_example.sh ./examples/light-switch-app/genio` `./out/light-switch-app`
+
+- To delete generated executable, libraries and object files use:
+
+ `$ cd ~/connectedhomeip`
+ `$ rm -rf ./out/`
+
+ OR use GN/Ninja directly
+
+ `$ cd ~/connectedhomeip/examples/light-switch-app/genio`
+ `$ git submodule update --init`
+ `$ source third_party/connectedhomeip/scripts/activate.sh`
+ `$ gn gen out/debug`
+ `$ ninja -C out/debug`
+
+- To delete generated executable, libraries and object files use:
+
+ `$ cd ~/connectedhomeip/examples/light-switch-app/genio`
+ `$ rm -rf out/`
+
+## Flashing the Application
+
+- Copy the GUI based
+ [Flash Tool](https://github.com/MediaTek-Labs/genio-matter-bsp/tree/main/flash_tool/FlashBurningTool_V2.83).
+ from the Linux Host that the example was build to a Windows PC.
+
+ Flash Tool can be found in this source tree under this directory
+
+ `third_party/mt793x_sdk/filogic/flash_tool`
+
+- On the Windows PC, run the Flash Tool
+
+ 1. Select the scatter.ini file in the `./out/light-switch-app` directory.
+ 2. Follow the instruction that comes with `EK-AI7931LD KIT` to switch the
+ kit to download mode.
+ 3. Click `Download` on FLASH TOOL.
+
+## Running the Complete Example
+
+- This example needs one lighting-app device and one light-switch-app device.
+
+- You can provision and control the Chip device using the python controller,
+ Chip tool standalone, Android or iOS app
+
+ [CHIP
+ Tool]](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/chip_tool_guide.md)
+
+- First of all, you have to commission with the light-switch-app (nodeID 1)
+ and the lighting-app (nodeID 2) with the CHIP tool by following commands.
+
+ ```
+ chip-tool pairing ble-wifi 1 my-ap myappassword 20202021 3840
+
+ chip-tool pairing ble-wifi 2 my-ap myappassword 20202021 3840
+ ```
+
+- Next, you have to configure the ACL in the lighting-app device to allow
+ access from switch device and chip-tool, and binding the lighting-app device
+ to the light-switch-app device by following commands.
+
+ ```
+ chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null },{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [1], "targets": null }]' 2 0
+
+ chip-tool binding write binding '[{"fabricIndex": 1, "node":2, "endpoint":1, "cluster":6}]' 1 1
+
+ ```
+
+- Once all setup successfully, you can control the lighting-app device through
+ the Matter Shell on the light-switch-app device.
+
+ ```
+ > switch onoff on
+ > switch onoff off
+ ```
+
+### Notes
+
+- Depending on your network settings your router might not provide native ipv6
+ addresses to your devices (Border router / PC). If this is the case, you
+ need to add a static ipv6 addresses on both device and then an ipv6 route to
+ the border router on your PC
diff --git a/examples/light-switch-app/genio/args.gni b/examples/light-switch-app/genio/args.gni
new file mode 100644
index 00000000000000..ddbfb9fa47f20d
--- /dev/null
+++ b/examples/light-switch-app/genio/args.gni
@@ -0,0 +1,34 @@
+# Copyright (c) 2022 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/mt793x/args.gni")
+
+mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain")
+
+pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip"
+pw_assert_BACKEND = "$dir_pw_assert_log"
+
+chip_enable_ble = true
+
+declare_args() {
+ chip_enable_ota_requestor = false
+
+ # Disable lock tracking, since our FreeRTOS configuration does not set
+ # INCLUDE_xSemaphoreGetMutexHolder
+ chip_stack_lock_tracking = "none"
+
+ chip_config_network_layer_ble = true
+}
diff --git a/examples/light-switch-app/genio/build_for_wifi_args.gni b/examples/light-switch-app/genio/build_for_wifi_args.gni
new file mode 100644
index 00000000000000..cb0ea7600a2dd5
--- /dev/null
+++ b/examples/light-switch-app/genio/build_for_wifi_args.gni
@@ -0,0 +1,22 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import("//build_overrides/chip.gni")
+import("//build_overrides/pigweed.gni")
+
+mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain")
+chip_enable_openthread = false
+import("${chip_root}/src/platform/MT793X/wifi_args.gni")
+
+pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip"
+pw_assert_BACKEND = "$dir_pw_assert_log"
diff --git a/examples/light-switch-app/genio/build_for_wifi_gnfile.gn b/examples/light-switch-app/genio/build_for_wifi_gnfile.gn
new file mode 100644
index 00000000000000..9752ee73e7c91d
--- /dev/null
+++ b/examples/light-switch-app/genio/build_for_wifi_gnfile.gn
@@ -0,0 +1,28 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+
+# The location of the build configuration file.
+buildconfig = "${build_root}/config/BUILDCONFIG.gn"
+
+# CHIP uses angle bracket includes.
+check_system_includes = true
+
+default_args = {
+ target_cpu = "arm"
+ target_os = "freertos"
+ use_thread = false
+ import("//build_for_wifi_args.gni")
+}
diff --git a/examples/light-switch-app/genio/build_overrides b/examples/light-switch-app/genio/build_overrides
new file mode 120000
index 00000000000000..e578e73312ebd1
--- /dev/null
+++ b/examples/light-switch-app/genio/build_overrides
@@ -0,0 +1 @@
+../../build_overrides
\ No newline at end of file
diff --git a/examples/light-switch-app/genio/include/AppConfig.h b/examples/light-switch-app/genio/include/AppConfig.h
new file mode 100644
index 00000000000000..b56761e90a1242
--- /dev/null
+++ b/examples/light-switch-app/genio/include/AppConfig.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// ---- Lighting Example App Config ----
+
+#define APP_TASK_NAME "Lit"
+
+// Time it takes in ms for the simulated actuator to move from one
+// state to another.
+#define ACTUATOR_MOVEMENT_PERIOS_MS 10
+
+// EFR Logging
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mt793xLogInit(void);
+
+void mt793xLog(const char * aFormat, ...);
+#define MT793X_LOG(aFormat...) mt793xLog(aFormat);
+void appError(int err);
+
+#ifdef __cplusplus
+}
+
+#include
+void appError(CHIP_ERROR error);
+#endif
diff --git a/examples/light-switch-app/genio/include/AppEvent.h b/examples/light-switch-app/genio/include/AppEvent.h
new file mode 100644
index 00000000000000..2483fe3cf9f831
--- /dev/null
+++ b/examples/light-switch-app/genio/include/AppEvent.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2020 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
+ {
+ bool Pressed;
+ } ButtonEvent;
+ struct
+ {
+ void * Context;
+ } TimerEvent;
+ struct
+ {
+ uint8_t Action;
+ int32_t Actor;
+ } LightEvent;
+ };
+
+ EventHandler Handler;
+};
diff --git a/examples/light-switch-app/genio/include/AppTask.h b/examples/light-switch-app/genio/include/AppTask.h
new file mode 100644
index 00000000000000..03f37a3b5f42b4
--- /dev/null
+++ b/examples/light-switch-app/genio/include/AppTask.h
@@ -0,0 +1,88 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "AppEvent.h"
+#include "filogic_button.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+#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)
+#define APP_ERROR_BHANDLER_INIT_FAILED CHIP_APPLICATION_ERROR(0x07)
+
+class AppTask
+{
+
+public:
+ CHIP_ERROR StartAppTask();
+ static void AppTaskMain(void * pvParameter);
+
+ void PostEvent(const AppEvent * event);
+
+ void ButtonHandler(const filogic_button_t & button);
+
+private:
+ friend AppTask & GetAppTask(void);
+
+ CHIP_ERROR Init();
+
+ void DispatchEvent(AppEvent * event);
+
+ static void SingleButtonEventHandler(AppEvent * aEvent);
+ static void ButtonTimerEventHandler(AppEvent * aEvent);
+
+ static void LightSwitchActionEventHandler(AppEvent * aEvent);
+
+ static void TimerEventHandler(TimerHandle_t xTimer);
+ void StartTimer(uint32_t aTimeoutMs);
+ void CancelTimer(void);
+
+ enum Function_t
+ {
+ kFunction_NoneSelected = 0,
+ kFunction_StartBleAdv = 1,
+ kFunction_LightSwitch = 2,
+ kFunction_FactoryReset = 3,
+ kFunction_SoftwareUpdate = 0,
+
+ kFunction_Invalid
+ } Function;
+
+ Function_t mFunction;
+ bool mFunctionTimerActive;
+
+ static AppTask sAppTask;
+};
+
+inline AppTask & GetAppTask(void)
+{
+ return AppTask::sAppTask;
+}
diff --git a/examples/light-switch-app/genio/include/BindingHandler.h b/examples/light-switch-app/genio/include/BindingHandler.h
new file mode 100644
index 00000000000000..aed08be25eb5bc
--- /dev/null
+++ b/examples/light-switch-app/genio/include/BindingHandler.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "app-common/zap-generated/ids/Clusters.h"
+#include "app-common/zap-generated/ids/Commands.h"
+#include "lib/core/CHIPError.h"
+
+CHIP_ERROR InitBindingHandler();
+void SwitchWorkerFunction(intptr_t context);
+void BindingWorkerFunction(intptr_t context);
+
+struct BindingCommandData
+{
+ chip::EndpointId localEndpointId = 1;
+ chip::CommandId commandId;
+ chip::ClusterId clusterId;
+ bool isGroup = false;
+};
diff --git a/examples/light-switch-app/genio/include/CHIPProjectConfig.h b/examples/light-switch-app/genio/include/CHIPProjectConfig.h
new file mode 100644
index 00000000000000..9dc6cad0065629
--- /dev/null
+++ b/examples/light-switch-app/genio/include/CHIPProjectConfig.h
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * Example project configuration file for CHIP.
+ *
+ * This is a place to put application or project-specific overrides
+ * to the default configuration values for general CHIP features.
+ *
+ */
+
+#pragma once
+
+// Use a default pairing code if one hasn't been provisioned in flash.
+#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021
+#endif
+
+#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00
+#endif
+
+// For convenience, Chip Security Test Mode can be enabled and the
+// requirement for authentication in various protocols can be disabled.
+//
+// WARNING: These options make it possible to circumvent basic Chip security functionality,
+// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS.
+//
+#define CHIP_CONFIG_SECURITY_TEST_MODE 0
+#define CHIP_CONFIG_REQUIRE_AUTH 1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID
+ *
+ * 0xFFF1: Test vendor
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID
+ *
+ * 0x8005: example lighting app
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION
+ *
+ * The hardware version 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 versions.
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
+ *
+ * A string identifying the software version running on the device.
+ * CHIP service currently expects the software version to be in the format
+ * {MAJOR_VERSION}.0d{MINOR_VERSION}
+ */
+#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_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)
+
+/**
+ * @def CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL
+ *
+ * @brief
+ * Active retransmit interval, or time to wait before retransmission after
+ * subsequent failures in milliseconds.
+ *
+ * This is the default value, that might be adjusted by end device depending on its
+ * needs (e.g. sleeping period) using Service Discovery TXT record CRA key.
+ *
+ */
+#define CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL (2000_ms32)
diff --git a/examples/light-switch-app/genio/include/LEDWidget.h b/examples/light-switch-app/genio/include/LEDWidget.h
new file mode 100644
index 00000000000000..35b0f52379e90c
--- /dev/null
+++ b/examples/light-switch-app/genio/include/LEDWidget.h
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include
+
+enum led_id
+{
+ LED_LIGHT,
+ LED_STATUS
+};
+
+enum led_color
+{
+ LED_RED,
+ LED_GREEN,
+ LED_BLUE
+};
+
+class LEDWidget
+{
+public:
+ // bind this LEDWidget with the specified LED
+ void Init(enum led_id led);
+ // retrieve the name of this LED
+ const char * Name(void);
+ // set to ON or OFF, no blink
+ void Set(bool state);
+ // change the color
+ void Color(enum led_color color);
+ // specify the ON, OFF duration
+ void Blink(int on, int off);
+ // specify evenly ON and OFF both to 'duration'
+ void Blink(int duration);
+
+private:
+ enum led_id mLed;
+ enum led_color mColor;
+ int mOn;
+ int mOff;
+ bool mState;
+ void Toggle(void);
+ void DoSet(bool state);
+
+ TimerHandle_t mTimer;
+ static void TimerHandler(TimerHandle_t xTimer);
+ void DoBlink(void);
+ void StartTimer(uint32_t aTimeoutInMs);
+ void CancelTimer(void);
+};
diff --git a/examples/light-switch-app/genio/mt793x_xip.ld b/examples/light-switch-app/genio/mt793x_xip.ld
new file mode 100755
index 00000000000000..fd577c07ca60a0
--- /dev/null
+++ b/examples/light-switch-app/genio/mt793x_xip.ld
@@ -0,0 +1,394 @@
+/*
+ * MT7933 CM33 Memory Map
+ */
+
+HIDDEN(__STACK_SIZE = 0x1000);
+HIDDEN(__SYSRAM_OFFSET = 0x0);
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Memory Spaces Definitions: 16MB flash */
+MEMORY
+{
+ ROM_BL(rx) : ORIGIN = 0x18000000, LENGTH = 64K
+ ROM_RBL(rx) : ORIGIN = 0x18010000, LENGTH = 8K
+ ROM_TFM(rx) : ORIGIN = 0x18012000, LENGTH = 200K
+ ROM_RTOS(rx) : ORIGIN = 0x18044000, LENGTH = 2092K
+ /*
+ Reserved : LENGTH = 228 K, 152 K For TFM
+ Free For Customer : LENGTH = 500 K
+ */
+ ROM_FOTA(r) : ORIGIN = 0x18305000, LENGTH = 3968K
+ ROM_NVDM(rx) : ORIGIN = 0x186E5000, LENGTH = 64K
+ ROM_LOG(rx) : ORIGIN = 0x186F5000, LENGTH = 64K
+ ROM_BT(rx) : ORIGIN = 0x18705000, LENGTH = 304K
+ /*
+ Reserved For FW : LENGTH = 40 K
+ */
+ ROM_WIFI_PWRTBL(rx): ORIGIN = 0x1875B000, LENGTH = 20K
+ ROM_WIFI_EXT(rx) : ORIGIN = 0x18760000, LENGTH = 636K
+ ROM_BUFFER_BIN(rx): ORIGIN = 0x187FF000, LENGTH = 4K
+
+ TCM(rwx) : ORIGIN = 0x0010C000, LENGTH = 20K
+ RAM_WFFW(rwx) : ORIGIN = 0xA0000000, LENGTH = 312K
+ RAM(rwx) : ORIGIN = 0xA004E000, LENGTH = 3272K
+ RAM_TFM(rwx) : ORIGIN = 0xA0380000, LENGTH = 512K
+ RAM_BTFW(rwx) : ORIGIN = 0xA0400000, LENGTH = 352K
+ SYSRAM(rwx) : ORIGIN = 0x80000000, LENGTH = 992K
+ /*
+ Reserved : LENGTH = 32K
+ */
+
+ VROM(rx) : ORIGIN = 0x18000000, LENGTH = 4096K
+ VRAM_WFFW(rwx) : ORIGIN = 0x10000000, LENGTH = 312K
+ VRAM(rwx) : ORIGIN = 0x1004E000, LENGTH = 3272K
+ VRAM_TFM(rwx) : ORIGIN = 0x10380000, LENGTH = 512K
+ VRAM_BTFW(rwx) : ORIGIN = 0x10400000, LENGTH = 352K
+ VSYSRAM(rwx) : ORIGIN = 0x08000000, LENGTH = 992K
+ /*
+ Reserved : LENGTH = 32K
+ */
+}
+
+/****************************************************************************
+ *
+ * FORWARD DECLARATIONS - SECTION SYMBOLS @ FLASH PHYSICAL ADDRESS
+ *
+ ****************************************************************************/
+
+
+_rom_bl_start = ORIGIN(ROM_BL) - ORIGIN(ROM_BL);
+_rom_bl_length = LENGTH(ROM_BL);
+_rom_rbl_start = ORIGIN(ROM_RBL) - ORIGIN(ROM_BL);
+_rom_rbl_length = LENGTH(ROM_RBL);
+_rom_tfm_start = ORIGIN(ROM_TFM) - ORIGIN(ROM_BL);
+_rom_tfm_length = LENGTH(ROM_TFM);
+_rom_rtos_start = ORIGIN(ROM_RTOS) - ORIGIN(ROM_BL);
+_rom_rtos_length = LENGTH(ROM_RTOS);
+_rom_fota_start = ORIGIN(ROM_FOTA) - ORIGIN(ROM_BL);
+_rom_fota_length = LENGTH(ROM_FOTA);
+_rom_wifi_patch_start = 0;/*ORIGIN(ROM_WIFI_PATCH) - ORIGIN(ROM_BL);*/
+_rom_wifi_patch_length = 0;/*LENGTH(ROM_WIFI_PATCH);*/
+_rom_wifi_start = 0;/*ORIGIN(ROM_WIFI) - ORIGIN(ROM_BL);*/
+_rom_wifi_length = 0;/*LENGTH(ROM_WIFI);*/
+_rom_wifi_ext_start = ORIGIN(ROM_WIFI_EXT) - ORIGIN(ROM_BL);
+_rom_wifi_ext_length = LENGTH(ROM_WIFI_EXT);
+_rom_wifi_pwrtbl_start = ORIGIN(ROM_WIFI_PWRTBL) - ORIGIN(ROM_BL);
+_rom_wifi_pwrtbl_length = LENGTH(ROM_WIFI_PWRTBL);
+_rom_buffer_bin_start = ORIGIN(ROM_BUFFER_BIN) - ORIGIN(ROM_BL);
+_rom_buffer_bin_length = LENGTH(ROM_BUFFER_BIN);
+_rom_bt_start = ORIGIN(ROM_BT) - ORIGIN(ROM_BL);
+_rom_bt_length = LENGTH(ROM_BT);
+_rom_nvdm_start = ORIGIN(ROM_NVDM) - ORIGIN(ROM_BL);
+_rom_nvdm_length = LENGTH(ROM_NVDM);
+_rom_log_start = ORIGIN(ROM_LOG) - ORIGIN(ROM_BL);
+_rom_log_length = LENGTH(ROM_LOG);
+
+
+/****************************************************************************
+ *
+ * FORWARD DECLARATIONS - SECTION SYMBOLS @ MEMORY BUS ADDRESS
+ *
+ ****************************************************************************/
+
+_xip_bl_addr = ORIGIN(ROM_BL);
+_xip_rbl_addr = ORIGIN(ROM_RBL);
+_xip_tfm_addr = ORIGIN(ROM_TFM);
+_xip_rtos_addr = ORIGIN(ROM_RTOS);
+_xip_nvdm_start = ORIGIN(ROM_NVDM);
+_xip_log_start = ORIGIN(ROM_LOG);
+_xip_bt_start = ORIGIN(ROM_BT);
+
+_sysram_start = ORIGIN(SYSRAM);
+_sysram_length = LENGTH(SYSRAM);
+_ram_start = ORIGIN(RAM);
+_ram_length = LENGTH(RAM);
+_ram_wifi_ext_start = ORIGIN(RAM_WFFW);
+_ram_wifi_ext_length = LENGTH(RAM_WFFW);
+_vram_start = ORIGIN(VRAM);
+_vram_length = LENGTH(VRAM);
+_vsysram_start = ORIGIN(VSYSRAM);
+_vsysram_length = LENGTH(VSYSRAM);
+_tcm_start = ORIGIN(TCM);
+_tcm_length = LENGTH(TCM);
+
+ /* Highest address of the stack */
+_stack_end = ORIGIN(TCM) + LENGTH(TCM); /* end of TCM */
+
+/* stack start */
+_stack_start = _stack_end - __STACK_SIZE;
+
+/* SYSRAM Region0 Offset for BROM */
+_region0_offset = 0x13000 ;
+
+SECTIONS
+{
+ . = ORIGIN(ROM_RTOS);
+ .text ALIGN(4):
+ {
+ _text_start = .;
+ KEEP(*(.vectorsTop))
+ KEEP(*(.vectors))
+ /* *(.text*) */
+ *(EXCLUDE_FILE(*/iperf_task.o *sockets*.o *netbuf*.o *pbuf*.o */mem.o *api_lib*.o */def.o *api_msg*.o *sys_arch*.o *ip4*.o *ip4_addr*.o *udp*.o *inet_chksum*.o *tcp_out*.o *tcp*.o */netif.o */ethernet.o *etharp*.o */lwip_cli.o *portasm*.o *event_groups*.o */heap_ext.o */queue.o */tasks.o *list*.o *os_port_callback*.o */port.o *timers*.o *hal_nvic*.o *libc_nano*.a:*memset*.o *libc_nano*.a:*memcpy*.o *libminisupp.a:*mem*.o) .text*)
+ KEEP(*(.init))
+ KEEP(*(.fini))
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+ *(.rodata*)
+ *(.rom_rtos)
+ KEEP(*(.eh_frame*))
+ . = ALIGN(4);
+ _text_end = .;
+ } > ROM_RTOS AT> ROM_RTOS
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > ROM_RTOS AT> ROM_RTOS
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > ROM_RTOS AT> ROM_RTOS
+ __exidx_end = .;
+
+ . = ALIGN(32);
+ _sysram_code_load = LOADADDR(.sysram_text);
+ .sysram_text ORIGIN(VSYSRAM)+_region0_offset :
+ {
+ _sysram_code_start = .;
+ *(.sysram_code)
+ *(.text*)
+ *(.sysram_rodata)
+ . = ALIGN(4);
+ _sysram_code_end = .;
+ } > VSYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _sysram_data_load = LOADADDR(.cached_sysram_data);
+ .cached_sysram_data :
+ {
+ _sysram_data_start = .;
+ *(vtable)
+ *(.data)
+ *(.data.*)
+ *(.sysram_rwdata)
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+ _sysram_data_end = .;
+ } > VSYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ .bss (NOLOAD) :
+ {
+ _sysram_bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ *(.sysram_zidata)
+ *(.sysram_swla_zidata)
+ . = ALIGN(4);
+ _sysram_bss_end = .;
+ } > VSYSRAM AT> ROM_RTOS
+
+
+ . = ALIGN(32);
+ _noncached_sysram_code_load = LOADADDR(.noncached_sysram_text);
+ . = . + ORIGIN(SYSRAM) - ORIGIN(VSYSRAM);
+ .noncached_sysram_text . :
+ {
+ _noncached_sysram_code_start = .;
+ *(.noncached_sysram_code)
+ *(.noncached_sysram_rodata)
+ . = ALIGN(4);
+ _noncached_sysram_code_end = .;
+ } > SYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _noncached_sysram_data_load = LOADADDR(.noncached_sysram_data);
+ .noncached_sysram_data . :
+ {
+ _noncached_sysram_data_start = .;
+ *(.noncached_sysram_rwdata)
+ *(.secure_settings_section)
+ . = ALIGN(4);
+ _noncached_sysram_data_end = .;
+ } > SYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ .noncached_sysram_bss . (NOLOAD) :
+ {
+ _noncached_sysram_bss_start = .;
+ *(.noncached_sysram_zidata)
+ . = ALIGN(4);
+ _noncached_sysram_bss_end = .;
+ } > SYSRAM AT> ROM_RTOS
+
+ . = ALIGN(32);
+ .btfw_code (NOLOAD) :
+ {
+ *(.bt_firmware_emi_code)
+ . = ALIGN(4);
+ } > RAM_BTFW AT> ROM_RTOS
+
+ . = ALIGN(32);
+ .wffw_code (NOLOAD) :
+ {
+ *(.wf_firmware_emi_code)
+ . = ALIGN(4);
+ } > RAM_WFFW AT> ROM_RTOS
+
+ . = ALIGN(32);
+ _ram_code_load = LOADADDR(.cached_ram_text);
+ .cached_ram_text :
+ {
+ _ram_code_start = .;
+ *(.ram_code)
+ *(.ram_rodata)
+ . = ALIGN(4);
+ _ram_code_end = .;
+ } > VRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _ram_data_load = LOADADDR(.cached_ram_data);
+ .cached_ram_data :
+ {
+ _ram_data_start = .;
+ *(.ram_rwdata)
+ . = ALIGN(4);
+ _ram_data_end = .;
+ } > VRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _ram_bss_load = LOADADDR(.cached_ram_bss);
+ .cached_ram_bss (NOLOAD) :
+ {
+ _ram_bss_start = .;
+ *(.ram_zidata)
+ . = ALIGN(4);
+ _ram_bss_end = .;
+ } > VRAM AT> ROM_RTOS
+
+ . = ALIGN(32);
+ _noncached_ram_code_load = LOADADDR(.noncached_ram_text);
+ . = . + ORIGIN(RAM) - ORIGIN(VRAM);
+ .noncached_ram_text . :
+ {
+ _noncached_ram_code_start = .;
+ *(.noncached_ram_code)
+ *(.noncached_ram_rodata)
+ . = ALIGN(4);
+ _noncached_ram_code_end = .;
+ } > RAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _noncached_ram_data_load = LOADADDR(.noncached_ram_data);
+ .noncached_ram_data . :
+ {
+ _noncached_ram_data_start = .;
+ *(.noncached_ram_rwdata)
+ . = ALIGN(4);
+ _noncached_ram_data_end = .;
+ } > RAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _noncached_ram_bss_load = LOADADDR(.noncached_ram_bss);
+ .noncached_ram_bss . (NOLOAD) :
+ {
+ _noncached_ram_bss_start = .;
+ *(.noncached_ram_zidata)
+ . = ALIGN(4);
+ _noncached_ram_bss_end = .;
+ } > RAM AT> ROM_RTOS
+
+
+ . = ALIGN(4);
+ _tcm_code_load = LOADADDR(.tcm_text);
+ .tcm_text :
+ {
+ _tcm_code_start = .;
+ *(.tcm_code)
+ *(.tcm_rodata)
+ . = ALIGN(4);
+ _tcm_code_end = .;
+ }> TCM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _tcm_data_load = LOADADDR(.tcm_data);
+ .tcm_data :
+ {
+ _tcm_data_start = .;
+ . = ALIGN(4);
+ *(.tcm_rwdata)
+ . = ALIGN(4);
+ _tcm_data_end = .;
+ }> TCM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ .tcm_bss (NOLOAD) :
+ {
+ _tcm_bss_start = .;
+ *(.tcm_zidata)
+ . = ALIGN(4);
+ *(.tcm_wakeup_info)
+ . = ALIGN(4);
+ _tcm_bss_end = .;
+ }> TCM AT> ROM_RTOS
+
+
+ __end__ = .;
+
+ .mcuboot_tlv_rsvd (NOLOAD) :
+ {
+ /* reserve 512 bytes for imgtool.py TLVs */
+ . = . + 512 ;
+ } > ROM_RTOS AT> ROM_RTOS
+
+ .stack (ORIGIN(TCM) + LENGTH(TCM) - __STACK_SIZE) (COPY) :
+ {
+ . = ALIGN(4);
+ __StackLimit = .;
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + __STACK_SIZE;
+ . = ALIGN(4);
+ __StackTop = .;
+ } > TCM
+
+ PROVIDE(__stack = __StackTop);
+
+ ASSERT(__StackLimit >= __end__, "region TCM overflowed with stack")
+}
+
+
+
diff --git a/examples/light-switch-app/genio/src/AppTask.cpp b/examples/light-switch-app/genio/src/AppTask.cpp
new file mode 100644
index 00000000000000..9f12f221846739
--- /dev/null
+++ b/examples/light-switch-app/genio/src/AppTask.cpp
@@ -0,0 +1,420 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AppTask.h"
+#include "AppConfig.h"
+#include "AppEvent.h"
+#include "BindingHandler.h"
+#include "LEDWidget.h"
+
+#include "qrcodegen.h"
+
+#include
+#include
+#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
+#define EXAMPLE_VENDOR_ID 0xcafe
+
+#ifdef portYIELD_FROM_ISR
+#define OS_YIELD_FROM_ISR(yield) portYIELD_FROM_ISR(yield)
+#elif portEND_SWITCHING_ISR
+#define OS_YIELD_FROM_ISR(yield) portEND_SWITCHING_ISR(yield)
+#else
+#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR"
+#endif
+
+namespace {
+
+TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer.
+TaskHandle_t sAppTaskHandle;
+QueueHandle_t sAppEventQueue;
+
+LEDWidget sStatusLED;
+
+bool sIsWiFiProvisioned = false;
+bool sIsWiFiEnabled = false;
+bool sIsWiFiAttached = false;
+
+uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(AppEvent)];
+StaticQueue_t sAppEventQueueStruct;
+
+StackType_t appStack[APP_TASK_STACK_SIZE * 2 / sizeof(StackType_t)];
+StaticTask_t appTaskStruct;
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
+using namespace chip::DeviceLayer::NetworkCommissioning;
+chip::app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */,
+ &GenioWiFiDriver::GetInstance());
+#endif
+
+} // 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)
+ {
+ MT793X_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);
+ if (sAppTaskHandle == nullptr)
+ return APP_ERROR_CREATE_TASK_FAILED;
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR AppTask::Init()
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+
+ // Wait for the WiFi to be initialized
+ MT793X_LOG("APP: Wait WiFi Init");
+ vTaskDelay(1000); // TODO
+ MT793X_LOG("APP: Done WiFi Init");
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
+ sWiFiNetworkCommissioningInstance.Init();
+#endif
+
+ // Init ZCL Data Model and start server
+ static chip::CommonCaseDeviceServerInitParams initParams;
+ (void) initParams.InitializeStaticResourcesBeforeServerInit();
+ chip::Server::GetInstance().Init(initParams);
+
+ // Initialize device attestation config
+ SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
+
+ // 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)
+ {
+ MT793X_LOG("funct timer create failed");
+ appError(APP_ERROR_CREATE_TIMER_FAILED);
+ }
+
+ MT793X_LOG("Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);
+
+ sStatusLED.Init(LED_STATUS);
+
+ ConfigurationMgr().LogDeviceConfig();
+
+ // Configure Bindings
+ if (CHIP_NO_ERROR != InitBindingHandler())
+ {
+ MT793X_LOG("InitBindingHandler() failed");
+ appError(APP_ERROR_BHANDLER_INIT_FAILED);
+ }
+
+ // PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE));
+ PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kSoftAP));
+
+ return error;
+}
+
+void AppTask::AppTaskMain(void * pvParameter)
+{
+ AppEvent event;
+
+ CHIP_ERROR error = sAppTask.Init();
+ if (error != CHIP_NO_ERROR)
+ {
+ MT793X_LOG("AppTask.Init() failed");
+ appError(error);
+ }
+
+ MT793X_LOG("AppTask 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())
+ {
+ sIsWiFiProvisioned = ConnectivityMgr().IsWiFiStationProvisioned();
+ sIsWiFiEnabled = ConnectivityMgr().IsWiFiStationEnabled();
+ sIsWiFiAttached = ConnectivityMgr().IsWiFiStationConnected();
+
+ 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 != kFunction_FactoryReset)
+ {
+ if (sIsWiFiProvisioned && sIsWiFiEnabled && !sIsWiFiAttached)
+ {
+ sStatusLED.Blink(950, 50);
+ }
+ else
+ {
+ sStatusLED.Blink(50, 950);
+ }
+ }
+ }
+}
+
+void AppTask::LightSwitchActionEventHandler(AppEvent * aEvent)
+{
+ bool initiated = false;
+ int32_t actor;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ if (aEvent->Type == AppEvent::kEventType_Button)
+ {
+ MT793X_LOG("Button was pressed!");
+
+ BindingCommandData * data = chip::Platform::New();
+ data->commandId = chip::app::Clusters::OnOff::Commands::Toggle::Id;
+ data->clusterId = chip::app::Clusters::OnOff::Id;
+
+ chip::DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ }
+}
+
+void AppTask::ButtonTimerEventHandler(AppEvent * aEvent)
+{
+ if (aEvent->Type != AppEvent::kEventType_Timer || sAppTask.mFunctionTimerActive == false)
+ {
+ return;
+ }
+
+ switch (sAppTask.mFunction)
+ {
+ case kFunction_NoneSelected:
+ break;
+
+ case kFunction_LightSwitch:
+ // Start timer for user to cancel the facotry reset, if needed
+ MT793X_LOG("Factory Reset Triggered.");
+ MT793X_LOG("Release button within %ums to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+ sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+ sAppTask.mFunction = kFunction_FactoryReset;
+
+ // Turn off all LEDs before starting blink to make sure blink is
+ // co-ordinated.
+ sStatusLED.Set(false);
+ sStatusLED.Blink(500);
+ break;
+
+ case kFunction_FactoryReset:
+ MT793X_LOG("Factory Reset Start.");
+ // Actually trigger Factory Reset
+ sAppTask.mFunction = kFunction_NoneSelected;
+ ConfigurationMgr().InitiateFactoryReset();
+ sStatusLED.Set(true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void AppTask::SingleButtonEventHandler(AppEvent * aEvent)
+{
+ if (aEvent->Type != AppEvent::kEventType_Button)
+ {
+ MT793X_LOG("A Non ButtonEvent received %d", aEvent->Type);
+ return;
+ }
+
+ if (aEvent->ButtonEvent.Pressed)
+ {
+ if (sAppTask.mFunctionTimerActive == false)
+ {
+ /* Start the timer to detect how long Button has been pressed */
+ sStatusLED.Set(true);
+ sAppTask.mFunction = kFunction_LightSwitch;
+ sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT);
+ }
+ else
+ {
+ MT793X_LOG("AppTask function timer already started");
+ }
+ }
+ else
+ {
+ /* Cancel the timer to detect how long Button has been pressed */
+ sAppTask.CancelTimer();
+
+ switch (sAppTask.mFunction)
+ {
+ case kFunction_LightSwitch:
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Button;
+ LightSwitchActionEventHandler(&event);
+ break;
+ case kFunction_FactoryReset:
+ // factory reset cancelled, restore LED
+ MT793X_LOG("AppTask factory reset cancelled");
+ break;
+ default:
+ MT793X_LOG("not handled key release event, mFunction = %x", sAppTask.mFunction);
+ break;
+ }
+
+ sStatusLED.Set(false);
+
+ sAppTask.mFunction = kFunction_NoneSelected;
+ }
+}
+
+void AppTask::ButtonHandler(const filogic_button_t & button)
+{
+ AppEvent button_event = {};
+ button_event.Type = AppEvent::kEventType_Button;
+ button_event.ButtonEvent.Pressed = button.press;
+ button_event.Handler = SingleButtonEventHandler;
+ sAppTask.PostEvent(&button_event);
+}
+
+void AppTask::TimerEventHandler(TimerHandle_t xTimer)
+{
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Timer;
+ event.TimerEvent.Context = (void *) xTimer;
+ event.Handler = ButtonTimerEventHandler;
+ sAppTask.PostEvent(&event);
+}
+
+void AppTask::CancelTimer()
+{
+ if (xTimerStop(sFunctionTimer, 0) == pdFAIL)
+ {
+ MT793X_LOG("app timer stop() failed");
+ appError(APP_ERROR_STOP_TIMER_FAILED);
+ }
+
+ mFunctionTimerActive = false;
+}
+
+void AppTask::StartTimer(uint32_t aTimeoutInMs)
+{
+ if (xTimerIsTimerActive(sFunctionTimer))
+ {
+ MT793X_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)
+ {
+ MT793X_LOG("app timer start() failed");
+ appError(APP_ERROR_START_TIMER_FAILED);
+ }
+
+ mFunctionTimerActive = true;
+}
+
+void AppTask::PostEvent(const AppEvent * aEvent)
+{
+ if (sAppEventQueue != NULL)
+ {
+ BaseType_t status;
+ if (xPortIsInsideInterrupt())
+ {
+ BaseType_t higherPrioTaskWoken;
+
+ higherPrioTaskWoken = pdFALSE;
+ status = xQueueSendFromISR(sAppEventQueue, aEvent, &higherPrioTaskWoken);
+ OS_YIELD_FROM_ISR(higherPrioTaskWoken);
+ }
+ else
+ {
+ status = xQueueSend(sAppEventQueue, aEvent, 1);
+ }
+
+ if (!status)
+ MT793X_LOG("Failed to post event to app task event queue");
+ }
+ else
+ {
+ MT793X_LOG("Event Queue is NULL should never happen");
+ }
+}
+
+void AppTask::DispatchEvent(AppEvent * aEvent)
+{
+ if (aEvent->Handler)
+ {
+ aEvent->Handler(aEvent);
+ }
+ else
+ {
+ MT793X_LOG("Event received with no handler. Dropping event.");
+ }
+}
diff --git a/examples/light-switch-app/genio/src/BindingHandler.cpp b/examples/light-switch-app/genio/src/BindingHandler.cpp
new file mode 100644
index 00000000000000..c8392f20ac9c4c
--- /dev/null
+++ b/examples/light-switch-app/genio/src/BindingHandler.cpp
@@ -0,0 +1,438 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BindingHandler.h"
+
+#include "AppConfig.h"
+#include "app/CommandSender.h"
+#include "app/clusters/bindings/BindingManager.h"
+#include "app/server/Server.h"
+#include "controller/InvokeInteraction.h"
+#include "platform/CHIPDeviceLayer.h"
+#include
+#include
+
+#if defined(ENABLE_CHIP_SHELL)
+#include "lib/shell/Engine.h"
+#include "lib/shell/commands/Help.h"
+#endif // ENABLE_CHIP_SHELL
+
+using namespace chip;
+using namespace chip::app;
+
+#if defined(ENABLE_CHIP_SHELL)
+using Shell::Engine;
+using Shell::shell_command_t;
+using Shell::streamer_get;
+using Shell::streamer_printf;
+
+Engine sShellSwitchSubCommands;
+Engine sShellSwitchOnOffSubCommands;
+
+Engine sShellSwitchGroupsSubCommands;
+Engine sShellSwitchGroupsOnOffSubCommands;
+
+Engine sShellSwitchBindingSubCommands;
+#endif // defined(ENABLE_CHIP_SHELL)
+
+namespace {
+
+void ProcessOnOffUnicastBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, DeviceProxy * peer_device)
+{
+ auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) {
+ ChipLogProgress(NotSpecified, "OnOff command succeeds");
+ };
+
+ auto onFailure = [](CHIP_ERROR error) {
+ ChipLogError(NotSpecified, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format());
+ };
+
+ // Eason+
+ ChipLogDetail(AppServer, "ProcessOnOffUnicastBindingCommand~~~~");
+
+ switch (commandId)
+ {
+ case Clusters::OnOff::Commands::Toggle::Id:
+ Clusters::OnOff::Commands::Toggle::Type toggleCommand;
+ Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
+ toggleCommand, onSuccess, onFailure);
+ break;
+
+ case Clusters::OnOff::Commands::On::Id:
+ Clusters::OnOff::Commands::On::Type onCommand;
+ Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
+ onCommand, onSuccess, onFailure);
+ break;
+
+ case Clusters::OnOff::Commands::Off::Id:
+ Clusters::OnOff::Commands::Off::Type offCommand;
+ Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
+ offCommand, onSuccess, onFailure);
+ break;
+ }
+}
+
+void ProcessOnOffGroupBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding)
+{
+ Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager();
+
+ switch (commandId)
+ {
+ case Clusters::OnOff::Commands::Toggle::Id:
+ Clusters::OnOff::Commands::Toggle::Type toggleCommand;
+ Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, toggleCommand);
+ break;
+
+ case Clusters::OnOff::Commands::On::Id:
+ Clusters::OnOff::Commands::On::Type onCommand;
+ Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, onCommand);
+
+ break;
+
+ case Clusters::OnOff::Commands::Off::Id:
+ Clusters::OnOff::Commands::Off::Type offCommand;
+ Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, offCommand);
+ break;
+ }
+}
+
+// void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, DeviceProxy * peer_device, void * context)
+void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, void * context)
+{
+ VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null"));
+ BindingCommandData * data = static_cast(context);
+
+ // Eason+
+ ChipLogDetail(AppServer, "LightSwitchChangedHandler~~~~~~~");
+
+ if (binding.type == EMBER_MULTICAST_BINDING && data->isGroup)
+ {
+ switch (data->clusterId)
+ {
+ case Clusters::OnOff::Id:
+ ProcessOnOffGroupBindingCommand(data->commandId, binding);
+ break;
+ }
+ }
+ else if (binding.type == EMBER_UNICAST_BINDING && !data->isGroup)
+ {
+ switch (data->clusterId)
+ {
+ case Clusters::OnOff::Id:
+ ProcessOnOffUnicastBindingCommand(data->commandId, binding, peer_device);
+ break;
+ }
+ }
+}
+
+void LightSwitchContextReleaseHandler(void * context)
+{
+ VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "LightSwitchContextReleaseHandler: context is null"));
+
+ Platform::Delete(static_cast(context));
+}
+
+#ifdef ENABLE_CHIP_SHELL
+
+/********************************************************
+ * Switch shell functions
+ *********************************************************/
+
+CHIP_ERROR SwitchHelpHandler(int argc, char ** argv)
+{
+ sShellSwitchSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR SwitchCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return SwitchHelpHandler(argc, argv);
+ }
+
+ return sShellSwitchSubCommands.ExecCommand(argc, argv);
+}
+
+/********************************************************
+ * OnOff switch shell functions
+ *********************************************************/
+
+CHIP_ERROR OnOffHelpHandler(int argc, char ** argv)
+{
+ sShellSwitchOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OnOffSwitchCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return OnOffHelpHandler(argc, argv);
+ }
+
+ return sShellSwitchOnOffSubCommands.ExecCommand(argc, argv);
+}
+
+CHIP_ERROR OnSwitchCommandHandler(int argc, char ** argv)
+{
+ BindingCommandData * data = Platform::New();
+ data->commandId = Clusters::OnOff::Commands::On::Id;
+ data->clusterId = Clusters::OnOff::Id;
+
+ DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OffSwitchCommandHandler(int argc, char ** argv)
+{
+ BindingCommandData * data = Platform::New();
+ data->commandId = Clusters::OnOff::Commands::Off::Id;
+ data->clusterId = Clusters::OnOff::Id;
+
+ DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ToggleSwitchCommandHandler(int argc, char ** argv)
+{
+ BindingCommandData * data = Platform::New();
+ data->commandId = Clusters::OnOff::Commands::Toggle::Id;
+ data->clusterId = Clusters::OnOff::Id;
+
+ DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ return CHIP_NO_ERROR;
+}
+
+/********************************************************
+ * bind switch shell functions
+ *********************************************************/
+
+CHIP_ERROR BindingHelpHandler(int argc, char ** argv)
+{
+ sShellSwitchBindingSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BindingSwitchCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return BindingHelpHandler(argc, argv);
+ }
+
+ return sShellSwitchBindingSubCommands.ExecCommand(argc, argv);
+}
+
+CHIP_ERROR BindingGroupBindCommandHandler(int argc, char ** argv)
+{
+ VerifyOrReturnError(argc == 2, CHIP_ERROR_INVALID_ARGUMENT);
+
+ EmberBindingTableEntry * entry = Platform::New();
+ entry->type = EMBER_MULTICAST_BINDING;
+ entry->fabricIndex = atoi(argv[0]);
+ entry->groupId = atoi(argv[1]);
+ entry->local = 1; // Hardcoded to endpoint 1 for now
+ entry->clusterId.SetValue(6); // Hardcoded to OnOff cluster for now
+
+ DeviceLayer::PlatformMgr().ScheduleWork(BindingWorkerFunction, reinterpret_cast(entry));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BindingUnicastBindCommandHandler(int argc, char ** argv)
+{
+ VerifyOrReturnError(argc == 3, CHIP_ERROR_INVALID_ARGUMENT);
+
+ EmberBindingTableEntry * entry = Platform::New();
+ entry->type = EMBER_UNICAST_BINDING;
+ entry->fabricIndex = atoi(argv[0]);
+ entry->nodeId = atoi(argv[1]);
+ entry->local = 1; // Hardcoded to endpoint 1 for now
+ entry->remote = atoi(argv[2]);
+ entry->clusterId.SetValue(6); // Hardcode to OnOff cluster for now
+
+ DeviceLayer::PlatformMgr().ScheduleWork(BindingWorkerFunction, reinterpret_cast(entry));
+ return CHIP_NO_ERROR;
+}
+
+/********************************************************
+ * Groups switch shell functions
+ *********************************************************/
+
+CHIP_ERROR GroupsHelpHandler(int argc, char ** argv)
+{
+ sShellSwitchGroupsSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR GroupsSwitchCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return GroupsHelpHandler(argc, argv);
+ }
+
+ return sShellSwitchGroupsSubCommands.ExecCommand(argc, argv);
+}
+
+/********************************************************
+ * Groups OnOff switch shell functions
+ *********************************************************/
+
+CHIP_ERROR GroupsOnOffHelpHandler(int argc, char ** argv)
+{
+ sShellSwitchGroupsOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR GroupsOnOffSwitchCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return GroupsOnOffHelpHandler(argc, argv);
+ }
+
+ return sShellSwitchGroupsOnOffSubCommands.ExecCommand(argc, argv);
+}
+
+CHIP_ERROR GroupOnSwitchCommandHandler(int argc, char ** argv)
+{
+ BindingCommandData * data = Platform::New();
+ data->commandId = Clusters::OnOff::Commands::On::Id;
+ data->clusterId = Clusters::OnOff::Id;
+ data->isGroup = true;
+
+ DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR GroupOffSwitchCommandHandler(int argc, char ** argv)
+{
+ BindingCommandData * data = Platform::New();
+ data->commandId = Clusters::OnOff::Commands::Off::Id;
+ data->clusterId = Clusters::OnOff::Id;
+ data->isGroup = true;
+
+ DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR GroupToggleSwitchCommandHandler(int argc, char ** argv)
+{
+ BindingCommandData * data = Platform::New();
+ data->commandId = Clusters::OnOff::Commands::Toggle::Id;
+ data->clusterId = Clusters::OnOff::Id;
+ data->isGroup = true;
+
+ DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
+ return CHIP_NO_ERROR;
+}
+
+/**
+ * @brief configures switch matter shell
+ *
+ */
+static void RegisterSwitchCommands()
+{
+ static const shell_command_t sSwitchSubCommands[] = {
+ { &SwitchHelpHandler, "help", "Usage: switch " },
+ { &OnOffSwitchCommandHandler, "onoff", " Usage: switch onoff " },
+ { &GroupsSwitchCommandHandler, "groups", "Usage: switch groups " },
+ { &BindingSwitchCommandHandler, "binding", "Usage: switch binding " }
+ };
+
+ static const shell_command_t sSwitchOnOffSubCommands[] = {
+ { &OnOffHelpHandler, "help", "Usage : switch ononff " },
+ { &OnSwitchCommandHandler, "on", "Sends on command to bound lighting app" },
+ { &OffSwitchCommandHandler, "off", "Sends off command to bound lighting app" },
+ { &ToggleSwitchCommandHandler, "toggle", "Sends toggle command to bound lighting app" }
+ };
+
+ static const shell_command_t sSwitchGroupsSubCommands[] = { { &GroupsHelpHandler, "help", "Usage: switch groups " },
+ { &GroupsOnOffSwitchCommandHandler, "onoff",
+ "Usage: switch groups onoff " } };
+
+ static const shell_command_t sSwitchGroupsOnOffSubCommands[] = {
+ { &GroupsOnOffHelpHandler, "help", "Usage: switch groups onoff " },
+ { &GroupOnSwitchCommandHandler, "on", "Sends on command to bound group" },
+ { &GroupOffSwitchCommandHandler, "off", "Sends off command to bound group" },
+ { &GroupToggleSwitchCommandHandler, "toggle", "Sends toggle command to group" }
+ };
+
+ static const shell_command_t sSwitchBindingSubCommands[] = {
+ { &BindingHelpHandler, "help", "Usage: switch binding " },
+ { &BindingGroupBindCommandHandler, "group", "Usage: switch binding group " },
+ { &BindingUnicastBindCommandHandler, "unicast", "Usage: switch binding group " }
+ };
+
+ static const shell_command_t sSwitchCommand = { &SwitchCommandHandler, "switch",
+ "Light-switch commands. Usage: switch " };
+
+ sShellSwitchGroupsOnOffSubCommands.RegisterCommands(sSwitchGroupsOnOffSubCommands, ArraySize(sSwitchGroupsOnOffSubCommands));
+ sShellSwitchOnOffSubCommands.RegisterCommands(sSwitchOnOffSubCommands, ArraySize(sSwitchOnOffSubCommands));
+ sShellSwitchGroupsSubCommands.RegisterCommands(sSwitchGroupsSubCommands, ArraySize(sSwitchGroupsSubCommands));
+ sShellSwitchBindingSubCommands.RegisterCommands(sSwitchBindingSubCommands, ArraySize(sSwitchBindingSubCommands));
+ sShellSwitchSubCommands.RegisterCommands(sSwitchSubCommands, ArraySize(sSwitchSubCommands));
+
+ Engine::Root().RegisterCommands(&sSwitchCommand, 1);
+}
+#endif // ENABLE_CHIP_SHELL
+
+void InitBindingHandlerInternal(intptr_t arg)
+{
+ auto & server = chip::Server::GetInstance();
+ chip::BindingManager::GetInstance().Init(
+ { &server.GetFabricTable(), server.GetCASESessionManager(), &server.GetPersistentStorage() });
+ chip::BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(LightSwitchChangedHandler);
+ chip::BindingManager::GetInstance().RegisterBoundDeviceContextReleaseHandler(LightSwitchContextReleaseHandler);
+}
+
+} // namespace
+
+/********************************************************
+ * Switch functions
+ *********************************************************/
+
+void SwitchWorkerFunction(intptr_t context)
+{
+ VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "SwitchWorkerFunction - Invalid work data"));
+
+ BindingCommandData * data = reinterpret_cast(context);
+ BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data));
+}
+
+void BindingWorkerFunction(intptr_t context)
+{
+ VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "BindingWorkerFunction - Invalid work data"));
+
+ EmberBindingTableEntry * entry = reinterpret_cast(context);
+ AddBindingEntry(*entry);
+
+ Platform::Delete(entry);
+}
+
+CHIP_ERROR InitBindingHandler()
+{
+ // The initialization of binding manager will try establishing connection with unicast peers
+ // so it requires the Server instance to be correctly initialized. Post the init function to
+ // the event queue so that everything is ready when initialization is conducted.
+ chip::DeviceLayer::PlatformMgr().ScheduleWork(InitBindingHandlerInternal);
+#if defined(ENABLE_CHIP_SHELL)
+ RegisterSwitchCommands();
+#endif
+ return CHIP_NO_ERROR;
+}
diff --git a/examples/light-switch-app/genio/src/LEDWidget.cpp b/examples/light-switch-app/genio/src/LEDWidget.cpp
new file mode 100644
index 00000000000000..f6a627af164ea9
--- /dev/null
+++ b/examples/light-switch-app/genio/src/LEDWidget.cpp
@@ -0,0 +1,153 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+
+#include
+
+#include "LEDWidget.h"
+
+void LEDWidget::TimerHandler(TimerHandle_t xTimer)
+{
+ LEDWidget * led_widget = (LEDWidget *) pvTimerGetTimerID(xTimer);
+ led_widget->Toggle();
+}
+
+void LEDWidget::StartTimer(uint32_t aTimeoutInMs)
+{
+ if (xTimerIsTimerActive(mTimer))
+ CancelTimer();
+
+ assert(xTimerChangePeriod(mTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) == pdPASS);
+}
+
+void LEDWidget::CancelTimer(void)
+{
+ assert(xTimerStop(mTimer, 0) == pdPASS);
+}
+
+void LEDWidget::Init(enum led_id led)
+{
+ filogic_led_init();
+
+ mLed = led;
+
+ mTimer = xTimerCreate(Name(),
+ 1, // == default timer period (mS)
+ false, // no timer reload (==one-shot)
+ (void *) this, // init timer id = app task obj context
+ TimerHandler); // timer callback handler
+}
+
+const char * LEDWidget::Name(void)
+{
+ const char * name;
+
+ switch (mLed)
+ {
+ case LED_LIGHT:
+ name = "LED_LIGHT";
+ break;
+ case LED_STATUS:
+ name = "LED_STATUS";
+ break;
+ default:
+ name = "LED UNKNOWN";
+ break;
+ }
+
+ return name;
+}
+
+void LEDWidget::Toggle(void)
+{
+ Set(!mState);
+ StartTimer(mState ? mOn : mOff);
+}
+
+void LEDWidget::DoBlink(void)
+{
+ // turn off then turn on
+ Set(false);
+ Set(true);
+ StartTimer(mOn);
+}
+
+void LEDWidget::DoSet(bool state)
+{
+ switch (mLed)
+ {
+ case LED_LIGHT:
+ filogic_led_light_toggle(state);
+ break;
+ case LED_STATUS:
+ filogic_led_status_toggle(state);
+ break;
+ }
+ mState = state;
+}
+
+void LEDWidget::Set(bool state)
+{
+ CancelTimer();
+ DoSet(state);
+ // printf("%s %s\n", Name(), state ? "on" : "off");
+}
+
+void LEDWidget::Blink(int on, int off)
+{
+ if (mOn != on || mOff != off)
+ {
+ mOn = on;
+ mOff = off;
+ printf("%s blink: on %d off %d\n", Name(), mOn, mOff);
+ DoBlink();
+ }
+}
+
+void LEDWidget::Blink(int duration)
+{
+ Blink(duration, duration);
+}
+
+void LEDWidget::Color(enum led_color color)
+{
+ filogic_led_color_t _color = FILOGIC_LED_OFF;
+
+ switch (color)
+ {
+ case LED_RED:
+ _color = FILOGIC_LED_R;
+ case LED_GREEN:
+ _color = FILOGIC_LED_G;
+ case LED_BLUE:
+ _color = FILOGIC_LED_B;
+ }
+
+ switch (mLed)
+ {
+ case LED_LIGHT:
+ filogic_led_light_color(_color);
+ break;
+ case LED_STATUS:
+ filogic_led_status_color(_color);
+ break;
+ }
+
+ printf("%s color %d\n", Name(), color);
+}
diff --git a/examples/light-switch-app/genio/src/ZclCallbacks.cpp b/examples/light-switch-app/genio/src/ZclCallbacks.cpp
new file mode 100644
index 00000000000000..52542ca88fb390
--- /dev/null
+++ b/examples/light-switch-app/genio/src/ZclCallbacks.cpp
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * This file implements the handler for data model messages.
+ */
+
+#include "AppConfig.h"
+
+#include
+#include
+#include
+#include
+
+using namespace ::chip;
+using namespace ::chip::app::Clusters;
+
+void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, 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 == OnOffSwitchConfiguration::Id)
+ {
+ ChipLogProgress(Zcl, "OnOff Switch Configuration attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
+ ChipLogValueMEI(attributeId), type, *value, size);
+
+ // WIP Apply attribute change to Light
+ }
+ else if (clusterId == Identify::Id)
+ {
+ ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
+ 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/light-switch-app/genio/src/main.cpp b/examples/light-switch-app/genio/src/main.cpp
new file mode 100644
index 00000000000000..93bb82a21b0735
--- /dev/null
+++ b/examples/light-switch-app/genio/src/main.cpp
@@ -0,0 +1,277 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "AppConfig.h"
+#include
+
+#ifdef HEAP_MONITORING
+#include "MemMonitoring.h"
+#endif
+
+#include
+
+#ifdef ENABLE_CHIP_SHELL
+#include "matter_shell.h"
+#endif
+
+#define WIFI_DEV_NAME "MediaTek-Light"
+
+using namespace ::chip;
+using namespace ::chip::Inet;
+using namespace ::chip::DeviceLayer;
+
+#define UNUSED_PARAMETER(a) (a = a)
+
+volatile int apperror_cnt;
+
+/***************************************************************************
+ * Application Error hang
+ ****************************************************************************/
+
+void appError(int err)
+{
+ printf("!!!!!!!!!!!! Application Critical Error: %d !!!!!!!!!!!", err);
+ portDISABLE_INTERRUPTS();
+ while (1)
+ ;
+}
+
+void appError(CHIP_ERROR error)
+{
+ appError(static_cast(error.AsInteger()));
+}
+
+/***************************************************************************
+ * FORWARD DECLARATIONS
+ ****************************************************************************/
+
+extern "C" void system_init(void);
+
+void vStartTask(void * pvParameters);
+
+/***************************************************************************
+ * FreeRTOS callback functions
+ ****************************************************************************/
+
+#if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
+
+extern "C" void vApplicationDaemonTaskStartupHook(void)
+{
+#define START_TASK_STACK_SIZE (1000)
+ BaseType_t xReturned;
+
+ xReturned = xTaskCreate(vStartTask, /* Function that implements the task. */
+ "startTask", /* Text name for the task. */
+ START_TASK_STACK_SIZE, /* Stack size in words, not bytes. */
+ (void *) 0, /* Parameter passed into the task. */
+ tskIDLE_PRIORITY, /* Priority at which the task is created. */
+ NULL); /* Used to pass out the created task's handle. */
+
+ configASSERT(xReturned == pdPASS);
+}
+
+#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */
+
+#if (configUSE_IDLE_HOOK == 1)
+
+/* for idle task feed wdt (DO NOT enter sleep mode)*/
+extern "C" void vApplicationIdleHook(void)
+{
+#ifdef MTK_SYSTEM_HANG_CHECK_ENABLE
+#ifdef HAL_WDT_MODULE_ENABLED
+ hal_wdt_feed(HAL_WDT_FEED_MAGIC);
+#endif
+#endif
+}
+
+#endif /* configUSE_IDLE_HOOK */
+
+#if (configSUPPORT_STATIC_ALLOCATION == 1)
+
+extern "C" void vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer,
+ uint32_t * pulTimerTaskStackSize)
+{
+ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
+ *ppxTimerTaskTCBBuffer = (StaticTask_t *) pvPortMalloc(sizeof(StaticTask_t));
+ if (*ppxTimerTaskTCBBuffer != NULL)
+ {
+ *ppxTimerTaskStackBuffer = (StackType_t *) pvPortMalloc((((size_t) *pulTimerTaskStackSize) * sizeof(StackType_t)));
+ }
+}
+
+extern "C" void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer,
+ uint32_t * pulIdleTaskStackSize)
+{
+ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
+ *ppxIdleTaskTCBBuffer = (StaticTask_t *) pvPortMalloc(sizeof(StaticTask_t));
+ if (*ppxIdleTaskTCBBuffer != NULL)
+ {
+ *ppxIdleTaskStackBuffer = (StackType_t *) pvPortMalloc((((size_t) *pulIdleTaskStackSize) * sizeof(StackType_t)));
+ }
+}
+
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/*******************************************************************************
+ * DECLARATIONS
+ ******************************************************************************/
+
+void mt793xLog(const char * aFormat, ...)
+{
+ va_list vargs;
+
+ va_start(vargs, aFormat);
+ vprintf(aFormat, vargs);
+ va_end(vargs);
+ printf("\n");
+}
+
+void mt793xLogRedirectCallback(const char * module, uint8_t category, const char * msg, va_list args)
+{
+ int len;
+ char * buf;
+
+ len = strlen(module) + 1 + vsnprintf(NULL, 0, msg, args) + 1;
+ buf = (char *) malloc(len);
+ if (buf)
+ {
+ len = sprintf(buf, "%s ", module);
+ vsprintf(buf + len, msg, args);
+ printf("%s\n", buf);
+ free(buf);
+ }
+}
+
+void mt793xSwdPortConfig(void)
+{
+ *(volatile uint32_t *) 0x30404358 = 0x00070700;
+ *(volatile uint32_t *) 0x30404354 = 0x00020200;
+ *(volatile uint32_t *) 0x304030e0 = 0x1e8210;
+ *(volatile uint32_t *) 0x304030d4 = 0;
+}
+
+/***************************************************************************
+ * Button Callback
+ ****************************************************************************/
+
+void vButtonCallback(const filogic_button_t * button_event)
+{
+ GetAppTask().ButtonHandler(*button_event);
+}
+
+/***************************************************************************
+ * Supplicant Log Redirect
+ ****************************************************************************/
+
+extern "C" {
+void mt793x_wpa_log_cb(void * ctx, int level, int type, const char * txt, size_t len)
+{
+ /* ignore ctx, type, len */
+ (void) ctx;
+ (void) level;
+ (void) len;
+
+ ChipLogProgress(DeviceLayer, "[%lu] FILOGIC supp %s", xTaskGetTickCount(), txt);
+}
+
+void wpa_msg_register_cb(void *);
+}
+
+/***************************************************************************
+ * Startup task
+ ****************************************************************************/
+
+void vStartRunning(void)
+{
+ CHIP_ERROR error;
+
+ chip::Logging::SetLogRedirectCallback(mt793xLogRedirectCallback);
+
+ wpa_msg_register_cb((void *) mt793x_wpa_log_cb);
+
+ assert(chip::Platform::MemoryInit() == CHIP_NO_ERROR);
+
+ assert(chip::DeviceLayer::PlatformMgr().InitChipStack() == CHIP_NO_ERROR);
+
+ // Wi-Fi ?
+ // chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(BLE_DEV_NAME);
+
+ assert(chip::DeviceLayer::PlatformMgr().StartEventLoopTask() == CHIP_NO_ERROR);
+
+ assert(GetAppTask().StartAppTask() == CHIP_NO_ERROR);
+
+ assert(filogic_button_set_callback(vButtonCallback));
+
+ assert(filogic_button_init());
+
+#ifdef ENABLE_CHIP_SHELL
+ chip::startShellTask();
+#endif
+}
+
+void vStartTask(void * pvParameters)
+{
+ (void) pvParameters;
+
+ vStartRunning();
+
+ vTaskDelete(NULL);
+}
+
+/***************************************************************************
+ * Main Function
+ ****************************************************************************/
+
+extern "C" int main(void)
+{
+ mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree);
+
+#ifdef HEAP_MONITORING
+ MemMonitoring::startHeapMonitoring();
+#endif
+
+ system_init();
+
+ mt793xSwdPortConfig();
+
+ vTaskStartScheduler();
+
+ chip::Platform::MemoryShutdown();
+
+ // Should never get here.
+ while (1)
+ ;
+
+ return 0;
+}
diff --git a/examples/light-switch-app/genio/third_party/connectedhomeip b/examples/light-switch-app/genio/third_party/connectedhomeip
new file mode 120000
index 00000000000000..c866b86874994d
--- /dev/null
+++ b/examples/light-switch-app/genio/third_party/connectedhomeip
@@ -0,0 +1 @@
+../../../..
\ No newline at end of file
diff --git a/examples/light-switch-app/genio/with_pw_rpc.gni b/examples/light-switch-app/genio/with_pw_rpc.gni
new file mode 100644
index 00000000000000..581b4f415d5654
--- /dev/null
+++ b/examples/light-switch-app/genio/with_pw_rpc.gni
@@ -0,0 +1,27 @@
+# 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.
+
+# add this gni as import in your build args to use pigweed in the example
+# 'import("//with_pw_rpc.gni")'
+
+import("//build_overrides/chip.gni")
+import("${chip_root}/config/mt793x/lib/pw_rpc/pw_rpc.gni")
+import("${chip_root}/examples/platform/mt793x/args.gni")
+
+mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain")
+
+chip_enable_pw_rpc = true
+chip_enable_openthread = true
+
+cpp_standard = "gnu++17"
diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap
index 4764e6a4b93051..d28695f5333ddf 100644
--- a/examples/light-switch-app/light-switch-common/light-switch-app.zap
+++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap
@@ -606,7 +606,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -632,7 +632,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -1572,7 +1572,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 1,
"commands": [
@@ -1624,7 +1624,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -1700,7 +1700,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -1736,7 +1736,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
diff --git a/examples/lighting-app/bouffalolab/bl602/src/main.cpp b/examples/lighting-app/bouffalolab/bl602/src/main.cpp
index de96a44d69608c..25620080817951 100644
--- a/examples/lighting-app/bouffalolab/bl602/src/main.cpp
+++ b/examples/lighting-app/bouffalolab/bl602/src/main.cpp
@@ -51,7 +51,7 @@ void appError(int err)
{
log_error("!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!\r\n", err);
portDISABLE_INTERRUPTS();
- while (1)
+ while (true)
;
}
diff --git a/examples/lighting-app/bouffalolab/bl702/src/main.cpp b/examples/lighting-app/bouffalolab/bl702/src/main.cpp
index 687c6c71212d84..ae194de5fbe0cb 100644
--- a/examples/lighting-app/bouffalolab/bl702/src/main.cpp
+++ b/examples/lighting-app/bouffalolab/bl702/src/main.cpp
@@ -65,7 +65,7 @@ void appError(int err)
{
ChipLogProgress(NotSpecified, "!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!", err);
portDISABLE_INTERRUPTS();
- while (1)
+ while (true)
;
}
@@ -87,7 +87,7 @@ extern "C" unsigned int sleep(unsigned int seconds)
extern "C" void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName)
{
ChipLogProgress(NotSpecified, "Stack Overflow checked. Stack name %s", pcTaskName);
- while (1)
+ while (true)
{
/*empty here*/
}
@@ -96,7 +96,7 @@ extern "C" void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskN
extern "C" void vApplicationMallocFailedHook(void)
{
ChipLogProgress(NotSpecified, "Memory Allocate Failed. Current left size is %d bytes", xPortGetFreeHeapSize());
- while (1)
+ while (true)
{
/*empty here*/
}
@@ -168,7 +168,7 @@ extern "C" void vAssertCalled(void)
taskDISABLE_INTERRUPTS();
ChipLogProgress(NotSpecified, "vAssertCalled, ra= %p", ra);
- while (1)
+ while (true)
;
}
diff --git a/examples/lighting-app/genio/BUILD.gn b/examples/lighting-app/genio/BUILD.gn
index d77706624fd8f7..6d7e34c9db4d8f 100644
--- a/examples/lighting-app/genio/BUILD.gn
+++ b/examples/lighting-app/genio/BUILD.gn
@@ -64,10 +64,14 @@ mt793x_sdk("sdk") {
mt793x_executable("lighting_app") {
output_name = "chip-mt793x-lighting-app-example.out"
include_dirs = [ "include" ]
- defines = []
+ defines = [
+ #"__PWM_DIMMABLE_LED__"
+ ]
sources = [
"src/AppTask.cpp",
+ "src/ColorFormat.cpp",
+ "src/DimmableLEDWidget.cpp",
"src/LEDWidget.cpp",
"src/LightingManager.cpp",
"src/ZclCallbacks.cpp",
diff --git a/examples/lighting-app/genio/README.md b/examples/lighting-app/genio/README.md
index 18dfa286261309..867882a3ba7e98 100644
--- a/examples/lighting-app/genio/README.md
+++ b/examples/lighting-app/genio/README.md
@@ -1,10 +1,10 @@
-#CHIP `Genio` Lighting Example
+#Matter `Genio` Lighting Example
-An example showing the use of CHIP on the MediaTek `Genio` MT793X.
+An example showing the use of Matter on the MediaTek `Genio` MT793X.
-- [CHIP Genio Lighting Example](#chip-genio-lighting-example)
+- [Matter Genio Lighting Example](#chip-genio-lighting-example)
- [Introduction](#introduction)
- [Building](#building)
- [Note](#note)
@@ -20,7 +20,7 @@ An example showing the use of CHIP on the MediaTek `Genio` MT793X.
## Introduction
The `Genio` (MT793X) lighting example provides a baseline demonstration of a
-Light control device, built using CHIP and the MediaTek `Genio` SDK. It can be
+Light control device, built using Matter and the MediaTek `Genio` SDK. It can be
controlled by a Chip controller over Wi-Fi network.
The `Genio` device can be commissioned over Bluetooth Low Energy where the
@@ -29,7 +29,7 @@ Rendez-vous procedure. Network credentials are then provided to the `Genio`
device which will then join the network.
The lighting example is intended to serve both as a means to explore the
-workings of CHIP as well as a template for creating real products based on the
+workings of Matter as well as a template for creating real products based on the
MediaTek platform.
@@ -104,6 +104,16 @@ MediaTek platform.
chiptool onoff off 1 1
```
+- You can test the LED by light command as shown below
+
+ ```
+ > light
+ help Usage: light
+ onoff Usage: light onoff
+ color Usage: light color
+ level Usage: light level
+ ```
+
### Notes
- Depending on your network settings your router might not provide native ipv6
diff --git a/examples/lighting-app/genio/include/AppEvent.h b/examples/lighting-app/genio/include/AppEvent.h
index 2483fe3cf9f831..3042d92ebd0d5b 100644
--- a/examples/lighting-app/genio/include/AppEvent.h
+++ b/examples/lighting-app/genio/include/AppEvent.h
@@ -30,6 +30,7 @@ struct AppEvent
kEventType_Timer,
kEventType_Light,
kEventType_Install,
+ kEventType_Occupancy,
};
uint16_t Type;
@@ -48,7 +49,12 @@ struct AppEvent
{
uint8_t Action;
int32_t Actor;
+ uint32_t Value;
} LightEvent;
+ struct
+ {
+ bool Present;
+ } OccupancytEvent;
};
EventHandler Handler;
diff --git a/examples/lighting-app/genio/include/AppTask.h b/examples/lighting-app/genio/include/AppTask.h
index 77d21715196189..9909e2e197f954 100644
--- a/examples/lighting-app/genio/include/AppTask.h
+++ b/examples/lighting-app/genio/include/AppTask.h
@@ -45,10 +45,11 @@ class AppTask
CHIP_ERROR StartAppTask();
static void AppTaskMain(void * pvParameter);
- void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction);
+ void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction, uint32_t uValue);
void PostEvent(const AppEvent * event);
void ButtonHandler(const filogic_button_t & button);
+ void OccupancyHandler(bool present);
private:
friend AppTask & GetAppTask(void);
@@ -62,6 +63,7 @@ class AppTask
static void SingleButtonEventHandler(AppEvent * aEvent);
static void ButtonTimerEventHandler(AppEvent * aEvent);
+ static void OccupancyEventHandler(AppEvent * aEvent);
static void LightActionEventHandler(AppEvent * aEvent);
diff --git a/examples/lighting-app/genio/include/ColorFormat.h b/examples/lighting-app/genio/include/ColorFormat.h
new file mode 100755
index 00000000000000..1ad0cb0e75f4f4
--- /dev/null
+++ b/examples/lighting-app/genio/include/ColorFormat.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+
+struct RgbColor_t
+{
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+};
+
+struct HsvColor_t
+{
+ uint8_t h;
+ uint8_t s;
+ uint8_t v;
+};
+
+struct XyColor_t
+{
+ uint16_t x;
+ uint16_t y;
+};
+
+struct CtColor_t
+{
+ uint16_t ctMireds;
+};
+
+RgbColor_t XYToRgb(uint8_t Level, uint16_t currentX, uint16_t currentY);
+RgbColor_t HsvToRgb(HsvColor_t hsv);
+RgbColor_t CTToRgb(CtColor_t ct);
diff --git a/examples/lighting-app/genio/include/DimmableLEDIf.h b/examples/lighting-app/genio/include/DimmableLEDIf.h
new file mode 100644
index 00000000000000..ce63aff1efce86
--- /dev/null
+++ b/examples/lighting-app/genio/include/DimmableLEDIf.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+class DimmableLEDIf
+{
+public:
+ /* set to ON or OFF */
+ virtual void Set(bool state) = 0;
+ /* Get On/Off state */
+ virtual bool Get(void) = 0;
+ /* change light level */
+ virtual void SetLevel(uint8_t level) = 0;
+ /* Get current level*/
+ virtual uint8_t GetLevel(void) = 0;
+ virtual uint8_t GetMaxLevel(void) = 0;
+ virtual uint8_t GetMinLevel(void) = 0;
+};
diff --git a/examples/lighting-app/genio/include/DimmableLEDWidget.h b/examples/lighting-app/genio/include/DimmableLEDWidget.h
new file mode 100644
index 00000000000000..7e7a354eca42ea
--- /dev/null
+++ b/examples/lighting-app/genio/include/DimmableLEDWidget.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "DimmableLEDIf.h"
+#include "hal_gpio.h"
+
+class DimmableLEDWidget : public DimmableLEDIf
+{
+public:
+ void Init(hal_gpio_pin_t gpio);
+ /* set to ON or OFF */
+ virtual void Set(bool state);
+ /* Get On/Off state */
+ virtual bool Get(void);
+ /* change light level */
+ virtual void SetLevel(uint8_t level);
+ /* Get current level*/
+ virtual uint8_t GetLevel(void);
+ virtual uint8_t GetMaxLevel(void);
+ virtual uint8_t GetMinLevel(void);
+
+private:
+ bool mState; /* On or Off status */
+ uint8_t mLevel; /* Current level */
+ hal_gpio_pin_t mGpioPin;
+};
diff --git a/examples/lighting-app/genio/include/LEDWidget.h b/examples/lighting-app/genio/include/LEDWidget.h
index 35b0f52379e90c..2690d5856930b3 100644
--- a/examples/lighting-app/genio/include/LEDWidget.h
+++ b/examples/lighting-app/genio/include/LEDWidget.h
@@ -20,6 +20,8 @@
#include
#include
+#include "ColorFormat.h"
+#include "DimmableLEDIf.h"
#include
enum led_id
@@ -35,27 +37,36 @@ enum led_color
LED_BLUE
};
-class LEDWidget
+class LEDWidget : public DimmableLEDIf
{
public:
// bind this LEDWidget with the specified LED
void Init(enum led_id led);
// retrieve the name of this LED
const char * Name(void);
- // set to ON or OFF, no blink
- void Set(bool state);
// change the color
- void Color(enum led_color color);
+ void Color(RgbColor_t color);
// specify the ON, OFF duration
void Blink(int on, int off);
// specify evenly ON and OFF both to 'duration'
void Blink(int duration);
+ /* set to ON or OFF */
+ virtual void Set(bool state);
+ /* Get On/Off state */
+ virtual bool Get(void);
+ /* change light level */
+ virtual void SetLevel(uint8_t level);
+ /* Get current level*/
+ virtual uint8_t GetLevel(void);
+ virtual uint8_t GetMaxLevel(void);
+ virtual uint8_t GetMinLevel(void);
+
private:
enum led_id mLed;
- enum led_color mColor;
int mOn;
int mOff;
+ uint8_t mLevel; /* Current level */
bool mState;
void Toggle(void);
void DoSet(bool state);
diff --git a/examples/lighting-app/genio/include/LightingManager.h b/examples/lighting-app/genio/include/LightingManager.h
index 3aa9871e919074..87769216bf9f8c 100644
--- a/examples/lighting-app/genio/include/LightingManager.h
+++ b/examples/lighting-app/genio/include/LightingManager.h
@@ -35,24 +35,33 @@ class LightingManager
{
ON_ACTION = 0,
OFF_ACTION,
+ LEVEL_ACTION,
+ COLOR_ACTION,
+ COLOR_ACTION_XY,
+ COLOR_ACTION_HSV,
+ COLOR_ACTION_CT,
+ OCCUPANCY_PRESENT_ACTION,
+ OCCUPANCY_CLEAR_ACTION,
INVALID_ACTION
} Action;
enum State_t
{
- kState_OffInitiated = 0,
- kState_OffCompleted,
- kState_OnInitiated,
+ kState_OnInitiated = 0,
kState_OnCompleted,
+ kState_OffInitiated,
+ kState_OffCompleted,
+ kState_LevelInitiated,
+ kState_ColorInitiated
} State;
CHIP_ERROR Init();
bool IsLightOn();
+ bool IsActionInProgress();
+ bool InitiateAction(int32_t aActor, Action_t aAction, uint8_t * aValue);
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);
diff --git a/examples/lighting-app/genio/src/AppTask.cpp b/examples/lighting-app/genio/src/AppTask.cpp
index 99b6bfb435c1ee..e681d28a22169a 100644
--- a/examples/lighting-app/genio/src/AppTask.cpp
+++ b/examples/lighting-app/genio/src/AppTask.cpp
@@ -20,12 +20,14 @@
#include "AppTask.h"
#include "AppConfig.h"
#include "AppEvent.h"
+#include "ColorFormat.h"
#include "LEDWidget.h"
#include "qrcodegen.h"
#include
#include
+#include
#include
#include
#include
@@ -47,6 +49,11 @@
#include
#include
+#if defined(ENABLE_CHIP_SHELL)
+#include "lib/shell/Engine.h"
+#include "lib/shell/commands/Help.h"
+#endif // ENABLE_CHIP_SHELL
+
#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
#define APP_TASK_STACK_SIZE (4096)
@@ -64,6 +71,20 @@
#define UNUSED_PARAMETER(a) (a = a)
+#if defined(ENABLE_CHIP_SHELL)
+using chip::Shell::Engine;
+using chip::Shell::PrintCommandHelp;
+using chip::Shell::shell_command_t;
+using chip::Shell::streamer_get;
+using chip::Shell::streamer_printf;
+
+using namespace chip::app::Clusters;
+
+Engine sShellLightSubCommands;
+Engine sShellLightOnOffSubCommands;
+
+#endif // defined(ENABLE_CHIP_SHELL)
+
namespace {
TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer.
@@ -71,7 +92,7 @@ TaskHandle_t sAppTaskHandle;
QueueHandle_t sAppEventQueue;
LEDWidget sStatusLED;
-LEDWidget sLightLED;
+uint8_t sLightLEDLevelChangedCount = 0;
bool sIsWiFiProvisioned = false;
bool sIsWiFiEnabled = false;
@@ -97,6 +118,182 @@ using namespace ::chip::DeviceLayer;
AppTask AppTask::sAppTask;
+#ifdef ENABLE_CHIP_SHELL
+
+/********************************************************
+ * Light shell functions
+ *********************************************************/
+
+CHIP_ERROR LightHelpHandler(int argc, char ** argv)
+{
+ sShellLightSubCommands.ForEachCommand(PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR LightCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return LightHelpHandler(argc, argv);
+ }
+
+ return sShellLightSubCommands.ExecCommand(argc, argv);
+}
+
+/********************************************************
+ * OnOff switch shell functions
+ *********************************************************/
+
+CHIP_ERROR OnOffHelpHandler(int argc, char ** argv)
+{
+ sShellLightOnOffSubCommands.ForEachCommand(PrintCommandHelp, nullptr);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OnOffLightCommandHandler(int argc, char ** argv)
+{
+ if (argc == 0)
+ {
+ return OnOffHelpHandler(argc, argv);
+ }
+
+ return sShellLightOnOffSubCommands.ExecCommand(argc, argv);
+}
+
+CHIP_ERROR OnLightCommandHandler(int argc, char ** argv)
+{
+ GetAppTask().PostLightActionRequest(0, LightingManager::ON_ACTION, 0);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OffLightCommandHandler(int argc, char ** argv)
+{
+ GetAppTask().PostLightActionRequest(0, LightingManager::OFF_ACTION, 0);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ColorLightCommandHandler(int argc, char ** argv)
+{
+ uint32_t rgb = 0;
+
+ if (argc < 3)
+ {
+ return LightHelpHandler(argc, argv);
+ }
+
+ rgb = (atoi(argv[2]) << 16) | (atoi(argv[1]) << 8) | atoi(argv[0]);
+ MT793X_LOG("ColorLightCommandHandler: %x", rgb);
+
+ GetAppTask().PostLightActionRequest(0, LightingManager::COLOR_ACTION, rgb);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR LevelLightCommandHandler(int argc, char ** argv)
+{
+ uint8_t level = 0;
+ if (argc < 1)
+ {
+ return LightHelpHandler(argc, argv);
+ }
+
+ level = atoi(argv[0]);
+ MT793X_LOG("LevelLightCommandHandler: %d", level);
+ GetAppTask().PostLightActionRequest(0, LightingManager::LEVEL_ACTION, level);
+ return CHIP_NO_ERROR;
+}
+
+/********************************************************
+ * Occupancy sensor simulation shell functions
+ *********************************************************/
+
+CHIP_ERROR OccuPresentLightCommandHandler(int argc, char ** argv)
+{
+ GetAppTask().OccupancyHandler(true);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OccuClearLightCommandHandler(int argc, char ** argv)
+{
+ GetAppTask().OccupancyHandler(false);
+ return CHIP_NO_ERROR;
+}
+
+/********************************************************
+ * Register all light commands
+ *********************************************************/
+
+/**
+ * @brief configures lighting-app matter shell
+ *
+ */
+static void RegisterLightCommands()
+{
+ static const shell_command_t sLightSubCommands[] = {
+ {
+ .cmd_func = LightHelpHandler,
+ .cmd_name = "help",
+ .cmd_help = "Usage: light ",
+ },
+ {
+ .cmd_func = OnOffLightCommandHandler,
+ .cmd_name = "onoff",
+ .cmd_help = "Usage: light onoff ",
+ },
+ {
+ .cmd_func = ColorLightCommandHandler,
+ .cmd_name = "color",
+ .cmd_help = "Usage: light color ",
+ },
+ {
+ .cmd_func = LevelLightCommandHandler,
+ .cmd_name = "level",
+ .cmd_help = "Usage: light level ",
+ },
+ {
+ .cmd_func = OccuPresentLightCommandHandler,
+ .cmd_name = "present",
+ .cmd_help = "Sends occupancy present event to lighting app",
+ },
+ {
+ .cmd_func = OccuClearLightCommandHandler,
+ .cmd_name = "clear",
+ .cmd_help = "Sends occupancy clear to lighting app",
+ },
+ };
+
+ static const shell_command_t sLightOnOffSubCommands[] = {
+ {
+ .cmd_func = OnOffHelpHandler,
+ .cmd_name = "help",
+ .cmd_help = "Usage : light ononff ",
+ },
+ {
+ .cmd_func = OnLightCommandHandler,
+ .cmd_name = "on",
+ .cmd_help = "Sends on command to lighting app",
+ },
+ {
+ .cmd_func = OffLightCommandHandler,
+ .cmd_name = "off",
+ .cmd_help = "Sends off command to lighting app",
+ },
+ };
+
+ static const shell_command_t sLightCommand[] = {
+ {
+ .cmd_func = LightCommandHandler,
+ .cmd_name = "light",
+ .cmd_help = "Lighting-app commands. Usage: light ",
+ },
+ };
+
+ sShellLightOnOffSubCommands.RegisterCommands(sLightOnOffSubCommands, ArraySize(sLightOnOffSubCommands));
+ sShellLightSubCommands.RegisterCommands(sLightSubCommands, ArraySize(sLightSubCommands));
+
+ Engine::Root().RegisterCommands(sLightCommand, ArraySize(sLightCommand));
+}
+#endif // ENABLE_CHIP_SHELL
+
CHIP_ERROR AppTask::StartAppTask()
{
sAppEventQueue = xQueueCreateStatic(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent), sAppEventQueueBuffer, &sAppEventQueueStruct);
@@ -118,6 +315,8 @@ CHIP_ERROR AppTask::Init()
{
CHIP_ERROR error = CHIP_NO_ERROR;
+ sLightLEDLevelChangedCount = 0;
+
// Wait for the WiFi to be initialized
MT793X_LOG("APP: Wait WiFi Init");
vTaskDelay(1000); // TODO
@@ -159,14 +358,16 @@ CHIP_ERROR AppTask::Init()
LightMgr().SetCallbacks(ActionInitiated, ActionCompleted);
sStatusLED.Init(LED_STATUS);
- sLightLED.Init(LED_LIGHT);
- sLightLED.Set(LightMgr().IsLightOn());
ConfigurationMgr().LogDeviceConfig();
// PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE));
PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kSoftAP));
+#if defined(ENABLE_CHIP_SHELL)
+ RegisterLightCommands();
+#endif
+
return error;
}
@@ -238,23 +439,32 @@ void AppTask::LightActionEventHandler(AppEvent * aEvent)
LightingManager::Action_t action;
int32_t actor;
CHIP_ERROR err = CHIP_NO_ERROR;
+ uint8_t level = 0;
if (aEvent->Type == AppEvent::kEventType_Light)
{
action = static_cast(aEvent->LightEvent.Action);
actor = aEvent->LightEvent.Actor;
+ level = aEvent->LightEvent.Value;
}
else if (aEvent->Type == AppEvent::kEventType_Button)
{
- if (LightMgr().IsLightOn())
+ if (LightMgr().IsLightOn() && sLightLEDLevelChangedCount >= 4)
{
- action = LightingManager::OFF_ACTION;
+ sLightLEDLevelChangedCount = 1;
+ action = LightingManager::OFF_ACTION;
+ }
+ else if (LightMgr().IsLightOn() && sLightLEDLevelChangedCount < 4)
+ {
+ sLightLEDLevelChangedCount += 1;
+ action = LightingManager::LEVEL_ACTION;
}
else
{
action = LightingManager::ON_ACTION;
}
actor = AppEvent::kEventType_Button;
+ level = sLightLEDLevelChangedCount * 25;
}
else
{
@@ -263,7 +473,20 @@ void AppTask::LightActionEventHandler(AppEvent * aEvent)
if (err == CHIP_NO_ERROR)
{
- initiated = LightMgr().InitiateAction(actor, action);
+ if (action == LightingManager::COLOR_ACTION)
+ {
+ RgbColor_t rbg;
+ uint32_t rbg_raw = aEvent->LightEvent.Value;
+ rbg.r = rbg_raw & 0xFF;
+ rbg.g = (rbg_raw & 0xFF00) >> 8;
+ rbg.b = (rbg_raw & 0xFF0000) >> 16;
+ initiated = LightMgr().InitiateAction(AppEvent::kEventType_Light, action, (uint8_t *) &rbg);
+ }
+ else
+ {
+ MT793X_LOG("Lighting level: %d", level);
+ initiated = LightMgr().InitiateAction(AppEvent::kEventType_Light, action, &level);
+ }
if (!initiated)
{
@@ -310,6 +533,21 @@ void AppTask::ButtonTimerEventHandler(AppEvent * aEvent)
}
}
+void AppTask::OccupancyEventHandler(AppEvent * aEvent)
+{
+ if (aEvent->Type != AppEvent::kEventType_Occupancy)
+ {
+ MT793X_LOG("A Non Occupancy received %d", aEvent->Type);
+ return;
+ }
+
+ uint8_t attributeValue = aEvent->OccupancytEvent.Present ? 1 : 0;
+
+ MT793X_LOG("Lighting occupancy: %u", attributeValue);
+
+ OccupancySensing::Attributes::Occupancy::Set(1, attributeValue);
+}
+
void AppTask::SingleButtonEventHandler(AppEvent * aEvent)
{
if (aEvent->Type != AppEvent::kEventType_Button)
@@ -361,6 +599,15 @@ void AppTask::SingleButtonEventHandler(AppEvent * aEvent)
}
}
+void AppTask::OccupancyHandler(bool present)
+{
+ AppEvent occupancy_event = {};
+ occupancy_event.Type = AppEvent::kEventType_Occupancy;
+ occupancy_event.OccupancytEvent.Present = present;
+ occupancy_event.Handler = OccupancyEventHandler;
+ sAppTask.PostEvent(&occupancy_event);
+}
+
void AppTask::ButtonHandler(const filogic_button_t & button)
{
AppEvent button_event = {};
@@ -416,12 +663,18 @@ void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor)
if (aAction == LightingManager::ON_ACTION)
{
MT793X_LOG("Turning light ON")
- sLightLED.Set(true);
}
else if (aAction == LightingManager::OFF_ACTION)
{
MT793X_LOG("Turning light OFF")
- sLightLED.Set(false);
+ }
+ else if (aAction == LightingManager::LEVEL_ACTION)
+ {
+ MT793X_LOG("Changing light level")
+ }
+ else if (aAction == LightingManager::COLOR_ACTION)
+ {
+ MT793X_LOG("Changing light color")
}
}
@@ -436,14 +689,23 @@ void AppTask::ActionCompleted(LightingManager::Action_t aAction)
{
MT793X_LOG("Light OFF")
}
+ else if (aAction == LightingManager::LEVEL_ACTION)
+ {
+ MT793X_LOG("Light level changed")
+ }
+ else if (aAction == LightingManager::COLOR_ACTION)
+ {
+ MT793X_LOG("Light color changed")
+ }
}
-void AppTask::PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction)
+void AppTask::PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction, uint32_t uValue)
{
AppEvent event;
event.Type = AppEvent::kEventType_Light;
event.LightEvent.Actor = aActor;
event.LightEvent.Action = aAction;
+ event.LightEvent.Value = uValue;
event.Handler = LightActionEventHandler;
PostEvent(&event);
}
diff --git a/examples/lighting-app/genio/src/ColorFormat.cpp b/examples/lighting-app/genio/src/ColorFormat.cpp
new file mode 100644
index 00000000000000..b68b6ca926e009
--- /dev/null
+++ b/examples/lighting-app/genio/src/ColorFormat.cpp
@@ -0,0 +1,187 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ColorFormat.h"
+
+#include
+
+// define a clamp macro to substitute the std::clamp macro which is available from C++17 onwards
+#define clamp(a, min, max) ((a) < (min) ? (min) : ((a) > (max) ? (max) : (a)))
+
+RgbColor_t HsvToRgb(HsvColor_t hsv)
+{
+ RgbColor_t rgb;
+
+ uint8_t region, p, q, t;
+ uint32_t h, s, v, remainder;
+
+ if (hsv.s == 0)
+ {
+ rgb.r = rgb.g = rgb.b = hsv.v;
+ }
+ else
+ {
+ h = hsv.h;
+ s = hsv.s;
+ v = hsv.v;
+
+ region = h / 43;
+ remainder = (h - (region * 43)) * 6;
+ p = (v * (255 - s)) >> 8;
+ q = (v * (255 - ((s * remainder) >> 8))) >> 8;
+ t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
+ switch (region)
+ {
+ case 0:
+ rgb.r = v, rgb.g = t, rgb.b = p;
+ break;
+ case 1:
+ rgb.r = q, rgb.g = v, rgb.b = p;
+ break;
+ case 2:
+ rgb.r = p, rgb.g = v, rgb.b = t;
+ break;
+ case 3:
+ rgb.r = p, rgb.g = q, rgb.b = v;
+ break;
+ case 4:
+ rgb.r = t, rgb.g = p, rgb.b = v;
+ break;
+ case 5:
+ default:
+ rgb.r = v, rgb.g = p, rgb.b = q;
+ break;
+ }
+ }
+
+ return rgb;
+}
+
+RgbColor_t XYToRgb(uint8_t Level, uint16_t currentX, uint16_t currentY)
+{
+ // convert xyY color space to RGB
+
+ // https://www.easyrgb.com/en/math.php
+ // https://en.wikipedia.org/wiki/SRGB
+ // refer https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space
+
+ // The currentX/currentY attribute contains the current value of the normalized chromaticity value of x/y.
+ // The value of x/y shall be related to the currentX/currentY attribute by the relationship
+ // x = currentX/65536
+ // y = currentY/65536
+ // z = 1-x-y
+
+ RgbColor_t rgb;
+
+ float x, y, z;
+ float X, Y, Z;
+ float r, g, b;
+
+ x = ((float) currentX) / 65535.0f;
+ y = ((float) currentY) / 65535.0f;
+
+ z = 1.0f - x - y;
+
+ // Calculate XYZ values
+
+ // Y - given brightness in 0 - 1 range
+ Y = ((float) Level) / 254.0f;
+ X = (Y / y) * x;
+ Z = (Y / y) * z;
+
+ // X, Y and Z input refer to a D65/2° standard illuminant.
+ // sR, sG and sB (standard RGB) output range = 0 ÷ 255
+ // convert XYZ to RGB - CIE XYZ to sRGB
+ X = X / 100.0f;
+ Y = Y / 100.0f;
+ Z = Z / 100.0f;
+
+ r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f);
+ g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f);
+ b = (X * 0.0557f) - (Y * 0.2040f) + (Z * 1.0570f);
+
+ // apply gamma 2.2 correction
+ r = (r <= 0.0031308f ? 12.92f * r : (1.055f) * pow(r, (1.0f / 2.4f)) - 0.055f);
+ g = (g <= 0.0031308f ? 12.92f * g : (1.055f) * pow(g, (1.0f / 2.4f)) - 0.055f);
+ b = (b <= 0.0031308f ? 12.92f * b : (1.055f) * pow(b, (1.0f / 2.4f)) - 0.055f);
+
+ // Round off
+ r = clamp(r, 0, 1);
+ g = clamp(g, 0, 1);
+ b = clamp(b, 0, 1);
+
+ // these rgb values are in the range of 0 to 1, convert to limit of HW specific LED
+ rgb.r = (uint8_t)(r * 255);
+ rgb.g = (uint8_t)(g * 255);
+ rgb.b = (uint8_t)(b * 255);
+
+ return rgb;
+}
+
+RgbColor_t CTToRgb(CtColor_t ct)
+{
+ RgbColor_t rgb;
+ float r, g, b;
+
+ // Algorithm credits to Tanner Helland: https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html
+
+ // Convert Mireds to centiKelvins. k = 1,000,000/mired
+ float ctCentiKelvin = 10000 / ct.ctMireds;
+
+ // Red
+ if (ctCentiKelvin <= 66)
+ {
+ r = 255;
+ }
+ else
+ {
+ r = 329.698727446f * pow(ctCentiKelvin - 60, -0.1332047592f);
+ }
+
+ // Green
+ if (ctCentiKelvin <= 66)
+ {
+ g = 99.4708025861f * log(ctCentiKelvin) - 161.1195681661f;
+ }
+ else
+ {
+ g = 288.1221695283f * pow(ctCentiKelvin - 60, -0.0755148492f);
+ }
+
+ // Blue
+ if (ctCentiKelvin >= 66)
+ {
+ b = 255;
+ }
+ else
+ {
+ if (ctCentiKelvin <= 19)
+ {
+ b = 0;
+ }
+ else
+ {
+ b = 138.5177312231 * log(ctCentiKelvin - 10) - 305.0447927307;
+ }
+ }
+ rgb.r = (uint8_t) clamp(r, 0, 255);
+ rgb.g = (uint8_t) clamp(g, 0, 255);
+ rgb.b = (uint8_t) clamp(b, 0, 255);
+
+ return rgb;
+}
diff --git a/examples/lighting-app/genio/src/DimmableLEDWidget.cpp b/examples/lighting-app/genio/src/DimmableLEDWidget.cpp
new file mode 100644
index 00000000000000..b176bbb0fd7a72
--- /dev/null
+++ b/examples/lighting-app/genio/src/DimmableLEDWidget.cpp
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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.
+ */
+
+#ifdef __PWM_DIMMABLE_LED__
+
+#include "DimmableLEDWidget.h"
+#include
+#include
+
+#include "hal_pwm.h"
+
+#define LIGHT_LEVEL_MIN (0)
+#define LIGHT_LEVEL_MAX (100)
+#define LIGHT_LEVEL_DEFAULT (50)
+#define PWM_FREQUENCY_DEFAULT (1000)
+#define LEVEL_TO_PWM_RATIO(level) ((level) *10)
+
+static hal_pwm_channel_t convert_gpio_to_pwm_channel(hal_gpio_pin_t gpio)
+{
+ hal_pwm_channel_t ret = HAL_PWM_MAX;
+ if (gpio >= HAL_GPIO_29 && gpio <= HAL_GPIO_40)
+ {
+ ret = (hal_pwm_channel_t)(gpio - HAL_GPIO_29);
+ }
+ else if (gpio >= HAL_GPIO_45 && gpio <= HAL_GPIO_52)
+ {
+ ret = (hal_pwm_channel_t)(gpio - HAL_GPIO_45);
+ }
+ else
+ {
+ assert(false);
+ }
+
+ return ret;
+}
+
+void DimmableLEDWidget::Init(hal_gpio_pin_t gpio)
+{
+ hal_pwm_channel_t pwm_channel = HAL_PWM_MAX;
+ uint32_t total_count = 0;
+ mGpioPin = gpio;
+ mState = false;
+ mLevel = LIGHT_LEVEL_DEFAULT;
+
+ hal_gpio_init(mGpioPin);
+ if (mGpioPin >= HAL_GPIO_29 && mGpioPin <= HAL_GPIO_40)
+ {
+ assert(HAL_PINMUX_STATUS_OK == hal_pinmux_set_function(mGpioPin, 3));
+ }
+ else if (mGpioPin >= HAL_GPIO_45 && mGpioPin <= HAL_GPIO_52)
+ {
+ assert(HAL_PINMUX_STATUS_OK == hal_pinmux_set_function(mGpioPin, 5));
+ }
+ else
+ {
+ /* This GPIO is not supported PWM */
+ assert(false);
+ }
+
+ pwm_channel = convert_gpio_to_pwm_channel(mGpioPin);
+
+ assert(HAL_PWM_STATUS_OK == hal_pwm_init(pwm_channel, HAL_PWM_CLOCK_26MHZ));
+ assert(HAL_PWM_STATUS_OK == hal_pwm_set_frequency(pwm_channel, PWM_FREQUENCY_DEFAULT, &total_count));
+ assert(HAL_PWM_STATUS_OK == hal_pwm_set_duty_cycle(pwm_channel, LEVEL_TO_PWM_RATIO(mLevel)));
+}
+
+void DimmableLEDWidget::Set(bool state)
+{
+ hal_pwm_channel_t pwm_channel = convert_gpio_to_pwm_channel(mGpioPin);
+
+ if (state && !mState)
+ {
+ mState = true;
+ assert(HAL_PWM_STATUS_OK == hal_pwm_start(pwm_channel));
+ }
+ else if (!state && mState)
+ {
+ mState = false;
+ assert(HAL_PWM_STATUS_OK == hal_pwm_stop(pwm_channel));
+ }
+}
+
+bool DimmableLEDWidget::Get(void)
+{
+ return mState;
+}
+
+void DimmableLEDWidget::SetLevel(uint8_t level)
+{
+ hal_pwm_channel_t pwm_channel = convert_gpio_to_pwm_channel(mGpioPin);
+
+ if (level >= LIGHT_LEVEL_MIN && level <= LIGHT_LEVEL_MAX && level != mLevel)
+ {
+ mLevel = level;
+ assert(HAL_PWM_STATUS_OK == hal_pwm_set_duty_cycle(pwm_channel, LEVEL_TO_PWM_RATIO(mLevel)));
+ }
+}
+
+uint8_t DimmableLEDWidget::GetLevel(void)
+{
+ return mLevel;
+}
+
+uint8_t DimmableLEDWidget::GetMaxLevel(void)
+{
+ return LIGHT_LEVEL_MAX;
+}
+
+uint8_t DimmableLEDWidget::GetMinLevel(void)
+{
+ return LIGHT_LEVEL_MIN;
+}
+
+#endif /* __PWM_DIMMABLE_LED__ */
diff --git a/examples/lighting-app/genio/src/LEDWidget.cpp b/examples/lighting-app/genio/src/LEDWidget.cpp
index 15ef981f7654b2..1882fe6efe377a 100644
--- a/examples/lighting-app/genio/src/LEDWidget.cpp
+++ b/examples/lighting-app/genio/src/LEDWidget.cpp
@@ -22,6 +22,9 @@
#include "LEDWidget.h"
+#define MIN_LVL (1)
+#define MAX_LVL (254)
+
void LEDWidget::TimerHandler(TimerHandle_t xTimer)
{
LEDWidget * led_widget = (LEDWidget *) pvTimerGetTimerID(xTimer);
@@ -45,7 +48,8 @@ void LEDWidget::Init(enum led_id led)
{
filogic_led_init();
- mLed = led;
+ mLed = led;
+ mLevel = MAX_LVL;
mTimer = xTimerCreate(Name(),
1, // == default timer period (mS)
@@ -106,6 +110,11 @@ void LEDWidget::Set(bool state)
// printf("%s %s\n", Name(), state ? "on" : "off");
}
+bool LEDWidget::Get(void)
+{
+ return mState;
+}
+
void LEDWidget::Blink(int on, int off)
{
if (mOn != on || mOff != off)
@@ -122,19 +131,12 @@ void LEDWidget::Blink(int duration)
Blink(duration, duration);
}
-void LEDWidget::Color(enum led_color color)
+void LEDWidget::Color(RgbColor_t rgb)
{
- filogic_led_color_t _color = FILOGIC_LED_OFF;
-
- switch (color)
- {
- case LED_RED:
- _color = FILOGIC_LED_R;
- case LED_GREEN:
- _color = FILOGIC_LED_G;
- case LED_BLUE:
- _color = FILOGIC_LED_B;
- }
+ filogic_led_color_t _color;
+ _color.r = rgb.r;
+ _color.g = rgb.g;
+ _color.b = rgb.b;
switch (mLed)
{
@@ -145,6 +147,69 @@ void LEDWidget::Color(enum led_color color)
filogic_led_status_color(_color);
break;
}
+}
+
+void LEDWidget::SetLevel(uint8_t level)
+{
+ uint8_t fdim = 0;
+
+ if (level >= MIN_LVL && level <= MAX_LVL)
+ {
+ mLevel = level;
+ }
+ else
+ {
+ return;
+ }
+
+ fdim = (level - MIN_LVL) / ((MAX_LVL - MIN_LVL) / (filogic_led_get_max_dim_level() - filogic_led_get_min_dim_level()));
+
+ if (fdim > filogic_led_get_max_dim_level())
+ {
+ fdim = filogic_led_get_max_dim_level();
+ }
+
+ if (mLed == LED_LIGHT)
+ {
+ filogic_led_light_dim(fdim);
+ }
+ else if (mLed == LED_STATUS)
+ {
+ filogic_led_status_dim(fdim);
+ }
+ else
+ {
+ assert(0);
+ }
+}
- // printf("%s color %d\n", Name(), color);
+uint8_t LEDWidget::GetLevel(void)
+{
+ uint8_t dim = 0;
+ if (mLed == LED_LIGHT)
+ {
+ dim = filogic_led_light_get_cur_dim_level();
+ }
+ else if (mLed == LED_STATUS)
+ {
+ dim = filogic_led_status_get_cur_dim_level();
+ }
+ else
+ {
+ assert(0);
+ }
+
+ dim = dim * ((MAX_LVL - MIN_LVL) / (filogic_led_get_max_dim_level() - filogic_led_get_min_dim_level()));
+
+ return dim;
+}
+
+uint8_t LEDWidget::GetMaxLevel(void)
+{
+ return MAX_LVL;
+}
+
+uint8_t LEDWidget::GetMinLevel(void)
+{
+ return MIN_LVL;
}
diff --git a/examples/lighting-app/genio/src/LightingManager.cpp b/examples/lighting-app/genio/src/LightingManager.cpp
index a9fcd2a0fc9789..6eaea0f6a918a7 100644
--- a/examples/lighting-app/genio/src/LightingManager.cpp
+++ b/examples/lighting-app/genio/src/LightingManager.cpp
@@ -18,14 +18,22 @@
*/
#include "LightingManager.h"
-
#include "AppConfig.h"
#include "AppTask.h"
+#include "ColorFormat.h"
#include
+#ifdef __PWM_DIMMABLE_LED__
+#include "DimmableLEDWidget.h"
+DimmableLEDWidget sDimLED;
+#else
+#include "LEDWidget.h"
+LEDWidget sDimLED;
+#endif /* __PWM_DIMMABLE_LED__ */
+
LightingManager LightingManager::sLight;
-TimerHandle_t sLightTimer;
+TimerHandle_t sLightTimer = NULL;
CHIP_ERROR LightingManager::Init()
{
@@ -48,6 +56,12 @@ CHIP_ERROR LightingManager::Init()
mAutoTurnOff = false;
mAutoTurnOffDuration = 0;
+#ifdef __PWM_DIMMABLE_LED__
+ sDimLED.Init(HAL_GPIO_35);
+#else
+ sDimLED.Init(LED_LIGHT);
+#endif
+
return CHIP_NO_ERROR;
}
@@ -77,23 +91,74 @@ void LightingManager::SetAutoTurnOffDuration(uint32_t aDurationInSecs)
mAutoTurnOffDuration = aDurationInSecs;
}
-bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction)
+bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction, uint8_t * aValue)
{
bool action_initiated = false;
State_t new_state;
+ RgbColor_t rgb;
- // Initiate Turn On/Off Action only when the previous one is complete.
- if (mState == kState_OffCompleted && aAction == ON_ACTION)
- {
- action_initiated = true;
+ if (sLightTimer == NULL)
+ return action_initiated;
- new_state = kState_OnInitiated;
+ switch (aAction)
+ {
+ case ON_ACTION:
+ if (mState == kState_OffCompleted)
+ {
+ action_initiated = true;
+ new_state = kState_OnInitiated;
+ }
+ if (*aValue == 0)
+ break;
+ case LEVEL_ACTION:
+ if (mState == kState_OnCompleted && *aValue >= sDimLED.GetMinLevel() && *aValue <= sDimLED.GetMaxLevel())
+ {
+ action_initiated = true;
+ /**
+ * NEST HUB uses minimal as off state.
+ */
+ new_state = ((*aValue == sDimLED.GetMinLevel()) ? kState_OffInitiated : kState_LevelInitiated);
+ }
+ break;
+ case OFF_ACTION:
+ if (mState == kState_OnCompleted)
+ {
+ action_initiated = true;
+ new_state = kState_OffInitiated;
+ }
+ break;
+ case COLOR_ACTION: {
+ rgb = *reinterpret_cast(aValue);
+ }
+ break;
+ case COLOR_ACTION_XY: {
+ XyColor_t xy = *reinterpret_cast(aValue);
+ rgb = XYToRgb(sDimLED.GetLevel(), xy.x, xy.y);
+ }
+ break;
+ case COLOR_ACTION_HSV: {
+ HsvColor_t hsv = *reinterpret_cast(aValue);
+ hsv.v = sDimLED.GetLevel();
+ rgb = HsvToRgb(hsv);
+ MT793X_LOG("LightingManager HSV(%d,%d) to RGB(%d,%d,%d)", hsv.h, hsv.s, rgb.r, rgb.g, rgb.b);
}
- else if (mState == kState_OnCompleted && aAction == OFF_ACTION)
+ break;
+ case COLOR_ACTION_CT: {
+ CtColor_t ct;
+ ct.ctMireds = *reinterpret_cast(aValue);
+ rgb = CTToRgb(ct);
+ }
+ break;
+ default:
+ ChipLogProgress(NotSpecified, "LightMgr:Unknown");
+ break;
+ }
+
+ if (aAction == COLOR_ACTION_XY || aAction == COLOR_ACTION_HSV || aAction == COLOR_ACTION_CT || aAction == COLOR_ACTION)
{
+ new_state = kState_ColorInitiated;
action_initiated = true;
-
- new_state = kState_OffInitiated;
+ aAction = COLOR_ACTION;
}
if (action_initiated)
@@ -116,6 +181,25 @@ bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction)
{
mActionInitiated_CB(aAction, aActor);
}
+
+ if (mState == kState_OnInitiated)
+ {
+ sDimLED.Set(true);
+ }
+ else if (mState == kState_OffInitiated)
+ {
+ sDimLED.Set(false);
+ }
+ else if (mState == kState_LevelInitiated)
+ {
+ MT793X_LOG("LightingManager: set level %d", *aValue);
+ sDimLED.SetLevel(*aValue);
+ }
+ else if (mState == kState_ColorInitiated)
+ {
+ MT793X_LOG("LightingManager: set color(%d,%d,%d)", rgb.r, rgb.g, rgb.b);
+ sDimLED.Color(rgb);
+ }
}
return action_initiated;
@@ -123,6 +207,9 @@ bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction)
void LightingManager::StartTimer(uint32_t aTimeoutMs)
{
+ if (sLightTimer == NULL)
+ return;
+
if (xTimerIsTimerActive(sLightTimer))
{
MT793X_LOG("app timer already started!");
@@ -185,7 +272,7 @@ void LightingManager::AutoTurnOffTimerEventHandler(AppEvent * aEvent)
MT793X_LOG("Auto Turn Off has been triggered!");
- light->InitiateAction(actor, OFF_ACTION);
+ light->InitiateAction(actor, OFF_ACTION, 0);
}
void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
@@ -204,6 +291,16 @@ void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
light->mState = kState_OnCompleted;
actionCompleted = ON_ACTION;
}
+ else if (light->mState == kState_LevelInitiated)
+ {
+ light->mState = kState_OnCompleted;
+ actionCompleted = LEVEL_ACTION;
+ }
+ else if (light->mState == kState_ColorInitiated)
+ {
+ light->mState = kState_OnCompleted;
+ actionCompleted = COLOR_ACTION;
+ }
if (actionCompleted != INVALID_ACTION)
{
@@ -212,7 +309,8 @@ void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
light->mActionCompleted_CB(actionCompleted);
}
- if (light->mAutoTurnOff && actionCompleted == ON_ACTION)
+ if (light->mAutoTurnOff &&
+ (actionCompleted == ON_ACTION || actionCompleted == LEVEL_ACTION || actionCompleted == COLOR_ACTION))
{
// Start the timer for auto turn off
light->StartTimer(light->mAutoTurnOffDuration * 1000);
diff --git a/examples/lighting-app/genio/src/ZclCallbacks.cpp b/examples/lighting-app/genio/src/ZclCallbacks.cpp
index 2e0dfe3dd2c912..8ab8d412204a68 100644
--- a/examples/lighting-app/genio/src/ZclCallbacks.cpp
+++ b/examples/lighting-app/genio/src/ZclCallbacks.cpp
@@ -21,11 +21,14 @@
*/
#include "AppConfig.h"
+#include "ColorFormat.h"
#include "LightingManager.h"
+#include
#include
#include
#include
+#include
#include
using namespace ::chip;
@@ -34,27 +37,89 @@ using namespace ::chip::app::Clusters;
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
uint8_t * value)
{
+ static HsvColor_t hsv;
+ static XyColor_t xy;
ClusterId clusterId = attributePath.mClusterId;
AttributeId attributeId = attributePath.mAttributeId;
+ EndpointId endpoint = attributePath.mEndpointId;
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);
+ LightMgr().InitiateAction(AppEvent::kEventType_Light, ((*value) ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION),
+ 0);
}
- else if (clusterId == LevelControl::Id)
+ else if (clusterId == LevelControl::Id && attributeId == LevelControl::Attributes::CurrentLevel::Id)
{
- ChipLogProgress(Zcl, "Level Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
- ChipLogValueMEI(attributeId), type, *value, size);
-
- // WIP Apply attribute change to Light
+ LightMgr().InitiateAction(AppEvent::kEventType_Light, LightingManager::LEVEL_ACTION, value);
}
else if (clusterId == ColorControl::Id)
{
- ChipLogProgress(Zcl, "Color Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
- ChipLogValueMEI(attributeId), type, *value, size);
+ EmberAfStatus status;
+ /* ignore several attributes that are currently not processed */
+ if ((attributeId == ColorControl::Attributes::RemainingTime::Id) ||
+ (attributeId == ColorControl::Attributes::EnhancedColorMode::Id) ||
+ (attributeId == ColorControl::Attributes::ColorMode::Id))
+ {
+ return;
+ }
- // WIP Apply attribute change to Light
+ /* XY color space */
+ if (attributeId == ColorControl::Attributes::CurrentX::Id || attributeId == ColorControl::Attributes::CurrentY::Id)
+ {
+ if (size != sizeof(uint16_t))
+ {
+ ChipLogError(Zcl, "Wrong length for ColorControl value: %d", size);
+ return;
+ }
+
+ if (attributeId == ColorControl::Attributes::CurrentX::Id)
+ {
+ xy.x = *reinterpret_cast(value);
+ }
+ if (attributeId == ColorControl::Attributes::CurrentY::Id)
+ {
+ xy.y = *reinterpret_cast(value);
+ }
+
+ ChipLogProgress(Zcl, "New XY color: %u|%u", xy.x, xy.y);
+ LightMgr().InitiateAction(AppEvent::kEventType_Light, LightingManager::COLOR_ACTION_XY, (uint8_t *) &xy);
+ }
+ /* HSV color space */
+ else if (attributeId == ColorControl::Attributes::CurrentHue::Id ||
+ attributeId == ColorControl::Attributes::CurrentSaturation::Id ||
+ attributeId == ColorControl::Attributes::EnhancedCurrentHue::Id)
+ {
+ /*
+ if (size != sizeof(uint8_t))
+ {
+ ChipLogError(Zcl, "Wrong length for ColorControl value: %d", size);
+ return;
+ }
+ */
+ if (attributeId == ColorControl::Attributes::EnhancedCurrentHue::Id)
+ {
+ hsv.h = (uint8_t)(((*reinterpret_cast(value)) & 0xFF00) >> 8);
+ hsv.s = (uint8_t)((*reinterpret_cast(value)) & 0xFF);
+ }
+ else if (attributeId == ColorControl::Attributes::CurrentHue::Id)
+ {
+ hsv.h = *value;
+ }
+ else if (attributeId == ColorControl::Attributes::CurrentSaturation::Id)
+ {
+ hsv.s = *value;
+ }
+ ChipLogProgress(Zcl, "New HSV color: %u|%u", hsv.h, hsv.s);
+ LightMgr().InitiateAction(AppEvent::kEventType_Light, LightingManager::COLOR_ACTION_HSV, (uint8_t *) &hsv);
+ }
+ else if (attributeId == ColorControl::Attributes::ColorTemperatureMireds::Id)
+ {
+ CtColor_t ct;
+ ct.ctMireds = *reinterpret_cast(value);
+ ChipLogProgress(Zcl, "New CT color: %u", ct.ctMireds);
+ LightMgr().InitiateAction(AppEvent::kEventType_Light, LightingManager::COLOR_ACTION_CT, (uint8_t *) &ct.ctMireds);
+ }
}
else if (clusterId == OnOffSwitchConfiguration::Id)
{
diff --git a/examples/lighting-app/genio/src/main.cpp b/examples/lighting-app/genio/src/main.cpp
index 93bb82a21b0735..ab578f3f2c75bd 100644
--- a/examples/lighting-app/genio/src/main.cpp
+++ b/examples/lighting-app/genio/src/main.cpp
@@ -63,7 +63,7 @@ void appError(int err)
{
printf("!!!!!!!!!!!! Application Critical Error: %d !!!!!!!!!!!", err);
portDISABLE_INTERRUPTS();
- while (1)
+ while (true)
;
}
@@ -270,7 +270,7 @@ extern "C" int main(void)
chip::Platform::MemoryShutdown();
// Should never get here.
- while (1)
+ while (true)
;
return 0;
diff --git a/examples/lighting-app/infineon/cyw30739/README.md b/examples/lighting-app/infineon/cyw30739/README.md
index 72753e2299f942..f085272b1c00d6 100644
--- a/examples/lighting-app/infineon/cyw30739/README.md
+++ b/examples/lighting-app/infineon/cyw30739/README.md
@@ -59,6 +59,24 @@ dataset and CASE credentials are then provided.
$ rm -rf out/
```
+## Building Options
+
+### DAC / DAC Key / PAI Certificate / Certificate Declaration
+
+Infineon CYW30739 examples use test certifications, keys, and CD by default. For
+a production build, manufacturers can provision certifications, keys, and CD by
+the following arguments:
+
+- `matter_dac`, `matter_dac_key`, `matter_pai`, `matter_cd`
+
+ ```bash
+ $ ./scripts/examples/gn_build_example.sh examples/lighting-app/infineon/cyw30739 out/lighting-app \
+ 'matter_dac="/path/to/dac.der"' \
+ 'matter_dac_key="/path/to/dac_key.der"' \
+ 'matter_pai="/path/to/pai.der"' \
+ 'matter_cd="/path/to/cd.der"'
+ ```
+
## Flashing the Application
### Enter Recovery Mode
diff --git a/examples/lighting-app/infineon/cyw30739/include/CHIPProjectConfig.h b/examples/lighting-app/infineon/cyw30739/include/CHIPProjectConfig.h
index 27952f445fbba7..233ffd19da1e59 100644
--- a/examples/lighting-app/infineon/cyw30739/include/CHIPProjectConfig.h
+++ b/examples/lighting-app/infineon/cyw30739/include/CHIPProjectConfig.h
@@ -34,13 +34,13 @@
#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "Infineon"
/* The VendorID attribute of the Basic cluster. */
-#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1
+#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF2
/* The ProductName attribute of the Basic cluster. */
#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "CYW30739 Lighting App"
/* The ProductID attribute of the Basic cluster. */
-#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005
+#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8002
/* The HardwareVersionString attribute of the Basic cluster. */
#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "30739"
diff --git a/examples/lighting-app/infineon/cyw30739/src/main.cpp b/examples/lighting-app/infineon/cyw30739/src/main.cpp
index 639ca07595c304..74ff57aa959763 100644
--- a/examples/lighting-app/infineon/cyw30739/src/main.cpp
+++ b/examples/lighting-app/infineon/cyw30739/src/main.cpp
@@ -35,6 +35,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -47,6 +48,8 @@ using namespace ::chip::DeviceLayer;
using namespace ::chip::Shell;
static chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+static FactoryDataProvider sFactoryDataProvider;
+
static void InitApp(intptr_t args);
static void LightManagerCallback(LightingManager::Actor_t actor, LightingManager::Action_t action, uint8_t value);
@@ -196,7 +199,7 @@ void InitApp(intptr_t args)
initParams.endpointNativeParams = static_cast(&nativeParams);
chip::Server::GetInstance().Init(initParams);
- SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
+ SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider);
LightMgr().Init();
LightMgr().SetCallbacks(LightManagerCallback, nullptr);
diff --git a/examples/lighting-app/infineon/cyw30739/static_config.txt b/examples/lighting-app/infineon/cyw30739/static_config.txt
deleted file mode 100644
index f256ac94aa5abf..00000000000000
--- a/examples/lighting-app/infineon/cyw30739/static_config.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# The post-building script uses this file to generate specified static configurations.
-# All '#' prefixed lines are ignored by the script.
-# Each line defines a static configuration by 3 fields separated by commas.
-#
-# The 1st field is a 16-bit ID from 0x2000 to 0x3ffff.
-# All IDs in this file have to be different.
-#
-# The 2nd field is a type to which the script interprets the value according.
-#
-# The 3rd field is a value of the static configuration. The value format depends on what the value type is:
-# - hex: Multiple hexadecimal values separated by commas.
-# - uint32/uint16/uint8/int16/int8: A integer.
-# - eui64: random or btext. If the value is btext, the configuration will be generated from the BT address.
-#
-# ID, type, value
-# EUI64
-0x2000, eui64, random
-# Setup Pin Code
-0x2105, uint32, 20202021
-# Setup Discriminator
-0x2107, uint32, 3840
diff --git a/examples/lighting-app/infineon/psoc6/src/main.cpp b/examples/lighting-app/infineon/psoc6/src/main.cpp
index a2dcdae1cc63f1..66ec9addd01aab 100644
--- a/examples/lighting-app/infineon/psoc6/src/main.cpp
+++ b/examples/lighting-app/infineon/psoc6/src/main.cpp
@@ -58,7 +58,7 @@ void appError(int err)
{
P6_LOG("!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!", err);
portDISABLE_INTERRUPTS();
- while (1)
+ while (true)
;
}
diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap
index 20746bbfe448be..d42c36437fe3e3 100644
--- a/examples/lighting-app/lighting-common/lighting-app.zap
+++ b/examples/lighting-app/lighting-common/lighting-app.zap
@@ -622,7 +622,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -648,7 +648,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -1524,7 +1524,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 1,
"commands": [
@@ -1576,7 +1576,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -1652,7 +1652,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -1688,7 +1688,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp
index bd2375e3d02001..c43a7c16334382 100644
--- a/examples/lighting-app/nrfconnect/main/AppTask.cpp
+++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -89,6 +90,17 @@ bool sHaveBLEConnections = false;
chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+// Define a custom attribute persister which makes actual write of the CurrentLevel attribute value
+// to the non-volatile storage only when it has remained constant for 5 seconds. This is to reduce
+// the flash wearout when the attribute changes frequently as a result of MoveToLevel command.
+// DeferredAttribute object describes a deferred attribute, but also holds a buffer with a value to
+// be written, so it must live so long as the DeferredAttributePersistenceProvider object.
+DeferredAttribute gCurrentLevelPersister(ConcreteAttributePath(kLightEndpointId, Clusters::LevelControl::Id,
+ Clusters::LevelControl::Attributes::CurrentLevel::Id));
+DeferredAttributePersistenceProvider gDeferredAttributePersister(Server::GetInstance().GetDefaultAttributePersister(),
+ Span(&gCurrentLevelPersister, 1),
+ System::Clock::Milliseconds32(5000));
+
} // namespace
AppTask AppTask::sAppTask;
@@ -195,6 +207,7 @@ CHIP_ERROR AppTask::Init()
gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
+ app::SetAttributePersistenceProvider(&gDeferredAttributePersister);
ConfigurationMgr().LogDeviceConfig();
PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.zap b/examples/lighting-app/nxp/zap/lighting-on-off.zap
index 051d0813981acd..5f82ebb3268c4d 100644
--- a/examples/lighting-app/nxp/zap/lighting-on-off.zap
+++ b/examples/lighting-app/nxp/zap/lighting-on-off.zap
@@ -622,7 +622,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "client",
"enabled": 0,
"attributes": [
@@ -648,7 +648,7 @@
"name": "On/off Switch Configuration",
"code": 7,
"mfgCode": null,
- "define": "ON_OFF_SWITCH_CONFIG_CLUSTER",
+ "define": "ON_OFF_SWITCH_CONFIGURATION_CLUSTER",
"side": "server",
"enabled": 0,
"attributes": [
@@ -1563,7 +1563,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "client",
"enabled": 1,
"commands": [
@@ -1615,7 +1615,7 @@
"name": "OTA Software Update Provider",
"code": 41,
"mfgCode": null,
- "define": "OTA_PROVIDER_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER",
"side": "server",
"enabled": 0,
"commands": [
@@ -1691,7 +1691,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
@@ -1727,7 +1727,7 @@
"name": "OTA Software Update Requestor",
"code": 42,
"mfgCode": null,
- "define": "OTA_REQUESTOR_CLUSTER",
+ "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER",
"side": "server",
"enabled": 1,
"attributes": [
diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp
index 55bf86deeedecc..1988455e958398 100644
--- a/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp
+++ b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp
@@ -96,7 +96,7 @@ int AppTask::StartAppTask()
if (sAppEventQueue == NULL)
{
PLAT_LOG("Failed to allocate app event queue");
- while (1)
+ while (true)
;
}
@@ -105,7 +105,7 @@ int AppTask::StartAppTask()
pdPASS)
{
PLAT_LOG("Failed to create app task");
- while (1)
+ while (true)
;
}
return ret;
@@ -125,7 +125,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().InitChipStack() failed");
- while (1)
+ while (true)
;
}
@@ -133,7 +133,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ThreadStackMgr().InitThreadStack() failed");
- while (1)
+ while (true)
;
}
#if CHIP_DEVICE_CONFIG_THREAD_FTD
@@ -144,7 +144,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed");
- while (1)
+ while (true)
;
}
@@ -152,7 +152,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().StartEventLoopTask() failed");
- while (1)
+ while (true)
;
}
@@ -160,7 +160,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("ThreadStackMgr().StartThreadTask() failed");
- while (1)
+ while (true)
;
}
@@ -229,7 +229,7 @@ void AppTask::AppTaskMain(void * pvParameter)
sAppTask.Init();
- while (1)
+ while (true)
{
/* Task pend until we have stuff to do */
if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE)
diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/BoltLockManager.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/BoltLockManager.cpp
index a6c927cb6cd04b..b048fc9e9d3f09 100644
--- a/examples/lock-app/cc13x2x7_26x2x7/main/BoltLockManager.cpp
+++ b/examples/lock-app/cc13x2x7_26x2x7/main/BoltLockManager.cpp
@@ -35,7 +35,7 @@ int BoltLockManager::Init()
if (NULL == mTimerHandle)
{
PLAT_LOG("failed to create bolt lock timer");
- while (1)
+ while (true)
;
}
diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/main.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/main.cpp
index cb0641fbc85ee0..8311c8990aa5c6 100644
--- a/examples/lock-app/cc13x2x7_26x2x7/main/main.cpp
+++ b/examples/lock-app/cc13x2x7_26x2x7/main/main.cpp
@@ -52,7 +52,7 @@ uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE;
// ================================================================================
extern "C" void vApplicationStackOverflowHook(void)
{
- while (1)
+ while (true)
{
;
}
@@ -85,13 +85,13 @@ int main(void)
{
// can't log until the kernel is started
// PLAT_LOG("GetAppTask().StartAppTask() failed");
- while (1)
+ while (true)
;
}
vTaskStartScheduler();
// Should never get here.
- while (1)
+ while (true)
;
}
diff --git a/examples/lock-app/cc32xx/main/AppTask.cpp b/examples/lock-app/cc32xx/main/AppTask.cpp
index 40390e66fc2c94..79da0749349665 100644
--- a/examples/lock-app/cc32xx/main/AppTask.cpp
+++ b/examples/lock-app/cc32xx/main/AppTask.cpp
@@ -76,7 +76,7 @@ int AppTask::StartAppTask()
if (sAppEventQueue == NULL)
{
PLAT_LOG("Failed to allocate app event queue");
- while (1)
+ while (true)
;
}
@@ -85,7 +85,7 @@ int AppTask::StartAppTask()
pdPASS)
{
PLAT_LOG("Failed to create app task");
- while (1)
+ while (true)
;
}
return ret;
@@ -136,7 +136,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().InitChipStack() failed");
- while (1)
+ while (true)
;
}
PLAT_LOG("Start Event Loop Task");
@@ -144,7 +144,7 @@ int AppTask::Init()
if (ret != CHIP_NO_ERROR)
{
PLAT_LOG("PlatformMgr().StartEventLoopTask() failed");
- while (1)
+ while (true)
;
}
@@ -179,7 +179,7 @@ void AppTask::AppTaskMain(void * pvParameter)
sAppTask.Init();
- while (1)
+ while (true)
{
/* Task pend until we have stuff to do */
if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE)
diff --git a/examples/lock-app/cc32xx/main/BoltLockManager.cpp b/examples/lock-app/cc32xx/main/BoltLockManager.cpp
index 31c995f7d34d4c..09b9603ff1663e 100644
--- a/examples/lock-app/cc32xx/main/BoltLockManager.cpp
+++ b/examples/lock-app/cc32xx/main/BoltLockManager.cpp
@@ -35,7 +35,7 @@ int BoltLockManager::Init()
if (NULL == mTimerHandle)
{
PLAT_LOG("failed to create bolt lock timer");
- while (1)
+ while (true)
;
}
diff --git a/examples/lock-app/cc32xx/main/main.cpp b/examples/lock-app/cc32xx/main/main.cpp
index 4546931d83aba6..aea9449590c69d 100644
--- a/examples/lock-app/cc32xx/main/main.cpp
+++ b/examples/lock-app/cc32xx/main/main.cpp
@@ -43,7 +43,7 @@ using namespace ::chip::DeviceLayer;
// ================================================================================
extern "C" void vApplicationStackOverflowHook(void)
{
- while (1)
+ while (true)
{
;
}
@@ -64,13 +64,13 @@ int main(void)
{
// can't log until the kernel is started
// PLAT_LOG("GetAppTask().StartAppTask() failed");
- while (1)
+ while (true)
;
}
vTaskStartScheduler();
// Should never get here.
- while (1)
+ while (true)
;
}
diff --git a/examples/lock-app/genio/.gn b/examples/lock-app/genio/.gn
new file mode 100644
index 00000000000000..0adefc6ff99c6a
--- /dev/null
+++ b/examples/lock-app/genio/.gn
@@ -0,0 +1,27 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+
+# The location of the build configuration file.
+buildconfig = "${build_root}/config/BUILDCONFIG.gn"
+
+# CHIP uses angle bracket includes.
+check_system_includes = true
+
+default_args = {
+ target_cpu = "arm"
+ target_os = "freertos"
+ import("//args.gni")
+}
diff --git a/examples/lock-app/genio/BUILD.gn b/examples/lock-app/genio/BUILD.gn
new file mode 100644
index 00000000000000..8b37e0202d10a8
--- /dev/null
+++ b/examples/lock-app/genio/BUILD.gn
@@ -0,0 +1,117 @@
+# Copyright (c) 2022 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/mt793x_sdk.gni")
+import("//build_overrides/pigweed.gni")
+
+import("${build_root}/config/defaults.gni")
+import("${mt793x_sdk_build_root}/mt793x_executable.gni")
+import("${mt793x_sdk_build_root}/mt793x_sdk.gni")
+
+import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
+import("${chip_root}/src/platform/device.gni")
+
+if (chip_enable_pw_rpc) {
+ import("//build_overrides/pigweed.gni")
+ import("$dir_pw_build/target_types.gni")
+}
+
+assert(current_os == "freertos")
+
+mt793x_project_dir = "${chip_root}/examples/lock-app/genio"
+mt793x_examples_plat_dir = "${chip_root}/examples/platform/mt793x"
+
+declare_args() {
+ # Dump memory usage at link time.
+ chip_print_memory_usage = true
+
+ # PIN code for PASE session establishment.
+ setupPinCode = 20202021
+ setupDiscriminator = 3940
+}
+
+mt793x_sdk("sdk") {
+ sources = [
+ "${mt793x_project_dir}/include/CHIPProjectConfig.h",
+ "${mt793x_project_dir}/include/FreeRTOSConfig.h",
+ ]
+
+ include_dirs = [
+ "${chip_root}/src/platform/mt793x",
+ "${mt793x_project_dir}/include",
+ "${mt793x_examples_plat_dir}",
+ "${chip_root}/src/lib",
+ ]
+
+ defines = [ "OPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_CONSOLE" ]
+
+ defines += [
+ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}",
+ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}",
+ ]
+}
+
+mt793x_executable("lock_app") {
+ output_name = "chip-mt793x-lock-app-example.out"
+ include_dirs = [ "include" ]
+ defines = []
+
+ sources = [
+ "src/AppTask.cpp",
+ "src/LEDWidget.cpp",
+ "src/LockManager.cpp",
+ "src/ZclCallbacks.cpp",
+ "src/main.cpp",
+ ]
+
+ deps = [
+ ":sdk",
+ "${chip_root}/examples/common/QRCode",
+ "${chip_root}/examples/lock-app/lock-common",
+ "${chip_root}/examples/providers:device_info_provider",
+ "${chip_root}/src/lib",
+ "${chip_root}/src/setup_payload",
+ "${mt793x_examples_plat_dir}:genio-matter-shell",
+ ]
+
+ if (chip_enable_ota_requestor) {
+ defines += [ "MT793X_OTA_ENABLED" ]
+ sources += [ "${examples_plat_dir}/OTAConfig.cpp" ]
+ }
+
+ ldscript = "mt793x_xip.ld"
+
+ inputs = [ ldscript ]
+
+ ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ]
+
+ if (chip_print_memory_usage) {
+ ldflags += [
+ "-Wl,--print-memory-usage",
+ "-fstack-usage",
+ ]
+ }
+
+ output_dir = root_out_dir
+}
+
+group("mt793x") {
+ deps = [ ":lock_app" ]
+}
+
+group("default") {
+ deps = [ ":mt793x" ]
+}
diff --git a/examples/lock-app/genio/README.md b/examples/lock-app/genio/README.md
new file mode 100644
index 00000000000000..f4d0653016e4b5
--- /dev/null
+++ b/examples/lock-app/genio/README.md
@@ -0,0 +1,125 @@
+#Matter `Genio` Lock Example
+
+An example showing the use of Matter on the MediaTek `Genio` MT793X.
+
+
+
+- [Matter Genio Lock Example](#chip-genio-lock-example)
+ - [Introduction](#introduction)
+ - [Building](#building)
+ - [Note](#note)
+ - [Flashing the Application](#flashing-the-application)
+ - [Viewing Logging Output](#viewing-logging-output)
+ - [Running the Complete Example](#running-the-complete-example)
+ - [Notes](#notes)
+
+
+
+
+
+## Introduction
+
+The `Genio` (MT793X) lock example provides a baseline demonstration of a door
+lock control device, built using Matter and the MediaTek `Genio` SDK. It can be
+controlled by a Chip controller over Wi-Fi network.
+
+The `Genio` device can be commissioned over Bluetooth Low Energy where the
+device and the Chip controller will exchange security information with the
+Rendez-vous procedure. Network credentials are then provided to the `Genio`
+device which will then join the network.
+
+The lighting example is intended to serve both as a means to explore the
+workings of Matter as well as a template for creating real products based on the
+MediaTek platform.
+
+
+
+## Building
+
+- Following the Linux related descriptions in
+ [Build Matter](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/BUILDING.md)
+ to prepare the build environment.
+
+- Supported hardware:
+
+ `Genio` 130A (MT7931) board:
+
+ - `EK-AI7931LD KIT`
+
+* Build the example application:
+
+ `cd ~/connectedhomeip`
+ `./scripts/examples/gn_genio_example.sh ./examples/lighting-app/genio` `./out/lighting-app`
+
+- To delete generated executable, libraries and object files use:
+
+ `$ cd ~/connectedhomeip`
+ `$ rm -rf ./out/`
+
+ OR use GN/Ninja directly
+
+ `$ cd ~/connectedhomeip/examples/lighting-app/genio`
+ `$ git submodule update --init`
+ `$ source third_party/connectedhomeip/scripts/activate.sh`
+ `$ gn gen out/debug`
+ `$ ninja -C out/debug`
+
+- To delete generated executable, libraries and object files use:
+
+ `$ cd ~/connectedhomeip/examples/lighting-app/genio`
+ `$ rm -rf out/`
+
+## Flashing the Application
+
+- Copy the GUI based
+ [Flash Tool](https://github.com/MediaTek-Labs/genio-matter-bsp/tree/main/flash_tool/FlashBurningTool_V2.83).
+ from the Linux Host that the example was build to a Windows PC.
+
+ Flash Tool can be found in this source tree under this directory
+
+ `third_party/mt793x_sdk/filogic/flash_tool`
+
+- On the Windows PC, run the Flash Tool
+
+ 1. Select the scatter.ini file in the `./out/lighting-app` directory.
+ 2. Follow the instruction that comes with `EK-AI7931LD KIT` to switch the
+ kit to download mode.
+ 3. Click `Download` on FLASH TOOL.
+
+## Running the Complete Example
+
+- You can provision and control the Chip device using the python controller,
+ Chip tool standalone, Android or iOS app
+
+ [CHIP
+ Tool]](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/chip_tool_guide.md)
+
+ Here is an example with the CHIP Tool controller:
+
+ ```
+ chiptool- pairing ble-wifi 1234 my-ap myappassword 20202021 3840
+
+ chiptool onoff on 1 1
+
+ chiptool onoff off 1 1
+ ```
+
+````
+
+- You can test the LED by light command as shown below
+
+ ```
+ > light
+ help Usage: light
+ onoff Usage: light onoff
+ color Usage: light color
+ level Usage: light level
+ ```
+
+### Notes
+
+- Depending on your network settings your router might not provide native ipv6
+ addresses to your devices (Border router / PC). If this is the case, you
+ need to add a static ipv6 addresses on both device and then an ipv6 route to
+ the border router on your PC
+````
diff --git a/examples/lock-app/genio/args.gni b/examples/lock-app/genio/args.gni
new file mode 100644
index 00000000000000..ddbfb9fa47f20d
--- /dev/null
+++ b/examples/lock-app/genio/args.gni
@@ -0,0 +1,34 @@
+# Copyright (c) 2022 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/mt793x/args.gni")
+
+mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain")
+
+pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip"
+pw_assert_BACKEND = "$dir_pw_assert_log"
+
+chip_enable_ble = true
+
+declare_args() {
+ chip_enable_ota_requestor = false
+
+ # Disable lock tracking, since our FreeRTOS configuration does not set
+ # INCLUDE_xSemaphoreGetMutexHolder
+ chip_stack_lock_tracking = "none"
+
+ chip_config_network_layer_ble = true
+}
diff --git a/examples/lock-app/genio/build_for_wifi_args.gni b/examples/lock-app/genio/build_for_wifi_args.gni
new file mode 100644
index 00000000000000..cb0ea7600a2dd5
--- /dev/null
+++ b/examples/lock-app/genio/build_for_wifi_args.gni
@@ -0,0 +1,22 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import("//build_overrides/chip.gni")
+import("//build_overrides/pigweed.gni")
+
+mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain")
+chip_enable_openthread = false
+import("${chip_root}/src/platform/MT793X/wifi_args.gni")
+
+pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip"
+pw_assert_BACKEND = "$dir_pw_assert_log"
diff --git a/examples/lock-app/genio/build_for_wifi_gnfile.gn b/examples/lock-app/genio/build_for_wifi_gnfile.gn
new file mode 100644
index 00000000000000..9752ee73e7c91d
--- /dev/null
+++ b/examples/lock-app/genio/build_for_wifi_gnfile.gn
@@ -0,0 +1,28 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+
+# The location of the build configuration file.
+buildconfig = "${build_root}/config/BUILDCONFIG.gn"
+
+# CHIP uses angle bracket includes.
+check_system_includes = true
+
+default_args = {
+ target_cpu = "arm"
+ target_os = "freertos"
+ use_thread = false
+ import("//build_for_wifi_args.gni")
+}
diff --git a/examples/lock-app/genio/build_overrides b/examples/lock-app/genio/build_overrides
new file mode 120000
index 00000000000000..e578e73312ebd1
--- /dev/null
+++ b/examples/lock-app/genio/build_overrides
@@ -0,0 +1 @@
+../../build_overrides
\ No newline at end of file
diff --git a/examples/lock-app/genio/include/AppConfig.h b/examples/lock-app/genio/include/AppConfig.h
new file mode 100644
index 00000000000000..eeb8213254c8ab
--- /dev/null
+++ b/examples/lock-app/genio/include/AppConfig.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// ---- Door lock Example App Config ----
+
+#define APP_TASK_NAME "Lock"
+
+// Time it takes in ms for the simulated actuator to move from one
+// state to another.
+#define ACTUATOR_MOVEMENT_PERIOS_MS (10)
+
+// Maximum number of users supported by lock
+#define CONFIG_LOCK_NUM_USERS (5)
+
+// Maximum number of credentials per user supported by lock
+#define CONFIG_LOCK_NUM_CREDENTIALS_PER_USER (2)
+
+// Genio Logging
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mt793xLogInit(void);
+
+void mt793xLog(const char * aFormat, ...);
+#define MT793X_LOG(aFormat...) mt793xLog(aFormat);
+void appError(int err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include
+void appError(CHIP_ERROR error);
diff --git a/examples/lock-app/genio/include/AppEvent.h b/examples/lock-app/genio/include/AppEvent.h
new file mode 100644
index 00000000000000..c50ac399061557
--- /dev/null
+++ b/examples/lock-app/genio/include/AppEvent.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2020 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_Lock,
+ kEventType_Install,
+ };
+
+ uint16_t Type;
+
+ union
+ {
+ struct
+ {
+ bool Pressed;
+ } ButtonEvent;
+ struct
+ {
+ void * Context;
+ } TimerEvent;
+ struct
+ {
+ uint8_t Action;
+ int32_t Actor;
+ } LockEvent;
+ };
+
+ EventHandler Handler;
+};
diff --git a/examples/lock-app/genio/include/AppTask.h b/examples/lock-app/genio/include/AppTask.h
new file mode 100644
index 00000000000000..23c70503ab3c33
--- /dev/null
+++ b/examples/lock-app/genio/include/AppTask.h
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "AppEvent.h"
+#include "LockManager.h"
+#include "filogic_button.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+#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)
+#define APP_ERROR_ALLOCATION_FAILED CHIP_APPLICATION_ERROR(0x07)
+
+class AppTask
+{
+
+public:
+ CHIP_ERROR StartAppTask();
+ static void AppTaskMain(void * pvParameter);
+
+ void ActionRequest(int32_t aActor, LockManager::Action_t aAction);
+ void PostEvent(const AppEvent * event);
+
+ void ButtonHandler(const filogic_button_t & button);
+
+private:
+ friend AppTask & GetAppTask(void);
+
+ CHIP_ERROR Init();
+
+ static void ActionInitiated(LockManager::Action_t aAction, int32_t aActor);
+ static void ActionCompleted(LockManager::Action_t aAction);
+
+ void DispatchEvent(AppEvent * event);
+ static void UpdateClusterState(intptr_t context);
+ static void SingleButtonEventHandler(AppEvent * aEvent);
+ static void ButtonTimerEventHandler(AppEvent * aEvent);
+
+ static void LockActionEventHandler(AppEvent * aEvent);
+
+ static void TimerEventHandler(TimerHandle_t xTimer);
+ void StartTimer(uint32_t aTimeoutMs);
+ void CancelTimer(void);
+
+ enum Function_t
+ {
+ kFunction_NoneSelected = 0,
+ kFunction_StartBleAdv = 1,
+ kFunction_LightSwitch = 2,
+ kFunction_FactoryReset = 3,
+ kFunction_SoftwareUpdate = 0,
+
+ kFunction_Invalid
+ } Function;
+
+ Function_t mFunction;
+ bool mFunctionTimerActive;
+
+ static AppTask sAppTask;
+};
+
+inline AppTask & GetAppTask(void)
+{
+ return AppTask::sAppTask;
+}
diff --git a/examples/lock-app/genio/include/CHIPProjectConfig.h b/examples/lock-app/genio/include/CHIPProjectConfig.h
new file mode 100644
index 00000000000000..25bb0732cdc547
--- /dev/null
+++ b/examples/lock-app/genio/include/CHIPProjectConfig.h
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * Example project configuration file for CHIP.
+ *
+ * This is a place to put application or project-specific overrides
+ * to the default configuration values for general CHIP features.
+ *
+ */
+
+#pragma once
+
+// Use a default pairing code if one hasn't been provisioned in flash.
+#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021
+#endif
+
+#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00
+#endif
+
+// For convenience, Chip Security Test Mode can be enabled and the
+// requirement for authentication in various protocols can be disabled.
+//
+// WARNING: These options make it possible to circumvent basic Chip security functionality,
+// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS.
+//
+#define CHIP_CONFIG_SECURITY_TEST_MODE 0
+#define CHIP_CONFIG_REQUIRE_AUTH 1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID
+ *
+ * 0x1373: MediaTek's Vendor Id.
+ * 0xFFF1: Common Test Vendor Id.
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID
+ *
+ * 0x1000: Genio lock-app
+ * 0x8006: Common test lock-app
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8006
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION
+ *
+ * The hardware version 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 versions.
+ */
+#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1
+
+/**
+ * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
+ *
+ * A string identifying the software version running on the device.
+ * CHIP service currently expects the software version to be in the format
+ * {MAJOR_VERSION}.0d{MINOR_VERSION}
+ */
+#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_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)
+
+/**
+ * @def CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL
+ *
+ * @brief
+ * Active retransmit interval, or time to wait before retransmission after
+ * subsequent failures in milliseconds.
+ *
+ * This is the default value, that might be adjusted by end device depending on its
+ * needs (e.g. sleeping period) using Service Discovery TXT record CRA key.
+ *
+ */
+#define CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL (2000_ms32)
diff --git a/examples/lock-app/genio/include/ColorFormat.h b/examples/lock-app/genio/include/ColorFormat.h
new file mode 100755
index 00000000000000..1ad0cb0e75f4f4
--- /dev/null
+++ b/examples/lock-app/genio/include/ColorFormat.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+
+struct RgbColor_t
+{
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+};
+
+struct HsvColor_t
+{
+ uint8_t h;
+ uint8_t s;
+ uint8_t v;
+};
+
+struct XyColor_t
+{
+ uint16_t x;
+ uint16_t y;
+};
+
+struct CtColor_t
+{
+ uint16_t ctMireds;
+};
+
+RgbColor_t XYToRgb(uint8_t Level, uint16_t currentX, uint16_t currentY);
+RgbColor_t HsvToRgb(HsvColor_t hsv);
+RgbColor_t CTToRgb(CtColor_t ct);
diff --git a/examples/lock-app/genio/include/DimmableLEDIf.h b/examples/lock-app/genio/include/DimmableLEDIf.h
new file mode 100644
index 00000000000000..ce63aff1efce86
--- /dev/null
+++ b/examples/lock-app/genio/include/DimmableLEDIf.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+class DimmableLEDIf
+{
+public:
+ /* set to ON or OFF */
+ virtual void Set(bool state) = 0;
+ /* Get On/Off state */
+ virtual bool Get(void) = 0;
+ /* change light level */
+ virtual void SetLevel(uint8_t level) = 0;
+ /* Get current level*/
+ virtual uint8_t GetLevel(void) = 0;
+ virtual uint8_t GetMaxLevel(void) = 0;
+ virtual uint8_t GetMinLevel(void) = 0;
+};
diff --git a/examples/lock-app/genio/include/LEDWidget.h b/examples/lock-app/genio/include/LEDWidget.h
new file mode 100644
index 00000000000000..2690d5856930b3
--- /dev/null
+++ b/examples/lock-app/genio/include/LEDWidget.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "ColorFormat.h"
+#include "DimmableLEDIf.h"
+#include
+
+enum led_id
+{
+ LED_LIGHT,
+ LED_STATUS
+};
+
+enum led_color
+{
+ LED_RED,
+ LED_GREEN,
+ LED_BLUE
+};
+
+class LEDWidget : public DimmableLEDIf
+{
+public:
+ // bind this LEDWidget with the specified LED
+ void Init(enum led_id led);
+ // retrieve the name of this LED
+ const char * Name(void);
+ // change the color
+ void Color(RgbColor_t color);
+ // specify the ON, OFF duration
+ void Blink(int on, int off);
+ // specify evenly ON and OFF both to 'duration'
+ void Blink(int duration);
+
+ /* set to ON or OFF */
+ virtual void Set(bool state);
+ /* Get On/Off state */
+ virtual bool Get(void);
+ /* change light level */
+ virtual void SetLevel(uint8_t level);
+ /* Get current level*/
+ virtual uint8_t GetLevel(void);
+ virtual uint8_t GetMaxLevel(void);
+ virtual uint8_t GetMinLevel(void);
+
+private:
+ enum led_id mLed;
+ int mOn;
+ int mOff;
+ uint8_t mLevel; /* Current level */
+ bool mState;
+ void Toggle(void);
+ void DoSet(bool state);
+
+ TimerHandle_t mTimer;
+ static void TimerHandler(TimerHandle_t xTimer);
+ void DoBlink(void);
+ void StartTimer(uint32_t aTimeoutInMs);
+ void CancelTimer(void);
+};
diff --git a/examples/lock-app/genio/include/LockManager.h b/examples/lock-app/genio/include/LockManager.h
new file mode 100755
index 00000000000000..084b77a029884d
--- /dev/null
+++ b/examples/lock-app/genio/include/LockManager.h
@@ -0,0 +1,224 @@
+/*
+ *
+ * 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
+
+#include "AppConfig.h"
+#include "AppEvent.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+
+#include
+
+struct WeekDaysScheduleInfo
+{
+ DlScheduleStatus status;
+ EmberAfPluginDoorLockWeekDaySchedule schedule;
+};
+
+struct YearDayScheduleInfo
+{
+ DlScheduleStatus status;
+ EmberAfPluginDoorLockYearDaySchedule schedule;
+};
+
+struct HolidayScheduleInfo
+{
+ DlScheduleStatus status;
+ EmberAfPluginDoorLockHolidaySchedule schedule;
+};
+
+namespace MT793XDoorLock {
+namespace ResourceRanges {
+
+// Used to size arrays
+static constexpr uint16_t kMaxUsers = CONFIG_LOCK_NUM_USERS;
+static constexpr uint8_t kMaxCredentialsPerUser = CONFIG_LOCK_NUM_CREDENTIALS_PER_USER;
+static constexpr uint8_t kMaxWeekdaySchedulesPerUser = 10;
+static constexpr uint8_t kMaxYeardaySchedulesPerUser = 10;
+static constexpr uint8_t kMaxHolidaySchedules = 10;
+static constexpr uint8_t kMaxCredentialSize = 8;
+
+// Indices received for user/credential/schedules are 1-indexed
+static constexpr uint8_t kStartIndexValue = 1;
+
+static constexpr uint8_t kMaxCredentials = kMaxUsers * kMaxCredentialsPerUser;
+} // namespace ResourceRanges
+
+namespace LockInitParams {
+
+struct LockParam
+{
+ // Read from zap attributes
+ uint16_t numberOfUsers = 0;
+ uint8_t numberOfCredentialsPerUser = 0;
+ uint8_t numberOfWeekdaySchedulesPerUser = 0;
+ uint8_t numberOfYeardaySchedulesPerUser = 0;
+ uint8_t numberOfHolidaySchedules = 0;
+};
+
+class ParamBuilder
+{
+public:
+ ParamBuilder & SetNumberOfUsers(uint16_t numberOfUsers)
+ {
+ lockParam_.numberOfUsers = numberOfUsers;
+ return *this;
+ }
+ ParamBuilder & SetNumberOfCredentialsPerUser(uint8_t numberOfCredentialsPerUser)
+ {
+ lockParam_.numberOfCredentialsPerUser = numberOfCredentialsPerUser;
+ return *this;
+ }
+ ParamBuilder & SetNumberOfWeekdaySchedulesPerUser(uint8_t numberOfWeekdaySchedulesPerUser)
+ {
+ lockParam_.numberOfWeekdaySchedulesPerUser = numberOfWeekdaySchedulesPerUser;
+ return *this;
+ }
+ ParamBuilder & SetNumberOfYeardaySchedulesPerUser(uint8_t numberOfYeardaySchedulesPerUser)
+ {
+ lockParam_.numberOfYeardaySchedulesPerUser = numberOfYeardaySchedulesPerUser;
+ return *this;
+ }
+ ParamBuilder & SetNumberOfHolidaySchedules(uint8_t numberOfHolidaySchedules)
+ {
+ lockParam_.numberOfHolidaySchedules = numberOfHolidaySchedules;
+ return *this;
+ }
+ LockParam GetLockParam() { return lockParam_; }
+
+private:
+ LockParam lockParam_;
+};
+
+} // namespace LockInitParams
+} // namespace MT793XDoorLock
+
+using namespace ::chip;
+using namespace MT793XDoorLock::ResourceRanges;
+
+class LockManager
+{
+public:
+ enum Action_t
+ {
+ LOCK_ACTION = 0,
+ UNLOCK_ACTION,
+
+ INVALID_ACTION
+ } Action;
+
+ enum State_t
+ {
+ kState_LockInitiated = 0,
+ kState_LockCompleted,
+ kState_UnlockInitiated,
+ kState_UnlockCompleted,
+ } State;
+
+ CHIP_ERROR Init(chip::app::DataModel::Nullable state,
+ MT793XDoorLock::LockInitParams::LockParam lockParam);
+ bool NextState();
+ 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);
+
+ bool Lock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err);
+ bool Unlock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err);
+
+ bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user);
+ bool SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
+ const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype,
+ DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials);
+
+ bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType,
+ EmberAfPluginDoorLockCredentialInfo & credential);
+
+ bool SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
+ DlCredentialStatus credentialStatus, DlCredentialType credentialType, const chip::ByteSpan & credentialData);
+
+ DlStatus GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
+ EmberAfPluginDoorLockWeekDaySchedule & schedule);
+
+ DlStatus SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, DlScheduleStatus status,
+ DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute);
+
+ DlStatus GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
+ EmberAfPluginDoorLockYearDaySchedule & schedule);
+
+ DlStatus SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status,
+ uint32_t localStartTime, uint32_t localEndTime);
+
+ DlStatus GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, EmberAfPluginDoorLockHolidaySchedule & schedule);
+
+ DlStatus SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime,
+ uint32_t localEndTime, DlOperatingMode operatingMode);
+
+ bool IsValidUserIndex(uint16_t userIndex);
+ bool IsValidCredentialIndex(uint16_t credentialIndex, DlCredentialType type);
+ bool IsValidWeekdayScheduleIndex(uint8_t scheduleIndex);
+ bool IsValidYeardayScheduleIndex(uint8_t scheduleIndex);
+ bool IsValidHolidayScheduleIndex(uint8_t scheduleIndex);
+
+ bool setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin,
+ DlOperationError & err);
+ const char * lockStateToString(DlLockState lockState) const;
+
+ bool ReadConfigValues();
+
+private:
+ friend LockManager & LockMgr();
+ chip::EndpointId mEndpointId;
+ State_t mState;
+
+ Callback_fn_initiated mActionInitiated_CB;
+ Callback_fn_completed mActionCompleted_CB;
+
+ void CancelTimer(void);
+ void StartTimer(uint32_t aTimeoutMs);
+
+ static void TimerEventHandler(TimerHandle_t xTimer);
+ static void AutoLockTimerEventHandler(AppEvent * aEvent);
+ static void ActuatorMovementTimerEventHandler(AppEvent * aEvent);
+
+ EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers];
+ EmberAfPluginDoorLockCredentialInfo mLockCredentials[kMaxCredentials];
+ WeekDaysScheduleInfo mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser];
+ YearDayScheduleInfo mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser];
+ HolidayScheduleInfo mHolidaySchedule[kMaxHolidaySchedules];
+
+ char mUserNames[ArraySize(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE];
+ uint8_t mCredentialData[kMaxCredentials][kMaxCredentialSize];
+ DlCredential mCredentials[kMaxUsers][kMaxCredentialsPerUser];
+
+ static LockManager sLock;
+ MT793XDoorLock::LockInitParams::LockParam LockParams;
+};
+
+inline LockManager & LockMgr()
+{
+ return LockManager::sLock;
+}
diff --git a/examples/lock-app/genio/mt793x_xip.ld b/examples/lock-app/genio/mt793x_xip.ld
new file mode 100755
index 00000000000000..fd577c07ca60a0
--- /dev/null
+++ b/examples/lock-app/genio/mt793x_xip.ld
@@ -0,0 +1,394 @@
+/*
+ * MT7933 CM33 Memory Map
+ */
+
+HIDDEN(__STACK_SIZE = 0x1000);
+HIDDEN(__SYSRAM_OFFSET = 0x0);
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Memory Spaces Definitions: 16MB flash */
+MEMORY
+{
+ ROM_BL(rx) : ORIGIN = 0x18000000, LENGTH = 64K
+ ROM_RBL(rx) : ORIGIN = 0x18010000, LENGTH = 8K
+ ROM_TFM(rx) : ORIGIN = 0x18012000, LENGTH = 200K
+ ROM_RTOS(rx) : ORIGIN = 0x18044000, LENGTH = 2092K
+ /*
+ Reserved : LENGTH = 228 K, 152 K For TFM
+ Free For Customer : LENGTH = 500 K
+ */
+ ROM_FOTA(r) : ORIGIN = 0x18305000, LENGTH = 3968K
+ ROM_NVDM(rx) : ORIGIN = 0x186E5000, LENGTH = 64K
+ ROM_LOG(rx) : ORIGIN = 0x186F5000, LENGTH = 64K
+ ROM_BT(rx) : ORIGIN = 0x18705000, LENGTH = 304K
+ /*
+ Reserved For FW : LENGTH = 40 K
+ */
+ ROM_WIFI_PWRTBL(rx): ORIGIN = 0x1875B000, LENGTH = 20K
+ ROM_WIFI_EXT(rx) : ORIGIN = 0x18760000, LENGTH = 636K
+ ROM_BUFFER_BIN(rx): ORIGIN = 0x187FF000, LENGTH = 4K
+
+ TCM(rwx) : ORIGIN = 0x0010C000, LENGTH = 20K
+ RAM_WFFW(rwx) : ORIGIN = 0xA0000000, LENGTH = 312K
+ RAM(rwx) : ORIGIN = 0xA004E000, LENGTH = 3272K
+ RAM_TFM(rwx) : ORIGIN = 0xA0380000, LENGTH = 512K
+ RAM_BTFW(rwx) : ORIGIN = 0xA0400000, LENGTH = 352K
+ SYSRAM(rwx) : ORIGIN = 0x80000000, LENGTH = 992K
+ /*
+ Reserved : LENGTH = 32K
+ */
+
+ VROM(rx) : ORIGIN = 0x18000000, LENGTH = 4096K
+ VRAM_WFFW(rwx) : ORIGIN = 0x10000000, LENGTH = 312K
+ VRAM(rwx) : ORIGIN = 0x1004E000, LENGTH = 3272K
+ VRAM_TFM(rwx) : ORIGIN = 0x10380000, LENGTH = 512K
+ VRAM_BTFW(rwx) : ORIGIN = 0x10400000, LENGTH = 352K
+ VSYSRAM(rwx) : ORIGIN = 0x08000000, LENGTH = 992K
+ /*
+ Reserved : LENGTH = 32K
+ */
+}
+
+/****************************************************************************
+ *
+ * FORWARD DECLARATIONS - SECTION SYMBOLS @ FLASH PHYSICAL ADDRESS
+ *
+ ****************************************************************************/
+
+
+_rom_bl_start = ORIGIN(ROM_BL) - ORIGIN(ROM_BL);
+_rom_bl_length = LENGTH(ROM_BL);
+_rom_rbl_start = ORIGIN(ROM_RBL) - ORIGIN(ROM_BL);
+_rom_rbl_length = LENGTH(ROM_RBL);
+_rom_tfm_start = ORIGIN(ROM_TFM) - ORIGIN(ROM_BL);
+_rom_tfm_length = LENGTH(ROM_TFM);
+_rom_rtos_start = ORIGIN(ROM_RTOS) - ORIGIN(ROM_BL);
+_rom_rtos_length = LENGTH(ROM_RTOS);
+_rom_fota_start = ORIGIN(ROM_FOTA) - ORIGIN(ROM_BL);
+_rom_fota_length = LENGTH(ROM_FOTA);
+_rom_wifi_patch_start = 0;/*ORIGIN(ROM_WIFI_PATCH) - ORIGIN(ROM_BL);*/
+_rom_wifi_patch_length = 0;/*LENGTH(ROM_WIFI_PATCH);*/
+_rom_wifi_start = 0;/*ORIGIN(ROM_WIFI) - ORIGIN(ROM_BL);*/
+_rom_wifi_length = 0;/*LENGTH(ROM_WIFI);*/
+_rom_wifi_ext_start = ORIGIN(ROM_WIFI_EXT) - ORIGIN(ROM_BL);
+_rom_wifi_ext_length = LENGTH(ROM_WIFI_EXT);
+_rom_wifi_pwrtbl_start = ORIGIN(ROM_WIFI_PWRTBL) - ORIGIN(ROM_BL);
+_rom_wifi_pwrtbl_length = LENGTH(ROM_WIFI_PWRTBL);
+_rom_buffer_bin_start = ORIGIN(ROM_BUFFER_BIN) - ORIGIN(ROM_BL);
+_rom_buffer_bin_length = LENGTH(ROM_BUFFER_BIN);
+_rom_bt_start = ORIGIN(ROM_BT) - ORIGIN(ROM_BL);
+_rom_bt_length = LENGTH(ROM_BT);
+_rom_nvdm_start = ORIGIN(ROM_NVDM) - ORIGIN(ROM_BL);
+_rom_nvdm_length = LENGTH(ROM_NVDM);
+_rom_log_start = ORIGIN(ROM_LOG) - ORIGIN(ROM_BL);
+_rom_log_length = LENGTH(ROM_LOG);
+
+
+/****************************************************************************
+ *
+ * FORWARD DECLARATIONS - SECTION SYMBOLS @ MEMORY BUS ADDRESS
+ *
+ ****************************************************************************/
+
+_xip_bl_addr = ORIGIN(ROM_BL);
+_xip_rbl_addr = ORIGIN(ROM_RBL);
+_xip_tfm_addr = ORIGIN(ROM_TFM);
+_xip_rtos_addr = ORIGIN(ROM_RTOS);
+_xip_nvdm_start = ORIGIN(ROM_NVDM);
+_xip_log_start = ORIGIN(ROM_LOG);
+_xip_bt_start = ORIGIN(ROM_BT);
+
+_sysram_start = ORIGIN(SYSRAM);
+_sysram_length = LENGTH(SYSRAM);
+_ram_start = ORIGIN(RAM);
+_ram_length = LENGTH(RAM);
+_ram_wifi_ext_start = ORIGIN(RAM_WFFW);
+_ram_wifi_ext_length = LENGTH(RAM_WFFW);
+_vram_start = ORIGIN(VRAM);
+_vram_length = LENGTH(VRAM);
+_vsysram_start = ORIGIN(VSYSRAM);
+_vsysram_length = LENGTH(VSYSRAM);
+_tcm_start = ORIGIN(TCM);
+_tcm_length = LENGTH(TCM);
+
+ /* Highest address of the stack */
+_stack_end = ORIGIN(TCM) + LENGTH(TCM); /* end of TCM */
+
+/* stack start */
+_stack_start = _stack_end - __STACK_SIZE;
+
+/* SYSRAM Region0 Offset for BROM */
+_region0_offset = 0x13000 ;
+
+SECTIONS
+{
+ . = ORIGIN(ROM_RTOS);
+ .text ALIGN(4):
+ {
+ _text_start = .;
+ KEEP(*(.vectorsTop))
+ KEEP(*(.vectors))
+ /* *(.text*) */
+ *(EXCLUDE_FILE(*/iperf_task.o *sockets*.o *netbuf*.o *pbuf*.o */mem.o *api_lib*.o */def.o *api_msg*.o *sys_arch*.o *ip4*.o *ip4_addr*.o *udp*.o *inet_chksum*.o *tcp_out*.o *tcp*.o */netif.o */ethernet.o *etharp*.o */lwip_cli.o *portasm*.o *event_groups*.o */heap_ext.o */queue.o */tasks.o *list*.o *os_port_callback*.o */port.o *timers*.o *hal_nvic*.o *libc_nano*.a:*memset*.o *libc_nano*.a:*memcpy*.o *libminisupp.a:*mem*.o) .text*)
+ KEEP(*(.init))
+ KEEP(*(.fini))
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+ *(.rodata*)
+ *(.rom_rtos)
+ KEEP(*(.eh_frame*))
+ . = ALIGN(4);
+ _text_end = .;
+ } > ROM_RTOS AT> ROM_RTOS
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > ROM_RTOS AT> ROM_RTOS
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > ROM_RTOS AT> ROM_RTOS
+ __exidx_end = .;
+
+ . = ALIGN(32);
+ _sysram_code_load = LOADADDR(.sysram_text);
+ .sysram_text ORIGIN(VSYSRAM)+_region0_offset :
+ {
+ _sysram_code_start = .;
+ *(.sysram_code)
+ *(.text*)
+ *(.sysram_rodata)
+ . = ALIGN(4);
+ _sysram_code_end = .;
+ } > VSYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _sysram_data_load = LOADADDR(.cached_sysram_data);
+ .cached_sysram_data :
+ {
+ _sysram_data_start = .;
+ *(vtable)
+ *(.data)
+ *(.data.*)
+ *(.sysram_rwdata)
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+ _sysram_data_end = .;
+ } > VSYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ .bss (NOLOAD) :
+ {
+ _sysram_bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ *(.sysram_zidata)
+ *(.sysram_swla_zidata)
+ . = ALIGN(4);
+ _sysram_bss_end = .;
+ } > VSYSRAM AT> ROM_RTOS
+
+
+ . = ALIGN(32);
+ _noncached_sysram_code_load = LOADADDR(.noncached_sysram_text);
+ . = . + ORIGIN(SYSRAM) - ORIGIN(VSYSRAM);
+ .noncached_sysram_text . :
+ {
+ _noncached_sysram_code_start = .;
+ *(.noncached_sysram_code)
+ *(.noncached_sysram_rodata)
+ . = ALIGN(4);
+ _noncached_sysram_code_end = .;
+ } > SYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _noncached_sysram_data_load = LOADADDR(.noncached_sysram_data);
+ .noncached_sysram_data . :
+ {
+ _noncached_sysram_data_start = .;
+ *(.noncached_sysram_rwdata)
+ *(.secure_settings_section)
+ . = ALIGN(4);
+ _noncached_sysram_data_end = .;
+ } > SYSRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ .noncached_sysram_bss . (NOLOAD) :
+ {
+ _noncached_sysram_bss_start = .;
+ *(.noncached_sysram_zidata)
+ . = ALIGN(4);
+ _noncached_sysram_bss_end = .;
+ } > SYSRAM AT> ROM_RTOS
+
+ . = ALIGN(32);
+ .btfw_code (NOLOAD) :
+ {
+ *(.bt_firmware_emi_code)
+ . = ALIGN(4);
+ } > RAM_BTFW AT> ROM_RTOS
+
+ . = ALIGN(32);
+ .wffw_code (NOLOAD) :
+ {
+ *(.wf_firmware_emi_code)
+ . = ALIGN(4);
+ } > RAM_WFFW AT> ROM_RTOS
+
+ . = ALIGN(32);
+ _ram_code_load = LOADADDR(.cached_ram_text);
+ .cached_ram_text :
+ {
+ _ram_code_start = .;
+ *(.ram_code)
+ *(.ram_rodata)
+ . = ALIGN(4);
+ _ram_code_end = .;
+ } > VRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _ram_data_load = LOADADDR(.cached_ram_data);
+ .cached_ram_data :
+ {
+ _ram_data_start = .;
+ *(.ram_rwdata)
+ . = ALIGN(4);
+ _ram_data_end = .;
+ } > VRAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _ram_bss_load = LOADADDR(.cached_ram_bss);
+ .cached_ram_bss (NOLOAD) :
+ {
+ _ram_bss_start = .;
+ *(.ram_zidata)
+ . = ALIGN(4);
+ _ram_bss_end = .;
+ } > VRAM AT> ROM_RTOS
+
+ . = ALIGN(32);
+ _noncached_ram_code_load = LOADADDR(.noncached_ram_text);
+ . = . + ORIGIN(RAM) - ORIGIN(VRAM);
+ .noncached_ram_text . :
+ {
+ _noncached_ram_code_start = .;
+ *(.noncached_ram_code)
+ *(.noncached_ram_rodata)
+ . = ALIGN(4);
+ _noncached_ram_code_end = .;
+ } > RAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _noncached_ram_data_load = LOADADDR(.noncached_ram_data);
+ .noncached_ram_data . :
+ {
+ _noncached_ram_data_start = .;
+ *(.noncached_ram_rwdata)
+ . = ALIGN(4);
+ _noncached_ram_data_end = .;
+ } > RAM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _noncached_ram_bss_load = LOADADDR(.noncached_ram_bss);
+ .noncached_ram_bss . (NOLOAD) :
+ {
+ _noncached_ram_bss_start = .;
+ *(.noncached_ram_zidata)
+ . = ALIGN(4);
+ _noncached_ram_bss_end = .;
+ } > RAM AT> ROM_RTOS
+
+
+ . = ALIGN(4);
+ _tcm_code_load = LOADADDR(.tcm_text);
+ .tcm_text :
+ {
+ _tcm_code_start = .;
+ *(.tcm_code)
+ *(.tcm_rodata)
+ . = ALIGN(4);
+ _tcm_code_end = .;
+ }> TCM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ _tcm_data_load = LOADADDR(.tcm_data);
+ .tcm_data :
+ {
+ _tcm_data_start = .;
+ . = ALIGN(4);
+ *(.tcm_rwdata)
+ . = ALIGN(4);
+ _tcm_data_end = .;
+ }> TCM AT> ROM_RTOS
+
+ . = ALIGN(4);
+ .tcm_bss (NOLOAD) :
+ {
+ _tcm_bss_start = .;
+ *(.tcm_zidata)
+ . = ALIGN(4);
+ *(.tcm_wakeup_info)
+ . = ALIGN(4);
+ _tcm_bss_end = .;
+ }> TCM AT> ROM_RTOS
+
+
+ __end__ = .;
+
+ .mcuboot_tlv_rsvd (NOLOAD) :
+ {
+ /* reserve 512 bytes for imgtool.py TLVs */
+ . = . + 512 ;
+ } > ROM_RTOS AT> ROM_RTOS
+
+ .stack (ORIGIN(TCM) + LENGTH(TCM) - __STACK_SIZE) (COPY) :
+ {
+ . = ALIGN(4);
+ __StackLimit = .;
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + __STACK_SIZE;
+ . = ALIGN(4);
+ __StackTop = .;
+ } > TCM
+
+ PROVIDE(__stack = __StackTop);
+
+ ASSERT(__StackLimit >= __end__, "region TCM overflowed with stack")
+}
+
+
+
diff --git a/examples/lock-app/genio/src/AppTask.cpp b/examples/lock-app/genio/src/AppTask.cpp
new file mode 100644
index 00000000000000..6c3e284991a9f2
--- /dev/null
+++ b/examples/lock-app/genio/src/AppTask.cpp
@@ -0,0 +1,610 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AppTask.h"
+#include "AppConfig.h"
+#include "AppEvent.h"
+#include "LEDWidget.h"
+
+#include "qrcodegen.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#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
+//#define EXAMPLE_VENDOR_ID 0xcafe
+
+#ifdef portYIELD_FROM_ISR
+#define OS_YIELD_FROM_ISR(yield) portYIELD_FROM_ISR(yield)
+#elif portEND_SWITCHING_ISR
+#define OS_YIELD_FROM_ISR(yield) portEND_SWITCHING_ISR(yield)
+#else
+#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR"
+#endif
+
+#define UNUSED_PARAMETER(a) (a = a)
+
+namespace {
+
+TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer.
+TaskHandle_t sAppTaskHandle;
+QueueHandle_t sAppEventQueue;
+
+LEDWidget sStatusLED;
+LEDWidget sLockLED;
+
+bool sIsWiFiProvisioned = false;
+bool sIsWiFiEnabled = false;
+bool sIsWiFiAttached = false;
+
+uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(AppEvent)];
+StaticQueue_t sAppEventQueueStruct;
+
+bool configValueSet = false;
+bool mSyncClusterToButtonAction = false;
+
+StackType_t appStack[APP_TASK_STACK_SIZE * 2 / sizeof(StackType_t)];
+StaticTask_t appTaskStruct;
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
+using namespace chip::DeviceLayer::NetworkCommissioning;
+chip::app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */,
+ &GenioWiFiDriver::GetInstance());
+#endif
+
+} // namespace
+
+using chip::app::Clusters::DoorLock::DlLockState;
+using chip::app::Clusters::DoorLock::DlOperationError;
+using chip::app::Clusters::DoorLock::DlOperationSource;
+
+using namespace chip;
+using namespace ::chip::DeviceLayer;
+using namespace ::chip::DeviceLayer::Internal;
+using namespace MT793XDoorLock::LockInitParams;
+
+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)
+ {
+ MT793X_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);
+ if (sAppTaskHandle == nullptr)
+ return APP_ERROR_CREATE_TASK_FAILED;
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR AppTask::Init()
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+
+ // Wait for the WiFi to be initialized
+ MT793X_LOG("APP: Wait WiFi Init");
+ vTaskDelay(1000); // TODO
+ MT793X_LOG("APP: Done WiFi Init");
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
+ sWiFiNetworkCommissioningInstance.Init();
+#endif
+ // Init ZCL Data Model and start server
+ static chip::CommonCaseDeviceServerInitParams initParams;
+ (void) initParams.InitializeStaticResourcesBeforeServerInit();
+ chip::Server::GetInstance().Init(initParams);
+
+ // Initialize device attestation config
+ SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
+
+ // 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)
+ {
+ MT793X_LOG("funct timer create failed");
+ appError(APP_ERROR_CREATE_TIMER_FAILED);
+ }
+
+ MT793X_LOG("Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);
+
+ // Initial lock state
+ chip::app::DataModel::Nullable state;
+ chip::EndpointId endpointId{ 1 };
+ chip::DeviceLayer::PlatformMgr().LockChipStack();
+ chip::app::Clusters::DoorLock::Attributes::LockState::Get(endpointId, state);
+
+ uint8_t numberOfCredentialsPerUser = 0;
+ if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, numberOfCredentialsPerUser))
+ {
+ ChipLogError(Zcl,
+ "Unable to get number of credentials supported per user when initializing lock endpoint, defaulting to 5 "
+ "[endpointId=%d]",
+ endpointId);
+ numberOfCredentialsPerUser = 5;
+ }
+
+ uint16_t numberOfUsers = 0;
+ if (!DoorLockServer::Instance().GetNumberOfUserSupported(endpointId, numberOfUsers))
+ {
+ ChipLogError(Zcl,
+ "Unable to get number of supported users when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
+ endpointId);
+ numberOfUsers = 10;
+ }
+
+ uint8_t numberOfWeekdaySchedulesPerUser = 0;
+ if (!DoorLockServer::Instance().GetNumberOfWeekDaySchedulesPerUserSupported(endpointId, numberOfWeekdaySchedulesPerUser))
+ {
+ ChipLogError(
+ Zcl,
+ "Unable to get number of supported weekday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
+ endpointId);
+ numberOfWeekdaySchedulesPerUser = 10;
+ }
+
+ uint8_t numberOfYeardaySchedulesPerUser = 0;
+ if (!DoorLockServer::Instance().GetNumberOfYearDaySchedulesPerUserSupported(endpointId, numberOfYeardaySchedulesPerUser))
+ {
+ ChipLogError(
+ Zcl,
+ "Unable to get number of supported yearday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
+ endpointId);
+ numberOfYeardaySchedulesPerUser = 10;
+ }
+
+ uint8_t numberOfHolidaySchedules = 0;
+ if (!DoorLockServer::Instance().GetNumberOfHolidaySchedulesSupported(endpointId, numberOfHolidaySchedules))
+ {
+ ChipLogError(
+ Zcl,
+ "Unable to get number of supported holiday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
+ endpointId);
+ numberOfHolidaySchedules = 10;
+ }
+
+ chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+
+ error = LockMgr().Init(state,
+ ParamBuilder()
+ .SetNumberOfUsers(numberOfUsers)
+ .SetNumberOfCredentialsPerUser(numberOfCredentialsPerUser)
+ .SetNumberOfWeekdaySchedulesPerUser(numberOfWeekdaySchedulesPerUser)
+ .SetNumberOfYeardaySchedulesPerUser(numberOfYeardaySchedulesPerUser)
+ .SetNumberOfHolidaySchedules(numberOfHolidaySchedules)
+ .GetLockParam());
+
+ if (error != CHIP_NO_ERROR)
+ {
+ MT793X_LOG("LockMgr().Init() failed");
+ appError(error);
+ }
+
+ LockMgr().SetCallbacks(ActionInitiated, ActionCompleted);
+
+ sStatusLED.Init(LED_STATUS);
+ sLockLED.Init(LED_LIGHT);
+
+ if (state.Value() == DlLockState::kUnlocked)
+ {
+ sLockLED.Set(false);
+ }
+ else
+ {
+ sLockLED.Set(true);
+ }
+ chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr));
+
+ ConfigurationMgr().LogDeviceConfig();
+
+ // PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE));
+ PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kSoftAP));
+
+ return error;
+}
+
+void AppTask::AppTaskMain(void * pvParameter)
+{
+ AppEvent event;
+
+ CHIP_ERROR error = sAppTask.Init();
+ if (error != CHIP_NO_ERROR)
+ {
+ MT793X_LOG("AppTask.Init() failed");
+ appError(error);
+ }
+
+ MT793X_LOG("AppTask started");
+
+ while (true)
+ {
+ // Users and credentials should be checked once from nvm flash on boot
+ if (!configValueSet)
+ {
+ LockMgr().ReadConfigValues();
+ configValueSet = 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())
+ {
+ sIsWiFiProvisioned = ConnectivityMgr().IsWiFiStationProvisioned();
+ sIsWiFiEnabled = ConnectivityMgr().IsWiFiStationEnabled();
+ sIsWiFiAttached = ConnectivityMgr().IsWiFiStationConnected();
+
+ 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 != kFunction_FactoryReset)
+ {
+ if (sIsWiFiProvisioned && sIsWiFiEnabled && !sIsWiFiAttached)
+ {
+ sStatusLED.Blink(950, 50);
+ }
+ else
+ {
+ sStatusLED.Blink(50, 950);
+ }
+ }
+ }
+}
+
+void AppTask::LockActionEventHandler(AppEvent * aEvent)
+{
+ bool initiated = false;
+ LockManager::Action_t action;
+ int32_t actor;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ if (aEvent->Type == AppEvent::kEventType_Lock)
+ {
+ action = static_cast(aEvent->LockEvent.Action);
+ actor = aEvent->LockEvent.Actor;
+ }
+ else if (aEvent->Type == AppEvent::kEventType_Button)
+ {
+ if (LockMgr().NextState() == true)
+ {
+ action = LockManager::LOCK_ACTION;
+ }
+ else
+ {
+ action = LockManager::UNLOCK_ACTION;
+ }
+ actor = AppEvent::kEventType_Button;
+ }
+ else
+ {
+ err = APP_ERROR_UNHANDLED_EVENT;
+ }
+
+ if (err == CHIP_NO_ERROR)
+ {
+ initiated = LockMgr().InitiateAction(actor, action);
+
+ if (!initiated)
+ {
+ MT793X_LOG("Action is already in progress or active.");
+ }
+ }
+}
+
+void AppTask::ButtonTimerEventHandler(AppEvent * aEvent)
+{
+ if (aEvent->Type != AppEvent::kEventType_Timer || sAppTask.mFunctionTimerActive == false)
+ {
+ return;
+ }
+
+ switch (sAppTask.mFunction)
+ {
+ case kFunction_NoneSelected:
+ break;
+
+ case kFunction_LightSwitch:
+ // Start timer for user to cancel the facotry reset, if needed
+ MT793X_LOG("Factory Reset Triggered.");
+ MT793X_LOG("Release button within %ums to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+ sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+ sAppTask.mFunction = kFunction_FactoryReset;
+
+ // Turn off all LEDs before starting blink to make sure blink is
+ // co-ordinated.
+ sStatusLED.Set(false);
+ sStatusLED.Blink(500);
+ break;
+
+ case kFunction_FactoryReset:
+ MT793X_LOG("Factory Reset Start.");
+ // Actually trigger Factory Reset
+ sAppTask.mFunction = kFunction_NoneSelected;
+ ConfigurationMgr().InitiateFactoryReset();
+ sStatusLED.Set(true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void AppTask::SingleButtonEventHandler(AppEvent * aEvent)
+{
+ if (aEvent->Type != AppEvent::kEventType_Button)
+ {
+ MT793X_LOG("A Non ButtonEvent received %d", aEvent->Type);
+ return;
+ }
+
+ if (aEvent->ButtonEvent.Pressed)
+ {
+ if (sAppTask.mFunctionTimerActive == false)
+ {
+ /* Start the timer to detect how long Button has been pressed */
+ MT793X_LOG("AppTask status LED on");
+ sStatusLED.Set(true);
+ sAppTask.mFunction = kFunction_LightSwitch;
+ sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT);
+ }
+ else
+ {
+ MT793X_LOG("AppTask function timer already started");
+ }
+ }
+ else
+ {
+ /* Cancel the timer to detect how long Button has been pressed */
+ sAppTask.CancelTimer();
+
+ switch (sAppTask.mFunction)
+ {
+ case kFunction_LightSwitch:
+ MT793X_LOG("AppTask light switch");
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Button;
+ LockActionEventHandler(&event);
+ break;
+ case kFunction_FactoryReset:
+ // factory reset cancelled, restore LED
+ MT793X_LOG("AppTask factory reset cancelled");
+ break;
+ default:
+ MT793X_LOG("not handled key release event, mFunction = %x", sAppTask.mFunction);
+ break;
+ }
+
+ sStatusLED.Set(false);
+
+ sAppTask.mFunction = kFunction_NoneSelected;
+ }
+}
+
+void AppTask::ButtonHandler(const filogic_button_t & button)
+{
+ AppEvent button_event = {};
+ button_event.Type = AppEvent::kEventType_Button;
+ button_event.ButtonEvent.Pressed = button.press;
+ button_event.Handler = SingleButtonEventHandler;
+ sAppTask.PostEvent(&button_event);
+}
+
+void AppTask::TimerEventHandler(TimerHandle_t xTimer)
+{
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Timer;
+ event.TimerEvent.Context = (void *) xTimer;
+ event.Handler = ButtonTimerEventHandler;
+ sAppTask.PostEvent(&event);
+}
+
+void AppTask::CancelTimer()
+{
+ if (xTimerStop(sFunctionTimer, 0) == pdFAIL)
+ {
+ MT793X_LOG("app timer stop() failed");
+ appError(APP_ERROR_STOP_TIMER_FAILED);
+ }
+
+ mFunctionTimerActive = false;
+}
+
+void AppTask::StartTimer(uint32_t aTimeoutInMs)
+{
+ if (xTimerIsTimerActive(sFunctionTimer))
+ {
+ MT793X_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)
+ {
+ MT793X_LOG("app timer start() failed");
+ appError(APP_ERROR_START_TIMER_FAILED);
+ }
+
+ mFunctionTimerActive = true;
+}
+
+void AppTask::ActionInitiated(LockManager::Action_t aAction, int32_t aActor)
+{
+ // Action initiated, update the light led
+ if (aAction == LockManager::LOCK_ACTION)
+ {
+ MT793X_LOG("Lock Action has been initiated")
+ sLockLED.Set(true);
+ }
+ else if (aAction == LockManager::UNLOCK_ACTION)
+ {
+ MT793X_LOG("Unlock Action has been initiated")
+ sLockLED.Set(false);
+ }
+
+ if (aActor == AppEvent::kEventType_Button)
+ {
+ mSyncClusterToButtonAction = true;
+ }
+}
+
+void AppTask::ActionCompleted(LockManager::Action_t aAction)
+{
+ // action has been completed bon the light
+ if (aAction == LockManager::LOCK_ACTION)
+ {
+ MT793X_LOG("Lock Action has been completed")
+ }
+ else if (aAction == LockManager::UNLOCK_ACTION)
+ {
+ MT793X_LOG("Unlock Action has been completed")
+ }
+
+ if (mSyncClusterToButtonAction)
+ {
+ chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr));
+ mSyncClusterToButtonAction = false;
+ }
+}
+
+void AppTask::ActionRequest(int32_t aActor, LockManager::Action_t aAction)
+{
+ AppEvent event;
+ event.Type = AppEvent::kEventType_Lock;
+ event.LockEvent.Actor = aActor;
+ event.LockEvent.Action = aAction;
+ event.Handler = LockActionEventHandler;
+ PostEvent(&event);
+}
+
+void AppTask::PostEvent(const AppEvent * aEvent)
+{
+ if (sAppEventQueue != NULL)
+ {
+ BaseType_t status;
+ if (xPortIsInsideInterrupt())
+ {
+ BaseType_t higherPrioTaskWoken;
+
+ higherPrioTaskWoken = pdFALSE;
+ status = xQueueSendFromISR(sAppEventQueue, aEvent, &higherPrioTaskWoken);
+ OS_YIELD_FROM_ISR(higherPrioTaskWoken);
+ }
+ else
+ {
+ status = xQueueSend(sAppEventQueue, aEvent, 1);
+ }
+
+ if (!status)
+ MT793X_LOG("Failed to post event to app task event queue");
+ }
+ else
+ {
+ MT793X_LOG("Event Queue is NULL should never happen");
+ }
+}
+
+void AppTask::DispatchEvent(AppEvent * aEvent)
+{
+ if (aEvent->Handler)
+ {
+ aEvent->Handler(aEvent);
+ }
+ else
+ {
+ MT793X_LOG("Event received with no handler. Dropping event.");
+ }
+}
+
+void AppTask::UpdateClusterState(intptr_t context)
+{
+ bool unlocked = LockMgr().NextState();
+ DlLockState newState = unlocked ? DlLockState::kUnlocked : DlLockState::kLocked;
+
+ DlOperationSource source = DlOperationSource::kUnspecified;
+
+ // write the new lock value
+ EmberAfStatus status =
+ DoorLockServer::Instance().SetLockState(1, newState, source) ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE;
+
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ MT793X_LOG("ERR: updating lock state %x", status);
+ }
+}
diff --git a/examples/lock-app/genio/src/LEDWidget.cpp b/examples/lock-app/genio/src/LEDWidget.cpp
new file mode 100644
index 00000000000000..1882fe6efe377a
--- /dev/null
+++ b/examples/lock-app/genio/src/LEDWidget.cpp
@@ -0,0 +1,215 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+
+#include
+
+#include "LEDWidget.h"
+
+#define MIN_LVL (1)
+#define MAX_LVL (254)
+
+void LEDWidget::TimerHandler(TimerHandle_t xTimer)
+{
+ LEDWidget * led_widget = (LEDWidget *) pvTimerGetTimerID(xTimer);
+ led_widget->Toggle();
+}
+
+void LEDWidget::StartTimer(uint32_t aTimeoutInMs)
+{
+ if (xTimerIsTimerActive(mTimer))
+ CancelTimer();
+
+ assert(xTimerChangePeriod(mTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) == pdPASS);
+}
+
+void LEDWidget::CancelTimer(void)
+{
+ assert(xTimerStop(mTimer, 0) == pdPASS);
+}
+
+void LEDWidget::Init(enum led_id led)
+{
+ filogic_led_init();
+
+ mLed = led;
+ mLevel = MAX_LVL;
+
+ mTimer = xTimerCreate(Name(),
+ 1, // == default timer period (mS)
+ false, // no timer reload (==one-shot)
+ (void *) this, // init timer id = app task obj context
+ TimerHandler); // timer callback handler
+}
+
+const char * LEDWidget::Name(void)
+{
+ const char * name;
+
+ switch (mLed)
+ {
+ case LED_LIGHT:
+ name = "LED_LIGHT";
+ break;
+ case LED_STATUS:
+ name = "LED_STATUS";
+ break;
+ default:
+ name = "LED UNKNOWN";
+ break;
+ }
+
+ return name;
+}
+
+void LEDWidget::Toggle(void)
+{
+ Set(!mState);
+ StartTimer(mState ? mOn : mOff);
+}
+
+void LEDWidget::DoBlink(void)
+{
+ StartTimer(mOn);
+}
+
+void LEDWidget::DoSet(bool state)
+{
+ switch (mLed)
+ {
+ case LED_LIGHT:
+ filogic_led_light_toggle(state);
+ break;
+ case LED_STATUS:
+ filogic_led_status_toggle(state);
+ break;
+ }
+ mState = state;
+}
+
+void LEDWidget::Set(bool state)
+{
+ CancelTimer();
+ DoSet(state);
+ // printf("%s %s\n", Name(), state ? "on" : "off");
+}
+
+bool LEDWidget::Get(void)
+{
+ return mState;
+}
+
+void LEDWidget::Blink(int on, int off)
+{
+ if (mOn != on || mOff != off)
+ {
+ mOn = on;
+ mOff = off;
+ // printf("%s blink: on %d off %d\n", Name(), mOn, mOff);
+ DoBlink();
+ }
+}
+
+void LEDWidget::Blink(int duration)
+{
+ Blink(duration, duration);
+}
+
+void LEDWidget::Color(RgbColor_t rgb)
+{
+ filogic_led_color_t _color;
+ _color.r = rgb.r;
+ _color.g = rgb.g;
+ _color.b = rgb.b;
+
+ switch (mLed)
+ {
+ case LED_LIGHT:
+ filogic_led_light_color(_color);
+ break;
+ case LED_STATUS:
+ filogic_led_status_color(_color);
+ break;
+ }
+}
+
+void LEDWidget::SetLevel(uint8_t level)
+{
+ uint8_t fdim = 0;
+
+ if (level >= MIN_LVL && level <= MAX_LVL)
+ {
+ mLevel = level;
+ }
+ else
+ {
+ return;
+ }
+
+ fdim = (level - MIN_LVL) / ((MAX_LVL - MIN_LVL) / (filogic_led_get_max_dim_level() - filogic_led_get_min_dim_level()));
+
+ if (fdim > filogic_led_get_max_dim_level())
+ {
+ fdim = filogic_led_get_max_dim_level();
+ }
+
+ if (mLed == LED_LIGHT)
+ {
+ filogic_led_light_dim(fdim);
+ }
+ else if (mLed == LED_STATUS)
+ {
+ filogic_led_status_dim(fdim);
+ }
+ else
+ {
+ assert(0);
+ }
+}
+
+uint8_t LEDWidget::GetLevel(void)
+{
+ uint8_t dim = 0;
+ if (mLed == LED_LIGHT)
+ {
+ dim = filogic_led_light_get_cur_dim_level();
+ }
+ else if (mLed == LED_STATUS)
+ {
+ dim = filogic_led_status_get_cur_dim_level();
+ }
+ else
+ {
+ assert(0);
+ }
+
+ dim = dim * ((MAX_LVL - MIN_LVL) / (filogic_led_get_max_dim_level() - filogic_led_get_min_dim_level()));
+
+ return dim;
+}
+
+uint8_t LEDWidget::GetMaxLevel(void)
+{
+ return MAX_LVL;
+}
+
+uint8_t LEDWidget::GetMinLevel(void)
+{
+ return MIN_LVL;
+}
diff --git a/examples/lock-app/genio/src/LockManager.cpp b/examples/lock-app/genio/src/LockManager.cpp
new file mode 100644
index 00000000000000..9ae7e4288695ea
--- /dev/null
+++ b/examples/lock-app/genio/src/LockManager.cpp
@@ -0,0 +1,707 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2019 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LockManager.h"
+
+#include "AppConfig.h"
+#include "AppTask.h"
+#include
+#include
+#include
+#include
+
+LockManager LockManager::sLock;
+
+TimerHandle_t sLockTimer;
+
+using namespace ::chip::DeviceLayer::Internal;
+using namespace MT793XDoorLock::LockInitParams;
+
+CHIP_ERROR LockManager::Init(chip::app::DataModel::Nullable state, LockParam lockParam)
+{
+
+ LockParams = lockParam;
+
+ if (LockParams.numberOfUsers > kMaxUsers)
+ {
+ MT793X_LOG("Max number of users is greater than %d, the maximum amount of users currently supported on this platform",
+ kMaxUsers);
+ return APP_ERROR_ALLOCATION_FAILED;
+ }
+
+ if (LockParams.numberOfCredentialsPerUser > kMaxCredentialsPerUser)
+ {
+ MT793X_LOG("Max number of credentials per user is greater than %d, the maximum amount of users currently supported on this "
+ "platform",
+ kMaxCredentialsPerUser);
+ return APP_ERROR_ALLOCATION_FAILED;
+ }
+
+ if (LockParams.numberOfWeekdaySchedulesPerUser > kMaxWeekdaySchedulesPerUser)
+ {
+ MT793X_LOG(
+ "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform",
+ kMaxWeekdaySchedulesPerUser);
+ return APP_ERROR_ALLOCATION_FAILED;
+ }
+
+ if (LockParams.numberOfYeardaySchedulesPerUser > kMaxYeardaySchedulesPerUser)
+ {
+ MT793X_LOG(
+ "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform",
+ kMaxYeardaySchedulesPerUser);
+ return APP_ERROR_ALLOCATION_FAILED;
+ }
+
+ if (LockParams.numberOfHolidaySchedules > kMaxHolidaySchedules)
+ {
+ MT793X_LOG(
+ "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform",
+ kMaxHolidaySchedules);
+ return APP_ERROR_ALLOCATION_FAILED;
+ }
+
+ // Create FreeRTOS sw timer for lock timer.
+ sLockTimer = xTimerCreate("lockTmr", // 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 = lock obj context
+ TimerEventHandler // timer callback handler
+ );
+
+ if (sLockTimer == NULL)
+ {
+ MT793X_LOG("sLockTimer timer create failed");
+ return APP_ERROR_CREATE_TIMER_FAILED;
+ }
+
+ if (state.Value() == DlLockState::kUnlocked)
+ mState = kState_UnlockCompleted;
+ else
+ mState = kState_LockCompleted;
+
+ return CHIP_NO_ERROR;
+}
+
+bool LockManager::IsValidUserIndex(uint16_t userIndex)
+{
+ return (userIndex < kMaxUsers);
+}
+
+bool LockManager::IsValidCredentialIndex(uint16_t credentialIndex, DlCredentialType type)
+{
+ if (DlCredentialType::kProgrammingPIN == type)
+ {
+ return (0 == credentialIndex); // 0 is required index for Programming PIN
+ }
+ return (credentialIndex < kMaxCredentialsPerUser);
+}
+
+bool LockManager::IsValidWeekdayScheduleIndex(uint8_t scheduleIndex)
+{
+ return (scheduleIndex < kMaxWeekdaySchedulesPerUser);
+}
+
+bool LockManager::IsValidYeardayScheduleIndex(uint8_t scheduleIndex)
+{
+ return (scheduleIndex < kMaxYeardaySchedulesPerUser);
+}
+
+bool LockManager::IsValidHolidayScheduleIndex(uint8_t scheduleIndex)
+{
+ return (scheduleIndex < kMaxHolidaySchedules);
+}
+
+bool LockManager::ReadConfigValues()
+{
+ size_t outLen;
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_LockUser, reinterpret_cast(&mLockUsers),
+ sizeof(EmberAfPluginDoorLockUserInfo) * ArraySize(mLockUsers), outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_Credential, reinterpret_cast(&mLockCredentials),
+ sizeof(EmberAfPluginDoorLockCredentialInfo) * ArraySize(mLockCredentials), outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_LockUserName, reinterpret_cast(mUserNames),
+ sizeof(mUserNames), outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_CredentialData, reinterpret_cast(mCredentialData),
+ sizeof(mCredentialData), outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_UserCredentials, reinterpret_cast(mCredentials),
+ sizeof(DlCredential) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser,
+ outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_WeekDaySchedules, reinterpret_cast(mWeekdaySchedule),
+ sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser *
+ LockParams.numberOfUsers,
+ outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_YearDaySchedules, reinterpret_cast(mYeardaySchedule),
+ sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser *
+ LockParams.numberOfUsers,
+ outLen);
+
+ MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_HolidaySchedules, reinterpret_cast(&(mHolidaySchedule)),
+ sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules, outLen);
+
+ return true;
+}
+
+void LockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB)
+{
+ mActionInitiated_CB = aActionInitiated_CB;
+ mActionCompleted_CB = aActionCompleted_CB;
+}
+
+bool LockManager::IsActionInProgress()
+{
+ return (mState == kState_LockInitiated || mState == kState_UnlockInitiated);
+}
+
+bool LockManager::NextState()
+{
+ return (mState == kState_UnlockCompleted);
+}
+
+bool LockManager::InitiateAction(int32_t aActor, Action_t aAction)
+{
+ bool action_initiated = false;
+ State_t new_state;
+
+ // Initiate Turn Lock/Unlock Action only when the previous one is complete.
+ if (mState == kState_LockCompleted && aAction == UNLOCK_ACTION)
+ {
+ action_initiated = true;
+
+ new_state = kState_UnlockInitiated;
+ }
+ else if (mState == kState_UnlockCompleted && aAction == LOCK_ACTION)
+ {
+ action_initiated = true;
+
+ new_state = kState_LockInitiated;
+ }
+
+ if (action_initiated)
+ {
+
+ 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 LockManager::StartTimer(uint32_t aTimeoutMs)
+{
+ if (xTimerIsTimerActive(sLockTimer))
+ {
+ MT793X_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(sLockTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS)
+ {
+ MT793X_LOG("sLockTimer timer start() failed");
+ appError(APP_ERROR_START_TIMER_FAILED);
+ }
+}
+
+void LockManager::CancelTimer(void)
+{
+ if (xTimerStop(sLockTimer, 0) == pdFAIL)
+ {
+ MT793X_LOG("sLockTimer stop() failed");
+ appError(APP_ERROR_STOP_TIMER_FAILED);
+ }
+}
+
+void LockManager::TimerEventHandler(TimerHandle_t xTimer)
+{
+ // Get lock obj context from timer id.
+ LockManager * lock = static_cast(pvTimerGetTimerID(xTimer));
+
+ // The timer event handler will be called in the context of the timer task
+ // once sLockTimer 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 = lock;
+ event.Handler = ActuatorMovementTimerEventHandler;
+ GetAppTask().PostEvent(&event);
+}
+
+void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
+{
+ Action_t actionCompleted = INVALID_ACTION;
+
+ LockManager * lock = static_cast(aEvent->TimerEvent.Context);
+
+ if (lock->mState == kState_LockInitiated)
+ {
+ lock->mState = kState_LockCompleted;
+ actionCompleted = LOCK_ACTION;
+ }
+ else if (lock->mState == kState_UnlockInitiated)
+ {
+ lock->mState = kState_UnlockCompleted;
+ actionCompleted = UNLOCK_ACTION;
+ }
+
+ if (actionCompleted != INVALID_ACTION)
+ {
+ if (lock->mActionCompleted_CB)
+ {
+ lock->mActionCompleted_CB(actionCompleted);
+ }
+ }
+}
+
+bool LockManager::Lock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err)
+{
+ return setLockState(endpointId, DlLockState::kLocked, pin, err);
+}
+
+bool LockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err)
+{
+ return setLockState(endpointId, DlLockState::kUnlocked, pin, err);
+}
+
+bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
+{
+ VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed
+
+ userIndex--;
+
+ VerifyOrReturnValue(IsValidUserIndex(userIndex), false);
+
+ ChipLogProgress(Zcl, "Door Lock App: LockManager::GetUser [endpoint=%d,userIndex=%hu]", endpointId, userIndex);
+
+ const auto & userInDb = mLockUsers[userIndex];
+
+ user.userStatus = userInDb.userStatus;
+ if (DlUserStatus::kAvailable == user.userStatus)
+ {
+ ChipLogDetail(Zcl, "Found unoccupied user [endpoint=%d]", endpointId);
+ return true;
+ }
+
+ user.userName = chip::CharSpan(userInDb.userName.data(), userInDb.userName.size());
+ user.credentials = chip::Span(mCredentials[userIndex], userInDb.credentials.size());
+ user.userUniqueId = userInDb.userUniqueId;
+ user.userType = userInDb.userType;
+ user.credentialRule = userInDb.credentialRule;
+ // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification
+ // source to Matter
+ user.creationSource = DlAssetSource::kMatterIM;
+ user.createdBy = userInDb.createdBy;
+ user.modificationSource = DlAssetSource::kMatterIM;
+ user.lastModifiedBy = userInDb.lastModifiedBy;
+
+ ChipLogDetail(Zcl,
+ "Found occupied user "
+ "[endpoint=%d,name=\"%.*s\",credentialsCount=%u,uniqueId=%lx,type=%u,credentialRule=%u,"
+ "createdBy=%d,lastModifiedBy=%d]",
+ endpointId, static_cast(user.userName.size()), user.userName.data(), user.credentials.size(),
+ user.userUniqueId, to_underlying(user.userType), to_underlying(user.credentialRule), user.createdBy,
+ user.lastModifiedBy);
+
+ return true;
+}
+
+bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
+ const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype,
+ DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials)
+{
+ ChipLogProgress(Zcl,
+ "Door Lock App: LockManager::SetUser "
+ "[endpoint=%d,userIndex=%d,creator=%d,modifier=%d,userName=%s,uniqueId=%ld "
+ "userStatus=%u,userType=%u,credentialRule=%u,credentials=%p,totalCredentials=%u]",
+ endpointId, userIndex, creator, modifier, userName.data(), uniqueId, to_underlying(userStatus),
+ to_underlying(usertype), to_underlying(credentialRule), credentials, totalCredentials);
+
+ VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed
+
+ userIndex--;
+
+ VerifyOrReturnValue(IsValidUserIndex(userIndex), false);
+
+ auto & userInStorage = mLockUsers[userIndex];
+
+ if (userName.size() > DOOR_LOCK_MAX_USER_NAME_SIZE)
+ {
+ ChipLogError(Zcl, "Cannot set user - user name is too long [endpoint=%d,index=%d]", endpointId, userIndex);
+ return false;
+ }
+
+ if (totalCredentials > LockParams.numberOfCredentialsPerUser)
+ {
+ ChipLogError(Zcl, "Cannot set user - total number of credentials is too big [endpoint=%d,index=%d,totalCredentials=%u]",
+ endpointId, userIndex, totalCredentials);
+ return false;
+ }
+
+ strncpy(mUserNames[userIndex], userName.data(), userName.size());
+ userInStorage.userName = chip::CharSpan(mUserNames[userIndex], userName.size());
+ userInStorage.userUniqueId = uniqueId;
+ userInStorage.userStatus = userStatus;
+ userInStorage.userType = usertype;
+ userInStorage.credentialRule = credentialRule;
+ userInStorage.lastModifiedBy = modifier;
+ userInStorage.createdBy = creator;
+
+ for (size_t i = 0; i < totalCredentials; ++i)
+ {
+ mCredentials[userIndex][i] = credentials[i];
+ }
+
+ userInStorage.credentials = chip::Span(mCredentials[userIndex], totalCredentials);
+
+ // Save user information in NVM flash
+ MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_LockUser, reinterpret_cast(&mLockUsers),
+ sizeof(EmberAfPluginDoorLockUserInfo) * LockParams.numberOfUsers);
+
+ MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_UserCredentials, reinterpret_cast(mCredentials),
+ sizeof(DlCredential) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser);
+
+ MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_LockUserName, reinterpret_cast(mUserNames),
+ sizeof(mUserNames));
+
+ ChipLogProgress(Zcl, "Successfully set the user [mEndpointId=%d,index=%d]", endpointId, userIndex);
+
+ return true;
+}
+
+bool LockManager::GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType,
+ EmberAfPluginDoorLockCredentialInfo & credential)
+{
+
+ if (DlCredentialType::kProgrammingPIN == credentialType)
+ {
+ VerifyOrReturnValue(IsValidCredentialIndex(credentialIndex, credentialType),
+ false); // programming pin index is only index allowed to contain 0
+ }
+ else
+ {
+ VerifyOrReturnValue(IsValidCredentialIndex(--credentialIndex, credentialType), false); // otherwise, indices are one-indexed
+ }
+
+ ChipLogProgress(Zcl, "Lock App: LockManager::GetCredential [credentialType=%u], credentialIndex=%d",
+ to_underlying(credentialType), credentialIndex);
+
+ const auto & credentialInStorage = mLockCredentials[credentialIndex];
+
+ credential.status = credentialInStorage.status;
+ ChipLogDetail(Zcl, "CredentialStatus: %d, CredentialIndex: %d ", (int) credential.status, credentialIndex);
+
+ if (DlCredentialStatus::kAvailable == credential.status)
+ {
+ ChipLogDetail(Zcl, "Found unoccupied credential ");
+ return true;
+ }
+ credential.credentialType = credentialInStorage.credentialType;
+ credential.credentialData = credentialInStorage.credentialData;
+ credential.createdBy = credentialInStorage.createdBy;
+ credential.lastModifiedBy = credentialInStorage.lastModifiedBy;
+ // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification
+ // source to Matter
+ credential.creationSource = DlAssetSource::kMatterIM;
+ credential.modificationSource = DlAssetSource::kMatterIM;
+
+ ChipLogDetail(Zcl, "Found occupied credential [type=%u,dataSize=%u]", to_underlying(credential.credentialType),
+ credential.credentialData.size());
+
+ return true;
+}
+
+bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator,
+ chip::FabricIndex modifier, DlCredentialStatus credentialStatus, DlCredentialType credentialType,
+ const chip::ByteSpan & credentialData)
+{
+
+ if (DlCredentialType::kProgrammingPIN == credentialType)
+ {
+ VerifyOrReturnValue(IsValidCredentialIndex(credentialIndex, credentialType),
+ false); // programming pin index is only index allowed to contain 0
+ }
+ else
+ {
+ VerifyOrReturnValue(IsValidCredentialIndex(--credentialIndex, credentialType), false); // otherwise, indices are one-indexed
+ }
+
+ ChipLogProgress(Zcl,
+ "Door Lock App: LockManager::SetCredential "
+ "[credentialStatus=%u,credentialType=%u,credentialDataSize=%u,creator=%d,modifier=%d]",
+ to_underlying(credentialStatus), to_underlying(credentialType), credentialData.size(), creator, modifier);
+
+ auto & credentialInStorage = mLockCredentials[credentialIndex];
+
+ credentialInStorage.status = credentialStatus;
+ credentialInStorage.credentialType = credentialType;
+ credentialInStorage.createdBy = creator;
+ credentialInStorage.lastModifiedBy = modifier;
+
+ memcpy(mCredentialData[credentialIndex], credentialData.data(), credentialData.size());
+ credentialInStorage.credentialData = chip::ByteSpan{ mCredentialData[credentialIndex], credentialData.size() };
+
+ // Save credential information in NVM flash
+ MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_Credential, reinterpret_cast(&mLockCredentials),
+ sizeof(EmberAfPluginDoorLockCredentialInfo) * LockParams.numberOfCredentialsPerUser);
+
+ MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_CredentialData, reinterpret_cast(&mCredentialData),
+ sizeof(mCredentialData));
+
+ ChipLogProgress(Zcl, "Successfully set the credential [credentialType=%u]", to_underlying(credentialType));
+
+ return true;
+}
+
+DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
+ EmberAfPluginDoorLockWeekDaySchedule & schedule)
+{
+
+ VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed
+ VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed
+
+ weekdayIndex--;
+ userIndex--;
+
+ VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure);
+ VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
+
+ const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];
+ if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
+ {
+ return DlStatus::kNotFound;
+ }
+
+ schedule = scheduleInStorage.schedule;
+
+ return DlStatus::kSuccess;
+}
+
+DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
+ DlScheduleStatus status, DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute,
+ uint8_t endHour, uint8_t endMinute)
+{
+
+ VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed
+ VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed
+
+ weekdayIndex--;
+ userIndex--;
+
+ VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure);
+ VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
+
+ auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];
+
+ scheduleInStorage.schedule.daysMask = daysMask;
+ scheduleInStorage.schedule.startHour = startHour;
+ scheduleInStorage.schedule.startMinute = startMinute;
+ scheduleInStorage.schedule.endHour = endHour;
+ scheduleInStorage.schedule.endMinute = endMinute;
+ scheduleInStorage.status = status;
+
+ // Save schedule information in NVM flash
+ MT793XConfig::WriteConfigValueBin(
+ MT793XConfig::kConfigKey_WeekDaySchedules, reinterpret_cast(mWeekdaySchedule),
+ sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser * LockParams.numberOfUsers);
+
+ return DlStatus::kSuccess;
+}
+
+DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
+ EmberAfPluginDoorLockYearDaySchedule & schedule)
+{
+ VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed
+ VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed
+
+ yearDayIndex--;
+ userIndex--;
+
+ VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure);
+ VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
+
+ const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
+ if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
+ {
+ return DlStatus::kNotFound;
+ }
+
+ schedule = scheduleInStorage.schedule;
+
+ return DlStatus::kSuccess;
+}
+
+DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
+ DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime)
+{
+ VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed
+ VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed
+
+ yearDayIndex--;
+ userIndex--;
+
+ VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure);
+ VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
+
+ auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
+
+ scheduleInStorage.schedule.localStartTime = localStartTime;
+ scheduleInStorage.schedule.localEndTime = localEndTime;
+ scheduleInStorage.status = status;
+
+ // Save schedule information in NVM flash
+ MT793XConfig::WriteConfigValueBin(
+ MT793XConfig::kConfigKey_YearDaySchedules, reinterpret_cast(mYeardaySchedule),
+ sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser * LockParams.numberOfUsers);
+
+ return DlStatus::kSuccess;
+}
+
+DlStatus LockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex,
+ EmberAfPluginDoorLockHolidaySchedule & schedule)
+{
+ VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed
+
+ holidayIndex--;
+
+ VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure);
+
+ const auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
+ if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
+ {
+ return DlStatus::kNotFound;
+ }
+
+ schedule = scheduleInStorage.schedule;
+
+ return DlStatus::kSuccess;
+}
+
+DlStatus LockManager::SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
+ uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode)
+{
+ VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed
+
+ holidayIndex--;
+
+ VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure);
+
+ auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
+
+ scheduleInStorage.schedule.localStartTime = localStartTime;
+ scheduleInStorage.schedule.localEndTime = localEndTime;
+ scheduleInStorage.schedule.operatingMode = operatingMode;
+ scheduleInStorage.status = status;
+
+ // Save schedule information in NVM flash
+ MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_HolidaySchedules,
+ reinterpret_cast(&(mHolidaySchedule)),
+ sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules);
+
+ return DlStatus::kSuccess;
+}
+
+const char * LockManager::lockStateToString(DlLockState lockState) const
+{
+ switch (lockState)
+ {
+ case DlLockState::kNotFullyLocked:
+ return "Not Fully Locked";
+ case DlLockState::kLocked:
+ return "Locked";
+ case DlLockState::kUnlocked:
+ return "Unlocked";
+ case DlLockState::kUnknownEnumValue:
+ break;
+ }
+
+ return "Unknown";
+}
+
+bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin,
+ DlOperationError & err)
+{
+
+ // Assume pin is required until told otherwise
+ bool requirePin = true;
+ chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin);
+
+ // If a pin code is not given
+ if (!pin.HasValue())
+ {
+ ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified [endpointId=%d]", endpointId);
+ // If a pin code is not required
+ if (!requirePin)
+ {
+ ChipLogDetail(Zcl, "Door Lock App: setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState),
+ endpointId);
+ DoorLockServer::Instance().SetLockState(endpointId, lockState);
+ return true;
+ }
+
+ ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", mEndpointId);
+
+ return false;
+ }
+
+ // Check the PIN code and the user status
+ for (uint8_t i = 0; i < kMaxUsers; i++)
+ {
+ for (uint8_t j = 0; j < kMaxCredentialsPerUser; j++)
+ {
+ if (mLockCredentials[mCredentials[i][j].CredentialIndex - 1].credentialType != DlCredentialType::kPin ||
+ mLockCredentials[mCredentials[i][j].CredentialIndex - 1].status == DlCredentialStatus::kAvailable)
+ {
+ continue;
+ }
+
+ if (mLockCredentials[mCredentials[i][j].CredentialIndex - 1].credentialData.data_equal(pin.Value()) &&
+ mLockUsers[i].userStatus != DlUserStatus::kOccupiedDisabled)
+ {
+ ChipLogDetail(
+ Zcl, "Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]",
+ lockStateToString(lockState), mEndpointId);
+ DoorLockServer::Instance().SetLockState(endpointId, lockState);
+
+ return true;
+ }
+ }
+ }
+
+ ChipLogDetail(Zcl,
+ "Door Lock App: specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" "
+ "[endpointId=%d]",
+ lockStateToString(lockState), mEndpointId);
+
+ err = DlOperationError::kInvalidCredential;
+ return false;
+}
diff --git a/examples/lock-app/genio/src/ZclCallbacks.cpp b/examples/lock-app/genio/src/ZclCallbacks.cpp
new file mode 100644
index 00000000000000..cca3ef947c9d86
--- /dev/null
+++ b/examples/lock-app/genio/src/ZclCallbacks.cpp
@@ -0,0 +1,192 @@
+/*
+ *
+ * Copyright (c) 2020 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * This file implements the handler for data model messages.
+ */
+
+#include "AppConfig.h"
+#include "LockManager.h"
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+using namespace ::chip::app::Clusters;
+using namespace ::chip::DeviceLayer::Internal;
+using namespace ::chip::app::Clusters::DoorLock;
+
+void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, 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 == DoorLock::Id && attributeId == DoorLock::Attributes::LockState::Id)
+ {
+ ChipLogProgress(Zcl, "Door lock cluster: " ChipLogFormatMEI, ChipLogValueMEI(clusterId));
+ }
+}
+
+/** @brief DoorLock 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
+ *
+ */
+void emberAfDoorLockClusterInitCallback(EndpointId endpoint)
+{
+ EmberAfStatus status;
+
+ status = DoorLock::Attributes::LockType::Set(endpoint, DlLockType::kDeadBolt);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(Zcl, "Failed to set LockType %x", status);
+ }
+
+ status = DoorLock::Attributes::NumberOfTotalUsersSupported::Set(endpoint, CONFIG_LOCK_NUM_USERS);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(Zcl, "Failed to set number of users %x", status);
+ }
+
+ status = DoorLock::Attributes::NumberOfPINUsersSupported::Set(endpoint, CONFIG_LOCK_NUM_USERS);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(Zcl, "Failed to set number of PIN users %x", status);
+ }
+
+ status = DoorLock::Attributes::NumberOfRFIDUsersSupported::Set(endpoint, 0);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(Zcl, "Failed to set number of RFID users %x", status);
+ }
+
+ status = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::Set(endpoint, CONFIG_LOCK_NUM_CREDENTIALS_PER_USER);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(Zcl, "Failed to set number of credentials per user %x", status);
+ }
+
+ // Note: Due to current logic of credential, do not enable PIN and RFID
+ // at the same time.
+ // Set FeatureMap to (kUsersManagement|kPINCredentials)
+ status = DoorLock::Attributes::FeatureMap::Set(endpoint, 0x101);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(Zcl, "Failed to set number of credentials per user %x", status);
+ }
+}
+
+bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, DlOperationError & err)
+{
+ ChipLogProgress(Zcl, "Door Lock App: Lock Command endpoint=%d", endpointId);
+ bool status = LockMgr().Lock(endpointId, pinCode, err);
+ if (status == true)
+ {
+ LockMgr().InitiateAction(AppEvent::kEventType_Lock, LockManager::LOCK_ACTION);
+ }
+ return status;
+}
+
+bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode,
+ DlOperationError & err)
+{
+ ChipLogProgress(Zcl, "Door Lock App: Unlock Command endpoint=%d", endpointId);
+ bool status = LockMgr().Unlock(endpointId, pinCode, err);
+ if (status == true)
+ {
+ LockMgr().InitiateAction(AppEvent::kEventType_Lock, LockManager::UNLOCK_ACTION);
+ }
+
+ return status;
+}
+
+bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType,
+ EmberAfPluginDoorLockCredentialInfo & credential)
+{
+ return LockMgr().GetCredential(endpointId, credentialIndex, credentialType, credential);
+}
+
+bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator,
+ chip::FabricIndex modifier, DlCredentialStatus credentialStatus,
+ DlCredentialType credentialType, const chip::ByteSpan & credentialData)
+{
+ return LockMgr().SetCredential(endpointId, credentialIndex, creator, modifier, credentialStatus, credentialType,
+ credentialData);
+}
+
+bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
+{
+ return LockMgr().GetUser(endpointId, userIndex, user);
+}
+
+bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator,
+ chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId,
+ DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule,
+ const DlCredential * credentials, size_t totalCredentials)
+{
+
+ return LockMgr().SetUser(endpointId, userIndex, creator, modifier, userName, uniqueId, userStatus, usertype, credentialRule,
+ credentials, totalCredentials);
+}
+
+DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
+ EmberAfPluginDoorLockWeekDaySchedule & schedule)
+{
+ return LockMgr().GetWeekdaySchedule(endpointId, weekdayIndex, userIndex, schedule);
+}
+
+DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
+ EmberAfPluginDoorLockYearDaySchedule & schedule)
+{
+ return LockMgr().GetYeardaySchedule(endpointId, yearDayIndex, userIndex, schedule);
+}
+
+DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex,
+ EmberAfPluginDoorLockHolidaySchedule & holidaySchedule)
+{
+ return LockMgr().GetHolidaySchedule(endpointId, holidayIndex, holidaySchedule);
+}
+
+DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
+ DlScheduleStatus status, DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute,
+ uint8_t endHour, uint8_t endMinute)
+{
+ return LockMgr().SetWeekdaySchedule(endpointId, weekdayIndex, userIndex, status, daysMask, startHour, startMinute, endHour,
+ endMinute);
+}
+
+DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
+ DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime)
+{
+ return LockMgr().SetYeardaySchedule(endpointId, yearDayIndex, userIndex, status, localStartTime, localEndTime);
+}
+
+DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
+ uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode)
+{
+ return LockMgr().SetHolidaySchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode);
+}
diff --git a/examples/lock-app/genio/src/main.cpp b/examples/lock-app/genio/src/main.cpp
new file mode 100644
index 00000000000000..416c81c53436d7
--- /dev/null
+++ b/examples/lock-app/genio/src/main.cpp
@@ -0,0 +1,277 @@
+/*
+ *
+ * Copyright (c) 2021 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include