rs_matter/im/busy.rs
1/*
2 *
3 * Copyright (c) 2024-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
18use core::future::Future;
19
20use crate::error::*;
21use crate::respond::ExchangeHandler;
22use crate::transport::exchange::Exchange;
23
24use super::{IMStatusCode, OpCode, StatusResp, PROTO_ID_INTERACTION_MODEL};
25
26/// A Interaction Model implementation that is only capable of sending Busy status codes
27///
28/// Use with e.g.
29///
30/// ```ignore
31/// let matter = Matter::new(...);
32///
33/// // ...
34///
35/// let busy_responder = Responder::new("IM Busy Responder", BusyInteractionModel::new(), &matter, 200/*ms*/);
36/// busy_responder.run::<10>().await?;
37/// ```
38///
39/// ... to respond with "I'm busy, please try later" or similar status codes to all incoming IM messages, which were
40/// not accepted in time by the actual Interaction Model responder, due to all its handlers being occupied with work.
41pub struct BusyInteractionModel(());
42
43impl Default for BusyInteractionModel {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49impl BusyInteractionModel {
50 #[inline(always)]
51 pub const fn new() -> Self {
52 Self(())
53 }
54
55 pub async fn handle(&self, mut exchange: Exchange<'_>) -> Result<(), Error> {
56 let meta = exchange.recv().await?.meta();
57 if meta.proto_id != PROTO_ID_INTERACTION_MODEL {
58 Err(ErrorCode::InvalidProto)?;
59 }
60
61 let status = match meta.opcode()? {
62 OpCode::ReadRequest
63 | OpCode::WriteRequest
64 | OpCode::SubscribeRequest
65 | OpCode::InvokeRequest => IMStatusCode::Busy,
66 _ => IMStatusCode::Failure,
67 };
68
69 exchange
70 .send_with(|_, wb| {
71 StatusResp::write(wb, status)?;
72
73 Ok(Some(OpCode::StatusResponse.meta()))
74 })
75 .await
76 }
77}
78
79impl ExchangeHandler for BusyInteractionModel {
80 fn handle(&self, exchange: Exchange<'_>) -> impl Future<Output = Result<(), Error>> {
81 BusyInteractionModel::handle(self, exchange)
82 }
83}