#![allow(clippy::too_many_arguments)]
use crate::tlv;
use anyhow;
use serde_json;
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
pub enum ConnectionStatus {
Connected = 0,
Notconnected = 1,
}
impl ConnectionStatus {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(ConnectionStatus::Connected),
1 => Some(ConnectionStatus::Notconnected),
_ => None,
}
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl From<ConnectionStatus> for u8 {
fn from(val: ConnectionStatus) -> Self {
val as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
pub enum NetworkFault {
Unspecified = 0,
Linkdown = 1,
Hardwarefailure = 2,
Networkjammed = 3,
}
impl NetworkFault {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(NetworkFault::Unspecified),
1 => Some(NetworkFault::Linkdown),
2 => Some(NetworkFault::Hardwarefailure),
3 => Some(NetworkFault::Networkjammed),
_ => None,
}
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl From<NetworkFault> for u8 {
fn from(val: NetworkFault) -> Self {
val as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
pub enum RoutingRole {
Unspecified = 0,
Unassigned = 1,
Sleepyenddevice = 2,
Enddevice = 3,
Reed = 4,
Router = 5,
Leader = 6,
}
impl RoutingRole {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(RoutingRole::Unspecified),
1 => Some(RoutingRole::Unassigned),
2 => Some(RoutingRole::Sleepyenddevice),
3 => Some(RoutingRole::Enddevice),
4 => Some(RoutingRole::Reed),
5 => Some(RoutingRole::Router),
6 => Some(RoutingRole::Leader),
_ => None,
}
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl From<RoutingRole> for u8 {
fn from(val: RoutingRole) -> Self {
val as u8
}
}
#[derive(Debug, serde::Serialize)]
pub struct NeighborTable {
pub ext_address: Option<u64>,
pub age: Option<u32>,
pub rloc16: Option<u16>,
pub link_frame_counter: Option<u32>,
pub mle_frame_counter: Option<u32>,
pub lqi: Option<u8>,
pub average_rssi: Option<i8>,
pub last_rssi: Option<i8>,
pub frame_error_rate: Option<u8>,
pub message_error_rate: Option<u8>,
pub rx_on_when_idle: Option<bool>,
pub full_thread_device: Option<bool>,
pub full_network_data: Option<bool>,
pub is_child: Option<bool>,
}
#[derive(Debug, serde::Serialize)]
pub struct OperationalDatasetComponents {
pub active_timestamp_present: Option<bool>,
pub pending_timestamp_present: Option<bool>,
pub master_key_present: Option<bool>,
pub network_name_present: Option<bool>,
pub extended_pan_id_present: Option<bool>,
pub mesh_local_prefix_present: Option<bool>,
pub delay_present: Option<bool>,
pub pan_id_present: Option<bool>,
pub channel_present: Option<bool>,
pub pskc_present: Option<bool>,
pub security_policy_present: Option<bool>,
pub channel_mask_present: Option<bool>,
}
#[derive(Debug, serde::Serialize)]
pub struct RouteTable {
pub ext_address: Option<u64>,
pub rloc16: Option<u16>,
pub router_id: Option<u8>,
pub next_hop: Option<u8>,
pub path_cost: Option<u8>,
pub lqi_in: Option<u8>,
pub lqi_out: Option<u8>,
pub age: Option<u8>,
pub allocated: Option<bool>,
pub link_established: Option<bool>,
}
#[derive(Debug, serde::Serialize)]
pub struct SecurityPolicy {
pub rotation_time: Option<u16>,
pub flags: Option<u16>,
}
pub fn decode_channel(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u16))
} else {
Ok(None)
}
}
pub fn decode_routing_role(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<RoutingRole>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(RoutingRole::from_u8(*v as u8))
} else {
Ok(None)
}
}
pub fn decode_network_name(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<String>> {
if let tlv::TlvItemValue::String(v) = inp {
Ok(Some(v.clone()))
} else {
Ok(None)
}
}
pub fn decode_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u16))
} else {
Ok(None)
}
}
pub fn decode_extended_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v))
} else {
Ok(None)
}
}
pub fn decode_mesh_local_prefix(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u8))
} else {
Ok(None)
}
}
pub fn decode_overrun_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v)
} else {
Err(anyhow::anyhow!("Expected UInt64"))
}
}
pub fn decode_neighbor_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NeighborTable>> {
let mut res = Vec::new();
if let tlv::TlvItemValue::List(v) = inp {
for item in v {
res.push(NeighborTable {
ext_address: item.get_int(&[0]),
age: item.get_int(&[1]).map(|v| v as u32),
rloc16: item.get_int(&[2]).map(|v| v as u16),
link_frame_counter: item.get_int(&[3]).map(|v| v as u32),
mle_frame_counter: item.get_int(&[4]).map(|v| v as u32),
lqi: item.get_int(&[5]).map(|v| v as u8),
average_rssi: item.get_int(&[6]).map(|v| v as i8),
last_rssi: item.get_int(&[7]).map(|v| v as i8),
frame_error_rate: item.get_int(&[8]).map(|v| v as u8),
message_error_rate: item.get_int(&[9]).map(|v| v as u8),
rx_on_when_idle: item.get_bool(&[10]),
full_thread_device: item.get_bool(&[11]),
full_network_data: item.get_bool(&[12]),
is_child: item.get_bool(&[13]),
});
}
}
Ok(res)
}
pub fn decode_route_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<RouteTable>> {
let mut res = Vec::new();
if let tlv::TlvItemValue::List(v) = inp {
for item in v {
res.push(RouteTable {
ext_address: item.get_int(&[0]),
rloc16: item.get_int(&[1]).map(|v| v as u16),
router_id: item.get_int(&[2]).map(|v| v as u8),
next_hop: item.get_int(&[3]).map(|v| v as u8),
path_cost: item.get_int(&[4]).map(|v| v as u8),
lqi_in: item.get_int(&[5]).map(|v| v as u8),
lqi_out: item.get_int(&[6]).map(|v| v as u8),
age: item.get_int(&[7]).map(|v| v as u8),
allocated: item.get_bool(&[8]),
link_established: item.get_bool(&[9]),
});
}
}
Ok(res)
}
pub fn decode_partition_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u32))
} else {
Ok(None)
}
}
pub fn decode_weighting(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u16))
} else {
Ok(None)
}
}
pub fn decode_data_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u16))
} else {
Ok(None)
}
}
pub fn decode_stable_data_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u16))
} else {
Ok(None)
}
}
pub fn decode_leader_router_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u8))
} else {
Ok(None)
}
}
pub fn decode_detached_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_child_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_router_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_leader_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_attach_attempt_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_partition_id_change_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_better_partition_attach_attempt_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_parent_change_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u16)
} else {
Err(anyhow::anyhow!("Expected UInt16"))
}
}
pub fn decode_tx_total_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_unicast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_broadcast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_ack_requested_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_acked_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_no_ack_requested_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_data_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_data_poll_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_beacon_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_beacon_request_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_retry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_direct_max_retry_expiry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_indirect_max_retry_expiry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_err_cca_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_err_abort_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_tx_err_busy_channel_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_total_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_unicast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_broadcast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_data_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_data_poll_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_beacon_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_beacon_request_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_address_filtered_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_dest_addr_filtered_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_duplicated_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_err_no_frame_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_err_unknown_neighbor_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_err_invalid_src_addr_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_err_sec_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_err_fcs_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_rx_err_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(*v as u32)
} else {
Err(anyhow::anyhow!("Expected UInt32"))
}
}
pub fn decode_active_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v))
} else {
Ok(None)
}
}
pub fn decode_pending_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v))
} else {
Ok(None)
}
}
pub fn decode_delay(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u32))
} else {
Ok(None)
}
}
pub fn decode_security_policy(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<SecurityPolicy>> {
if let tlv::TlvItemValue::List(_fields) = inp {
let item = tlv::TlvItem { tag: 0, value: inp.clone() };
Ok(Some(SecurityPolicy {
rotation_time: item.get_int(&[0]).map(|v| v as u16),
flags: item.get_int(&[1]).map(|v| v as u16),
}))
} else {
Ok(None)
}
}
pub fn decode_channel_page0_mask(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
if let tlv::TlvItemValue::OctetString(v) = inp {
Ok(Some(v.clone()))
} else {
Ok(None)
}
}
pub fn decode_operational_dataset_components(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<OperationalDatasetComponents>> {
if let tlv::TlvItemValue::List(_fields) = inp {
let item = tlv::TlvItem { tag: 0, value: inp.clone() };
Ok(Some(OperationalDatasetComponents {
active_timestamp_present: item.get_bool(&[0]),
pending_timestamp_present: item.get_bool(&[1]),
master_key_present: item.get_bool(&[2]),
network_name_present: item.get_bool(&[3]),
extended_pan_id_present: item.get_bool(&[4]),
mesh_local_prefix_present: item.get_bool(&[5]),
delay_present: item.get_bool(&[6]),
pan_id_present: item.get_bool(&[7]),
channel_present: item.get_bool(&[8]),
pskc_present: item.get_bool(&[9]),
security_policy_present: item.get_bool(&[10]),
channel_mask_present: item.get_bool(&[11]),
}))
} else {
Ok(None)
}
}
pub fn decode_active_network_faults_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NetworkFault>> {
let mut res = Vec::new();
if let tlv::TlvItemValue::List(v) = inp {
for item in v {
if let tlv::TlvItemValue::Int(i) = &item.value {
if let Some(enum_val) = NetworkFault::from_u8(*i as u8) {
res.push(enum_val);
}
}
}
}
Ok(res)
}
pub fn decode_ext_address(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v))
} else {
Ok(None)
}
}
pub fn decode_rloc16(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
if let tlv::TlvItemValue::Int(v) = inp {
Ok(Some(*v as u16))
} else {
Ok(None)
}
}
pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
if cluster_id != 0x0035 {
return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0035, got {}\"}}", cluster_id);
}
match attribute_id {
0x0000 => {
match decode_channel(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0001 => {
match decode_routing_role(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0002 => {
match decode_network_name(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0003 => {
match decode_pan_id(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0004 => {
match decode_extended_pan_id(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0005 => {
match decode_mesh_local_prefix(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0006 => {
match decode_overrun_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0007 => {
match decode_neighbor_table(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0008 => {
match decode_route_table(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0009 => {
match decode_partition_id(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x000A => {
match decode_weighting(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x000B => {
match decode_data_version(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x000C => {
match decode_stable_data_version(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x000D => {
match decode_leader_router_id(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x000E => {
match decode_detached_role_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x000F => {
match decode_child_role_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0010 => {
match decode_router_role_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0011 => {
match decode_leader_role_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0012 => {
match decode_attach_attempt_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0013 => {
match decode_partition_id_change_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0014 => {
match decode_better_partition_attach_attempt_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0015 => {
match decode_parent_change_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0016 => {
match decode_tx_total_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0017 => {
match decode_tx_unicast_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0018 => {
match decode_tx_broadcast_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0019 => {
match decode_tx_ack_requested_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x001A => {
match decode_tx_acked_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x001B => {
match decode_tx_no_ack_requested_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x001C => {
match decode_tx_data_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x001D => {
match decode_tx_data_poll_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x001E => {
match decode_tx_beacon_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x001F => {
match decode_tx_beacon_request_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0020 => {
match decode_tx_other_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0021 => {
match decode_tx_retry_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0022 => {
match decode_tx_direct_max_retry_expiry_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0023 => {
match decode_tx_indirect_max_retry_expiry_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0024 => {
match decode_tx_err_cca_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0025 => {
match decode_tx_err_abort_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0026 => {
match decode_tx_err_busy_channel_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0027 => {
match decode_rx_total_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0028 => {
match decode_rx_unicast_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0029 => {
match decode_rx_broadcast_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x002A => {
match decode_rx_data_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x002B => {
match decode_rx_data_poll_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x002C => {
match decode_rx_beacon_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x002D => {
match decode_rx_beacon_request_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x002E => {
match decode_rx_other_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x002F => {
match decode_rx_address_filtered_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0030 => {
match decode_rx_dest_addr_filtered_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0031 => {
match decode_rx_duplicated_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0032 => {
match decode_rx_err_no_frame_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0033 => {
match decode_rx_err_unknown_neighbor_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0034 => {
match decode_rx_err_invalid_src_addr_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0035 => {
match decode_rx_err_sec_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0036 => {
match decode_rx_err_fcs_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0037 => {
match decode_rx_err_other_count(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0038 => {
match decode_active_timestamp(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0039 => {
match decode_pending_timestamp(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x003A => {
match decode_delay(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x003B => {
match decode_security_policy(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x003C => {
match decode_channel_page0_mask(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x003D => {
match decode_operational_dataset_components(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x003E => {
match decode_active_network_faults_list(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x003F => {
match decode_ext_address(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
0x0040 => {
match decode_rloc16(tlv_value) {
Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
Err(e) => format!("{{\"error\": \"{}\"}}", e),
}
}
_ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
}
}
pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
vec![
(0x0000, "Channel"),
(0x0001, "RoutingRole"),
(0x0002, "NetworkName"),
(0x0003, "PanId"),
(0x0004, "ExtendedPanId"),
(0x0005, "MeshLocalPrefix"),
(0x0006, "OverrunCount"),
(0x0007, "NeighborTable"),
(0x0008, "RouteTable"),
(0x0009, "PartitionId"),
(0x000A, "Weighting"),
(0x000B, "DataVersion"),
(0x000C, "StableDataVersion"),
(0x000D, "LeaderRouterId"),
(0x000E, "DetachedRoleCount"),
(0x000F, "ChildRoleCount"),
(0x0010, "RouterRoleCount"),
(0x0011, "LeaderRoleCount"),
(0x0012, "AttachAttemptCount"),
(0x0013, "PartitionIdChangeCount"),
(0x0014, "BetterPartitionAttachAttemptCount"),
(0x0015, "ParentChangeCount"),
(0x0016, "TxTotalCount"),
(0x0017, "TxUnicastCount"),
(0x0018, "TxBroadcastCount"),
(0x0019, "TxAckRequestedCount"),
(0x001A, "TxAckedCount"),
(0x001B, "TxNoAckRequestedCount"),
(0x001C, "TxDataCount"),
(0x001D, "TxDataPollCount"),
(0x001E, "TxBeaconCount"),
(0x001F, "TxBeaconRequestCount"),
(0x0020, "TxOtherCount"),
(0x0021, "TxRetryCount"),
(0x0022, "TxDirectMaxRetryExpiryCount"),
(0x0023, "TxIndirectMaxRetryExpiryCount"),
(0x0024, "TxErrCcaCount"),
(0x0025, "TxErrAbortCount"),
(0x0026, "TxErrBusyChannelCount"),
(0x0027, "RxTotalCount"),
(0x0028, "RxUnicastCount"),
(0x0029, "RxBroadcastCount"),
(0x002A, "RxDataCount"),
(0x002B, "RxDataPollCount"),
(0x002C, "RxBeaconCount"),
(0x002D, "RxBeaconRequestCount"),
(0x002E, "RxOtherCount"),
(0x002F, "RxAddressFilteredCount"),
(0x0030, "RxDestAddrFilteredCount"),
(0x0031, "RxDuplicatedCount"),
(0x0032, "RxErrNoFrameCount"),
(0x0033, "RxErrUnknownNeighborCount"),
(0x0034, "RxErrInvalidSrcAddrCount"),
(0x0035, "RxErrSecCount"),
(0x0036, "RxErrFcsCount"),
(0x0037, "RxErrOtherCount"),
(0x0038, "ActiveTimestamp"),
(0x0039, "PendingTimestamp"),
(0x003A, "Delay"),
(0x003B, "SecurityPolicy"),
(0x003C, "ChannelPage0Mask"),
(0x003D, "OperationalDatasetComponents"),
(0x003E, "ActiveNetworkFaultsList"),
(0x003F, "ExtAddress"),
(0x0040, "Rloc16"),
]
}
pub fn get_command_list() -> Vec<(u32, &'static str)> {
vec![
(0x00, "ResetCounts"),
]
}
pub fn get_command_name(cmd_id: u32) -> Option<&'static str> {
match cmd_id {
0x00 => Some("ResetCounts"),
_ => None,
}
}
pub fn get_command_schema(cmd_id: u32) -> Option<Vec<crate::clusters::codec::CommandField>> {
match cmd_id {
0x00 => Some(vec![]),
_ => None,
}
}
pub fn encode_command_json(cmd_id: u32, _args: &serde_json::Value) -> anyhow::Result<Vec<u8>> {
match cmd_id {
0x00 => Ok(vec![]),
_ => Err(anyhow::anyhow!("unknown command ID: 0x{:02X}", cmd_id)),
}
}
pub async fn reset_counts(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<()> {
conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_CMD_ID_RESETCOUNTS, &[]).await?;
Ok(())
}
pub async fn read_channel(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_CHANNEL).await?;
decode_channel(&tlv)
}
pub async fn read_routing_role(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<RoutingRole>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_ROUTINGROLE).await?;
decode_routing_role(&tlv)
}
pub async fn read_network_name(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<String>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_NETWORKNAME).await?;
decode_network_name(&tlv)
}
pub async fn read_pan_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_PANID).await?;
decode_pan_id(&tlv)
}
pub async fn read_extended_pan_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u64>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_EXTENDEDPANID).await?;
decode_extended_pan_id(&tlv)
}
pub async fn read_mesh_local_prefix(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_MESHLOCALPREFIX).await?;
decode_mesh_local_prefix(&tlv)
}
pub async fn read_overrun_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u64> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_OVERRUNCOUNT).await?;
decode_overrun_count(&tlv)
}
pub async fn read_neighbor_table(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<NeighborTable>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_NEIGHBORTABLE).await?;
decode_neighbor_table(&tlv)
}
pub async fn read_route_table(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<RouteTable>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_ROUTETABLE).await?;
decode_route_table(&tlv)
}
pub async fn read_partition_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_PARTITIONID).await?;
decode_partition_id(&tlv)
}
pub async fn read_weighting(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_WEIGHTING).await?;
decode_weighting(&tlv)
}
pub async fn read_data_version(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_DATAVERSION).await?;
decode_data_version(&tlv)
}
pub async fn read_stable_data_version(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_STABLEDATAVERSION).await?;
decode_stable_data_version(&tlv)
}
pub async fn read_leader_router_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_LEADERROUTERID).await?;
decode_leader_router_id(&tlv)
}
pub async fn read_detached_role_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_DETACHEDROLECOUNT).await?;
decode_detached_role_count(&tlv)
}
pub async fn read_child_role_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_CHILDROLECOUNT).await?;
decode_child_role_count(&tlv)
}
pub async fn read_router_role_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_ROUTERROLECOUNT).await?;
decode_router_role_count(&tlv)
}
pub async fn read_leader_role_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_LEADERROLECOUNT).await?;
decode_leader_role_count(&tlv)
}
pub async fn read_attach_attempt_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_ATTACHATTEMPTCOUNT).await?;
decode_attach_attempt_count(&tlv)
}
pub async fn read_partition_id_change_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_PARTITIONIDCHANGECOUNT).await?;
decode_partition_id_change_count(&tlv)
}
pub async fn read_better_partition_attach_attempt_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_BETTERPARTITIONATTACHATTEMPTCOUNT).await?;
decode_better_partition_attach_attempt_count(&tlv)
}
pub async fn read_parent_change_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_PARENTCHANGECOUNT).await?;
decode_parent_change_count(&tlv)
}
pub async fn read_tx_total_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXTOTALCOUNT).await?;
decode_tx_total_count(&tlv)
}
pub async fn read_tx_unicast_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXUNICASTCOUNT).await?;
decode_tx_unicast_count(&tlv)
}
pub async fn read_tx_broadcast_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXBROADCASTCOUNT).await?;
decode_tx_broadcast_count(&tlv)
}
pub async fn read_tx_ack_requested_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXACKREQUESTEDCOUNT).await?;
decode_tx_ack_requested_count(&tlv)
}
pub async fn read_tx_acked_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXACKEDCOUNT).await?;
decode_tx_acked_count(&tlv)
}
pub async fn read_tx_no_ack_requested_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXNOACKREQUESTEDCOUNT).await?;
decode_tx_no_ack_requested_count(&tlv)
}
pub async fn read_tx_data_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXDATACOUNT).await?;
decode_tx_data_count(&tlv)
}
pub async fn read_tx_data_poll_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXDATAPOLLCOUNT).await?;
decode_tx_data_poll_count(&tlv)
}
pub async fn read_tx_beacon_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXBEACONCOUNT).await?;
decode_tx_beacon_count(&tlv)
}
pub async fn read_tx_beacon_request_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXBEACONREQUESTCOUNT).await?;
decode_tx_beacon_request_count(&tlv)
}
pub async fn read_tx_other_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXOTHERCOUNT).await?;
decode_tx_other_count(&tlv)
}
pub async fn read_tx_retry_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXRETRYCOUNT).await?;
decode_tx_retry_count(&tlv)
}
pub async fn read_tx_direct_max_retry_expiry_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXDIRECTMAXRETRYEXPIRYCOUNT).await?;
decode_tx_direct_max_retry_expiry_count(&tlv)
}
pub async fn read_tx_indirect_max_retry_expiry_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXINDIRECTMAXRETRYEXPIRYCOUNT).await?;
decode_tx_indirect_max_retry_expiry_count(&tlv)
}
pub async fn read_tx_err_cca_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXERRCCACOUNT).await?;
decode_tx_err_cca_count(&tlv)
}
pub async fn read_tx_err_abort_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXERRABORTCOUNT).await?;
decode_tx_err_abort_count(&tlv)
}
pub async fn read_tx_err_busy_channel_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_TXERRBUSYCHANNELCOUNT).await?;
decode_tx_err_busy_channel_count(&tlv)
}
pub async fn read_rx_total_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXTOTALCOUNT).await?;
decode_rx_total_count(&tlv)
}
pub async fn read_rx_unicast_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXUNICASTCOUNT).await?;
decode_rx_unicast_count(&tlv)
}
pub async fn read_rx_broadcast_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXBROADCASTCOUNT).await?;
decode_rx_broadcast_count(&tlv)
}
pub async fn read_rx_data_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXDATACOUNT).await?;
decode_rx_data_count(&tlv)
}
pub async fn read_rx_data_poll_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXDATAPOLLCOUNT).await?;
decode_rx_data_poll_count(&tlv)
}
pub async fn read_rx_beacon_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXBEACONCOUNT).await?;
decode_rx_beacon_count(&tlv)
}
pub async fn read_rx_beacon_request_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXBEACONREQUESTCOUNT).await?;
decode_rx_beacon_request_count(&tlv)
}
pub async fn read_rx_other_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXOTHERCOUNT).await?;
decode_rx_other_count(&tlv)
}
pub async fn read_rx_address_filtered_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXADDRESSFILTEREDCOUNT).await?;
decode_rx_address_filtered_count(&tlv)
}
pub async fn read_rx_dest_addr_filtered_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXDESTADDRFILTEREDCOUNT).await?;
decode_rx_dest_addr_filtered_count(&tlv)
}
pub async fn read_rx_duplicated_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXDUPLICATEDCOUNT).await?;
decode_rx_duplicated_count(&tlv)
}
pub async fn read_rx_err_no_frame_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXERRNOFRAMECOUNT).await?;
decode_rx_err_no_frame_count(&tlv)
}
pub async fn read_rx_err_unknown_neighbor_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXERRUNKNOWNNEIGHBORCOUNT).await?;
decode_rx_err_unknown_neighbor_count(&tlv)
}
pub async fn read_rx_err_invalid_src_addr_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXERRINVALIDSRCADDRCOUNT).await?;
decode_rx_err_invalid_src_addr_count(&tlv)
}
pub async fn read_rx_err_sec_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXERRSECCOUNT).await?;
decode_rx_err_sec_count(&tlv)
}
pub async fn read_rx_err_fcs_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXERRFCSCOUNT).await?;
decode_rx_err_fcs_count(&tlv)
}
pub async fn read_rx_err_other_count(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RXERROTHERCOUNT).await?;
decode_rx_err_other_count(&tlv)
}
pub async fn read_active_timestamp(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u64>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_ACTIVETIMESTAMP).await?;
decode_active_timestamp(&tlv)
}
pub async fn read_pending_timestamp(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u64>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_PENDINGTIMESTAMP).await?;
decode_pending_timestamp(&tlv)
}
pub async fn read_delay(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_DELAY).await?;
decode_delay(&tlv)
}
pub async fn read_security_policy(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<SecurityPolicy>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_SECURITYPOLICY).await?;
decode_security_policy(&tlv)
}
pub async fn read_channel_page0_mask(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<Vec<u8>>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_CHANNELPAGE0MASK).await?;
decode_channel_page0_mask(&tlv)
}
pub async fn read_operational_dataset_components(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<OperationalDatasetComponents>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_OPERATIONALDATASETCOMPONENTS).await?;
decode_operational_dataset_components(&tlv)
}
pub async fn read_active_network_faults_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<NetworkFault>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_ACTIVENETWORKFAULTSLIST).await?;
decode_active_network_faults_list(&tlv)
}
pub async fn read_ext_address(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u64>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_EXTADDRESS).await?;
decode_ext_address(&tlv)
}
pub async fn read_rloc16(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_THREAD_NETWORK_DIAGNOSTICS, crate::clusters::defs::CLUSTER_THREAD_NETWORK_DIAGNOSTICS_ATTR_ID_RLOC16).await?;
decode_rloc16(&tlv)
}
#[derive(Debug, serde::Serialize)]
pub struct ConnectionStatusEvent {
pub connection_status: Option<ConnectionStatus>,
}
#[derive(Debug, serde::Serialize)]
pub struct NetworkFaultChangeEvent {
pub current: Option<Vec<NetworkFault>>,
pub previous: Option<Vec<NetworkFault>>,
}
pub fn decode_connection_status_event(inp: &tlv::TlvItemValue) -> anyhow::Result<ConnectionStatusEvent> {
if let tlv::TlvItemValue::List(_fields) = inp {
let item = tlv::TlvItem { tag: 0, value: inp.clone() };
Ok(ConnectionStatusEvent {
connection_status: item.get_int(&[0]).and_then(|v| ConnectionStatus::from_u8(v as u8)),
})
} else {
Err(anyhow::anyhow!("Expected struct fields"))
}
}
pub fn decode_network_fault_change_event(inp: &tlv::TlvItemValue) -> anyhow::Result<NetworkFaultChangeEvent> {
if let tlv::TlvItemValue::List(_fields) = inp {
let item = tlv::TlvItem { tag: 0, value: inp.clone() };
Ok(NetworkFaultChangeEvent {
current: {
if let Some(tlv::TlvItemValue::List(l)) = item.get(&[0]) {
let items: Vec<NetworkFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { NetworkFault::from_u8(*v as u8) } else { None } }).collect();
Some(items)
} else {
None
}
},
previous: {
if let Some(tlv::TlvItemValue::List(l)) = item.get(&[1]) {
let items: Vec<NetworkFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { NetworkFault::from_u8(*v as u8) } else { None } }).collect();
Some(items)
} else {
None
}
},
})
} else {
Err(anyhow::anyhow!("Expected struct fields"))
}
}