@@ -63,6 +63,10 @@ const SC_CONSTRAINT_ERROR: u8 = 0x87;
6363/// Reserved (invalid) `SceneID` value per Matter Core Spec.
6464const 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).
6872const 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