Skip to content

Commit 3906723

Browse files
mrjerryjohnspull[bot]
authored andcommitted
Strongly Typed Bitmaps (#15697)
1 parent 39404eb commit 3906723

File tree

27 files changed

+1243
-426
lines changed

27 files changed

+1243
-426
lines changed

examples/all-clusters-app/all-clusters-common/all-clusters-app.matter

+36-8
Original file line numberDiff line numberDiff line change
@@ -2816,6 +2816,34 @@ server cluster TestCluster = 1295 {
28162816
kValueC = 3;
28172817
}
28182818

2819+
bitmap Bitmap16MaskMap : BITMAP16 {
2820+
kMaskVal1 = 0x1;
2821+
kMaskVal2 = 0x2;
2822+
kMaskVal3 = 0x4;
2823+
kMaskVal4 = 0x4000;
2824+
}
2825+
2826+
bitmap Bitmap32MaskMap : BITMAP32 {
2827+
kMaskVal1 = 0x1;
2828+
kMaskVal2 = 0x2;
2829+
kMaskVal3 = 0x4;
2830+
kMaskVal4 = 0x40000000;
2831+
}
2832+
2833+
bitmap Bitmap64MaskMap : BITMAP64 {
2834+
kMaskVal1 = 0x1;
2835+
kMaskVal2 = 0x2;
2836+
kMaskVal3 = 0x4;
2837+
kMaskVal4 = 0x4000000000000000;
2838+
}
2839+
2840+
bitmap Bitmap8MaskMap : BITMAP8 {
2841+
kMaskVal1 = 0x1;
2842+
kMaskVal2 = 0x2;
2843+
kMaskVal3 = 0x4;
2844+
kMaskVal4 = 0x40;
2845+
}
2846+
28192847
bitmap SimpleBitmap : BITMAP8 {
28202848
kValueA = 0x1;
28212849
kValueB = 0x2;
@@ -2894,10 +2922,10 @@ server cluster TestCluster = 1295 {
28942922
}
28952923

28962924
attribute boolean boolean = 0;
2897-
attribute bitmap8 bitmap8 = 1;
2898-
attribute bitmap16 bitmap16 = 2;
2899-
attribute bitmap32 bitmap32 = 3;
2900-
attribute bitmap64 bitmap64 = 4;
2925+
attribute Bitmap8MaskMap bitmap8 = 1;
2926+
attribute Bitmap16MaskMap bitmap16 = 2;
2927+
attribute Bitmap32MaskMap bitmap32 = 3;
2928+
attribute Bitmap64MaskMap bitmap64 = 4;
29012929
attribute int8u int8u = 5;
29022930
attribute int16u int16u = 6;
29032931
attribute int24u int24u = 7;
@@ -2941,10 +2969,10 @@ server cluster TestCluster = 1295 {
29412969
attribute boolean generalErrorBoolean = 49;
29422970
attribute boolean clusterErrorBoolean = 50;
29432971
attribute nullable boolean nullableBoolean = 32768;
2944-
attribute nullable bitmap8 nullableBitmap8 = 32769;
2945-
attribute nullable bitmap16 nullableBitmap16 = 32770;
2946-
attribute nullable bitmap32 nullableBitmap32 = 32771;
2947-
attribute nullable bitmap64 nullableBitmap64 = 32772;
2972+
attribute nullable Bitmap8MaskMap nullableBitmap8 = 32769;
2973+
attribute nullable Bitmap16MaskMap nullableBitmap16 = 32770;
2974+
attribute nullable Bitmap32MaskMap nullableBitmap32 = 32771;
2975+
attribute nullable Bitmap64MaskMap nullableBitmap64 = 32772;
29482976
attribute nullable int8u nullableInt8u = 32773;
29492977
attribute nullable int16u nullableInt16u = 32774;
29502978
attribute nullable int24u nullableInt24u = 32775;

examples/chip-tool/templates/tests/partials/command_value.zapt

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
chip::ByteSpan(chip::Uint8::from_const_char("{{octetStringEscapedForCLiteral definedValue}}garbage: not in length on purpose"), {{definedValue.length}});
4949
{{else}}
5050
{{#if_is_bitmap type}}
51-
static_cast<{{zapTypeToEncodableClusterObjectType type ns=ns}}>({{definedValue}});
51+
static_cast<{{zapTypeToEncodableClusterObjectType type ns=ns}}>({{asTypedLiteral definedValue type}});
5252
{{else if (chip_tests_config_has definedValue)}}
5353
m{{asUpperCamelCase definedValue}}.HasValue() ? m{{asUpperCamelCase definedValue}}.Value() : {{asTypedLiteral (chip_tests_config_get_default_value definedValue) (chip_tests_config_get_type definedValue)}};
5454
{{else}}

examples/tv-casting-app/tv-casting-common/tv-casting-app.matter

+32-4
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,34 @@ server cluster TestCluster = 1295 {
24162416
kValueC = 3;
24172417
}
24182418

2419+
bitmap Bitmap16MaskMap : BITMAP16 {
2420+
kMaskVal1 = 0x1;
2421+
kMaskVal2 = 0x2;
2422+
kMaskVal3 = 0x4;
2423+
kMaskVal4 = 0x4000;
2424+
}
2425+
2426+
bitmap Bitmap32MaskMap : BITMAP32 {
2427+
kMaskVal1 = 0x1;
2428+
kMaskVal2 = 0x2;
2429+
kMaskVal3 = 0x4;
2430+
kMaskVal4 = 0x40000000;
2431+
}
2432+
2433+
bitmap Bitmap64MaskMap : BITMAP64 {
2434+
kMaskVal1 = 0x1;
2435+
kMaskVal2 = 0x2;
2436+
kMaskVal3 = 0x4;
2437+
kMaskVal4 = 0x4000000000000000;
2438+
}
2439+
2440+
bitmap Bitmap8MaskMap : BITMAP8 {
2441+
kMaskVal1 = 0x1;
2442+
kMaskVal2 = 0x2;
2443+
kMaskVal3 = 0x4;
2444+
kMaskVal4 = 0x40;
2445+
}
2446+
24192447
bitmap SimpleBitmap : BITMAP8 {
24202448
kValueA = 0x1;
24212449
kValueB = 0x2;
@@ -2441,10 +2469,10 @@ server cluster TestCluster = 1295 {
24412469
}
24422470

24432471
attribute boolean boolean = 0;
2444-
attribute bitmap8 bitmap8 = 1;
2445-
attribute bitmap16 bitmap16 = 2;
2446-
attribute bitmap32 bitmap32 = 3;
2447-
attribute bitmap64 bitmap64 = 4;
2472+
attribute Bitmap8MaskMap bitmap8 = 1;
2473+
attribute Bitmap16MaskMap bitmap16 = 2;
2474+
attribute Bitmap32MaskMap bitmap32 = 3;
2475+
attribute Bitmap64MaskMap bitmap64 = 4;
24482476
attribute int8u int8u = 5;
24492477
attribute int16u int16u = 6;
24502478
attribute int32u int32u = 8;

src/app/tests/suites/include/ConstraintsChecker.h

+12
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@ class ConstraintsChecker
257257
return true;
258258
}
259259

260+
template <typename T>
261+
bool CheckConstraintNotValue(const char * itemName, chip::BitFlags<T> current, chip::BitFlags<T> expected)
262+
{
263+
if (current == expected)
264+
{
265+
Exit(std::string(itemName) + " got unexpected value: " + std::to_string(current.Raw()));
266+
return false;
267+
}
268+
269+
return true;
270+
}
271+
260272
template <typename T, typename U>
261273
bool CheckConstraintNotValue(const char * itemName, const chip::app::DataModel::Nullable<T> & current, U expected)
262274
{

src/app/tests/suites/include/ValueChecker.h

+6
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ class ValueChecker
8383
return CheckValue(itemName, current.Raw(), expected);
8484
}
8585

86+
template <typename T>
87+
bool CheckValue(const char * itemName, chip::BitFlags<T> current, chip::BitFlags<T> expected)
88+
{
89+
return CheckValue(itemName, current.Raw(), expected.Raw());
90+
}
91+
8692
template <typename T>
8793
bool CheckValuePresent(const char * itemName, const chip::Optional<T> & value)
8894
{

src/app/util/attribute-storage-null-handling.h

+46
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <lib/support/TypeTraits.h>
2222

2323
#include <limits>
24+
#include <type_traits>
2425

2526
namespace chip {
2627
namespace app {
@@ -125,6 +126,51 @@ struct NumericAttributeTraits
125126
static uint8_t * ToAttributeStoreRepresentation(StorageType & value) { return reinterpret_cast<uint8_t *>(&value); }
126127
};
127128

129+
template <typename T>
130+
struct NumericAttributeTraits<BitFlags<T>>
131+
{
132+
using StorageType = T;
133+
using WorkingType = BitFlags<T>;
134+
135+
static constexpr void WorkingToStorage(WorkingType workingValue, StorageType & storageValue)
136+
{
137+
storageValue = static_cast<StorageType>(workingValue.Raw());
138+
}
139+
140+
static constexpr WorkingType StorageToWorking(StorageType storageValue) { return WorkingType(storageValue); }
141+
142+
static constexpr void SetNull(StorageType & value)
143+
{
144+
//
145+
// When setting to null, store a value that has all bits set. This aliases to the same behavior
146+
// we do for other integral types, ensuring consistency across all underlying integral types in the data store as well as
147+
// re-using logic for serialization/de-serialization of that data in the IM.
148+
//
149+
value = static_cast<StorageType>(std::numeric_limits<std::underlying_type_t<T>>::max());
150+
}
151+
152+
static constexpr bool IsNullValue(StorageType value)
153+
{
154+
//
155+
// While we store a nullable bitmap value by setting all its bits, we can be a bit more conservative when actually
156+
// testing for null since the spec only mandates that the MSB be reserved for nullable bitmaps.
157+
//
158+
constexpr auto msbSetValue = std::underlying_type_t<T>(1) << (std::numeric_limits<std::underlying_type_t<T>>::digits - 1);
159+
return !!(std::underlying_type_t<T>(value) & msbSetValue);
160+
}
161+
162+
static constexpr bool CanRepresentValue(bool isNullable, StorageType value)
163+
{
164+
//
165+
// We permit the full-range of the underlying StorageType if !isNullable,
166+
// and the restricted range otherwise.
167+
//
168+
return !isNullable || !IsNullValue(value);
169+
}
170+
171+
static uint8_t * ToAttributeStoreRepresentation(StorageType & value) { return reinterpret_cast<uint8_t *>(&value); }
172+
};
173+
128174
template <>
129175
struct NumericAttributeTraits<bool>
130176
{

src/app/zap-templates/zcl/data-model/chip/test-cluster.xml

+40-8
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,38 @@ limitations under the License.
105105
array="true" optional="true"/>
106106
</struct>
107107

108+
<bitmap name="Bitmap8MaskMap" type="BITMAP8">
109+
<cluster code="0x050F" />
110+
<field mask="0x01" name="MaskVal1" />
111+
<field mask="0x02" name="MaskVal2" />
112+
<field mask="0x04" name="MaskVal3" />
113+
<field mask="0x40" name="MaskVal4" />
114+
</bitmap>
115+
116+
<bitmap name="Bitmap16MaskMap" type="BITMAP16">
117+
<cluster code="0x050F" />
118+
<field mask="0x01" name="MaskVal1" />
119+
<field mask="0x02" name="MaskVal2" />
120+
<field mask="0x04" name="MaskVal3" />
121+
<field mask="0x4000" name="MaskVal4" />
122+
</bitmap>
123+
124+
<bitmap name="Bitmap32MaskMap" type="BITMAP32">
125+
<cluster code="0x050F" />
126+
<field mask="0x01" name="MaskVal1" />
127+
<field mask="0x02" name="MaskVal2" />
128+
<field mask="0x04" name="MaskVal3" />
129+
<field mask="0x40000000" name="MaskVal4" />
130+
</bitmap>
131+
132+
<bitmap name="Bitmap64MaskMap" type="BITMAP64">
133+
<cluster code="0x050F" />
134+
<field mask="0x01" name="MaskVal1" />
135+
<field mask="0x02" name="MaskVal2" />
136+
<field mask="0x04" name="MaskVal3" />
137+
<field mask="0x4000000000000000" name="MaskVal4" />
138+
</bitmap>
139+
108140
<cluster>
109141
<domain>CHIP</domain>
110142
<name>Test Cluster</name>
@@ -113,10 +145,10 @@ limitations under the License.
113145
<description>The Test Cluster is meant to validate the generated code</description>
114146
<!-- Base data types -->
115147
<attribute side="server" code="0x0000" define="BOOLEAN" type="BOOLEAN" writable="true" default="false" optional="false">boolean</attribute>
116-
<attribute side="server" code="0x0001" define="BITMAP8" type="BITMAP8" writable="true" default="0" optional="false">bitmap8</attribute>
117-
<attribute side="server" code="0x0002" define="BITMAP16" type="BITMAP16" writable="true" default="0" optional="false">bitmap16</attribute>
118-
<attribute side="server" code="0x0003" define="BITMAP32" type="BITMAP32" writable="true" default="0" optional="false">bitmap32</attribute>
119-
<attribute side="server" code="0x0004" define="BITMAP64" type="BITMAP64" writable="true" default="0" optional="false">bitmap64</attribute>
148+
<attribute side="server" code="0x0001" define="BITMAP8" type="Bitmap8MaskMap" writable="true" default="0" optional="false">bitmap8</attribute>
149+
<attribute side="server" code="0x0002" define="BITMAP16" type="Bitmap16MaskMap" writable="true" default="0" optional="false">bitmap16</attribute>
150+
<attribute side="server" code="0x0003" define="BITMAP32" type="Bitmap32MaskMap" writable="true" default="0" optional="false">bitmap32</attribute>
151+
<attribute side="server" code="0x0004" define="BITMAP64" type="Bitmap64MaskMap" writable="true" default="0" optional="false">bitmap64</attribute>
120152
<attribute side="server" code="0x0005" define="INT8U" type="INT8U" writable="true" default="0" optional="false">int8u</attribute>
121153
<attribute side="server" code="0x0006" define="INT16U" type="INT16U" writable="true" default="0" optional="false">int16u</attribute>
122154
<attribute side="server" code="0x0007" define="INT24U" type="INT24U" writable="true" default="0" optional="false">int24u</attribute>
@@ -168,10 +200,10 @@ limitations under the License.
168200
type="BOOLEAN" writable="true" optional="false">cluster_error_boolean</attribute>
169201

170202
<attribute side="server" code="0x8000" define="NULLABLE_BOOLEAN" type="BOOLEAN" writable="true" default="false" isNullable="true" optional="false">nullable_boolean</attribute>
171-
<attribute side="server" code="0x8001" define="NULLABLE_BITMAP8" type="BITMAP8" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap8</attribute>
172-
<attribute side="server" code="0x8002" define="NULLABLE_BITMAP16" type="BITMAP16" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap16</attribute>
173-
<attribute side="server" code="0x8003" define="NULLABLE_BITMAP32" type="BITMAP32" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap32</attribute>
174-
<attribute side="server" code="0x8004" define="NULLABLE_BITMAP64" type="BITMAP64" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap64</attribute>
203+
<attribute side="server" code="0x8001" define="NULLABLE_BITMAP8" type="Bitmap8MaskMap" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap8</attribute>
204+
<attribute side="server" code="0x8002" define="NULLABLE_BITMAP16" type="Bitmap16MaskMap" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap16</attribute>
205+
<attribute side="server" code="0x8003" define="NULLABLE_BITMAP32" type="Bitmap32MaskMap" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap32</attribute>
206+
<attribute side="server" code="0x8004" define="NULLABLE_BITMAP64" type="Bitmap64MaskMap" writable="true" default="0" isNullable="true" optional="false">nullable_bitmap64</attribute>
175207
<attribute side="server" code="0x8005" define="NULLABLE_INT8U" type="INT8U" writable="true" default="0" isNullable="true" optional="false">nullable_int8u</attribute>
176208
<attribute side="server" code="0x8006" define="NULLABLE_INT16U" type="INT16U" writable="true" default="0" isNullable="true" optional="false">nullable_int16u</attribute>
177209
<attribute side="server" code="0x8007" define="NULLABLE_INT24U" type="INT24U" writable="true" default="0" isNullable="true" optional="false">nullable_int24u</attribute>

src/controller/data_model/controller-clusters.matter

+36-8
Original file line numberDiff line numberDiff line change
@@ -3279,6 +3279,34 @@ client cluster TestCluster = 1295 {
32793279
kValueC = 3;
32803280
}
32813281

3282+
bitmap Bitmap16MaskMap : BITMAP16 {
3283+
kMaskVal1 = 0x1;
3284+
kMaskVal2 = 0x2;
3285+
kMaskVal3 = 0x4;
3286+
kMaskVal4 = 0x4000;
3287+
}
3288+
3289+
bitmap Bitmap32MaskMap : BITMAP32 {
3290+
kMaskVal1 = 0x1;
3291+
kMaskVal2 = 0x2;
3292+
kMaskVal3 = 0x4;
3293+
kMaskVal4 = 0x40000000;
3294+
}
3295+
3296+
bitmap Bitmap64MaskMap : BITMAP64 {
3297+
kMaskVal1 = 0x1;
3298+
kMaskVal2 = 0x2;
3299+
kMaskVal3 = 0x4;
3300+
kMaskVal4 = 0x4000000000000000;
3301+
}
3302+
3303+
bitmap Bitmap8MaskMap : BITMAP8 {
3304+
kMaskVal1 = 0x1;
3305+
kMaskVal2 = 0x2;
3306+
kMaskVal3 = 0x4;
3307+
kMaskVal4 = 0x40;
3308+
}
3309+
32823310
bitmap SimpleBitmap : BITMAP8 {
32833311
kValueA = 0x1;
32843312
kValueB = 0x2;
@@ -3357,10 +3385,10 @@ client cluster TestCluster = 1295 {
33573385
}
33583386

33593387
attribute boolean boolean = 0;
3360-
attribute bitmap8 bitmap8 = 1;
3361-
attribute bitmap16 bitmap16 = 2;
3362-
attribute bitmap32 bitmap32 = 3;
3363-
attribute bitmap64 bitmap64 = 4;
3388+
attribute Bitmap8MaskMap bitmap8 = 1;
3389+
attribute Bitmap16MaskMap bitmap16 = 2;
3390+
attribute Bitmap32MaskMap bitmap32 = 3;
3391+
attribute Bitmap64MaskMap bitmap64 = 4;
33643392
attribute int8u int8u = 5;
33653393
attribute int16u int16u = 6;
33663394
attribute int24u int24u = 7;
@@ -3405,10 +3433,10 @@ client cluster TestCluster = 1295 {
34053433
attribute boolean clusterErrorBoolean = 50;
34063434
attribute boolean unsupported = 255;
34073435
attribute nullable boolean nullableBoolean = 32768;
3408-
attribute nullable bitmap8 nullableBitmap8 = 32769;
3409-
attribute nullable bitmap16 nullableBitmap16 = 32770;
3410-
attribute nullable bitmap32 nullableBitmap32 = 32771;
3411-
attribute nullable bitmap64 nullableBitmap64 = 32772;
3436+
attribute nullable Bitmap8MaskMap nullableBitmap8 = 32769;
3437+
attribute nullable Bitmap16MaskMap nullableBitmap16 = 32770;
3438+
attribute nullable Bitmap32MaskMap nullableBitmap32 = 32771;
3439+
attribute nullable Bitmap64MaskMap nullableBitmap64 = 32772;
34123440
attribute nullable int8u nullableInt8u = 32773;
34133441
attribute nullable int16u nullableInt16u = 32774;
34143442
attribute nullable int24u nullableInt24u = 32775;

0 commit comments

Comments
 (0)