Skip to main content

matc/clusters/codec/
thread_border_router_diagnostics.rs

1//! Matter TLV encoders and decoders for Thread Border Router Diagnostics Cluster
2//! Cluster ID: 0x0454
3//!
4//! This file is automatically generated from ThreadBorderRouterDiagnostics.xml
5
6#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13// Enum definitions
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum BorderRouterOperationalStatus {
18    /// Border routing service is active and operational
19    Running = 0,
20    /// Border routing service is not operational due to fault or error
21    Stopped = 1,
22    /// Border routing service is not operational due to administrative configuration
23    Disabled = 2,
24}
25
26impl BorderRouterOperationalStatus {
27    /// Convert from u8 value
28    pub fn from_u8(value: u8) -> Option<Self> {
29        match value {
30            0 => Some(BorderRouterOperationalStatus::Running),
31            1 => Some(BorderRouterOperationalStatus::Stopped),
32            2 => Some(BorderRouterOperationalStatus::Disabled),
33            _ => None,
34        }
35    }
36
37    /// Convert to u8 value
38    pub fn to_u8(self) -> u8 {
39        self as u8
40    }
41}
42
43impl From<BorderRouterOperationalStatus> for u8 {
44    fn from(val: BorderRouterOperationalStatus) -> Self {
45        val as u8
46    }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
50#[repr(u8)]
51pub enum ThreadBorderRouterFault {
52    /// Indicates a generic unspecified fault related to the Border Router function.
53    Brgeneralfault = 0,
54    /// Indicates the adjacent infrastructure interface cannot be used for border routing.
55    Adjacentinfraiffault = 1,
56    /// Indicates that a service or function associated with border routing has reached its maximum capacity (e.g., SRP server table full).
57    Servicesatcapacity = 2,
58    /// Indicates that the Thread Border Router has reached its maximum supported number of direct MTD children.
59    Childrenatcapacity = 3,
60}
61
62impl ThreadBorderRouterFault {
63    /// Convert from u8 value
64    pub fn from_u8(value: u8) -> Option<Self> {
65        match value {
66            0 => Some(ThreadBorderRouterFault::Brgeneralfault),
67            1 => Some(ThreadBorderRouterFault::Adjacentinfraiffault),
68            2 => Some(ThreadBorderRouterFault::Servicesatcapacity),
69            3 => Some(ThreadBorderRouterFault::Childrenatcapacity),
70            _ => None,
71        }
72    }
73
74    /// Convert to u8 value
75    pub fn to_u8(self) -> u8 {
76        self as u8
77    }
78}
79
80impl From<ThreadBorderRouterFault> for u8 {
81    fn from(val: ThreadBorderRouterFault) -> Self {
82        val as u8
83    }
84}
85
86// Attribute decoders
87
88/// Decode BrStatus attribute (0x0000)
89pub fn decode_br_status(inp: &tlv::TlvItemValue) -> anyhow::Result<BorderRouterOperationalStatus> {
90    if let tlv::TlvItemValue::Int(v) = inp {
91        BorderRouterOperationalStatus::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
92    } else {
93        Err(anyhow::anyhow!("Expected Integer"))
94    }
95}
96
97/// Decode ActiveTbrFaultsList attribute (0x0001)
98pub fn decode_active_tbr_faults_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<ThreadBorderRouterFault>> {
99    let mut res = Vec::new();
100    if let tlv::TlvItemValue::List(v) = inp {
101        for item in v {
102            if let tlv::TlvItemValue::Int(i) = &item.value {
103                if let Some(enum_val) = ThreadBorderRouterFault::from_u8(*i as u8) {
104                    res.push(enum_val);
105                }
106            }
107        }
108    }
109    Ok(res)
110}
111
112
113// JSON dispatcher function
114
115/// Decode attribute value and return as JSON string
116///
117/// # Parameters
118/// * `cluster_id` - The cluster identifier
119/// * `attribute_id` - The attribute identifier
120/// * `tlv_value` - The TLV value to decode
121///
122/// # Returns
123/// JSON string representation of the decoded value or error
124pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
125    // Verify this is the correct cluster
126    if cluster_id != 0x0454 {
127        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0454, got {}\"}}", cluster_id);
128    }
129
130    match attribute_id {
131        0x0000 => {
132            match decode_br_status(tlv_value) {
133                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
134                Err(e) => format!("{{\"error\": \"{}\"}}", e),
135            }
136        }
137        0x0001 => {
138            match decode_active_tbr_faults_list(tlv_value) {
139                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
140                Err(e) => format!("{{\"error\": \"{}\"}}", e),
141            }
142        }
143        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
144    }
145}
146
147/// Get list of all attributes supported by this cluster
148///
149/// # Returns
150/// Vector of tuples containing (attribute_id, attribute_name)
151pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
152    vec![
153        (0x0000, "BrStatus"),
154        (0x0001, "ActiveTbrFaultsList"),
155    ]
156}
157
158// Typed facade (invokes + reads)
159
160/// Read `BrStatus` attribute from cluster `Thread Border Router Diagnostics`.
161pub async fn read_br_status(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<BorderRouterOperationalStatus> {
162    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_BORDER_ROUTER_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_BORDER_ROUTER_DIAGNOSTICS_ATTR_ID_BRSTATUS).await?;
163    decode_br_status(&tlv)
164}
165
166/// Read `ActiveTbrFaultsList` attribute from cluster `Thread Border Router Diagnostics`.
167pub async fn read_active_tbr_faults_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<ThreadBorderRouterFault>> {
168    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_BORDER_ROUTER_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_BORDER_ROUTER_DIAGNOSTICS_ATTR_ID_ACTIVETBRFAULTSLIST).await?;
169    decode_active_tbr_faults_list(&tlv)
170}
171