matc/clusters/codec/
diagnostics_software.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct ThreadMetrics {
15 pub id: Option<u64>,
16 pub name: Option<String>,
17 pub stack_free_current: Option<u32>,
18 pub stack_free_minimum: Option<u32>,
19 pub stack_size: Option<u32>,
20}
21
22pub fn decode_thread_metrics(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<ThreadMetrics>> {
28 let mut res = Vec::new();
29 if let tlv::TlvItemValue::List(v) = inp {
30 for item in v {
31 res.push(ThreadMetrics {
32 id: item.get_int(&[0]),
33 name: item.get_string_owned(&[1]),
34 stack_free_current: item.get_int(&[2]).map(|v| v as u32),
35 stack_free_minimum: item.get_int(&[3]).map(|v| v as u32),
36 stack_size: item.get_int(&[4]).map(|v| v as u32),
37 });
38 }
39 }
40 Ok(res)
41}
42
43pub fn decode_current_heap_free(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
45 if let tlv::TlvItemValue::Int(v) = inp {
46 Ok(*v)
47 } else {
48 Err(anyhow::anyhow!("Expected Integer"))
49 }
50}
51
52pub fn decode_current_heap_used(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
54 if let tlv::TlvItemValue::Int(v) = inp {
55 Ok(*v)
56 } else {
57 Err(anyhow::anyhow!("Expected Integer"))
58 }
59}
60
61pub fn decode_current_heap_high_watermark(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
63 if let tlv::TlvItemValue::Int(v) = inp {
64 Ok(*v)
65 } else {
66 Err(anyhow::anyhow!("Expected Integer"))
67 }
68}
69
70
71pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
83 if cluster_id != 0x0034 {
85 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0034, got {}\"}}", cluster_id);
86 }
87
88 match attribute_id {
89 0x0000 => {
90 match decode_thread_metrics(tlv_value) {
91 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
92 Err(e) => format!("{{\"error\": \"{}\"}}", e),
93 }
94 }
95 0x0001 => {
96 match decode_current_heap_free(tlv_value) {
97 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
98 Err(e) => format!("{{\"error\": \"{}\"}}", e),
99 }
100 }
101 0x0002 => {
102 match decode_current_heap_used(tlv_value) {
103 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
104 Err(e) => format!("{{\"error\": \"{}\"}}", e),
105 }
106 }
107 0x0003 => {
108 match decode_current_heap_high_watermark(tlv_value) {
109 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
110 Err(e) => format!("{{\"error\": \"{}\"}}", e),
111 }
112 }
113 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
114 }
115}
116
117pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
122 vec![
123 (0x0000, "ThreadMetrics"),
124 (0x0001, "CurrentHeapFree"),
125 (0x0002, "CurrentHeapUsed"),
126 (0x0003, "CurrentHeapHighWatermark"),
127 ]
128}
129