diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index f7685cf760..fde62765dd 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -143,9 +143,6 @@ endif() if(CONFIG_ENABLE_ICD_SERVER) chip_gn_arg_append("chip_enable_icd_server" "true") - if(CONFIG_ICD_ENFORCE_SIT_SLOW_POLL_LIMIT) - chip_gn_arg_append("icd_enforce_sit_slow_poll_limit" "true") - endif() if(CONFIG_ICD_REPORT_ON_ACTIVE_MODE) chip_gn_arg_append("chip_icd_report_on_active_mode" "true") endif() diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index 5c36284f07..c61ac770a6 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -32,7 +32,7 @@ menu "CHIP Core" default 8 help The maximum number of simultaneously active CHIP exchange contexts. - + An exchange context object is used to track the state of an ongoing CHIP message exchange (conversation) with a peer, e.g. a cloud service, a mobile application, or another device. @@ -410,13 +410,6 @@ menu "CHIP Device Layer" help Enables or Disables ICD server - config ICD_ENFORCE_SIT_SLOW_POLL_LIMIT - bool "Enforce SIT Slow Polling Max value to 15 seconds" - depends on ENABLE_ICD_SERVER - default n - help - Set to true to enforce SIT Slow Polling Max value to 15seconds - config ICD_REPORT_ON_ACTIVE_MODE bool "Emit a report on entering active mode" depends on ENABLE_ICD_SERVER diff --git a/config/esp32/components/chip/idf_component.yml b/config/esp32/components/chip/idf_component.yml index aeffec708d..1917fcf4de 100644 --- a/config/esp32/components/chip/idf_component.yml +++ b/config/esp32/components/chip/idf_component.yml @@ -26,6 +26,14 @@ dependencies: - if: "idf_version >=5.0" - if: "target != esp32h2" + # This matches the dependency of esp_insights + espressif/esp_diag_data_store: + version: "1.0.1" + require: public + rules: + - if: "idf_version >=5.0" + - if: "target != esp32h2" + espressif/esp_rcp_update: version: "1.2.0" rules: diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 3896ed6be7..b3180fdc1b 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -156,7 +156,6 @@ if (CONFIG_CHIP_ENABLE_ICD_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_checkin" CONFIG_CHIP_ICD_CHECK_IN_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_user_active_mode_trigger" CONFIG_CHIP_ICD_UAT_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_dsls" CONFIG_CHIP_ICD_DSLS_SUPPORT) - matter_add_gn_arg_bool ("icd_enforce_sit_slow_poll_limit" TRUE) endif() if (CONFIG_CHIP_FACTORY_DATA OR CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) diff --git a/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md index 50495a601e..b024b90b40 100644 --- a/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md +++ b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md @@ -24,9 +24,6 @@ Trigger Support, set the following parameter to true: chip_enable_icd_lit = true ``` -TI examples have only been tested with the ICD Server configuration. To enable -the client configuration, set `chip_enable_icd_client` to true. - Persistent subscriptions allow devices to attempt resuming existing subscriptions following a device reset. To enable persistent subscriptions, set the following parameter to true: diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt index 97b2576827..f7049b68ea 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt @@ -289,7 +289,7 @@ class DeviceProvisioningFragment : Fragment() { override fun onICDRegistrationInfoRequired() { Log.d(TAG, "onICDRegistrationInfoRequired") deviceController.updateCommissioningICDRegistrationInfo( - ICDRegistrationInfo.newBuilder().build() + ICDRegistrationInfo.newBuilder().setICDStayActiveDurationMsec(30000L).build() ) } diff --git a/examples/contact-sensor-app/nxp/k32w0/args.gni b/examples/contact-sensor-app/nxp/k32w0/args.gni index 1709f1da73..f4b68ae740 100644 --- a/examples/contact-sensor-app/nxp/k32w0/args.gni +++ b/examples/contact-sensor-app/nxp/k32w0/args.gni @@ -28,7 +28,6 @@ chip_generate_link_map_file = true chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w1/args.gni index 98372f4b82..e5654bdbc7 100644 --- a/examples/contact-sensor-app/nxp/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w1/args.gni @@ -32,7 +32,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false chip_enable_icd_dsls = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/mcxw71/args.gni b/examples/contact-sensor-app/nxp/mcxw71/args.gni index 72634a2308..6e6015933d 100644 --- a/examples/contact-sensor-app/nxp/mcxw71/args.gni +++ b/examples/contact-sensor-app/nxp/mcxw71/args.gni @@ -30,7 +30,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 947a24740f..e2fea1bdb8 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -3222,7 +3222,7 @@ endpoint 2 { callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; - ram attribute featureMap default = 2; + ram attribute featureMap default = 6; ram attribute clusterRevision default = 2; } } 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 89f718140f..595b0d8f83 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 @@ -5587,7 +5587,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "6", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lit-icd-app/silabs/build_for_wifi_args.gni b/examples/lit-icd-app/silabs/build_for_wifi_args.gni index 56cd70b217..6ef009e906 100644 --- a/examples/lit-icd-app/silabs/build_for_wifi_args.gni +++ b/examples/lit-icd-app/silabs/build_for_wifi_args.gni @@ -29,7 +29,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_enable_icd_lit = true # ICD Matter Configuration flags diff --git a/examples/lit-icd-app/silabs/openthread.gni b/examples/lit-icd-app/silabs/openthread.gni index b12529c2ca..e84e7be8ed 100644 --- a/examples/lit-icd-app/silabs/openthread.gni +++ b/examples/lit-icd-app/silabs/openthread.gni @@ -32,7 +32,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_icd_report_on_active_mode = true chip_enable_icd_lit = true diff --git a/examples/lock-app/nxp/k32w1/args.gni b/examples/lock-app/nxp/k32w1/args.gni index e0c41d1e34..b7a2d790ef 100644 --- a/examples/lock-app/nxp/k32w1/args.gni +++ b/examples/lock-app/nxp/k32w1/args.gni @@ -30,7 +30,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/lock-app/nxp/mcxw71/args.gni b/examples/lock-app/nxp/mcxw71/args.gni index 761b050b80..1a0940c96a 100644 --- a/examples/lock-app/nxp/mcxw71/args.gni +++ b/examples/lock-app/nxp/mcxw71/args.gni @@ -30,7 +30,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/platform/silabs/Si70xxSensor.cpp b/examples/platform/silabs/Si70xxSensor.cpp new file mode 100644 index 0000000000..0b03ca040f --- /dev/null +++ b/examples/platform/silabs/Si70xxSensor.cpp @@ -0,0 +1,67 @@ +/* + * + * 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 "sl_board_control.h" +#include "sl_i2cspm_instances.h" +#include "sl_si70xx.h" +#include +#include + +namespace { + +constexpr uint16_t kSensorTemperatureOffset = 475; +bool initialized = false; + +} // namespace + +namespace Si70xxSensor { + +sl_status_t Init() +{ + sl_status_t status = SL_STATUS_OK; + + status = sl_board_enable_sensor(SL_BOARD_SENSOR_RHT); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + status = sl_si70xx_init(sl_i2cspm_sensor, SI7021_ADDR); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + initialized = true; + return status; +} + +sl_status_t GetSensorData(uint16_t & relativeHumidity, int16_t & temperature) +{ + VerifyOrReturnError(initialized, SL_STATUS_NOT_INITIALIZED); + + sl_status_t status = SL_STATUS_OK; + int32_t tempTemperature = 0; + uint32_t tempHumidity = 0; + + status = sl_si70xx_measure_rh_and_temp(sl_i2cspm_sensor, SI7021_ADDR, &tempHumidity, &tempTemperature); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + // Sensor precision is milliX. We need to reduce to change the precision to centiX to fit with the cluster attributes presicion. + temperature = static_cast(tempTemperature / 10) - kSensorTemperatureOffset; + relativeHumidity = static_cast(tempHumidity / 10); + + return status; +} + +}; // namespace Si70xxSensor diff --git a/examples/platform/silabs/Si70xxSensor.h b/examples/platform/silabs/Si70xxSensor.h new file mode 100644 index 0000000000..8dc31a8daf --- /dev/null +++ b/examples/platform/silabs/Si70xxSensor.h @@ -0,0 +1,48 @@ +/* + * + * 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 "sl_status.h" +#include + +namespace Si70xxSensor { + +/** + * @brief Initialises the Si70xx Sensor. + * + * @return sl_status_t SL_STATUS_OK if there were no errors occured during initialisation. + * Error if an underlying platform error occured + */ +sl_status_t Init(); + +/** + * @brief Reads Humidity and temperature values from the Si70xx sensor. + * The init function must be called before calling the GetSensorData. + * + * @param[out] relativeHumidity Relative humidity percentage in centi-pourcentage (1000 == 10.00%) + * @param[out] temperature Ambiant temperature in centi-celsium (1000 == 10.00C) + * + * @return sl_status_t SL_STATUS_OK if there were no errors occured during initialisation. + * SL_STATUS_NOT_INITIALIZED if the sensor was not initialised + * Error if an underlying platform error occured + */ +sl_status_t GetSensorData(uint16_t & relativeHumidity, int16_t & temperature); + +}; // namespace Si70xxSensor diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 156fb38e49..cf7b7aedbf 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -252,6 +252,13 @@ source_set("siwx917-common") { public_deps += [ ":test-event-trigger" ] } + if (sl_enable_si70xx_sensor) { + sources += [ + "${silabs_common_plat_dir}/Si70xxSensor.cpp", + "${silabs_common_plat_dir}/Si70xxSensor.h", + ] + } + if (app_data_model != "") { public_deps += [ app_data_model ] } diff --git a/examples/platform/silabs/TemperatureSensor.cpp b/examples/platform/silabs/TemperatureSensor.cpp deleted file mode 100644 index d7e13e1993..0000000000 --- a/examples/platform/silabs/TemperatureSensor.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "TemperatureSensor.h" - -#include "sl_board_control.h" -#include "sl_i2cspm_instances.h" -#include "sl_si70xx.h" - -namespace TemperatureSensor { -constexpr uint16_t kSensorTemperatureOffset = 800; -static bool initialized = false; - -sl_status_t Init() -{ - sl_status_t status; - sl_i2cspm_t * rht_sensor = sl_i2cspm_sensor; - (void) sl_board_enable_sensor(SL_BOARD_SENSOR_RHT); - - status = sl_si70xx_init(rht_sensor, SI7021_ADDR); - initialized = (SL_STATUS_OK == status); - return status; -} - -sl_status_t GetTemp(uint32_t * relativeHumidity, int16_t * temperature) -{ - if (!initialized) - { - return SL_STATUS_NOT_INITIALIZED; - } - - // Sensor resolution 0.001 C - // DataModel resolution 0.01 C - sl_status_t status; - sl_i2cspm_t * rht_sensor = sl_i2cspm_sensor; - int32_t temp = 0; - status = sl_si70xx_measure_rh_and_temp(rht_sensor, SI7021_ADDR, relativeHumidity, &temp); - - if (temperature != nullptr) - { - *temperature = static_cast(temp / 10) - kSensorTemperatureOffset; - } - - return status; -} -}; // namespace TemperatureSensor diff --git a/examples/platform/silabs/TemperatureSensor.h b/examples/platform/silabs/TemperatureSensor.h deleted file mode 100644 index 116287e9a3..0000000000 --- a/examples/platform/silabs/TemperatureSensor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "sl_status.h" -#include - -namespace TemperatureSensor { -sl_status_t Init(); -sl_status_t GetTemp(uint32_t * relativeHumidity, int16_t * temperature); -}; // namespace TemperatureSensor diff --git a/examples/platform/silabs/display/demo-ui.c b/examples/platform/silabs/display/demo-ui.c index e0fe37ec9c..d909cb1f88 100644 --- a/examples/platform/silabs/display/demo-ui.c +++ b/examples/platform/silabs/display/demo-ui.c @@ -167,6 +167,5 @@ void demoUIClearMainScreen(uint8_t * name) { GLIB_clear(&glibContext); demoUIDisplayHeader((char *) name); - demoUIDisplayApp(false); demoUIDisplayProtocols(); } diff --git a/examples/platform/silabs/display/lcd.h b/examples/platform/silabs/display/lcd.h index b62664c9b4..61fa816743 100644 --- a/examples/platform/silabs/display/lcd.h +++ b/examples/platform/silabs/display/lcd.h @@ -65,6 +65,7 @@ class SilabsLCD int DrawPixel(void * pContext, int32_t x, int32_t y); int Update(void); void WriteDemoUI(bool state); + void WriteDemoUI(); void SetCustomUI(customUICB cb); void GetScreen(Screen_e & screen); @@ -85,8 +86,6 @@ class SilabsLCD bool protocol1 = false; /* data */ } DemoState_t; - void WriteDemoUI(); - #ifdef QR_CODE_ENABLED void WriteQRCode(); void LCDFillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h); diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 91cd2c1a0a..f5c79a2252 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -308,6 +308,13 @@ source_set("efr32-common") { public_deps += [ ":test-event-trigger" ] } + if (sl_enable_si70xx_sensor) { + sources += [ + "${silabs_common_plat_dir}/Si70xxSensor.cpp", + "${silabs_common_plat_dir}/Si70xxSensor.h", + ] + } + if (app_data_model != "") { public_deps += [ app_data_model ] } diff --git a/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni b/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni index 0619082413..e5097f8a1d 100644 --- a/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni +++ b/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni @@ -28,7 +28,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_enable_icd_lit = true # ICD Matter Configuration flags diff --git a/examples/smoke-co-alarm-app/silabs/openthread.gni b/examples/smoke-co-alarm-app/silabs/openthread.gni index 845b2220b4..f2a7ab6ed7 100644 --- a/examples/smoke-co-alarm-app/silabs/openthread.gni +++ b/examples/smoke-co-alarm-app/silabs/openthread.gni @@ -32,7 +32,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_icd_report_on_active_mode = true chip_enable_icd_lit = true diff --git a/examples/thermostat/silabs/BUILD.gn b/examples/thermostat/silabs/BUILD.gn index 75b2f75c15..f51ee14825 100644 --- a/examples/thermostat/silabs/BUILD.gn +++ b/examples/thermostat/silabs/BUILD.gn @@ -47,10 +47,6 @@ import("${examples_common_plat_dir}/args.gni") declare_args() { # Dump memory usage at link time. chip_print_memory_usage = false - - # Enable the temperature sensor - # Some boards do not have a temperature sensor - use_temp_sensor = false } if (wifi_soc) { @@ -112,19 +108,6 @@ if (wifi_soc) { "PW_RPC_ENABLED", ] } - - if (use_temp_sensor) { - include_dirs += [ - "${efr32_sdk_root}/platform/driver/i2cspm/inc", - "${efr32_sdk_root}/app/bluetooth/common/sensor_rht", - "${efr32_sdk_root}/app/bluetooth/common/sensor_rht/config", - "${efr32_sdk_root}/hardware/driver/si70xx/inc", - "${efr32_sdk_root}/app/bluetooth/common/sensor_select", - "${efr32_sdk_root}/platform/common/config", - ] - - defines += [ "USE_TEMP_SENSOR" ] - } } } @@ -141,17 +124,6 @@ silabs_executable("thermostat_app") { "src/ZclCallbacks.cpp", ] - if (use_temp_sensor) { - sources += [ - "${efr32_sdk_root}/hardware/driver/si70xx/src/sl_si70xx.c", - "${efr32_sdk_root}/platform/common/src/sl_status.c", - "${efr32_sdk_root}/platform/driver/i2cspm/src/sl_i2cspm.c", - "${efr32_sdk_root}/platform/emlib/src/em_i2c.c", - "${examples_common_plat_dir}/TemperatureSensor.cpp", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_i2cspm_init.c", - ] - } - if (!disable_lcd) { sources += [ "src/ThermostatUI.cpp" ] } diff --git a/examples/thermostat/silabs/src/SensorManager.cpp b/examples/thermostat/silabs/src/SensorManager.cpp index abecd899d5..3522e9f5a3 100644 --- a/examples/thermostat/silabs/src/SensorManager.cpp +++ b/examples/thermostat/silabs/src/SensorManager.cpp @@ -26,14 +26,15 @@ #include "AppEvent.h" #include "AppTask.h" -#ifdef USE_TEMP_SENSOR -#include "TemperatureSensor.h" -#endif +#if defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR +#include "Si70xxSensor.h" +#endif // defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR /********************************************************** * Defines and Constants *********************************************************/ using namespace chip; +using namespace chip::app; using namespace ::chip::DeviceLayer; constexpr EndpointId kThermostatEndpoint = 1; @@ -45,10 +46,10 @@ constexpr uint16_t kMinTemperatureDelta = 50; // 0.5 degree Celcius *********************************************************/ SensorManager SensorManager::sSensorManager; -#ifndef USE_TEMP_SENSOR +#if !(defined(SL_MATTER_USE_SI70XX_SENSOR) && (SL_MATTER_USE_SI70XX_SENSOR)) constexpr uint16_t kSimulatedReadingFrequency = (60000 / kSensorTImerPeriodMs); // Change Simulated number at each minutes static int16_t mSimulatedTemp[] = { 2300, 2400, 2800, 2550, 2200, 2125, 2100, 2600, 1800, 2700 }; -#endif +#endif // !(defined(SL_MATTER_USE_SI70XX_SENSOR) && (SL_MATTER_USE_SI70XX_SENSOR)) CHIP_ERROR SensorManager::Init() { @@ -61,13 +62,13 @@ CHIP_ERROR SensorManager::Init() return APP_ERROR_CREATE_TIMER_FAILED; } -#ifdef USE_TEMP_SENSOR - if (SL_STATUS_OK != TemperatureSensor::Init()) +#if defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR + if (SL_STATUS_OK != Si70xxSensor::Init()) { SILABS_LOG("Failed to Init Sensor"); return CHIP_ERROR_INTERNAL; } -#endif +#endif // defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR // Update Temp immediatly at bootup SensorTimerEventHandler(nullptr); @@ -81,19 +82,20 @@ void SensorManager::SensorTimerEventHandler(void * arg) int16_t temperature = 0; static int16_t lastTemperature = 0; -#ifdef USE_TEMP_SENSOR +#if defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR int32_t tempSum = 0; - uint32_t humidity = 0; + uint16_t humidity = 0; for (uint8_t i = 0; i < 100; i++) { - if (SL_STATUS_OK != TemperatureSensor::GetTemp(&humidity, &temperature)) + if (SL_STATUS_OK != Si70xxSensor::GetSensorData(humidity, temperature)) { SILABS_LOG("Failed to read Temperature !!!"); } tempSum += temperature; } temperature = static_cast(tempSum / 100); + #else static uint8_t nbOfRepetition = 0; static uint8_t simulatedIndex = 0; @@ -109,18 +111,20 @@ void SensorManager::SensorTimerEventHandler(void * arg) simulatedIndex++; nbOfRepetition = 0; } -#endif // USE_TEMP_SENSOR +#endif // defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR SILABS_LOG("Sensor Temp is : %d", temperature); + MarkAttributeDirty reportState = MarkAttributeDirty::kNo; if ((temperature >= (lastTemperature + kMinTemperatureDelta)) || temperature <= (lastTemperature - kMinTemperatureDelta)) { - lastTemperature = temperature; - PlatformMgr().LockChipStack(); - // The SensorMagager shouldn't be aware of the Endpoint ID TODO Fix this. - // TODO Per Spec we should also apply the Offset stored in the same cluster before saving the temp - - app::Clusters::Thermostat::Attributes::LocalTemperature::Set(kThermostatEndpoint, temperature); - PlatformMgr().UnlockChipStack(); + reportState = MarkAttributeDirty::kIfChanged; } + + lastTemperature = temperature; + PlatformMgr().LockChipStack(); + // The SensorMagager shouldn't be aware of the Endpoint ID TODO Fix this. + // TODO Per Spec we should also apply the Offset stored in the same cluster before saving the temp + app::Clusters::Thermostat::Attributes::LocalTemperature::Set(kThermostatEndpoint, temperature, reportState); + PlatformMgr().UnlockChipStack(); } diff --git a/src/app/icd/client/CheckInHandler.cpp b/src/app/icd/client/CheckInHandler.cpp index 8f0a4de9c1..f4eaa48b11 100644 --- a/src/app/icd/client/CheckInHandler.cpp +++ b/src/app/icd/client/CheckInHandler.cpp @@ -52,8 +52,12 @@ CHIP_ERROR CheckInHandler::Init(Messaging::ExchangeManager * exchangeManager, IC { VerifyOrReturnError(exchangeManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(clientStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(engine != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(mpExchangeManager == nullptr, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mpICDClientStorage == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mpCheckInDelegate == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mpImEngine == nullptr, CHIP_ERROR_INCORRECT_STATE); mpExchangeManager = exchangeManager; mpICDClientStorage = clientStorage; @@ -113,6 +117,7 @@ CHIP_ERROR CheckInHandler::OnMessageReceived(Messaging::ExchangeContext * ec, co if (refreshKey) { + ChipLogProgress(ICD, "Key Refresh is required"); RefreshKeySender * refreshKeySender = mpCheckInDelegate->OnKeyRefreshNeeded(clientInfo, mpICDClientStorage); if (refreshKeySender == nullptr) { @@ -130,6 +135,7 @@ CHIP_ERROR CheckInHandler::OnMessageReceived(Messaging::ExchangeContext * ec, co } else { + mpICDClientStorage->StoreEntry(clientInfo); mpCheckInDelegate->OnCheckInComplete(clientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT mpImEngine->OnActiveModeNotification(clientInfo.peer_node); diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp index 2b6b3a1aff..0c6a0f7e13 100644 --- a/src/app/icd/client/DefaultICDClientStorage.cpp +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -51,6 +51,11 @@ CHIP_ERROR DefaultICDClientStorage::UpdateFabricList(FabricIndex fabricIndex) mFabricList.push_back(fabricIndex); + return StoreFabricList(); +} + +CHIP_ERROR DefaultICDClientStorage::StoreFabricList() +{ Platform::ScopedMemoryBuffer backingBuffer; size_t counter = mFabricList.size(); size_t total = kFabricIndexTlvSize * counter + kArrayOverHead; @@ -68,7 +73,7 @@ CHIP_ERROR DefaultICDClientStorage::UpdateFabricList(FabricIndex fabricIndex) const auto len = writer.GetLengthWritten(); VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); - writer.Finalize(backingBuffer); + ReturnErrorOnFailure(writer.Finalize(backingBuffer)); return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(), static_cast(len)); } @@ -211,6 +216,7 @@ CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector 0, CHIP_NO_ERROR); size_t len = clientInfoSize * count + kArrayOverHead; Platform::ScopedMemoryBuffer backingBuffer; VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); @@ -344,8 +350,21 @@ CHIP_ERROR DefaultICDClientStorage::SerializeToTlv(TLV::TLVWriter & writer, cons return writer.EndContainer(arrayType); } +bool DefaultICDClientStorage::FabricExists(FabricIndex fabricIndex) +{ + for (auto & fabric_idx : mFabricList) + { + if (fabric_idx == fabricIndex) + { + return true; + } + } + return false; +} + CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo) { + VerifyOrReturnError(FabricExists(clientInfo.peer_node.GetFabricIndex()), CHIP_ERROR_INVALID_FABRIC_INDEX); std::vector clientInfoVector; size_t clientInfoSize = MaxICDClientInfoSize(); ReturnErrorOnFailure(Load(clientInfo.peer_node.GetFabricIndex(), clientInfoVector, clientInfoSize)); @@ -359,7 +378,6 @@ CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo) break; } } - clientInfoVector.push_back(clientInfo); size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead; Platform::ScopedMemoryBuffer backingBuffer; @@ -371,7 +389,7 @@ CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo) const auto len = writer.GetLengthWritten(); VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); - writer.Finalize(backingBuffer); + ReturnErrorOnFailure(writer.Finalize(backingBuffer)); ReturnErrorOnFailure(mpClientInfoStore->SyncSetKeyValue( DefaultStorageKeyAllocator::ICDClientInfoKey(clientInfo.peer_node.GetFabricIndex()).KeyName(), backingBuffer.Get(), static_cast(len))); @@ -416,7 +434,7 @@ CHIP_ERROR DefaultICDClientStorage::UpdateEntryCountForFabric(FabricIndex fabric const auto len = writer.GetLengthWritten(); VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); - writer.Finalize(backingBuffer); + ReturnErrorOnFailure(writer.Finalize(backingBuffer)); return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(), backingBuffer.Get(), static_cast(len)); @@ -424,9 +442,11 @@ CHIP_ERROR DefaultICDClientStorage::UpdateEntryCountForFabric(FabricIndex fabric CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) { + VerifyOrReturnError(FabricExists(peerNode.GetFabricIndex()), CHIP_NO_ERROR); size_t clientInfoSize = 0; std::vector clientInfoVector; ReturnErrorOnFailure(Load(peerNode.GetFabricIndex(), clientInfoVector, clientInfoSize)); + VerifyOrReturnError(clientInfoVector.size() > 0, CHIP_NO_ERROR); for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++) { @@ -440,7 +460,6 @@ CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) ReturnErrorOnFailure( mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName())); - size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead; Platform::ScopedMemoryBuffer backingBuffer; ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); @@ -451,7 +470,7 @@ CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) const auto len = writer.GetLengthWritten(); VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); - writer.Finalize(backingBuffer); + ReturnErrorOnFailure(writer.Finalize(backingBuffer)); ReturnErrorOnFailure( mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName(), backingBuffer.Get(), static_cast(len))); @@ -461,6 +480,8 @@ CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex) { + VerifyOrReturnError(FabricExists(fabricIndex), CHIP_NO_ERROR); + size_t clientInfoSize = 0; std::vector clientInfoVector; ReturnErrorOnFailure(Load(fabricIndex, clientInfoVector, clientInfoSize)); @@ -471,7 +492,23 @@ CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex) } ReturnErrorOnFailure( mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName())); - return mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName()); + ReturnErrorOnFailure( + mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName())); + + for (auto fabric = mFabricList.begin(); fabric != mFabricList.end(); fabric++) + { + if (*fabric == fabricIndex) + { + mFabricList.erase(fabric); + break; + } + } + + if (mFabricList.size() == 0) + { + return mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName()); + } + return StoreFabricList(); } CHIP_ERROR DefaultICDClientStorage::ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo, diff --git a/src/app/icd/client/DefaultICDClientStorage.h b/src/app/icd/client/DefaultICDClientStorage.h index 76faeb9afc..13064fe649 100644 --- a/src/app/icd/client/DefaultICDClientStorage.h +++ b/src/app/icd/client/DefaultICDClientStorage.h @@ -120,6 +120,12 @@ class DefaultICDClientStorage : public ICDClientStorage CHIP_ERROR ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo, Protocols::SecureChannel::CounterType & counter) override; +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + size_t GetFabricListSize() { return mFabricList.size(); } + + PersistentStorageDelegate * GetClientInfoStore() { return mpClientInfoStore; } +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST + protected: enum class ClientInfoTag : uint8_t { @@ -173,9 +179,12 @@ class DefaultICDClientStorage : public ICDClientStorage private: friend class ICDClientInfoIteratorImpl; + CHIP_ERROR StoreFabricList(); CHIP_ERROR LoadFabricList(); CHIP_ERROR LoadCounter(FabricIndex fabricIndex, size_t & count, size_t & clientInfoSize); + bool FabricExists(FabricIndex fabricIndex); + CHIP_ERROR IncreaseEntryCountForFabric(FabricIndex fabricIndex); CHIP_ERROR DecreaseEntryCountForFabric(FabricIndex fabricIndex); CHIP_ERROR UpdateEntryCountForFabric(FabricIndex fabricIndex, bool increase); diff --git a/src/app/icd/icd.gni b/src/app/icd/icd.gni index ed3fd0518f..b7fef896f5 100644 --- a/src/app/icd/icd.gni +++ b/src/app/icd/icd.gni @@ -14,23 +14,15 @@ declare_args() { # Matter SDK Configuration flag to enable ICD server functionality - # TODO - Add Specifics when the design is refined chip_enable_icd_server = false chip_enable_icd_lit = false - # Matter SDK Configuration flag to enable ICD client functionality - # TODO - Add Specifics when the design is refined - chip_enable_icd_client = false - # Matter SDK Configuration flag to make the ICD manager emit a report on entering active mode chip_icd_report_on_active_mode = false icd_max_notification_subscribers = 1 - # Set to true to enforce SIT Slow Polling Max value to 15seconds (spec 9.16.1.5) - icd_enforce_sit_slow_poll_limit = false - # Set to true if device supports dynamic switching from SIT to LIT operating modes (DSLS) chip_enable_icd_dsls = false } diff --git a/src/app/icd/server/BUILD.gn b/src/app/icd/server/BUILD.gn index e1967c23f5..bef9a0730a 100644 --- a/src/app/icd/server/BUILD.gn +++ b/src/app/icd/server/BUILD.gn @@ -39,7 +39,6 @@ buildconfig_header("icd-server-buildconfig") { "CHIP_CONFIG_ENABLE_ICD_DSLS=${chip_enable_icd_dsls}", "ICD_REPORT_ON_ENTER_ACTIVE_MODE=${chip_icd_report_on_active_mode}", "ICD_MAX_NOTIFICATION_SUBSCRIBERS=${icd_max_notification_subscribers}", - "ICD_ENFORCE_SIT_SLOW_POLL_LIMIT=${icd_enforce_sit_slow_poll_limit}", ] visibility = [ ":icd-server-config" ] diff --git a/src/app/icd/server/ICDConfigurationData.cpp b/src/app/icd/server/ICDConfigurationData.cpp index cfd2325671..44d78bfadf 100644 --- a/src/app/icd/server/ICDConfigurationData.cpp +++ b/src/app/icd/server/ICDConfigurationData.cpp @@ -16,7 +16,6 @@ */ #include "ICDConfigurationData.h" -#include #include namespace chip { @@ -25,15 +24,16 @@ ICDConfigurationData ICDConfigurationData::instance; System::Clock::Milliseconds32 ICDConfigurationData::GetSlowPollingInterval() { -#if ICD_ENFORCE_SIT_SLOW_POLL_LIMIT - // When in SIT mode, the slow poll interval SHOULDN'T be greater than the SIT mode polling threshold, per spec. +#if CHIP_CONFIG_ENABLE_ICD_LIT + // When in SIT mode, the slow poll interval SHALL NOT be greater than the SIT mode polling threshold, per spec. // This is important for ICD device configured for LIT operation but currently operating as a SIT // due to a lack of client registration if (mICDMode == ICDMode::SIT && mSlowPollingInterval > kSITPollingThreshold) { return kSITPollingThreshold; } -#endif +#endif // CHIP_CONFIG_ENABLE_ICD_LIT + return mSlowPollingInterval; } diff --git a/src/app/icd/server/ICDConfigurationData.h b/src/app/icd/server/ICDConfigurationData.h index 0d6e17e55e..4d2597ef26 100644 --- a/src/app/icd/server/ICDConfigurationData.h +++ b/src/app/icd/server/ICDConfigurationData.h @@ -17,6 +17,7 @@ #pragma once +#include #include #include #include @@ -77,14 +78,11 @@ class ICDConfigurationData System::Clock::Seconds32 GetMaximumCheckInBackoff() { return mMaximumCheckInBackOff; } /** - * If ICD_ENFORCE_SIT_SLOW_POLL_LIMIT is set to 0, function will always return the configured Slow Polling interval - * (CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL). - * - * If ICD_ENFORCE_SIT_SLOW_POLL_LIMIT is set to 1, the returned value will depend on the devices operating mode. + * The returned value will depend on the devices operating mode. * If ICDMode == SIT && the configured slow poll interval is superior to the maximum threshold (15s), the function will return - * the threshold (15s). If ICDMode == SIT but the configured slow poll interval is equal or inferior to the threshold, the - * function will the return the configured slow poll interval. If ICDMode == LIT, the function will return the configured slow - * poll interval. + * the threshold kSITPollingThreshold (<= 15s). If ICDMode == SIT but the configured slow poll interval is equal or inferior to + * the threshold, the function will the return the configured slow poll interval. If ICDMode == LIT, the function will return + * the configured slow poll interval. * * @return System::Clock::Milliseconds32 */ @@ -158,12 +156,18 @@ class ICDConfigurationData "Spec requires the MaximumCheckInBackOff to be equal or superior to the IdleModeDuration"); System::Clock::Seconds32 mMaximumCheckInBackOff = System::Clock::Seconds32(CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC); - // SIT ICDs should have a SlowPollingThreshold shorter than or equal to 15s (spec 9.16.1.5) - static_assert((CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT).count() <= 15000, + // SIT ICDs SHALL have a SlowPollingThreshold shorter than or equal to 15s (spec 9.16.1.5) + static constexpr System::Clock::Milliseconds32 kSitIcdSlowPollMaximum = System::Clock::Milliseconds32(15000); + static_assert((CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT).count() <= kSitIcdSlowPollMaximum.count(), "Spec requires the maximum slow poll interval for the SIT device to be smaller or equal than 15 s."); static constexpr System::Clock::Milliseconds32 kSITPollingThreshold = CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT; - System::Clock::Milliseconds32 mSlowPollingInterval = CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL; - System::Clock::Milliseconds32 mFastPollingInterval = CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL; + +#if CHIP_CONFIG_ENABLE_ICD_LIT == 0 + static_assert((CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL <= kSitIcdSlowPollMaximum), + "LIT support is required for slow polling intervals superior to 15 seconds"); +#endif + System::Clock::Milliseconds32 mSlowPollingInterval = CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL; + System::Clock::Milliseconds32 mFastPollingInterval = CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL; ICDMode mICDMode = ICDMode::SIT; }; diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp index 3e89af1e16..ba349b22b9 100644 --- a/src/app/icd/server/ICDManager.cpp +++ b/src/app/icd/server/ICDManager.cpp @@ -80,9 +80,6 @@ void ICDManager::Init() VerifyOrDieWithMsg(ICDConfigurationData::GetInstance().GetMinLitActiveModeThreshold() <= ICDConfigurationData::GetInstance().GetActiveModeThreshold(), AppServer, "The minimum ActiveModeThreshold value for a LIT ICD is 5 seconds."); - // Disabling check until LIT support is compelte - // VerifyOrDieWithMsg((GetSlowPollingInterval() <= GetSITPollingThreshold()) , AppServer, - // "LIT support is required for slow polling intervals superior to 15 seconds"); } #endif // CHIP_CONFIG_ENABLE_ICD_LIT diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 104a57a2fc..09dcb304ea 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -194,6 +194,7 @@ chip_test_suite("tests") { "TestBasicCommandPathRegistry.cpp", "TestBindingTable.cpp", "TestBuilderParser.cpp", + "TestCheckInHandler.cpp", "TestCommandHandlerInterfaceRegistry.cpp", "TestCommandInteraction.cpp", "TestCommandPathParams.cpp", @@ -236,6 +237,7 @@ chip_test_suite("tests") { "${chip_root}/src/app", "${chip_root}/src/app/codegen-data-model-provider:instance-header", "${chip_root}/src/app/common:cluster-objects", + "${chip_root}/src/app/icd/client:handler", "${chip_root}/src/app/icd/client:manager", "${chip_root}/src/app/tests:helpers", "${chip_root}/src/app/util/mock:mock_codegen_data_model", diff --git a/src/app/tests/TestCheckInHandler.cpp b/src/app/tests/TestCheckInHandler.cpp new file mode 100644 index 0000000000..0d57eb6b42 --- /dev/null +++ b/src/app/tests/TestCheckInHandler.cpp @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2024 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace app; +using namespace System; +using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore; + +constexpr uint8_t kKeyBuffer1[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f +}; + +constexpr uint8_t kKeyBuffer2[] = { + 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x14, 0x31, 0x21, 0x11, 0x01 +}; + +class TestCheckInHandler : public chip::Test::AppContext +{ +}; + +class CheckInHandlerWrapper : public chip::app::CheckInHandler +{ +public: + CHIP_ERROR ValidateOnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, + System::PacketBufferHandle && payload) + { + return OnMessageReceived(ec, payloadHeader, std::move(payload)); + } +}; + +TEST_F(TestCheckInHandler, TestOnMessageReceived) +{ + InteractionModelEngine * engine = InteractionModelEngine::GetInstance(); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); + TestPersistentStorageDelegate clientInfoStorage; + TestSessionKeystoreImpl keystore; + + DefaultICDClientStorage manager; + EXPECT_EQ(manager.Init(&clientInfoStorage, &keystore), CHIP_NO_ERROR); + + DefaultCheckInDelegate checkInDelegate; + EXPECT_EQ(checkInDelegate.Init(&manager, engine), CHIP_NO_ERROR); + + CheckInHandlerWrapper checkInHandler; + EXPECT_EQ(checkInHandler.Init(&GetExchangeManager(), &manager, &checkInDelegate, engine), CHIP_NO_ERROR); + + FabricIndex fabricIdA = 1; + NodeId nodeIdA = 6666; + + ICDClientInfo clientInfoA; + clientInfoA.peer_node = ScopedNodeId(nodeIdA, fabricIdA); + clientInfoA.start_icd_counter = 0; + clientInfoA.offset = 0; + EXPECT_EQ(manager.UpdateFabricList(fabricIdA), CHIP_NO_ERROR); + EXPECT_EQ(manager.SetKey(clientInfoA, ByteSpan(kKeyBuffer1)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfoA), CHIP_NO_ERROR); + + FabricIndex fabricIdB = 2; + NodeId nodeIdB = 6667; + + ICDClientInfo clientInfoB; + clientInfoB.peer_node = ScopedNodeId(nodeIdB, fabricIdB); + clientInfoB.offset = 0; + EXPECT_EQ(manager.UpdateFabricList(fabricIdB), CHIP_NO_ERROR); + EXPECT_EQ(manager.SetKey(clientInfoB, ByteSpan(kKeyBuffer2)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfoB), CHIP_NO_ERROR); + + PayloadHeader payloadHeader; + payloadHeader.SetExchangeID(0); + payloadHeader.SetMessageType(chip::Protocols::SecureChannel::MsgType::ICD_CheckIn); + + uint32_t counter = 1; + System::PacketBufferHandle buffer1 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output1{ buffer1->Start(), buffer1->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoA.aes_key_handle, clientInfoA.hmac_key_handle, counter, ByteSpan(), output1), + CHIP_NO_ERROR); + + buffer1->SetDataLength(static_cast(output1.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer1)), CHIP_NO_ERROR); + + ICDClientInfo clientInfo1; + auto * iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo1)) + { + if (clientInfo1.peer_node.GetNodeId() == nodeIdA && clientInfo1.peer_node.GetFabricIndex() == fabricIdA) + { + break; + } + } + iterator->Release(); + + EXPECT_EQ(clientInfo1.offset, counter - clientInfoA.start_icd_counter); + + // Validate duplicate check-in message handling + chip::System::PacketBufferHandle buffer2 = + MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output2{ buffer2->Start(), buffer2->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoA.aes_key_handle, clientInfoA.hmac_key_handle, counter, ByteSpan(), output2), + CHIP_NO_ERROR); + + buffer2->SetDataLength(static_cast(output2.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer2)), CHIP_NO_ERROR); + + ICDClientInfo clientInfo2; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo2)) + { + if (clientInfo2.peer_node.GetNodeId() == nodeIdA && clientInfo2.peer_node.GetFabricIndex() == fabricIdA) + { + break; + } + } + iterator->Release(); + EXPECT_EQ(clientInfo2.offset, counter - clientInfoA.start_icd_counter); + + // Validate second check-in message with increased counter + counter++; + System::PacketBufferHandle buffer3 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output3{ buffer3->Start(), buffer3->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoA.aes_key_handle, clientInfoA.hmac_key_handle, counter, ByteSpan(), output3), + CHIP_NO_ERROR); + buffer3->SetDataLength(static_cast(output3.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer3)), CHIP_NO_ERROR); + ICDClientInfo clientInfo3; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo3)) + { + if (clientInfo3.peer_node.GetNodeId() == nodeIdA && clientInfo3.peer_node.GetFabricIndex() == fabricIdA) + { + break; + } + } + iterator->Release(); + EXPECT_EQ(clientInfo3.offset, counter - clientInfoA.start_icd_counter); + + // Validate check-in message from fabricB + counter++; + System::PacketBufferHandle buffer4 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output4{ buffer4->Start(), buffer4->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoB.aes_key_handle, clientInfoB.hmac_key_handle, counter, ByteSpan(), output4), + CHIP_NO_ERROR); + buffer4->SetDataLength(static_cast(output4.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer4)), CHIP_NO_ERROR); + ICDClientInfo clientInfo4; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo4)) + { + if (clientInfo4.peer_node.GetNodeId() == nodeIdB && clientInfo4.peer_node.GetFabricIndex() == fabricIdB) + { + break; + } + } + iterator->Release(); + EXPECT_EQ(clientInfo4.offset, counter - clientInfoB.start_icd_counter); + + // Validate check-in message from removed fabricB + counter++; + System::PacketBufferHandle buffer5 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output5{ buffer5->Start(), buffer5->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoB.aes_key_handle, clientInfoB.hmac_key_handle, counter, ByteSpan(), output5), + CHIP_NO_ERROR); + + EXPECT_EQ(manager.DeleteAllEntries(fabricIdB), CHIP_NO_ERROR); + buffer5->SetDataLength(static_cast(output5.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer5)), CHIP_NO_ERROR); + ICDClientInfo clientInfo5; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + bool located = false; + while (iterator->Next(clientInfo5)) + { + if (clientInfo5.peer_node.GetFabricIndex() == fabricIdB) + { + located = true; + break; + } + } + iterator->Release(); + EXPECT_FALSE(located); + + // Add back fabricB and validate check-in message again + EXPECT_EQ(manager.UpdateFabricList(fabricIdB), CHIP_NO_ERROR); + EXPECT_EQ(manager.SetKey(clientInfoB, ByteSpan(kKeyBuffer2)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfoB), CHIP_NO_ERROR); + counter++; + System::PacketBufferHandle buffer6 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output6{ buffer6->Start(), buffer6->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoB.aes_key_handle, clientInfoB.hmac_key_handle, counter, ByteSpan(), output6), + CHIP_NO_ERROR); + buffer6->SetDataLength(static_cast(output4.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer6)), CHIP_NO_ERROR); + ICDClientInfo clientInfo6; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo6)) + { + if (clientInfo6.peer_node.GetNodeId() == nodeIdB && clientInfo6.peer_node.GetFabricIndex() == fabricIdB) + { + break; + } + } + iterator->Release(); + EXPECT_EQ(clientInfo6.offset, counter - clientInfoB.start_icd_counter); + + // Clear fabric table + EXPECT_EQ(manager.DeleteAllEntries(fabricIdA), CHIP_NO_ERROR); + EXPECT_EQ(manager.DeleteAllEntries(fabricIdB), CHIP_NO_ERROR); + // Add back fabricA and validate check-in message again + EXPECT_EQ(manager.UpdateFabricList(fabricIdA), CHIP_NO_ERROR); + EXPECT_EQ(manager.SetKey(clientInfoA, ByteSpan(kKeyBuffer1)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfoA), CHIP_NO_ERROR); + counter++; + System::PacketBufferHandle buffer7 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output7{ buffer7->Start(), buffer7->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoA.aes_key_handle, clientInfoA.hmac_key_handle, counter, ByteSpan(), output7), + CHIP_NO_ERROR); + buffer7->SetDataLength(static_cast(output7.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer7)), CHIP_NO_ERROR); + ICDClientInfo clientInfo7; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo7)) + { + if (clientInfo7.peer_node.GetNodeId() == nodeIdA && clientInfo7.peer_node.GetFabricIndex() == fabricIdA) + { + break; + } + } + iterator->Release(); + EXPECT_EQ(clientInfo7.offset, counter - clientInfoA.start_icd_counter); + + // Validate IcdclientInfo is not updated when handling overlimited counter and fail to create case session + uint32_t old_start_icd_counter = clientInfo7.start_icd_counter; + uint32_t old_counter = counter; + counter = (1U << 31) + 100U + clientInfo7.start_icd_counter; + System::PacketBufferHandle buffer8 = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output8{ buffer8->Start(), buffer8->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfoA.aes_key_handle, clientInfoA.hmac_key_handle, counter, ByteSpan(), output8), + CHIP_NO_ERROR); + + buffer8->SetDataLength(static_cast(output8.size())); + EXPECT_EQ(checkInHandler.ValidateOnMessageReceived(nullptr, payloadHeader, std::move(buffer8)), CHIP_NO_ERROR); + ICDClientInfo clientInfo8; + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + while (iterator->Next(clientInfo8)) + { + if (clientInfo8.peer_node.GetNodeId() == nodeIdA && clientInfo8.peer_node.GetFabricIndex() == fabricIdA) + { + break; + } + } + iterator->Release(); + EXPECT_EQ(clientInfo8.offset, old_counter - clientInfoA.start_icd_counter); + EXPECT_EQ(clientInfo8.start_icd_counter, old_start_icd_counter); + + checkInHandler.Shutdown(); +} diff --git a/src/app/tests/TestDefaultICDClientStorage.cpp b/src/app/tests/TestDefaultICDClientStorage.cpp index ac950fdbc7..0ea48d3326 100644 --- a/src/app/tests/TestDefaultICDClientStorage.cpp +++ b/src/app/tests/TestDefaultICDClientStorage.cpp @@ -103,6 +103,12 @@ TEST_F(TestDefaultICDClientStorage, TestClientInfoCount) iterator->Release(); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDFabricList().KeyName())); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist( + DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricId).KeyName())); + EXPECT_TRUE( + manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricId).KeyName())); + // Delete all and verify iterator counts 0 EXPECT_EQ(manager.DeleteAllEntries(fabricId), CHIP_NO_ERROR); iterator = manager.IterateICDClientInfo(); @@ -116,6 +122,14 @@ TEST_F(TestDefaultICDClientStorage, TestClientInfoCount) } iterator->Release(); EXPECT_EQ(count, 0u); + EXPECT_EQ(manager.GetFabricListSize(), 0u); + EXPECT_FALSE(manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDFabricList().KeyName())); + EXPECT_FALSE(manager.GetClientInfoStore()->SyncDoesKeyExist( + DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricId).KeyName())); + EXPECT_FALSE( + manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricId).KeyName())); + + EXPECT_EQ(manager.DeleteAllEntries(fabricId), CHIP_NO_ERROR); } { @@ -174,6 +188,15 @@ TEST_F(TestDefaultICDClientStorage, TestClientInfoCountMultipleFabric) EXPECT_EQ(manager.DeleteEntry(ScopedNodeId(nodeId3, fabricId2)), CHIP_NO_ERROR); EXPECT_EQ(iterator->Count(), 0u); + EXPECT_EQ(manager.GetFabricListSize(), 2u); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDFabricList().KeyName())); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist( + DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricId1).KeyName())); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricId1).KeyName())); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist( + DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricId2).KeyName())); + EXPECT_TRUE(manager.GetClientInfoStore()->SyncDoesKeyExist(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricId2).KeyName())); + // Verify ClientInfos manually count correctly size_t count = 0; ICDClientInfo clientInfo; @@ -183,6 +206,59 @@ TEST_F(TestDefaultICDClientStorage, TestClientInfoCountMultipleFabric) } EXPECT_FALSE(count); + + EXPECT_EQ(manager.DeleteEntry(ScopedNodeId(nodeId3, fabricId2)), CHIP_NO_ERROR); +} + +TEST_F(TestDefaultICDClientStorage, TestClientInfoCountMultipleFabricWithRemovingFabric) +{ + + FabricIndex fabricId1 = 1; + FabricIndex fabricId2 = 2; + NodeId nodeId1 = 6666; + NodeId nodeId2 = 6667; + NodeId nodeId3 = 6668; + DefaultICDClientStorage manager; + TestPersistentStorageDelegate clientInfoStorage; + TestSessionKeystoreImpl keystore; + EXPECT_EQ(manager.Init(&clientInfoStorage, &keystore), CHIP_NO_ERROR); + EXPECT_EQ(manager.UpdateFabricList(fabricId1), CHIP_NO_ERROR); + EXPECT_EQ(manager.UpdateFabricList(fabricId2), CHIP_NO_ERROR); + + // Write some ClientInfos and see the counts are correct + ICDClientInfo clientInfo1; + clientInfo1.peer_node = ScopedNodeId(nodeId1, fabricId1); + ICDClientInfo clientInfo2; + clientInfo2.peer_node = ScopedNodeId(nodeId2, fabricId1); + ICDClientInfo clientInfo3; + clientInfo3.peer_node = ScopedNodeId(nodeId3, fabricId2); + + EXPECT_EQ(manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfo1), CHIP_NO_ERROR); + + EXPECT_EQ(manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfo2), CHIP_NO_ERROR); + + EXPECT_EQ(manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfo3), CHIP_NO_ERROR); + // Make sure iterator counts correctly + auto * iterator = manager.IterateICDClientInfo(); + EXPECT_EQ(iterator->Count(), 3u); + iterator->Release(); + + EXPECT_EQ(manager.DeleteAllEntries(fabricId1), CHIP_NO_ERROR); + + iterator = manager.IterateICDClientInfo(); + ASSERT_NE(iterator, nullptr); + DefaultICDClientStorage::ICDClientInfoIteratorWrapper clientInfoIteratorWrapper(iterator); + EXPECT_EQ(iterator->Count(), 1u); + + EXPECT_EQ(manager.DeleteAllEntries(fabricId2), CHIP_NO_ERROR); + EXPECT_EQ(iterator->Count(), 0u); + + EXPECT_EQ(manager.StoreEntry(clientInfo1), CHIP_ERROR_INVALID_FABRIC_INDEX); + EXPECT_EQ(manager.StoreEntry(clientInfo2), CHIP_ERROR_INVALID_FABRIC_INDEX); + EXPECT_EQ(manager.StoreEntry(clientInfo3), CHIP_ERROR_INVALID_FABRIC_INDEX); } TEST_F(TestDefaultICDClientStorage, TestProcessCheckInPayload) @@ -214,9 +290,103 @@ TEST_F(TestDefaultICDClientStorage, TestProcessCheckInPayload) uint32_t checkInCounter = 0; ByteSpan payload{ buffer->Start(), buffer->DataLength() }; EXPECT_EQ(manager.ProcessCheckInPayload(payload, decodeClientInfo, checkInCounter), CHIP_NO_ERROR); + EXPECT_EQ(checkInCounter, counter); + + // Validate second check-in message with increased counter + counter++; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output), + CHIP_NO_ERROR); + buffer->SetDataLength(static_cast(output.size())); + ByteSpan payload1{ buffer->Start(), buffer->DataLength() }; + EXPECT_EQ(manager.ProcessCheckInPayload(payload1, decodeClientInfo, checkInCounter), CHIP_NO_ERROR); + EXPECT_EQ(checkInCounter, counter); - // 2. Use a key not available in the storage for encoding + // Use a key not available in the storage for encoding EXPECT_EQ(manager.SetKey(clientInfo, ByteSpan(kKeyBuffer2)), CHIP_NO_ERROR); + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output), + CHIP_NO_ERROR); + + buffer->SetDataLength(static_cast(output.size())); + ByteSpan payload2{ buffer->Start(), buffer->DataLength() }; + EXPECT_EQ(manager.ProcessCheckInPayload(payload2, decodeClientInfo, checkInCounter), CHIP_ERROR_NOT_FOUND); +} + +TEST_F(TestDefaultICDClientStorage, TestProcessCheckInPayloadWithRemovedKey) +{ + FabricIndex fabricId = 1; + NodeId nodeId = 6666; + TestPersistentStorageDelegate clientInfoStorage; + TestSessionKeystoreImpl keystore; + + DefaultICDClientStorage manager; + EXPECT_EQ(manager.Init(&clientInfoStorage, &keystore), CHIP_NO_ERROR); + EXPECT_EQ(manager.UpdateFabricList(fabricId), CHIP_NO_ERROR); + // Populate clientInfo + ICDClientInfo clientInfo; + clientInfo.peer_node = ScopedNodeId(nodeId, fabricId); + + EXPECT_EQ(manager.SetKey(clientInfo, ByteSpan(kKeyBuffer1)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfo), CHIP_NO_ERROR); + + uint32_t counter = 1; + System::PacketBufferHandle buffer = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output{ buffer->Start(), buffer->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output), + CHIP_NO_ERROR); + + buffer->SetDataLength(static_cast(output.size())); + ICDClientInfo decodeClientInfo; + uint32_t checkInCounter = 0; + ByteSpan payload{ buffer->Start(), buffer->DataLength() }; + EXPECT_EQ(manager.ProcessCheckInPayload(payload, decodeClientInfo, checkInCounter), CHIP_NO_ERROR); + EXPECT_EQ(checkInCounter, counter); + + // Use a removed key in the storage for encoding + manager.RemoveKey(clientInfo), CHIP_NO_ERROR; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output), + CHIP_NO_ERROR); + + buffer->SetDataLength(static_cast(output.size())); + ByteSpan payload1{ buffer->Start(), buffer->DataLength() }; + EXPECT_EQ(manager.ProcessCheckInPayload(payload1, decodeClientInfo, checkInCounter), CHIP_ERROR_NOT_FOUND); +} + +TEST_F(TestDefaultICDClientStorage, TestProcessCheckInPayloadWithEmptyIcdStorage) +{ + FabricIndex fabricId = 1; + NodeId nodeId = 6666; + TestPersistentStorageDelegate clientInfoStorage; + TestSessionKeystoreImpl keystore; + + DefaultICDClientStorage manager; + EXPECT_EQ(manager.Init(&clientInfoStorage, &keystore), CHIP_NO_ERROR); + EXPECT_EQ(manager.UpdateFabricList(fabricId), CHIP_NO_ERROR); + // Populate clientInfo + ICDClientInfo clientInfo; + clientInfo.peer_node = ScopedNodeId(nodeId, fabricId); + + EXPECT_EQ(manager.SetKey(clientInfo, ByteSpan(kKeyBuffer1)), CHIP_NO_ERROR); + EXPECT_EQ(manager.StoreEntry(clientInfo), CHIP_NO_ERROR); + + uint32_t counter = 1; + System::PacketBufferHandle buffer = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); + MutableByteSpan output{ buffer->Start(), buffer->MaxDataLength() }; + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( + clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output), + CHIP_NO_ERROR); + + buffer->SetDataLength(static_cast(output.size())); + ICDClientInfo decodeClientInfo; + uint32_t checkInCounter = 0; + ByteSpan payload{ buffer->Start(), buffer->DataLength() }; + EXPECT_EQ(manager.ProcessCheckInPayload(payload, decodeClientInfo, checkInCounter), CHIP_NO_ERROR); + EXPECT_EQ(checkInCounter, counter); + manager.DeleteAllEntries(fabricId); + EXPECT_EQ(chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output), CHIP_NO_ERROR); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index f634f8a26f..ba0342629a 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -508,28 +508,50 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyICDRegistrationInfo(chip::Contro VerifyOrReturnError(icdRegistrationInfo != nullptr, CHIP_ERROR_INVALID_ARGUMENT); JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Controller, "Failed to retrieve JNIEnv in %s.", __func__); + return CHIP_ERROR_INCORRECT_STATE; + } + + jmethodID getICDStayActiveDurationMsecMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getICDStayActiveDurationMsec", + "()Ljava/lang/Long;", &getICDStayActiveDurationMsecMethod); + ReturnErrorOnFailure(err); + jobject jStayActiveMsec = env->CallObjectMethod(icdRegistrationInfo, getICDStayActiveDurationMsecMethod); + if (jStayActiveMsec != nullptr) + { + jlong stayActiveMsec = chip::JniReferences::GetInstance().LongToPrimitive(jStayActiveMsec); + if (!chip::CanCastTo(stayActiveMsec)) + { + ChipLogError(Controller, "Failed to process stayActiveMsec in %s since this is not a valid 32-bit integer.", __func__); + return CHIP_ERROR_INVALID_ARGUMENT; + } + params.SetICDStayActiveDurationMsec(static_cast(stayActiveMsec)); + } + jmethodID getCheckInNodeIdMethod; err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getCheckInNodeId", "()Ljava/lang/Long;", &getCheckInNodeIdMethod); - VerifyOrReturnError(err == CHIP_NO_ERROR, err); + ReturnErrorOnFailure(err); jobject jCheckInNodeId = env->CallObjectMethod(icdRegistrationInfo, getCheckInNodeIdMethod); jmethodID getMonitoredSubjectMethod; err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getMonitoredSubject", "()Ljava/lang/Long;", &getMonitoredSubjectMethod); - VerifyOrReturnError(err == CHIP_NO_ERROR, err); + ReturnErrorOnFailure(err); jobject jMonitoredSubject = env->CallObjectMethod(icdRegistrationInfo, getMonitoredSubjectMethod); jmethodID getSymmetricKeyMethod; err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getSymmetricKey", "()[B", &getSymmetricKeyMethod); - VerifyOrReturnError(err == CHIP_NO_ERROR, err); + ReturnErrorOnFailure(err); jbyteArray jSymmetricKey = static_cast(env->CallObjectMethod(icdRegistrationInfo, getSymmetricKeyMethod)); jmethodID getClientTypeMethod; err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getClientType", "()Ljava/lang/Integer;", &getClientTypeMethod); - VerifyOrReturnError(err == CHIP_NO_ERROR, err); + ReturnErrorOnFailure(err); jobject jClientType = env->CallObjectMethod(icdRegistrationInfo, getClientTypeMethod); chip::NodeId checkInNodeId = chip::kUndefinedNodeId; diff --git a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java index 417d147238..b8fcde3a36 100644 --- a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java +++ b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java @@ -25,12 +25,19 @@ public class ICDRegistrationInfo { @Nullable private final Long monitoredSubject; @Nullable private final byte[] symmetricKey; @Nullable private final Integer clientType; + @Nullable private final Long stayActiveDurationMsec; private ICDRegistrationInfo(Builder builder) { this.checkInNodeId = builder.checkInNodeId; this.monitoredSubject = builder.monitoredSubject; this.symmetricKey = builder.symmetricKey; this.clientType = builder.clientType; + this.stayActiveDurationMsec = builder.stayActiveDurationMsec; + } + + /** Returns the duration period to stay active. */ + public Long getICDStayActiveDurationMsec() { + return stayActiveDurationMsec; } /** Returns the check in node ID. */ @@ -62,6 +69,7 @@ public static class Builder { @Nullable private Long monitoredSubject = null; @Nullable private byte[] symmetricKey = null; @Nullable private Integer clientType = null; + @Nullable private Long stayActiveDurationMsec = null; private Builder() {} @@ -93,6 +101,15 @@ public Builder setClientType(Integer clientType) { return this; } + /** + * Request LIT device to stay active for specific duration after commission completes, the upper + * bound is 30 seconds. + */ + public Builder setICDStayActiveDurationMsec(Long stayActiveDurationMsec) { + this.stayActiveDurationMsec = stayActiveDurationMsec; + return this; + } + public ICDRegistrationInfo build() { return new ICDRegistrationInfo(this); } diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 470c812505..146077372f 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -415,6 +415,17 @@ template("efr32_sdk") { _include_dirs += [ "${chip_root}/third_party/silabs/mqtt/stack" ] } + if (sl_enable_si70xx_sensor) { + _include_dirs += [ + "${efr32_sdk_root}/platform/driver/i2cspm/inc", + "${efr32_sdk_root}/app/bluetooth/common/sensor_rht", + "${efr32_sdk_root}/app/bluetooth/common/sensor_rht/config", + "${efr32_sdk_root}/hardware/driver/si70xx/inc", + "${efr32_sdk_root}/app/bluetooth/common/sensor_select", + "${efr32_sdk_root}/platform/common/config", + ] + } + # Note that we're setting the mbedTLS and PSA configuration files through a # define. This means the build system by default does not pick up changes in # the content of these, only when changing the filename itself. @@ -672,6 +683,12 @@ template("efr32_sdk") { defines += [ "CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED=1" ] } + if (sl_enable_si70xx_sensor) { + defines += [ "SL_MATTER_USE_SI70XX_SENSOR=1" ] + } else { + defines += [ "SL_MATTER_USE_SI70XX_SENSOR=0" ] + } + cflags = [] foreach(include_dir, _include_dirs) { cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] @@ -1068,6 +1085,16 @@ template("efr32_sdk") { ] } + if (sl_enable_si70xx_sensor) { + sources += [ + "${efr32_sdk_root}/hardware/driver/si70xx/src/sl_si70xx.c", + "${efr32_sdk_root}/platform/common/src/sl_status.c", + "${efr32_sdk_root}/platform/driver/i2cspm/src/sl_i2cspm.c", + "${efr32_sdk_root}/platform/emlib/src/em_i2c.c", + "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_i2cspm_init.c", + ] + } + public_deps = [ ":efr32_mbedtls_config", "${segger_rtt_root}:segger_rtt", diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index c3e993cea4..841d43db7e 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit c3e993cea4aad32adc178fe487afb66822f0b42d +Subproject commit 841d43db7e86877636cd73b5244da4c34d38d544 diff --git a/third_party/silabs/silabs_board.gni b/third_party/silabs/silabs_board.gni index 213417976d..03b2ea7cb6 100644 --- a/third_party/silabs/silabs_board.gni +++ b/third_party/silabs/silabs_board.gni @@ -53,6 +53,9 @@ declare_args() { # Self-provision enabled use_provision_channel = false + + # Temperature Sensor support + sl_enable_si70xx_sensor = false } declare_args() { @@ -75,6 +78,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { silabs_mcu = "SiWG917M111MGTBA" wifi_soc = true + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") + # EFR32 MG24 series ---------- } else if (silabs_board == "BRD4186A" || silabs_board == "BRD4187A") { variant = string_replace(silabs_board, "A", "C") @@ -104,6 +110,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { show_qr_code = false disable_lcd = true + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") + # EFR32 MG24 Modules series ---------- } else if (silabs_board == "BRD4316A") { silabs_family = "mgm24" @@ -128,6 +137,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { use_external_flash = false show_qr_code = false disable_lcd = true + + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") } else if (silabs_board == "BRD2704A") { silabs_family = "mgm24" silabs_mcu = "MGM240PB32VNA" @@ -137,6 +149,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { use_external_flash = false show_qr_code = false disable_lcd = true + + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") } else if (silabs_board == "BRD4318A") { silabs_family = "mgm24" silabs_mcu = "MGM240SD22VNA"