From 3820723564f6c7a502e9d275b7f7e6ae0c73e19a Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Thu, 23 Nov 2023 10:06:46 -0500 Subject: [PATCH] [NetworkCommissioning]Add Encoding of the new NetworkCommisisoning attributes (#30551) * Add Encoder for the new NetworkCommisisoning attributes, add virtual function in the two related wirelessDrivers, Implement them for thread, provide default implementation for wifi * Restyled by whitespace * Fix build error * regen .matter file for silabs lighting-app * Leave GetThreadVersion() unimplemented for Tizen,WebOs and Linux app * Modify GetSupportedThreadFeatures implementation for Tizen as it errors out on conversion types. Assumed that it is due to how the type of a define vs enum is seeing on their platform * Fix comment typo * Fix type cast error in SetField function seen on Tizen platform. Re-apply original implementation GetSupportedThreadFeatures on Tizen, matching the other platforms implementation. Check featuremap before dereferencing mpDriver->Get * Apply latest comments --------- Co-authored-by: Restyled.io --- .../data_model/lighting-thread-app.matter | 4 +++ .../silabs/data_model/lighting-thread-app.zap | 32 +++++++++++++++++++ .../efr32/project_include/OpenThreadConfig.h | 2 +- .../network-commissioning.cpp | 15 +++++++++ src/include/platform/CHIPDeviceConfig.h | 10 ++++++ src/include/platform/NetworkCommissioning.h | 19 +++++++++++ src/lib/support/BitMask.h | 2 +- src/platform/BUILD.gn | 1 + .../Linux/NetworkCommissioningDriver.h | 2 ++ .../NetworkCommissioningThreadDriver.cpp | 19 +++++++++++ ...enericNetworkCommissioningThreadDriver.cpp | 18 +++++++++++ .../GenericNetworkCommissioningThreadDriver.h | 2 ++ .../Tizen/NetworkCommissioningDriver.h | 2 ++ .../NetworkCommissioningThreadDriver.cpp | 19 +++++++++++ src/platform/device.gni | 5 +++ .../webos/NetworkCommissioningDriver.h | 2 ++ .../NetworkCommissioningThreadDriver.cpp | 19 +++++++++++ 17 files changed, 171 insertions(+), 2 deletions(-) diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index 82f93501448725..d49b6a2f6f8879 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -1249,6 +1249,8 @@ server cluster NetworkCommissioning = 49 { readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + readonly attribute int16u threadVersion = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2304,6 +2306,8 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute supportedThreadFeatures; + callback attribute threadVersion; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.zap b/examples/lighting-app/silabs/data_model/lighting-thread-app.zap index 9089ef70539c9a..dc69ec278ff7ca 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.zap +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.zap @@ -1428,6 +1428,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h b/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h index e563f31d638b40..e906e48ab02684 100644 --- a/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h +++ b/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h @@ -86,7 +86,7 @@ #define OPENTHREAD_CONFIG_JOINER_ENABLE 0 #define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 0 #define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 0 -#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0 +#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER #define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 0 #define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 0 #define OPENTHREAD_CONFIG_TCP_ENABLE 0 diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index 471b6038b85b09..19ddd5025a7346 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -266,6 +266,21 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu case Attributes::FeatureMap::Id: return aEncoder.Encode(mFeatureFlags); + case Attributes::SupportedWiFiBands::Id: + VerifyOrReturnError(mFeatureFlags.Has(Feature::kWiFiNetworkInterface), CHIP_NO_ERROR); + VerifyOrReturnError(mpDriver.Valid(), CHIP_NO_ERROR); + return aEncoder.Encode(mpDriver.Get()->GetSupportedWiFiBands()); + + case Attributes::SupportedThreadFeatures::Id: + VerifyOrReturnError(mFeatureFlags.Has(Feature::kThreadNetworkInterface), CHIP_NO_ERROR); + VerifyOrReturnError(mpDriver.Valid(), CHIP_NO_ERROR); + return aEncoder.Encode(mpDriver.Get()->GetSupportedThreadFeatures()); + + case Attributes::ThreadVersion::Id: + VerifyOrReturnError(mFeatureFlags.Has(Feature::kThreadNetworkInterface), CHIP_NO_ERROR); + VerifyOrReturnError(mpDriver.Valid(), CHIP_NO_ERROR); + return aEncoder.Encode(mpDriver.Get()->GetThreadVersion()); + default: return CHIP_NO_ERROR; } diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index f6989ac2590942..bafca37458c8a3 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -874,6 +874,16 @@ #define CHIP_DEVICE_CONFIG_THREAD_SSED 0 #endif +/** + * CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER + * + * Enable Thread Border Router service. + * Users should ensure OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE is set accordingly within their thread stack + * + */ +#ifndef CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER +#define CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER 0 +#endif /** * CHIP_DEVICE_CONFIG_THREAD_TASK_NAME * diff --git a/src/include/platform/NetworkCommissioning.h b/src/include/platform/NetworkCommissioning.h index 90b0d515269147..c24648b3e582b8 100644 --- a/src/include/platform/NetworkCommissioning.h +++ b/src/include/platform/NetworkCommissioning.h @@ -131,6 +131,7 @@ using ThreadScanResponseIterator = Iterator; using Status = app::Clusters::NetworkCommissioning::NetworkCommissioningStatusEnum; using WiFiBand = app::Clusters::NetworkCommissioning::WiFiBandEnum; using WiFiSecurity = app::Clusters::NetworkCommissioning::WiFiSecurityBitmap; +using ThreadCapabilities = app::Clusters::NetworkCommissioning::ThreadCapabilitiesBitmap; // BaseDriver and WirelessDriver are the common interfaces for a network driver, platform drivers should not implement this // directly, instead, users are expected to implement WiFiDriver, ThreadDriver and EthernetDriver. @@ -350,6 +351,14 @@ class WiFiDriver : public Internal::WirelessDriver } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC + /** + * @brief Provide all the frequency bands supported by the Wi-Fi interface + * + * Provide a default implementation that returns the 2.4 Ghz band support. + * Note: WiFi platforms should implement this function in their WiFiDriver to provide their complete device capabilities + */ + virtual WiFiBand GetSupportedWiFiBands() { return WiFiBand::k2g4; } + ~WiFiDriver() override = default; }; @@ -389,6 +398,16 @@ class ThreadDriver : public Internal::WirelessDriver */ virtual void ScanNetworks(ScanCallback * callback) = 0; + /** + * @brief Provide all of the Thread features supported by the Thread interface + */ + virtual ThreadCapabilities GetSupportedThreadFeatures() = 0; + + /** + * @brief Return the Thread version supported by the Thread interface + */ + virtual uint16_t GetThreadVersion() = 0; + ~ThreadDriver() override = default; }; diff --git a/src/lib/support/BitMask.h b/src/lib/support/BitMask.h index 313f113ad80154..d614e681f4e945 100644 --- a/src/lib/support/BitMask.h +++ b/src/lib/support/BitMask.h @@ -87,7 +87,7 @@ class BitMask : public BitFlags IntegerType updated = static_cast(BitFlags::Raw() & ~bitMask); // Set the right bits - updated |= static_cast(bitMask & (value << shift)); + updated = static_cast(updated | (bitMask & (value << shift))); BitFlags::SetRaw(updated); diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 39d94748c117a6..e00c3618bd59da 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -111,6 +111,7 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "CHIP_DEVICE_CONFIG_ENABLE_WPA=${chip_device_config_enable_wpa}", "CHIP_ENABLE_OPENTHREAD=${chip_enable_openthread}", "CHIP_DEVICE_CONFIG_THREAD_FTD=${chip_device_config_thread_ftd}", + "CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER=${chip_openthread_border_router}", "CHIP_STACK_LOCK_TRACKING_ENABLED=${chip_stack_lock_tracking_log}", "CHIP_STACK_LOCK_TRACKING_ERROR_FATAL=${chip_stack_lock_tracking_fatal}", "CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING=${chip_enable_additional_data_advertising}", diff --git a/src/platform/Linux/NetworkCommissioningDriver.h b/src/platform/Linux/NetworkCommissioningDriver.h index d54470e70cb7fe..69169b697864d1 100644 --- a/src/platform/Linux/NetworkCommissioningDriver.h +++ b/src/platform/Linux/NetworkCommissioningDriver.h @@ -145,6 +145,8 @@ class LinuxThreadDriver final : public ThreadDriver // ThreadDriver Status AddOrUpdateNetwork(ByteSpan operationalDataset, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; void ScanNetworks(ThreadDriver::ScanCallback * callback) override; + ThreadCapabilities GetSupportedThreadFeatures() override; + uint16_t GetThreadVersion() override; private: ThreadNetworkIterator mThreadIterator = ThreadNetworkIterator(this); diff --git a/src/platform/Linux/NetworkCommissioningThreadDriver.cpp b/src/platform/Linux/NetworkCommissioningThreadDriver.cpp index ed82e2a08e636f..9bb6015809fc9a 100644 --- a/src/platform/Linux/NetworkCommissioningThreadDriver.cpp +++ b/src/platform/Linux/NetworkCommissioningThreadDriver.cpp @@ -197,6 +197,25 @@ bool LinuxThreadDriver::ThreadNetworkIterator::Next(Network & item) return true; } +ThreadCapabilities LinuxThreadDriver::GetSupportedThreadFeatures() +{ + BitMask capabilites = 0; + capabilites.SetField(ThreadCapabilities::kIsBorderRouterCapable, CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER); + capabilites.SetField(ThreadCapabilities::kIsRouterCapable, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSleepyEndDeviceCapable, !CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsFullThreadDevice, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSynchronizedSleepyEndDeviceCapable, + (!CHIP_DEVICE_CONFIG_THREAD_FTD && CHIP_DEVICE_CONFIG_THREAD_SSED)); + return capabilites; +} + +uint16_t LinuxThreadDriver::GetThreadVersion() +{ + // TODO https://github.com/project-chip/connectedhomeip/issues/30602 + // Needs to be implemented with DBUS io.openthread.BorderRouter Thread API + return 0; +} + #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD } // namespace NetworkCommissioning diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp index 90d4191b1f1428..0859c3f723d5d5 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp @@ -245,6 +245,24 @@ bool GenericThreadDriver::ThreadNetworkIterator::Next(Network & item) return true; } +ThreadCapabilities GenericThreadDriver::GetSupportedThreadFeatures() +{ + BitMask capabilites = 0; + capabilites.SetField(ThreadCapabilities::kIsBorderRouterCapable, + CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER /*OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE*/); + capabilites.SetField(ThreadCapabilities::kIsRouterCapable, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSleepyEndDeviceCapable, !CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsFullThreadDevice, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSynchronizedSleepyEndDeviceCapable, + (!CHIP_DEVICE_CONFIG_THREAD_FTD && CHIP_DEVICE_CONFIG_THREAD_SSED)); + return capabilites; +} + +uint16_t GenericThreadDriver::GetThreadVersion() +{ + return otThreadGetVersion(); +} + } // namespace NetworkCommissioning } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h index 4a87d07e2fb084..bbfec6a44ff879 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h @@ -96,6 +96,8 @@ class GenericThreadDriver final : public ThreadDriver uint8_t GetMaxNetworks() override { return 1; } uint8_t GetScanNetworkTimeoutSeconds() override { return scanNetworkTimeoutSeconds; } uint8_t GetConnectNetworkTimeoutSeconds() override { return connectNetworkTimeout; } + ThreadCapabilities GetSupportedThreadFeatures() override; + uint16_t GetThreadVersion() override; void SetScanNetworkTimeoutSeconds(uint8_t scanTimeoutSec) { scanNetworkTimeoutSeconds = scanTimeoutSec; } void SetConnectNetworkTimeoutSeconds(uint8_t connectTimeoutSec) { connectNetworkTimeout = connectTimeoutSec; } diff --git a/src/platform/Tizen/NetworkCommissioningDriver.h b/src/platform/Tizen/NetworkCommissioningDriver.h index cdd0ceecd2abd2..64db40b2d5ce23 100644 --- a/src/platform/Tizen/NetworkCommissioningDriver.h +++ b/src/platform/Tizen/NetworkCommissioningDriver.h @@ -147,6 +147,8 @@ class TizenThreadDriver final : public ThreadDriver // ThreadDriver Status AddOrUpdateNetwork(ByteSpan operationalDataset, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; void ScanNetworks(ThreadDriver::ScanCallback * callback) override; + ThreadCapabilities GetSupportedThreadFeatures() override; + uint16_t GetThreadVersion() override; private: ThreadNetworkIterator mThreadIterator = ThreadNetworkIterator(this); diff --git a/src/platform/Tizen/NetworkCommissioningThreadDriver.cpp b/src/platform/Tizen/NetworkCommissioningThreadDriver.cpp index 8d61c5c4bd3627..003564b4c90f0f 100644 --- a/src/platform/Tizen/NetworkCommissioningThreadDriver.cpp +++ b/src/platform/Tizen/NetworkCommissioningThreadDriver.cpp @@ -164,6 +164,25 @@ bool TizenThreadDriver::ThreadNetworkIterator::Next(Network & item) return false; } +ThreadCapabilities TizenThreadDriver::GetSupportedThreadFeatures() +{ + BitMask capabilites = 0; + capabilites.SetField(ThreadCapabilities::kIsBorderRouterCapable, + CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER /*OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE*/); + capabilites.SetField(ThreadCapabilities::kIsRouterCapable, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSleepyEndDeviceCapable, !CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsFullThreadDevice, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSynchronizedSleepyEndDeviceCapable, + (!CHIP_DEVICE_CONFIG_THREAD_FTD && CHIP_DEVICE_CONFIG_THREAD_SSED)); + return capabilites; +} + +uint16_t TizenThreadDriver::GetThreadVersion() +{ + // TODO Needs to be implemented with Tizen Thread stack api + return 0; +} + #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD } // namespace NetworkCommissioning diff --git a/src/platform/device.gni b/src/platform/device.gni index cf1dc07325a664..9afb252ca0b809 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -59,6 +59,11 @@ declare_args() { declare_args() { chip_openthread_ftd = chip_enable_openthread + # Set platform define CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER + # Users should ensure that it sets their thread stack define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE + # or that their setting matches. + chip_openthread_border_router = false + # Enable wifi support. chip_enable_wifi = chip_device_platform == "linux" || chip_device_platform == "esp32" || diff --git a/src/platform/webos/NetworkCommissioningDriver.h b/src/platform/webos/NetworkCommissioningDriver.h index b466353743d713..b862e32966e65d 100644 --- a/src/platform/webos/NetworkCommissioningDriver.h +++ b/src/platform/webos/NetworkCommissioningDriver.h @@ -145,6 +145,8 @@ class LinuxThreadDriver final : public ThreadDriver // ThreadDriver Status AddOrUpdateNetwork(ByteSpan operationalDataset, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; void ScanNetworks(ThreadDriver::ScanCallback * callback) override; + ThreadCapabilities GetSupportedThreadFeatures() override; + uint16_t GetThreadVersion() override; private: ThreadNetworkIterator mThreadIterator = ThreadNetworkIterator(this); diff --git a/src/platform/webos/NetworkCommissioningThreadDriver.cpp b/src/platform/webos/NetworkCommissioningThreadDriver.cpp index fbc7e68ba68592..557d3f6f7f7cf7 100644 --- a/src/platform/webos/NetworkCommissioningThreadDriver.cpp +++ b/src/platform/webos/NetworkCommissioningThreadDriver.cpp @@ -197,6 +197,25 @@ bool LinuxThreadDriver::ThreadNetworkIterator::Next(Network & item) return true; } +ThreadCapabilities LinuxThreadDriver::GetSupportedThreadFeatures() +{ + BitMask capabilites = 0; + capabilites.SetField(ThreadCapabilities::kIsBorderRouterCapable, CHIP_DEVICE_CONFIG_THREAD_BORDER_ROUTER); + capabilites.SetField(ThreadCapabilities::kIsRouterCapable, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSleepyEndDeviceCapable, !CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsFullThreadDevice, CHIP_DEVICE_CONFIG_THREAD_FTD); + capabilites.SetField(ThreadCapabilities::kIsSynchronizedSleepyEndDeviceCapable, + (!CHIP_DEVICE_CONFIG_THREAD_FTD && CHIP_DEVICE_CONFIG_THREAD_SSED)); + return capabilites; +} + +uint16_t LinuxThreadDriver::GetThreadVersion() +{ + // TODO https://github.com/project-chip/connectedhomeip/issues/30602 + // Needs to be implemented with DBUS io.openthread.BorderRouter Thread API + return 0; +} + #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD } // namespace NetworkCommissioning