diff --git a/src/app/common/BUILD.gn b/src/app/common/BUILD.gn index 648016563ac5d5..fee9795dc5982c 100644 --- a/src/app/common/BUILD.gn +++ b/src/app/common/BUILD.gn @@ -18,6 +18,8 @@ static_library("cluster-objects") { output_name = "libClusterObjects" sources = [ + "${chip_root}/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h", + "${chip_root}/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h", "${chip_root}/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp", "${chip_root}/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h", ] diff --git a/src/app/common/templates/templates.json b/src/app/common/templates/templates.json index b21737864ca180..2e1ba3043bc24b 100644 --- a/src/app/common/templates/templates.json +++ b/src/app/common/templates/templates.json @@ -120,13 +120,18 @@ }, { "path": "../../zap-templates/templates/app/cluster-objects-src.zapt", - "name": "Cluster objects header for Interaction Model", + "name": "Cluster objects source for Interaction Model", "output": "cluster-objects.cpp" }, { "path": "../../zap-templates/templates/app/cluster-enums.zapt", - "name": "Enum and bitmap definitions for clusters", + "name": "Enum and bitmap header for clusters", "output": "cluster-enums.h" + }, + { + "path": "../../zap-templates/templates/app/cluster-enums-check.zapt", + "name": "Enum and bitmap method check header for clusters", + "output": "cluster-enums-check.h" } ] } diff --git a/src/app/data-model/Decode.h b/src/app/data-model/Decode.h index 9becc5af42a551..6e31d22b4aafb4 100644 --- a/src/app/data-model/Decode.h +++ b/src/app/data-model/Decode.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include #include @@ -28,6 +29,13 @@ namespace chip { namespace app { +namespace Clusters { +static auto __attribute__((unused)) EnsureKnownEnumValue(chip::VendorId val) +{ + return val; +} +} // namespace Clusters + namespace DataModel { // @@ -48,7 +56,9 @@ CHIP_ERROR Decode(TLV::TLVReader & reader, X & x) template ::value, int> = 0> CHIP_ERROR Decode(TLV::TLVReader & reader, X & x) { - return reader.Get(x); + ReturnErrorOnFailure(reader.Get(x)); + x = Clusters::EnsureKnownEnumValue(x); + return CHIP_NO_ERROR; } template diff --git a/src/app/tests/TestDataModelSerialization.cpp b/src/app/tests/TestDataModelSerialization.cpp index 368b6e7d9d23a9..3c922f348b4514 100644 --- a/src/app/tests/TestDataModelSerialization.cpp +++ b/src/app/tests/TestDataModelSerialization.cpp @@ -42,6 +42,7 @@ class TestDataModelSerialization { public: static void TestDataModelSerialization_EncAndDecSimpleStruct(nlTestSuite * apSuite, void * apContext); + static void TestDataModelSerialization_EncAndDecSimpleStructNegativeEnum(nlTestSuite * apSuite, void * apContext); static void TestDataModelSerialization_EncAndDecNestedStruct(nlTestSuite * apSuite, void * apContext); static void TestDataModelSerialization_EncAndDecNestedStructList(nlTestSuite * apSuite, void * apContext); static void TestDataModelSerialization_EncAndDecDecodableNestedStructList(nlTestSuite * apSuite, void * apContext); @@ -221,6 +222,55 @@ void TestDataModelSerialization::TestDataModelSerialization_EncAndDecSimpleStruc } } +void TestDataModelSerialization::TestDataModelSerialization_EncAndDecSimpleStructNegativeEnum(nlTestSuite * apSuite, + void * apContext) +{ + CHIP_ERROR err; + auto * _this = static_cast(apContext); + + _this->mpSuite = apSuite; + _this->SetupBuf(); + + // + // Encode + // + { + TestCluster::Structs::SimpleStruct::Type t; + uint8_t buf[4] = { 0, 1, 2, 3 }; + char strbuf[10] = "chip"; + + t.a = 20; + t.b = true; + t.c = static_cast(10); + t.d = buf; + + t.e = Span{ strbuf, strlen(strbuf) }; + + t.f.Set(TestCluster::SimpleBitmap::kValueC); + + err = DataModel::Encode(_this->mWriter, TLV::AnonymousTag(), t); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + err = _this->mWriter.Finalize(); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + _this->DumpBuf(); + } + + // + // Decode + // + { + TestCluster::Structs::SimpleStruct::Type t; + + _this->SetupReader(); + + err = DataModel::Decode(_this->mReader, t); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, to_underlying(t.c) == 4); + } +} + void TestDataModelSerialization::TestDataModelSerialization_EncAndDecNestedStruct(nlTestSuite * apSuite, void * apContext) { CHIP_ERROR err; @@ -1057,6 +1107,7 @@ int Finalize(void * aContext) const nlTest sTests[] = { NL_TEST_DEF("TestDataModelSerialization_EncAndDecSimple", TestDataModelSerialization::TestDataModelSerialization_EncAndDecSimpleStruct), + NL_TEST_DEF("TestDataModelSerialization_EncAndDecSimpleStructNegativeEnum", TestDataModelSerialization::TestDataModelSerialization_EncAndDecSimpleStructNegativeEnum), NL_TEST_DEF("TestDataModelSerialization_EncAndDecNestedStruct", TestDataModelSerialization::TestDataModelSerialization_EncAndDecNestedStruct), NL_TEST_DEF("TestDataModelSerialization_EncAndDecDecodableNestedStructList", TestDataModelSerialization::TestDataModelSerialization_EncAndDecDecodableNestedStructList), NL_TEST_DEF("TestDataModelSerialization_EncAndDecDecodableDoubleNestedStructList", TestDataModelSerialization::TestDataModelSerialization_EncAndDecDecodableDoubleNestedStructList), diff --git a/src/app/tests/suites/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index 85b33b6525d9a0..e1ddaba5939780 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -1038,13 +1038,28 @@ tests: - name: "arg1" value: 20003 - name: "arg2" - value: 101 + value: 1 response: + values: + - name: "arg1" + value: 20003 + - name: "arg2" + value: 1 + + - label: "Send a command with a vendor_id and invalid enum" + command: "TestEnumsRequest" + arguments: values: - name: "arg1" value: 20003 - name: "arg2" value: 101 + response: + values: + - name: "arg1" + value: 20003 + - name: "arg2" + value: 4 # Tests for Struct @@ -2766,13 +2781,13 @@ tests: command: "writeAttribute" attribute: "nullable_enum_attr" arguments: - value: 254 + value: 3 - label: "Read attribute NULLABLE_SIMPLE_ENUM Max Value" command: "readAttribute" attribute: "nullable_enum_attr" response: - value: 254 + value: 3 - label: "Write attribute NULLABLE_SIMPLE_ENUM Invalid Value" command: "writeAttribute" @@ -2786,8 +2801,8 @@ tests: command: "readAttribute" attribute: "nullable_enum_attr" response: - saveAs: nullableEnumAttr254 - value: 254 + saveAs: nullableEnumAttr3 + value: 3 - label: "Write attribute NULLABLE_SIMPLE_ENUM null Value" command: "writeAttribute" @@ -2801,12 +2816,12 @@ tests: response: value: null - - label: "Read attribute NULLABLE_SIMPLE_ENUM not 254 Value" + - label: "Read attribute NULLABLE_SIMPLE_ENUM not 3 Value" command: "readAttribute" attribute: "nullable_enum_attr" response: constraints: - notValue: nullableEnumAttr254 + notValue: nullableEnumAttr3 # Tests for Octet String attribute diff --git a/src/app/tests/suites/TestEvents.yaml b/src/app/tests/suites/TestEvents.yaml index 5b40c8bf9a888c..7c6592f32070bb 100644 --- a/src/app/tests/suites/TestEvents.yaml +++ b/src/app/tests/suites/TestEvents.yaml @@ -112,7 +112,7 @@ tests: - name: "arg1" value: 4 - name: "arg2" - value: 5 + value: 3 - name: "arg3" value: true response: @@ -126,4 +126,4 @@ tests: response: values: - name: "TestEvent" - value: { arg1: 4, arg2: 5, arg3: true } + value: { arg1: 4, arg2: 3, arg3: true } diff --git a/src/app/zap-templates/templates/app/cluster-enums-check.zapt b/src/app/zap-templates/templates/app/cluster-enums-check.zapt new file mode 100644 index 00000000000000..883a19b5cf0aee --- /dev/null +++ b/src/app/zap-templates/templates/app/cluster-enums-check.zapt @@ -0,0 +1,41 @@ +{{> header}} + +#pragma once + +#include + +namespace chip { +namespace app { +namespace Clusters { +{{#zcl_clusters}} +{{#zcl_enums}} +static auto __attribute__((unused)) EnsureKnownEnumValue({{asUpperCamelCase ../name}}::{{asType label}} val) +{ + using EnumType = {{asUpperCamelCase ../name}}::{{asType label}}; + switch (val) { +{{#if (isWeaklyTypedEnum label)}} +// Need to convert consumers to using the new enum classes, so we +// don't just have casts all over. +#ifdef CHIP_USE_ENUM_CLASS_FOR_IM_ENUM +{{/if}} + {{#zcl_enum_items}} + case EnumType::k{{asUpperCamelCase label}}: + {{/zcl_enum_items}} +{{#if (isWeaklyTypedEnum label)}} +#else // CHIP_USE_ENUM_CLASS_FOR_IM_ENUM + {{#zcl_enum_items}} + case EMBER_ZCL_{{asDelimitedMacro parent.label}}_{{asDelimitedMacro label}}: + {{/zcl_enum_items}} +#endif // CHIP_USE_ENUM_CLASS_FOR_IM_ENUM +{{/if}} + return val; + default: + return static_cast({{first_unused_enum_value mode="first_unused"}}); + } +} +{{/zcl_enums}} + +{{/zcl_clusters}} +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/zap-templates/templates/app/cluster-enums.zapt b/src/app/zap-templates/templates/app/cluster-enums.zapt index b03ba4ec0d054f..2a6ac5a1f3ed35 100644 --- a/src/app/zap-templates/templates/app/cluster-enums.zapt +++ b/src/app/zap-templates/templates/app/cluster-enums.zapt @@ -24,11 +24,13 @@ enum class {{asType label}} : {{asUnderlyingZclType name}} { {{#zcl_enum_items}} k{{asUpperCamelCase label}} = {{asHex value 2}}, {{/zcl_enum_items}} +// kUnknownEnumValue = {{first_unused_enum_value mode="first_unused"}}, }; {{#if (isWeaklyTypedEnum label)}} #else // CHIP_USE_ENUM_CLASS_FOR_IM_ENUM using {{asType label}} = EmberAf{{asType label}}; -#endif +static {{asType label}} __attribute__((unused)) k{{asType label}}kUnknownEnumValue = static_cast<{{asType label}}>({{first_unused_enum_value mode="first_unused"}}); +#endif // CHIP_USE_ENUM_CLASS_FOR_IM_ENUM {{/if}} {{/zcl_enums}} {{#zcl_bitmaps}} diff --git a/src/platform/bouffalolab/BL602/args.gni b/src/platform/bouffalolab/BL602/args.gni index 8fe6c1a52b7de0..8cbed6f1ef1f19 100644 --- a/src/platform/bouffalolab/BL602/args.gni +++ b/src/platform/bouffalolab/BL602/args.gni @@ -37,7 +37,7 @@ chip_inet_config_enable_dns_resolver = false chip_inet_config_enable_tun_endpoint = false chip_inet_config_enable_tcp_endpoint = true chip_inet_config_enable_udp_endpoint = true - +chip_detail_logging = false pw_build_LINK_DEPS = [ "$dir_pw_assert:impl", "$dir_pw_log:impl",