Skip to content

Commit ddb39c6

Browse files
committed
Apply fixes as per the code review feedback
1 parent 12b4b02 commit ddb39c6

2 files changed

Lines changed: 43 additions & 25 deletions

File tree

rs-matter/src/dm/clusters/app/color_control.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,16 @@ impl<'a, H: ColorControlHooks> ColorControlHandler<'a, H> {
152152
}
153153
}
154154

155-
/// Apply the `CurrentHueAndCurrentSaturation` mode. Hue is
156-
/// stored in `EnhancedCurrentHue` as the low byte.
155+
/// Apply the `CurrentHueAndCurrentSaturation` mode. `CurrentHue`
156+
/// is the high byte of `EnhancedCurrentHue`.
157157
fn apply_hue_saturation<N: AttrChangeNotifier>(
158158
&self,
159159
ctx: &N,
160160
hue_u8: u8,
161161
saturation: u8,
162162
scene_apply: bool,
163163
) {
164-
self.hooks.set_enhanced_current_hue(hue_u8 as u16);
164+
self.hooks.set_enhanced_current_hue((hue_u8 as u16) << 8);
165165
self.hooks.set_current_saturation(saturation);
166166
self.hooks
167167
.set_enhanced_color_mode(EnhancedColorModeEnum::CurrentHueAndCurrentSaturation);
@@ -417,9 +417,9 @@ impl<H: ColorControlHooks> ColorControlHandler<'_, H> {
417417
self.apply_color_temperature(ctx, mireds, true);
418418
}
419419
EnhancedColorModeEnum::CurrentHueAndCurrentSaturation => {
420-
// Non-enhanced hue is the low byte of EnhancedCurrentHue.
420+
// `CurrentHue` is the high byte of `EnhancedCurrentHue`.
421421
let (Some(hue), Some(sat)) = (
422-
enhanced_current_hue.map(|h| (h & 0xFF) as u8),
422+
enhanced_current_hue.map(|h| (h >> 8) as u8),
423423
current_saturation,
424424
) else {
425425
return Ok(());
@@ -851,9 +851,9 @@ mod tests {
851851

852852
#[test]
853853
fn apply_hue_saturation_mode_truncates_enhanced_hue_to_u8() {
854-
// Captured EnhancedCurrentHue is u16; non-enhanced apply
855-
// path takes the low byte. Mirrors chip's `ApplyScene`
856-
// behaviour and is documented on `apply_hue_saturation`.
854+
// `CurrentHue` (u8) is the high byte of `EnhancedCurrentHue`
855+
// (u16). Captured EnhancedHue=0x12FF → CurrentHue=0x12 →
856+
// round-trip stored as 0x1200.
857857
let h = handler(Feature::HUE_AND_SATURATION);
858858
let mut buf = [0u8; 128];
859859
let len = {
@@ -862,7 +862,6 @@ mod tests {
862862
let array =
863863
AttributeValuePairStructArrayBuilder::new(parent, &crate::tlv::TLVTag::Anonymous)
864864
.unwrap();
865-
// Hue = 0x12FF → low byte 0xFF after truncation.
866865
let array = array
867866
.push_u16(AttributeId::EnhancedCurrentHue as _, 0x12FF)
868867
.unwrap()
@@ -882,10 +881,7 @@ mod tests {
882881
let avp_list: TLVArray<'_, AttributeValuePairStruct<'_>> = TLVArray::new(elem).unwrap();
883882
h.apply_inner(NULL_CTX, &avp_list, 0).unwrap();
884883

885-
// The mutator writes the low byte into the enhanced field
886-
// (the cluster's only hue storage); the mode flips to
887-
// non-enhanced.
888-
assert_eq!(h.hooks.enhanced_current_hue(), 0xFF);
884+
assert_eq!(h.hooks.enhanced_current_hue(), 0x1200);
889885
assert_eq!(h.hooks.current_saturation(), 100);
890886
assert!(matches!(
891887
h.hooks.enhanced_color_mode(),

rs-matter/src/dm/clusters/scenes.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ const SC_CONSTRAINT_ERROR: u8 = 0x87;
6363
/// Reserved (invalid) `SceneID` value per Matter Core Spec.
6464
const RESERVED_SCENE_ID: SceneId = 0xFF;
6565

66+
/// `SceneID` 0 is reserved for the Global Scene; never valid in
67+
/// add/view/remove/store/recall/copy.
68+
const GLOBAL_SCENE_ID: SceneId = 0;
69+
6670
/// Maximum legal `AddScene.TransitionTime` in milliseconds
6771
/// (60 000 seconds / 1000 minutes per Matter Core Spec).
6872
const MAX_TRANSITION_TIME_MS: u32 = 60_000_000;
@@ -962,7 +966,10 @@ where
962966

963967
// Bad request shape (reserved scene id or oversized
964968
// transition) takes precedence over the group-table check.
965-
if scene_id == RESERVED_SCENE_ID || transition_time > MAX_TRANSITION_TIME_MS {
969+
if scene_id == GLOBAL_SCENE_ID
970+
|| scene_id == RESERVED_SCENE_ID
971+
|| transition_time > MAX_TRANSITION_TIME_MS
972+
{
966973
return response
967974
.status(SC_CONSTRAINT_ERROR)?
968975
.group_id(group_id)?
@@ -1012,6 +1019,16 @@ where
10121019
}
10131020
}
10141021

1022+
// An oversized EFS payload is a per-scene capacity failure,
1023+
// surfaced via `SC_INSUFFICIENT_SPACE` (not a transaction error).
1024+
if raw.len() > M {
1025+
return response
1026+
.status(SC_INSUFFICIENT_SPACE)?
1027+
.group_id(group_id)?
1028+
.scene_id(scene_id)?
1029+
.end();
1030+
}
1031+
10151032
let status_code = self.state.with(|inner| {
10161033
Self::upsert_scene(
10171034
inner,
@@ -1112,8 +1129,8 @@ where
11121129
let group_id = request.group_id()?;
11131130
let scene_id = request.scene_id()?;
11141131

1115-
// `SceneID = 0xFF` is reserved.
1116-
if scene_id == RESERVED_SCENE_ID {
1132+
// `SceneID = 0x00` (Global Scene) and `0xFF` are reserved.
1133+
if scene_id == GLOBAL_SCENE_ID || scene_id == RESERVED_SCENE_ID {
11171134
return response
11181135
.status(SC_CONSTRAINT_ERROR)?
11191136
.group_id(group_id)?
@@ -1198,8 +1215,8 @@ where
11981215
let group_id = request.group_id()?;
11991216
let scene_id = request.scene_id()?;
12001217

1201-
// `SceneID = 0xFF` is reserved.
1202-
if scene_id == RESERVED_SCENE_ID {
1218+
// `SceneID = 0x00` (Global Scene) and `0xFF` are reserved.
1219+
if scene_id == GLOBAL_SCENE_ID || scene_id == RESERVED_SCENE_ID {
12031220
return response
12041221
.status(SC_CONSTRAINT_ERROR)?
12051222
.group_id(group_id)?
@@ -1292,8 +1309,8 @@ where
12921309
let group_id = request.group_id()?;
12931310
let scene_id = request.scene_id()?;
12941311

1295-
// `SceneID = 0xFF` is reserved.
1296-
if scene_id == RESERVED_SCENE_ID {
1312+
// `SceneID = 0x00` (Global Scene) and `0xFF` are reserved.
1313+
if scene_id == GLOBAL_SCENE_ID || scene_id == RESERVED_SCENE_ID {
12971314
return response
12981315
.status(SC_CONSTRAINT_ERROR)?
12991316
.group_id(group_id)?
@@ -1397,8 +1414,8 @@ where
13971414
// `FAILURE` and chip-tool's certification suites reject that
13981415
// shape.
13991416

1400-
// `SceneID = 0xFF` is reserved.
1401-
if scene_id == RESERVED_SCENE_ID {
1417+
// `SceneID = 0x00` (Global Scene) and `0xFF` are reserved.
1418+
if scene_id == GLOBAL_SCENE_ID || scene_id == RESERVED_SCENE_ID {
14021419
return Err(ErrorCode::ConstraintError.into());
14031420
}
14041421

@@ -1518,9 +1535,14 @@ where
15181535
// SceneIDs are ignored in this mode).
15191536
let copy_all = (mode.bits() & 0x01) != 0;
15201537

1521-
// The reserved `SceneID = 0xFF` is only invalid in
1522-
// single-scene mode (COPY_ALL ignores those fields).
1523-
if !copy_all && (scene_from == RESERVED_SCENE_ID || scene_to == RESERVED_SCENE_ID) {
1538+
// Reserved `SceneID`s (Global Scene `0x00`, `0xFF`) are only
1539+
// invalid in single-scene mode (COPY_ALL ignores those fields).
1540+
if !copy_all
1541+
&& (scene_from == GLOBAL_SCENE_ID
1542+
|| scene_from == RESERVED_SCENE_ID
1543+
|| scene_to == GLOBAL_SCENE_ID
1544+
|| scene_to == RESERVED_SCENE_ID)
1545+
{
15241546
return response
15251547
.status(SC_CONSTRAINT_ERROR)?
15261548
.group_identifier_from(group_from)?

0 commit comments

Comments
 (0)