diff --git a/scripts/py_matter_idl/matter_idl/test_zapxml.py b/scripts/py_matter_idl/matter_idl/test_zapxml.py
index 38ba9c85d1fd2a..6e6cd3d8761ca9 100755
--- a/scripts/py_matter_idl/matter_idl/test_zapxml.py
+++ b/scripts/py_matter_idl/matter_idl/test_zapxml.py
@@ -274,6 +274,40 @@ def testEnum(self):
Cluster(name='Test2', code=20, enums=[e3])],
))
+ def testFeatures(self):
+ idl = XmlToIdl('''
+
+
+ TestFeatures
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ''')
+ bitmap = Bitmap(
+ name='Feature',
+ base_type='bitmap32',
+ entries=[
+ ConstantEntry(name='OnOff', code=1),
+ ConstantEntry(name='TestFeature', code=2),
+ ConstantEntry(name='AnotherTest', code=4),
+ ])
+ self.assertEqual(idl,
+ Idl(clusters=[
+ Cluster(name='TestFeatures', code=20, bitmaps=[bitmap])
+ ])),
+
def testStruct(self):
idl = XmlToIdl('''
diff --git a/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py b/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py
index ae943bfc70a082..866ce71f914214 100644
--- a/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py
+++ b/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py
@@ -337,6 +337,33 @@ def EndProcessing(self):
self.context.AddIdlPostProcessor(self)
+class FeaturesHandler(BaseHandler):
+ """Handles .../features
+
+ Attaches a "Feature" bitmap to the given structure
+ """
+
+ def __init__(self, context: Context, cluster: Cluster):
+ super().__init__(context)
+ self._features = Bitmap(name='Feature', base_type="bitmap32", entries=[])
+ self._cluster = cluster
+
+ def GetNextProcessor(self, name, attrs):
+ if name.lower() == 'feature':
+ self._features.entries.append(ConstantEntry(
+ name=attrs['name'],
+ code=1 << ParseInt(attrs['bit']),
+ ))
+
+ # Sub-elements are conformance which is not representable in IDL
+ return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE)
+ return BaseHandler(self.context)
+
+ def EndProcessing(self):
+ if self._features.entries:
+ self._cluster.bitmaps.append(self._features)
+
+
class DescriptionHandler(BaseHandler):
"""Handles .../description text elements
@@ -511,6 +538,8 @@ def GetNextProcessor(self, name: str, attrs):
return CommandHandler(self.context, self._cluster, attrs)
elif name.lower() == 'description':
return DescriptionHandler(self.context, self._cluster)
+ elif name.lower() == 'features':
+ return FeaturesHandler(self.context, self._cluster)
elif name.lower() in ['define', 'domain', 'tag', 'client', 'server']:
# NOTE: we COULD use client and server to create separate definitions
# of each, but the usefulness of this is unclear as the definitions are