Skip to content

Commit

Permalink
add enum check
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhanw-google committed Jul 13, 2022
1 parent aa2f050 commit 33e5e8e
Show file tree
Hide file tree
Showing 11 changed files with 4,631 additions and 2,167 deletions.
2 changes: 2 additions & 0 deletions src/app/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]
Expand Down
9 changes: 7 additions & 2 deletions src/app/common/templates/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}
12 changes: 11 additions & 1 deletion src/app/data-model/Decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#pragma once

#include <app-common/zap-generated/cluster-enums-check.h>
#include <app/ConcreteAttributePath.h>
#include <app/data-model/Nullable.h>
#include <lib/core/CHIPError.h>
Expand All @@ -28,6 +29,13 @@

namespace chip {
namespace app {
namespace Clusters {
static auto __attribute__((unused)) EnsureKnownEnumValue(chip::VendorId val)
{
return val;
}
} // namespace Clusters

namespace DataModel {

//
Expand All @@ -48,7 +56,9 @@ CHIP_ERROR Decode(TLV::TLVReader & reader, X & x)
template <typename X, typename std::enable_if_t<std::is_enum<X>::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 <typename X>
Expand Down
51 changes: 51 additions & 0 deletions src/app/tests/TestDataModelSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -221,6 +222,55 @@ void TestDataModelSerialization::TestDataModelSerialization_EncAndDecSimpleStruc
}
}

void TestDataModelSerialization::TestDataModelSerialization_EncAndDecSimpleStructNegativeEnum(nlTestSuite * apSuite,
void * apContext)
{
CHIP_ERROR err;
auto * _this = static_cast<TestDataModelSerialization *>(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<TestCluster::SimpleEnum>(10);
t.d = buf;

t.e = Span<char>{ 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;
Expand Down Expand Up @@ -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),
Expand Down
29 changes: 22 additions & 7 deletions src/app/tests/suites/TestCluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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

Expand Down
41 changes: 41 additions & 0 deletions src/app/zap-templates/templates/app/cluster-enums-check.zapt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{{> header}}

#pragma once

#include <app-common/zap-generated/cluster-enums.h>

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<EnumType>({{first_unused_enum_value mode="first_unused"}});
}
}
{{/zcl_enums}}

{{/zcl_clusters}}
} // namespace Clusters
} // namespace app
} // namespace chip
3 changes: 2 additions & 1 deletion src/app/zap-templates/templates/app/cluster-enums.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ k{{asUpperCamelCase label}} = {{asHex value 2}},
{{#if (isWeaklyTypedEnum label)}}
#else // CHIP_USE_ENUM_CLASS_FOR_IM_ENUM
using {{asType label}} = EmberAf{{asType label}};
#endif
#endif // CHIP_USE_ENUM_CLASS_FOR_IM_ENUM
{{/if}}
static {{asType label}} __attribute__((unused)) k{{asType label}}FirstUnusedEnumVal = static_cast<{{asType label}}>({{first_unused_enum_value mode="first_unused"}});
{{/zcl_enums}}
{{#zcl_bitmaps}}

Expand Down
Loading

0 comments on commit 33e5e8e

Please sign in to comment.