Skip to main content

matter_interaction/
timed.rs

1//! `TimedRequestMessage` framing — Matter §8.7 (timed interactions).
2//!
3//! IM opcode `0x0a`. Body: `{ 0: TimeoutMs (u16), 0xFF: InteractionModelRevision }`.
4//! The client sends this first; the device replies `StatusResponse(SUCCESS)` and
5//! then expects the Write/Invoke (with its `TimedRequest` flag set) on the **same
6//! exchange** within `timeout_ms`. Byte-parity with matter.js is enforced by
7//! `tests/im_byte_parity.rs`.
8
9#![forbid(unsafe_code)]
10
11use crate::IM_REVISION;
12use matter_codec::{Tag, TlvWriter};
13
14/// Build a `TimedRequestMessage` requesting `timeout_ms` milliseconds for the
15/// follow-up Write/Invoke (which the device expects on the same exchange).
16#[must_use]
17#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
18pub fn build_timed_request(timeout_ms: u16) -> Vec<u8> {
19    let mut buf = Vec::new();
20    let mut w = TlvWriter::new(&mut buf);
21    w.start_structure(Tag::Anonymous)
22        .expect("infallible: vec writer");
23    w.put_uint(Tag::Context(0), u64::from(timeout_ms))
24        .expect("infallible: vec writer"); // TimeoutMs
25    w.put_uint(Tag::Context(0xFF), u64::from(IM_REVISION))
26        .expect("infallible: vec writer");
27    w.end_container().expect("infallible: vec writer");
28    buf
29}
30
31#[cfg(test)]
32mod tests {
33    #![allow(clippy::unwrap_used)] // Test code: CLAUDE.md test-code carve-out.
34    use super::*;
35    use matter_codec::{Element, TlvReader, Value};
36
37    #[test]
38    fn timed_request_has_timeout_at_tag_0() {
39        let bytes = build_timed_request(10000);
40        let mut r = TlvReader::new(&bytes);
41        assert!(matches!(
42            r.next().unwrap(),
43            Some(Element::ContainerStart { .. })
44        ));
45        assert!(matches!(
46            r.next().unwrap(),
47            Some(Element::Scalar {
48                tag: Tag::Context(0),
49                value: Value::Uint(10000)
50            })
51        ));
52    }
53}