diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 7983d1667b9a04..9c1e3a60bd4e42 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -43,6 +43,13 @@ declare_args() { #default Wifi Password chip_default_wifi_psk = "" + + # Enable TestEventTrigger in GeneralDiagnostics cluster + silabs_test_event_trigger_enabled = false + + # The EnableKey in hex string format used by TestEventTrigger command in + # GeneralDiagnostics cluster. The length of the string should be 32. + silabs_test_event_trigger_enable_key = "00112233445566778899aabbccddeeff" } import("${chip_root}/src/platform/silabs/wifi_args.gni") @@ -226,6 +233,7 @@ config("silabs-wifi-config") { source_set("siwx917-common") { deps = [] + defines = [] public_deps = [] public_configs = [ ":siwx917-common-config", @@ -294,6 +302,12 @@ source_set("siwx917-common") { public_deps += [ ":silabs-factory-data-provider" ] } + if (silabs_test_event_trigger_enabled) { + sources += + [ "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.cpp" ] + defines += [ "SILABS_TEST_EVENT_TRIGGER_ENABLE_KEY=\"${silabs_test_event_trigger_enable_key}\"" ] + } + public_deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", diff --git a/examples/platform/silabs/SiWx917/matter_config.cpp b/examples/platform/silabs/SiWx917/matter_config.cpp index 9d6344132ce8f1..4422a5474c862c 100644 --- a/examples/platform/silabs/SiWx917/matter_config.cpp +++ b/examples/platform/silabs/SiWx917/matter_config.cpp @@ -55,6 +55,8 @@ using namespace ::chip::DeviceLayer; // If building with the SiWx917-provided crypto backend, we can use the #include "SilabsDeviceDataProvider.h" +#include "SilabsTestEventTriggerDelegate.h" +#include #if SILABS_OTA_ENABLED void SilabsMatterConfig::InitOTARequestorHandler(System::Layer * systemLayer, void * appState) @@ -65,7 +67,8 @@ void SilabsMatterConfig::InitOTARequestorHandler(System::Layer * systemLayer, vo } #endif -void SilabsMatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event, intptr_t arg){ +void SilabsMatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ // Initialize OTA only when Thread or WiFi connectivity is established /*if (((event->Type == DeviceEventType::kThreadConnectivityChange) && (event->ThreadConnectivityChange.Result == kConnectivity_Established)) || @@ -79,6 +82,51 @@ void SilabsMatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event SILABS_LOG("Scheduling OTA Requestor initialization") } +#if SILABS_TEST_EVENT_TRIGGER_ENABLED +static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff }; + +static int hex_digit_to_int(char hex) +{ + if ('A' <= hex && hex <= 'F') + { + return 10 + hex - 'A'; + } + if ('a' <= hex && hex <= 'f') + { + return 10 + hex - 'a'; + } + if ('0' <= hex && hex <= '9') + { + return hex - '0'; + } + return -1; +} + +static size_t hex_string_to_binary(const char * hex_string, uint8_t * buf, size_t buf_size) +{ + size_t num_char = strlen(hex_string); + if (num_char != buf_size * 2) + { + return 0; + } + for (size_t i = 0; i < num_char; i += 2) + { + int digit0 = hex_digit_to_int(hex_string[i]); + int digit1 = hex_digit_to_int(hex_string[i + 1]); + + if (digit0 < 0 || digit1 < 0) + { + return 0; + } + buf[i / 2] = (digit0 << 4) + digit1; + } + + return buf_size; +} +#endif // SILABS_TEST_EVENT_TRIGGER_ENABLED + CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) { CHIP_ERROR err; @@ -131,6 +179,17 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) // Create initParams with SDK example defaults here static chip::CommonCaseDeviceServerInitParams initParams; +#if SILABS_TEST_EVENT_TRIGGER_ENABLED + if (hex_string_to_binary(SILABS_TEST_EVENT_TRIGGER_ENABLE_KEY, sTestEventTriggerEnableKey, + sizeof(sTestEventTriggerEnableKey)) == 0) + { + SILABS_LOG("Failed to convert the EnableKey string to octstr type value"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } + static SilabsTestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &testEventTriggerDelegate; +#endif // SILABS_TEST_EVENT_TRIGGER_ENABLED + // Initialize the remaining (not overridden) providers to the SDK example defaults (void) initParams.InitializeStaticResourcesBeforeServerInit(); diff --git a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp new file mode 100644 index 00000000000000..f9a11df74d7ae9 --- /dev/null +++ b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2023 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 "SilabsTestEventTriggerDelegate.h" + +using namespace ::chip::DeviceLayer; + +namespace chip { + +bool SilabsTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +{ + return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); +} + +} // namespace chip diff --git a/examples/platform/silabs/SilabsTestEventTriggerDelegate.h b/examples/platform/silabs/SilabsTestEventTriggerDelegate.h new file mode 100644 index 00000000000000..a69bd56c633afd --- /dev/null +++ b/examples/platform/silabs/SilabsTestEventTriggerDelegate.h @@ -0,0 +1,48 @@ +/* + * + * Copyright (c) 2023 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 + +namespace chip { + +class SilabsTestEventTriggerDelegate : public TestEventTriggerDelegate +{ +public: + explicit SilabsTestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {} + + /** + * @brief Checks to see if `enableKey` provided matches value chosen by the manufacturer. + * @param enableKey Buffer of the key to verify. + * @return True or False. + */ + bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; + + /** + * @brief User handler for handling the test event trigger based on `eventTrigger` provided. + * @param eventTrigger Event trigger to handle. + * @return CHIP_NO_ERROR on success or another CHIP_ERROR on failure. + */ + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override; + +private: + ByteSpan mEnableKey; +}; + +} // namespace chip diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 6d08c1d47a532b..d4fabaacef17cc 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -41,6 +41,13 @@ declare_args() { # Use default handler to negotiate subscription max interval chip_config_use_icd_subscription_callbacks = enable_sleepy_device + + # Enable TestEventTrigger in GeneralDiagnostics cluster + silabs_test_event_trigger_enabled = false + + # The EnableKey in hex string format used by TestEventTrigger command in + # GeneralDiagnostics cluster. The length of the string should be 32. + silabs_test_event_trigger_enable_key = "00112233445566778899aabbccddeeff" } silabs_common_plat_dir = "${chip_root}/examples/platform/silabs" @@ -262,6 +269,7 @@ config("silabs-wifi-config") { source_set("efr32-common") { deps = [] + defines = [] public_deps = [] public_configs = [ ":efr32-common-config", @@ -351,6 +359,15 @@ source_set("efr32-common") { public_deps += [ ":efr32-ICD-subscription-callback" ] } + if (silabs_test_event_trigger_enabled) { + sources += + [ "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.cpp" ] + defines += [ + "SILABS_TEST_EVENT_TRIGGER_ENABLED=true", + "SILABS_TEST_EVENT_TRIGGER_ENABLE_KEY=\"${silabs_test_event_trigger_enable_key}\"", + ] + } + public_deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/app/server", diff --git a/examples/platform/silabs/efr32/matter_config.cpp b/examples/platform/silabs/efr32/matter_config.cpp index 14118d071e892b..fdecec6279b3da 100644 --- a/examples/platform/silabs/efr32/matter_config.cpp +++ b/examples/platform/silabs/efr32/matter_config.cpp @@ -54,7 +54,9 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys #endif #include "SilabsDeviceDataProvider.h" +#include "SilabsTestEventTriggerDelegate.h" #include +#include #ifdef CHIP_CONFIG_USE_ICD_SUBSCRIPTION_CALLBACKS ICDSubscriptionCallback SilabsMatterConfig::mICDSubscriptionHandler; @@ -133,6 +135,51 @@ void SilabsMatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event } } +#if SILABS_TEST_EVENT_TRIGGER_ENABLED +static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff }; + +static int hex_digit_to_int(char hex) +{ + if ('A' <= hex && hex <= 'F') + { + return 10 + hex - 'A'; + } + if ('a' <= hex && hex <= 'f') + { + return 10 + hex - 'a'; + } + if ('0' <= hex && hex <= '9') + { + return hex - '0'; + } + return -1; +} + +static size_t hex_string_to_binary(const char * hex_string, uint8_t * buf, size_t buf_size) +{ + size_t num_char = strlen(hex_string); + if (num_char != buf_size * 2) + { + return 0; + } + for (size_t i = 0; i < num_char; i += 2) + { + int digit0 = hex_digit_to_int(hex_string[i]); + int digit1 = hex_digit_to_int(hex_string[i + 1]); + + if (digit0 < 0 || digit1 < 0) + { + return 0; + } + buf[i / 2] = (digit0 << 4) + digit1; + } + + return buf_size; +} +#endif // SILABS_TEST_EVENT_TRIGGER_ENABLED + CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) { CHIP_ERROR err; @@ -174,6 +221,17 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) // Create initParams with SDK example defaults here static chip::CommonCaseDeviceServerInitParams initParams; +#if SILABS_TEST_EVENT_TRIGGER_ENABLED + if (hex_string_to_binary(SILABS_TEST_EVENT_TRIGGER_ENABLE_KEY, sTestEventTriggerEnableKey, + sizeof(sTestEventTriggerEnableKey)) == 0) + { + SILABS_LOG("Failed to convert the EnableKey string to octstr type value"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } + static SilabsTestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &testEventTriggerDelegate; +#endif // SILABS_TEST_EVENT_TRIGGER_ENABLED + #if CHIP_CRYPTO_PLATFORM // When building with EFR32 crypto, use the opaque key store // instead of the default (insecure) one.