rs_matter/im/encoding/timed.rs
1/*
2 *
3 * Copyright (c) 2025-2026 Project CHIP Authors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18//! This module contains types related to the Timed Request feature in the Matter Interaction Model.
19
20use embassy_time::{Duration, Instant};
21
22use crate::im::IM_REVISION;
23use crate::tlv::{FromTLV, ToTLV};
24
25/// A structure representing a timed request in the Interaction Model.
26///
27/// Corresponds to the `TimedRequestMessage` struct in the Interaction Model.
28#[derive(Debug, Clone, PartialEq, Eq, Hash, FromTLV, ToTLV)]
29#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub struct TimedReq {
31 /// The timeout duration in milliseconds for the request.
32 pub timeout: u16,
33 /// `interactionModelRevision` — mandatory in every IM message we send;
34 /// modelled as `Option<u8>` so we tolerate peers that omit it (the C++
35 /// SDK is tolerant in practice).
36 #[tagval(crate::im::encoding::IM_REVISION_TAG)]
37 pub interaction_model_revision: Option<u8>,
38}
39
40impl TimedReq {
41 /// Create a new `TimedReq` with the given timeout (in milliseconds).
42 pub const fn new(timeout: u16) -> Self {
43 Self {
44 timeout,
45 interaction_model_revision: Some(IM_REVISION),
46 }
47 }
48
49 /// Returns the monotonic [`Instant`] at which the request following this
50 /// timed request should be considered expired.
51 ///
52 /// Saturates to [`Instant::MAX`] if the addition would overflow.
53 pub fn timeout_instant(&self) -> Instant {
54 Instant::now().saturating_add(Duration::from_millis(self.timeout as _))
55 }
56}