Skip to content

Commit 64b0220

Browse files
committed
optional attribute takes precedence on conformance for backward compability
1 parent ce89ea7 commit 64b0220

4 files changed

Lines changed: 47 additions & 45 deletions

File tree

docs/api.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20180,10 +20180,10 @@ When they appear, stop recursing and return the name inside directly
2018020180
<a name="module_Validation API_ Parse conformance data from XML..getOptionalAttributeFromXML"></a>
2018120181

2018220182
### Validation API: Parse conformance data from XML~getOptionalAttributeFromXML(element) ⇒
20183-
if conformance is defined, check if it is mandatory
20184-
if conformance is undefined, check the value of the optional attribute
20183+
if optional attribute is defined, return its value
20184+
if optional attribute is undefined, check if the element conformance is mandatory
2018520185
if both optional attribute and conformance are undefined, return false
20186-
Conformance should take precedence over the optional attribute
20186+
Optional attribute takes precedence over conformance for backward compatibility on certain elements
2018720187

2018820188
**Kind**: inner method of [<code>Validation API: Parse conformance data from XML</code>](#module_Validation API_ Parse conformance data from XML)
2018920189
**Returns**: true if the element is optional, false if the element is mandatory

src-electron/validation/conformance-xml-parser.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,25 +159,27 @@ function parseConformanceRecursively(operand, depth = 0, parentJoinChar = '') {
159159
}
160160

161161
/**
162-
* if conformance is defined, check if it is mandatory
163-
* if conformance is undefined, check the value of the optional attribute
162+
* if optional attribute is defined, return its value
163+
* if optional attribute is undefined, check if the element conformance is mandatory
164164
* if both optional attribute and conformance are undefined, return false
165-
* Conformance should take precedence over the optional attribute
165+
* Optional attribute takes precedence over conformance for backward compatibility on certain elements
166166
*
167167
* @param {*} element
168168
* @returns true if the element is optional, false if the element is mandatory
169169
*/
170170
function getOptionalAttributeFromXML(element) {
171-
let conformance = parseConformanceFromXML(element)
172-
if (conformance) {
173-
return !conformEvaluator.checkIfExpressionHasTerm(
174-
conformance,
175-
dbEnum.conformance.mandatory
176-
)
177-
} else if (element.$.optional) {
171+
if (element.$.optional) {
178172
return element.$.optional == 'true'
179173
} else {
180-
return false
174+
let conformance = parseConformanceFromXML(element)
175+
if (conformance) {
176+
return !conformEvaluator.checkIfExpressionHasTerm(
177+
conformance,
178+
dbEnum.conformance.mandatory
179+
)
180+
} else {
181+
return false
182+
}
181183
}
182184
}
183185

test/zcl-loader.test.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -659,69 +659,69 @@ test(
659659
expect(
660660
testQuery.checkIfElementIsOptional(attributes, 'LockType')
661661
).toBeFalsy()
662-
// mandatory conformance, optional="true" -> mandatory as conformance takes precedence
663-
expect(
664-
testQuery.checkIfElementIsOptional(attributes, 'LockState')
665-
).toBeFalsy()
666-
// mandatoryConform to feature DPS, optional="false" -> optional as conformance takes precedence
667-
expect(
668-
testQuery.checkIfElementIsOptional(attributes, 'DoorState')
669-
).toBeTruthy()
670-
// optionalConform to feature DPS, optional="true" -> optional
662+
// optionalConform to feature DPS, optional attribute undefined -> optional
671663
expect(
672664
testQuery.checkIfElementIsOptional(attributes, 'DoorOpenEvents')
673665
).toBeTruthy()
674-
// optional conformance, optional="false" -> optional as conformance takes precedence
666+
// optional conformance, optional attribute undefined -> optional
675667
expect(
676668
testQuery.checkIfElementIsOptional(attributes, 'Language')
677669
).toBeTruthy()
670+
// mandatory conformance, optional="true" -> optional as optional="true" takes precedence
671+
expect(
672+
testQuery.checkIfElementIsOptional(attributes, 'LockState')
673+
).toBeTruthy()
674+
// mandatoryConform to feature DPS, optional="false" -> mandatory as optional="false" takes precedence
675+
expect(
676+
testQuery.checkIfElementIsOptional(attributes, 'DoorState')
677+
).toBeFalsy()
678678

679679
let commands = await queryCommand.selectCommandsByClusterId(
680680
db,
681681
doorLockClusterId,
682682
[packageId]
683683
)
684-
// optional="true", conformance undefined -> optional
685-
expect(
686-
testQuery.checkIfElementIsOptional(commands, 'GetWeekDaySchedule')
687-
).toBeTruthy()
688684
// optional attribute undefined, conformance undefined -> mandatory
689685
expect(
690686
testQuery.checkIfElementIsOptional(commands, 'LockDoor')
691687
).toBeFalsy()
692-
// mandatory conformance, optional="true" -> mandatory as conformance takes precedence
688+
// optional="true", conformance undefined -> optional
693689
expect(
694-
testQuery.checkIfElementIsOptional(commands, 'UnlockDoor')
695-
).toBeFalsy()
690+
testQuery.checkIfElementIsOptional(commands, 'GetWeekDaySchedule')
691+
).toBeTruthy()
692+
// optional conformance, optional attribute undefined -> optional
693+
expect(
694+
testQuery.checkIfElementIsOptional(commands, 'UnlockWithTimeout')
695+
).toBeTruthy()
696696
// mandatoryConform to feature WDSCH, optional="true" -> optional
697697
expect(
698698
testQuery.checkIfElementIsOptional(commands, 'SetWeekDaySchedule')
699699
).toBeTruthy()
700-
// optional conformance, optional="false" -> optional as conformance takes precedence
700+
// mandatory conformance, optional="true" -> optional as optional="true" takes precedence
701701
expect(
702-
testQuery.checkIfElementIsOptional(commands, 'UnlockWithTimeout')
702+
testQuery.checkIfElementIsOptional(commands, 'UnlockDoor')
703703
).toBeTruthy()
704704

705705
let events = await queryEvent.selectEventsByClusterId(
706706
db,
707707
doorLockClusterId
708708
)
709-
// optional="true", conformance undefined -> optional
710-
expect(
711-
testQuery.checkIfElementIsOptional(events, 'LockOperation')
712-
).toBeTruthy()
713709
// optional attribute undefined, conformance undefined -> mandatory
714710
expect(
715711
testQuery.checkIfElementIsOptional(events, 'LockUserChange')
716712
).toBeFalsy()
717-
// mandatory conformance, optional="true" -> mandatory as conformance takes precedence
713+
// optional="true", conformance undefined -> optional
718714
expect(
719-
testQuery.checkIfElementIsOptional(events, 'DoorLockAlarm')
720-
).toBeFalsy()
721-
// mandatoryConform to feature DPS, optional="false" -> optional as conformance takes precedence
715+
testQuery.checkIfElementIsOptional(events, 'LockOperation')
716+
).toBeTruthy()
717+
// mandatoryConform to feature DPS, optional attribute undefined -> optional
722718
expect(
723719
testQuery.checkIfElementIsOptional(events, 'DoorStateChange')
724720
).toBeTruthy()
721+
// mandatory conformance, optional="true" -> optional as optional="true" takes precedence
722+
expect(
723+
testQuery.checkIfElementIsOptional(events, 'DoorLockAlarm')
724+
).toBeTruthy()
725725
} finally {
726726
await dbApi.closeDatabase(db)
727727
}

zcl-builtin/matter/data-model/chip/door-lock-cluster.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ limitations under the License.
8181
</mandatoryConform>
8282
</attribute>
8383
<!-- Conformance feature [DPS] - for now optional -->
84-
<attribute side="server" code="4" define="DOOR_OPEN_EVENTS" type="INT32U" writable="true" optional="true">
84+
<attribute side="server" code="4" define="DOOR_OPEN_EVENTS" type="INT32U" writable="true">
8585
<description>DoorOpenEvents</description>
8686
<access op="read" role="view" />
8787
<access op="write" role="manage" />
@@ -125,7 +125,7 @@ limitations under the License.
125125
<attribute side="server" code="27" define="CREDENTIAL_RULES_SUPPORT" type="DlCredentialRuleMask" min="0x00" max="0xFF" default="1" writable="false" optional="true">CredentialRulesSupport</attribute>
126126
<!-- Conformance feature USR - for now optional -->
127127
<attribute side="server" code="28" define="NUM_CREDENTIALS_SUPPORTED_PER_USER" type="INT8U" default="0" writable="false" optional="true">NumberOfCredentialsSupportedPerUser</attribute>
128-
<attribute side="server" code="33" define="LANGUAGE" type="CHAR_STRING" length="3" reportable="true" writable="true" optional="false">
128+
<attribute side="server" code="33" define="LANGUAGE" type="CHAR_STRING" length="3" reportable="true" writable="true">
129129
<description>Language</description>
130130
<access op="read" role="view" />
131131
<access op="write" role="manage" />
@@ -223,7 +223,7 @@ limitations under the License.
223223
<mandatoryConform/>
224224
</command>
225225
<!-- Command Toggle with ID 2 is deprecated/disallowed -->
226-
<command source="client" code="3" name="UnlockWithTimeout" mustUseTimedInvoke="true" optional="false">
226+
<command source="client" code="3" name="UnlockWithTimeout" mustUseTimedInvoke="true">
227227
<description>This command causes the lock device to unlock the door with a timeout parameter.</description>
228228
<arg name="Timeout" type="INT16U" />
229229
<!-- Conformance feature [COTA & PIN] - for now optional -->
@@ -419,7 +419,7 @@ limitations under the License.
419419
<mandatoryConform/>
420420
</event>
421421
<!-- Conformance feature DPS - for now optional -->
422-
<event side="server" code="1" name="DoorStateChange" priority="critical" optional="false">
422+
<event side="server" code="1" name="DoorStateChange" priority="critical">
423423
<description>The door lock server sends out a DoorStateChange event when the door lock door state changes.</description>
424424
<field id="0" name="DoorState" type="DoorStateEnum" />
425425
<mandatoryConform>

0 commit comments

Comments
 (0)