diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index 52990915d492dd..87edf85f5c06c9 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,8 @@ * limitations under the License. */ +#include + #include "network-commissioning.h" #include @@ -54,8 +56,7 @@ namespace { // For WiFi and Thread scan results, each item will cost ~60 bytes in TLV, thus 15 is a safe upper bound of scan results. constexpr size_t kMaxNetworksInScanResponse = 15; -// The maximum number of Wi-Fi bands a device can support. -constexpr size_t kMaxWiFiBands = 6; +constexpr uint16_t kCurrentClusterRevision = 2; #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC constexpr size_t kPossessionNonceSize = 32; @@ -269,22 +270,31 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu case Attributes::FeatureMap::Id: return aEncoder.Encode(mFeatureFlags); + case Attributes::ClusterRevision::Id: + return aEncoder.Encode(kCurrentClusterRevision); + case Attributes::SupportedWiFiBands::Id: - VerifyOrReturnError(mFeatureFlags.Has(Feature::kWiFiNetworkInterface), CHIP_NO_ERROR); - VerifyOrReturnError(mpDriver.Valid(), CHIP_NO_ERROR); +#if (!CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION && !CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP) + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); +#else + VerifyOrReturnError(mFeatureFlags.Has(Feature::kWiFiNetworkInterface), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); - return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { - WiFiBand bandsBuffer[kMaxWiFiBands]; - Span bands(bandsBuffer); - ReturnErrorOnFailure(mpDriver.Get()->GetSupportedWiFiBands(bands)); + return aEncoder.EncodeList([this](const auto & encoder) { + uint32_t bands = mpDriver.Get()->GetSupportedWiFiBandsMask(); - for (WiFiBand band : bands) + // Extract every band from the bitmap of supported bands, starting positionally on the right. + for (uint32_t band_bit_pos = 0; band_bit_pos < std::numeric_limits::digits; ++band_bit_pos) { - ReturnErrorOnFailure(encoder.Encode(band)); + uint32_t band_mask = static_cast(1UL << band_bit_pos); + if ((bands & band_mask) != 0) + { + ReturnErrorOnFailure(encoder.Encode(static_cast(band_bit_pos))); + } } - return CHIP_NO_ERROR; }); +#endif + break; case Attributes::SupportedThreadFeatures::Id: VerifyOrReturnError(mFeatureFlags.Has(Feature::kThreadNetworkInterface), CHIP_NO_ERROR); @@ -310,7 +320,7 @@ CHIP_ERROR Instance::Write(const ConcreteDataAttributePath & aPath, AttributeVal ReturnErrorOnFailure(aDecoder.Decode(value)); return mpBaseDriver->SetEnabled(value); default: - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + return CHIP_IM_GLOBAL_STATUS(InvalidAction); } } diff --git a/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml b/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml index 0422d108ac71ff..b28b4fbb548f2a 100644 --- a/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml @@ -37,7 +37,7 @@ tests: command: "readAttribute" attribute: "ClusterRevision" response: - value: 1 + value: 2 constraints: type: int16u diff --git a/src/include/platform/NetworkCommissioning.h b/src/include/platform/NetworkCommissioning.h index be33a98779ed58..6c2741d81201c5 100644 --- a/src/include/platform/NetworkCommissioning.h +++ b/src/include/platform/NetworkCommissioning.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include +#include namespace chip { namespace DeviceLayer { @@ -129,9 +131,13 @@ using NetworkIterator = Iterator; using WiFiScanResponseIterator = Iterator; 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; +using WiFiBandEnum = app::Clusters::NetworkCommissioning::WiFiBandEnum; +// For backwards compatibility with pre-rename enum values. +using WiFiBand = WiFiBandEnum; +using WiFiSecurityBitmap = app::Clusters::NetworkCommissioning::WiFiSecurityBitmap; +// For backwards compatibility with pre-rename bitmap values. +using WiFiSecurity = 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. @@ -352,24 +358,26 @@ class WiFiDriver : public Internal::WirelessDriver #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC /** - * @brief Provide all the frequency bands supported by the Wi-Fi interface + * @brief Provide all the frequency bands supported by the Wi-Fi interface. * * The default implementation returns the 2.4 GHz band support. - * Note: WiFi platforms should implement this function in their WiFiDriver to provide their complete device capabilities + * Note: WiFi platforms should implement this function in their WiFiDriver to provide their complete device capabilities. * - * @param bands Reference to a span that is used to return the supported bands. - * The span is initialized with a fixed-size buffer. - * The implementation is expected to resize the span to match the number of returned results. + * The returned bit mask has values of WiFiBandEnum packed into the bits. For example: * - * @return CHIP_NO_ERROR on success or a CHIP_ERROR on failure. + * - Bit 0 = (WiFiBandEnum::k2g4 == 0) --> (1 << 0) == (1 << WiFiBandEnum::k2g4) + * - Bit 2 = (WiFiBandEnum::k5g == 2) --> (1 << 2) == (1 << WiFiBandEnum::k5g) + * - If both 2.4G and 5G are supported --> ((1 << k2g4) || (1 << k5g)) == (1 || 4) == 5 + * + * On error, return 0 (no bands supported). This should never happen... Note that + * certification tests will REQUIRE at least one bit set in the set. + * + * @return a bitmask of supported Wi-Fi bands where each bit is associated with a WiFiBandEnum value. */ - virtual CHIP_ERROR GetSupportedWiFiBands(Span & bands) + virtual uint32_t GetSupportedWiFiBandsMask() const { - ReturnErrorCodeIf(bands.empty(), CHIP_ERROR_BUFFER_TOO_SMALL); - bands.front() = WiFiBand::k2g4; - bands.reduce_size(1); - - return CHIP_NO_ERROR; + // Default to 2.4G support (100% example platform coverage as of Matter 1.3) listed. + return static_cast(1UL << chip::to_underlying(WiFiBandEnum::k2g4)); } ~WiFiDriver() override = default; diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp index d8eb9b17d473b3..1efe5c863f8753 100644 --- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp +++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp @@ -17,10 +17,13 @@ #include "NrfWiFiDriver.h" +#include + #include #include #include +#include #include using namespace ::chip; @@ -276,20 +279,13 @@ void NrfWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callb } } -CHIP_ERROR NrfWiFiDriver::GetSupportedWiFiBands(Span & bands) +uint32_t NrfWiFiDriver::GetSupportedWiFiBandsMask() const { - static constexpr WiFiBand kBands[] = { - WiFiBand::k2g4, + uint32_t bands = static_cast(1UL << chip::to_underlying(WiFiBandEnum::k2g4)); #ifndef CONFIG_BOARD_NRF7001 - WiFiBand::k5g, + bands |= static_cast(1UL << chip::to_underlying(WiFiBandEnum::k5g)); #endif - }; - - VerifyOrReturnError(ArraySize(kBands) <= bands.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(bands.data(), kBands, sizeof(kBands)); - bands.reduce_size(ArraySize(kBands)); - - return CHIP_NO_ERROR; + return bands; } } // namespace NetworkCommissioning diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h index 1dd73a967d1f3e..7fe1ff1695351d 100644 --- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h +++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h @@ -86,7 +86,7 @@ class NrfWiFiDriver final : public WiFiDriver Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override; - CHIP_ERROR GetSupportedWiFiBands(Span & bands) override; + uint32_t GetSupportedWiFiBandsMask() const override; static NrfWiFiDriver & Instance() { diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index a69442a3e058a9..fcffb2ec55a525 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -46111,7 +46111,7 @@ class Test_TC_CNET_1_3 : public TestCommandBridge { { id actualValue = value; - VerifyOrReturn(CheckValue("ClusterRevision", actualValue, 1U)); + VerifyOrReturn(CheckValue("ClusterRevision", actualValue, 2U)); } VerifyOrReturn(CheckConstraintType("clusterRevision", "int16u", "int16u"));