1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14#[repr(u8)]
15pub enum ConnectionStatus {
16 Connected = 0,
18 Notconnected = 1,
20}
21
22impl ConnectionStatus {
23 pub fn from_u8(value: u8) -> Option<Self> {
25 match value {
26 0 => Some(ConnectionStatus::Connected),
27 1 => Some(ConnectionStatus::Notconnected),
28 _ => None,
29 }
30 }
31
32 pub fn to_u8(self) -> u8 {
34 self as u8
35 }
36}
37
38impl From<ConnectionStatus> for u8 {
39 fn from(val: ConnectionStatus) -> Self {
40 val as u8
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
45#[repr(u8)]
46pub enum NetworkFault {
47 Unspecified = 0,
49 Linkdown = 1,
51 Hardwarefailure = 2,
53 Networkjammed = 3,
55}
56
57impl NetworkFault {
58 pub fn from_u8(value: u8) -> Option<Self> {
60 match value {
61 0 => Some(NetworkFault::Unspecified),
62 1 => Some(NetworkFault::Linkdown),
63 2 => Some(NetworkFault::Hardwarefailure),
64 3 => Some(NetworkFault::Networkjammed),
65 _ => None,
66 }
67 }
68
69 pub fn to_u8(self) -> u8 {
71 self as u8
72 }
73}
74
75impl From<NetworkFault> for u8 {
76 fn from(val: NetworkFault) -> Self {
77 val as u8
78 }
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
82#[repr(u8)]
83pub enum RoutingRole {
84 Unspecified = 0,
86 Unassigned = 1,
88 Sleepyenddevice = 2,
90 Enddevice = 3,
92 Reed = 4,
94 Router = 5,
96 Leader = 6,
98}
99
100impl RoutingRole {
101 pub fn from_u8(value: u8) -> Option<Self> {
103 match value {
104 0 => Some(RoutingRole::Unspecified),
105 1 => Some(RoutingRole::Unassigned),
106 2 => Some(RoutingRole::Sleepyenddevice),
107 3 => Some(RoutingRole::Enddevice),
108 4 => Some(RoutingRole::Reed),
109 5 => Some(RoutingRole::Router),
110 6 => Some(RoutingRole::Leader),
111 _ => None,
112 }
113 }
114
115 pub fn to_u8(self) -> u8 {
117 self as u8
118 }
119}
120
121impl From<RoutingRole> for u8 {
122 fn from(val: RoutingRole) -> Self {
123 val as u8
124 }
125}
126
127#[derive(Debug, serde::Serialize)]
130pub struct NeighborTable {
131 pub ext_address: Option<u64>,
132 pub age: Option<u32>,
133 pub rloc16: Option<u16>,
134 pub link_frame_counter: Option<u32>,
135 pub mle_frame_counter: Option<u32>,
136 pub lqi: Option<u8>,
137 pub average_rssi: Option<i8>,
138 pub last_rssi: Option<i8>,
139 pub frame_error_rate: Option<u8>,
140 pub message_error_rate: Option<u8>,
141 pub rx_on_when_idle: Option<bool>,
142 pub full_thread_device: Option<bool>,
143 pub full_network_data: Option<bool>,
144 pub is_child: Option<bool>,
145}
146
147#[derive(Debug, serde::Serialize)]
148pub struct OperationalDatasetComponents {
149 pub active_timestamp_present: Option<bool>,
150 pub pending_timestamp_present: Option<bool>,
151 pub master_key_present: Option<bool>,
152 pub network_name_present: Option<bool>,
153 pub extended_pan_id_present: Option<bool>,
154 pub mesh_local_prefix_present: Option<bool>,
155 pub delay_present: Option<bool>,
156 pub pan_id_present: Option<bool>,
157 pub channel_present: Option<bool>,
158 pub pskc_present: Option<bool>,
159 pub security_policy_present: Option<bool>,
160 pub channel_mask_present: Option<bool>,
161}
162
163#[derive(Debug, serde::Serialize)]
164pub struct RouteTable {
165 pub ext_address: Option<u64>,
166 pub rloc16: Option<u16>,
167 pub router_id: Option<u8>,
168 pub next_hop: Option<u8>,
169 pub path_cost: Option<u8>,
170 pub lqi_in: Option<u8>,
171 pub lqi_out: Option<u8>,
172 pub age: Option<u8>,
173 pub allocated: Option<bool>,
174 pub link_established: Option<bool>,
175}
176
177#[derive(Debug, serde::Serialize)]
178pub struct SecurityPolicy {
179 pub rotation_time: Option<u16>,
180 pub flags: Option<u16>,
181}
182
183pub fn decode_channel(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
189 if let tlv::TlvItemValue::Int(v) = inp {
190 Ok(Some(*v as u16))
191 } else {
192 Ok(None)
193 }
194}
195
196pub fn decode_routing_role(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<RoutingRole>> {
198 if let tlv::TlvItemValue::Int(v) = inp {
199 Ok(RoutingRole::from_u8(*v as u8))
200 } else {
201 Ok(None)
202 }
203}
204
205pub fn decode_network_name(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<String>> {
207 if let tlv::TlvItemValue::String(v) = inp {
208 Ok(Some(v.clone()))
209 } else {
210 Ok(None)
211 }
212}
213
214pub fn decode_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
216 if let tlv::TlvItemValue::Int(v) = inp {
217 Ok(Some(*v as u16))
218 } else {
219 Ok(None)
220 }
221}
222
223pub fn decode_extended_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
225 if let tlv::TlvItemValue::Int(v) = inp {
226 Ok(Some(*v))
227 } else {
228 Ok(None)
229 }
230}
231
232pub fn decode_mesh_local_prefix(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
234 if let tlv::TlvItemValue::Int(v) = inp {
235 Ok(Some(*v as u8))
236 } else {
237 Ok(None)
238 }
239}
240
241pub fn decode_overrun_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
243 if let tlv::TlvItemValue::Int(v) = inp {
244 Ok(*v)
245 } else {
246 Err(anyhow::anyhow!("Expected UInt64"))
247 }
248}
249
250pub fn decode_neighbor_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NeighborTable>> {
252 let mut res = Vec::new();
253 if let tlv::TlvItemValue::List(v) = inp {
254 for item in v {
255 res.push(NeighborTable {
256 ext_address: item.get_int(&[0]),
257 age: item.get_int(&[1]).map(|v| v as u32),
258 rloc16: item.get_int(&[2]).map(|v| v as u16),
259 link_frame_counter: item.get_int(&[3]).map(|v| v as u32),
260 mle_frame_counter: item.get_int(&[4]).map(|v| v as u32),
261 lqi: item.get_int(&[5]).map(|v| v as u8),
262 average_rssi: item.get_int(&[6]).map(|v| v as i8),
263 last_rssi: item.get_int(&[7]).map(|v| v as i8),
264 frame_error_rate: item.get_int(&[8]).map(|v| v as u8),
265 message_error_rate: item.get_int(&[9]).map(|v| v as u8),
266 rx_on_when_idle: item.get_bool(&[10]),
267 full_thread_device: item.get_bool(&[11]),
268 full_network_data: item.get_bool(&[12]),
269 is_child: item.get_bool(&[13]),
270 });
271 }
272 }
273 Ok(res)
274}
275
276pub fn decode_route_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<RouteTable>> {
278 let mut res = Vec::new();
279 if let tlv::TlvItemValue::List(v) = inp {
280 for item in v {
281 res.push(RouteTable {
282 ext_address: item.get_int(&[0]),
283 rloc16: item.get_int(&[1]).map(|v| v as u16),
284 router_id: item.get_int(&[2]).map(|v| v as u8),
285 next_hop: item.get_int(&[3]).map(|v| v as u8),
286 path_cost: item.get_int(&[4]).map(|v| v as u8),
287 lqi_in: item.get_int(&[5]).map(|v| v as u8),
288 lqi_out: item.get_int(&[6]).map(|v| v as u8),
289 age: item.get_int(&[7]).map(|v| v as u8),
290 allocated: item.get_bool(&[8]),
291 link_established: item.get_bool(&[9]),
292 });
293 }
294 }
295 Ok(res)
296}
297
298pub fn decode_partition_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
300 if let tlv::TlvItemValue::Int(v) = inp {
301 Ok(Some(*v as u32))
302 } else {
303 Ok(None)
304 }
305}
306
307pub fn decode_weighting(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
309 if let tlv::TlvItemValue::Int(v) = inp {
310 Ok(Some(*v as u16))
311 } else {
312 Ok(None)
313 }
314}
315
316pub fn decode_data_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
318 if let tlv::TlvItemValue::Int(v) = inp {
319 Ok(Some(*v as u16))
320 } else {
321 Ok(None)
322 }
323}
324
325pub fn decode_stable_data_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
327 if let tlv::TlvItemValue::Int(v) = inp {
328 Ok(Some(*v as u16))
329 } else {
330 Ok(None)
331 }
332}
333
334pub fn decode_leader_router_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
336 if let tlv::TlvItemValue::Int(v) = inp {
337 Ok(Some(*v as u8))
338 } else {
339 Ok(None)
340 }
341}
342
343pub fn decode_detached_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
345 if let tlv::TlvItemValue::Int(v) = inp {
346 Ok(*v as u16)
347 } else {
348 Err(anyhow::anyhow!("Expected UInt16"))
349 }
350}
351
352pub fn decode_child_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
354 if let tlv::TlvItemValue::Int(v) = inp {
355 Ok(*v as u16)
356 } else {
357 Err(anyhow::anyhow!("Expected UInt16"))
358 }
359}
360
361pub fn decode_router_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
363 if let tlv::TlvItemValue::Int(v) = inp {
364 Ok(*v as u16)
365 } else {
366 Err(anyhow::anyhow!("Expected UInt16"))
367 }
368}
369
370pub fn decode_leader_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
372 if let tlv::TlvItemValue::Int(v) = inp {
373 Ok(*v as u16)
374 } else {
375 Err(anyhow::anyhow!("Expected UInt16"))
376 }
377}
378
379pub fn decode_attach_attempt_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
381 if let tlv::TlvItemValue::Int(v) = inp {
382 Ok(*v as u16)
383 } else {
384 Err(anyhow::anyhow!("Expected UInt16"))
385 }
386}
387
388pub fn decode_partition_id_change_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
390 if let tlv::TlvItemValue::Int(v) = inp {
391 Ok(*v as u16)
392 } else {
393 Err(anyhow::anyhow!("Expected UInt16"))
394 }
395}
396
397pub fn decode_better_partition_attach_attempt_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
399 if let tlv::TlvItemValue::Int(v) = inp {
400 Ok(*v as u16)
401 } else {
402 Err(anyhow::anyhow!("Expected UInt16"))
403 }
404}
405
406pub fn decode_parent_change_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
408 if let tlv::TlvItemValue::Int(v) = inp {
409 Ok(*v as u16)
410 } else {
411 Err(anyhow::anyhow!("Expected UInt16"))
412 }
413}
414
415pub fn decode_tx_total_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
417 if let tlv::TlvItemValue::Int(v) = inp {
418 Ok(*v as u32)
419 } else {
420 Err(anyhow::anyhow!("Expected UInt32"))
421 }
422}
423
424pub fn decode_tx_unicast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
426 if let tlv::TlvItemValue::Int(v) = inp {
427 Ok(*v as u32)
428 } else {
429 Err(anyhow::anyhow!("Expected UInt32"))
430 }
431}
432
433pub fn decode_tx_broadcast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
435 if let tlv::TlvItemValue::Int(v) = inp {
436 Ok(*v as u32)
437 } else {
438 Err(anyhow::anyhow!("Expected UInt32"))
439 }
440}
441
442pub fn decode_tx_ack_requested_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
444 if let tlv::TlvItemValue::Int(v) = inp {
445 Ok(*v as u32)
446 } else {
447 Err(anyhow::anyhow!("Expected UInt32"))
448 }
449}
450
451pub fn decode_tx_acked_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
453 if let tlv::TlvItemValue::Int(v) = inp {
454 Ok(*v as u32)
455 } else {
456 Err(anyhow::anyhow!("Expected UInt32"))
457 }
458}
459
460pub fn decode_tx_no_ack_requested_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
462 if let tlv::TlvItemValue::Int(v) = inp {
463 Ok(*v as u32)
464 } else {
465 Err(anyhow::anyhow!("Expected UInt32"))
466 }
467}
468
469pub fn decode_tx_data_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
471 if let tlv::TlvItemValue::Int(v) = inp {
472 Ok(*v as u32)
473 } else {
474 Err(anyhow::anyhow!("Expected UInt32"))
475 }
476}
477
478pub fn decode_tx_data_poll_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
480 if let tlv::TlvItemValue::Int(v) = inp {
481 Ok(*v as u32)
482 } else {
483 Err(anyhow::anyhow!("Expected UInt32"))
484 }
485}
486
487pub fn decode_tx_beacon_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
489 if let tlv::TlvItemValue::Int(v) = inp {
490 Ok(*v as u32)
491 } else {
492 Err(anyhow::anyhow!("Expected UInt32"))
493 }
494}
495
496pub fn decode_tx_beacon_request_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
498 if let tlv::TlvItemValue::Int(v) = inp {
499 Ok(*v as u32)
500 } else {
501 Err(anyhow::anyhow!("Expected UInt32"))
502 }
503}
504
505pub fn decode_tx_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
507 if let tlv::TlvItemValue::Int(v) = inp {
508 Ok(*v as u32)
509 } else {
510 Err(anyhow::anyhow!("Expected UInt32"))
511 }
512}
513
514pub fn decode_tx_retry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
516 if let tlv::TlvItemValue::Int(v) = inp {
517 Ok(*v as u32)
518 } else {
519 Err(anyhow::anyhow!("Expected UInt32"))
520 }
521}
522
523pub fn decode_tx_direct_max_retry_expiry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
525 if let tlv::TlvItemValue::Int(v) = inp {
526 Ok(*v as u32)
527 } else {
528 Err(anyhow::anyhow!("Expected UInt32"))
529 }
530}
531
532pub fn decode_tx_indirect_max_retry_expiry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
534 if let tlv::TlvItemValue::Int(v) = inp {
535 Ok(*v as u32)
536 } else {
537 Err(anyhow::anyhow!("Expected UInt32"))
538 }
539}
540
541pub fn decode_tx_err_cca_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
543 if let tlv::TlvItemValue::Int(v) = inp {
544 Ok(*v as u32)
545 } else {
546 Err(anyhow::anyhow!("Expected UInt32"))
547 }
548}
549
550pub fn decode_tx_err_abort_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
552 if let tlv::TlvItemValue::Int(v) = inp {
553 Ok(*v as u32)
554 } else {
555 Err(anyhow::anyhow!("Expected UInt32"))
556 }
557}
558
559pub fn decode_tx_err_busy_channel_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
561 if let tlv::TlvItemValue::Int(v) = inp {
562 Ok(*v as u32)
563 } else {
564 Err(anyhow::anyhow!("Expected UInt32"))
565 }
566}
567
568pub fn decode_rx_total_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
570 if let tlv::TlvItemValue::Int(v) = inp {
571 Ok(*v as u32)
572 } else {
573 Err(anyhow::anyhow!("Expected UInt32"))
574 }
575}
576
577pub fn decode_rx_unicast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
579 if let tlv::TlvItemValue::Int(v) = inp {
580 Ok(*v as u32)
581 } else {
582 Err(anyhow::anyhow!("Expected UInt32"))
583 }
584}
585
586pub fn decode_rx_broadcast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
588 if let tlv::TlvItemValue::Int(v) = inp {
589 Ok(*v as u32)
590 } else {
591 Err(anyhow::anyhow!("Expected UInt32"))
592 }
593}
594
595pub fn decode_rx_data_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
597 if let tlv::TlvItemValue::Int(v) = inp {
598 Ok(*v as u32)
599 } else {
600 Err(anyhow::anyhow!("Expected UInt32"))
601 }
602}
603
604pub fn decode_rx_data_poll_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
606 if let tlv::TlvItemValue::Int(v) = inp {
607 Ok(*v as u32)
608 } else {
609 Err(anyhow::anyhow!("Expected UInt32"))
610 }
611}
612
613pub fn decode_rx_beacon_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
615 if let tlv::TlvItemValue::Int(v) = inp {
616 Ok(*v as u32)
617 } else {
618 Err(anyhow::anyhow!("Expected UInt32"))
619 }
620}
621
622pub fn decode_rx_beacon_request_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
624 if let tlv::TlvItemValue::Int(v) = inp {
625 Ok(*v as u32)
626 } else {
627 Err(anyhow::anyhow!("Expected UInt32"))
628 }
629}
630
631pub fn decode_rx_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
633 if let tlv::TlvItemValue::Int(v) = inp {
634 Ok(*v as u32)
635 } else {
636 Err(anyhow::anyhow!("Expected UInt32"))
637 }
638}
639
640pub fn decode_rx_address_filtered_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
642 if let tlv::TlvItemValue::Int(v) = inp {
643 Ok(*v as u32)
644 } else {
645 Err(anyhow::anyhow!("Expected UInt32"))
646 }
647}
648
649pub fn decode_rx_dest_addr_filtered_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
651 if let tlv::TlvItemValue::Int(v) = inp {
652 Ok(*v as u32)
653 } else {
654 Err(anyhow::anyhow!("Expected UInt32"))
655 }
656}
657
658pub fn decode_rx_duplicated_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
660 if let tlv::TlvItemValue::Int(v) = inp {
661 Ok(*v as u32)
662 } else {
663 Err(anyhow::anyhow!("Expected UInt32"))
664 }
665}
666
667pub fn decode_rx_err_no_frame_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
669 if let tlv::TlvItemValue::Int(v) = inp {
670 Ok(*v as u32)
671 } else {
672 Err(anyhow::anyhow!("Expected UInt32"))
673 }
674}
675
676pub fn decode_rx_err_unknown_neighbor_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
678 if let tlv::TlvItemValue::Int(v) = inp {
679 Ok(*v as u32)
680 } else {
681 Err(anyhow::anyhow!("Expected UInt32"))
682 }
683}
684
685pub fn decode_rx_err_invalid_src_addr_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
687 if let tlv::TlvItemValue::Int(v) = inp {
688 Ok(*v as u32)
689 } else {
690 Err(anyhow::anyhow!("Expected UInt32"))
691 }
692}
693
694pub fn decode_rx_err_sec_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
696 if let tlv::TlvItemValue::Int(v) = inp {
697 Ok(*v as u32)
698 } else {
699 Err(anyhow::anyhow!("Expected UInt32"))
700 }
701}
702
703pub fn decode_rx_err_fcs_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
705 if let tlv::TlvItemValue::Int(v) = inp {
706 Ok(*v as u32)
707 } else {
708 Err(anyhow::anyhow!("Expected UInt32"))
709 }
710}
711
712pub fn decode_rx_err_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
714 if let tlv::TlvItemValue::Int(v) = inp {
715 Ok(*v as u32)
716 } else {
717 Err(anyhow::anyhow!("Expected UInt32"))
718 }
719}
720
721pub fn decode_active_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
723 if let tlv::TlvItemValue::Int(v) = inp {
724 Ok(Some(*v))
725 } else {
726 Ok(None)
727 }
728}
729
730pub fn decode_pending_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
732 if let tlv::TlvItemValue::Int(v) = inp {
733 Ok(Some(*v))
734 } else {
735 Ok(None)
736 }
737}
738
739pub fn decode_delay(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
741 if let tlv::TlvItemValue::Int(v) = inp {
742 Ok(Some(*v as u32))
743 } else {
744 Ok(None)
745 }
746}
747
748pub fn decode_security_policy(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<SecurityPolicy>> {
750 if let tlv::TlvItemValue::List(_fields) = inp {
751 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
753 Ok(Some(SecurityPolicy {
754 rotation_time: item.get_int(&[0]).map(|v| v as u16),
755 flags: item.get_int(&[1]).map(|v| v as u16),
756 }))
757 } else {
761 Ok(None)
762 }
764}
765
766pub fn decode_channel_page0_mask(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
768 if let tlv::TlvItemValue::OctetString(v) = inp {
769 Ok(Some(v.clone()))
770 } else {
771 Ok(None)
772 }
773}
774
775pub fn decode_operational_dataset_components(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<OperationalDatasetComponents>> {
777 if let tlv::TlvItemValue::List(_fields) = inp {
778 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
780 Ok(Some(OperationalDatasetComponents {
781 active_timestamp_present: item.get_bool(&[0]),
782 pending_timestamp_present: item.get_bool(&[1]),
783 master_key_present: item.get_bool(&[2]),
784 network_name_present: item.get_bool(&[3]),
785 extended_pan_id_present: item.get_bool(&[4]),
786 mesh_local_prefix_present: item.get_bool(&[5]),
787 delay_present: item.get_bool(&[6]),
788 pan_id_present: item.get_bool(&[7]),
789 channel_present: item.get_bool(&[8]),
790 pskc_present: item.get_bool(&[9]),
791 security_policy_present: item.get_bool(&[10]),
792 channel_mask_present: item.get_bool(&[11]),
793 }))
794 } else {
798 Ok(None)
799 }
801}
802
803pub fn decode_active_network_faults_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NetworkFault>> {
805 let mut res = Vec::new();
806 if let tlv::TlvItemValue::List(v) = inp {
807 for item in v {
808 if let tlv::TlvItemValue::Int(i) = &item.value {
809 if let Some(enum_val) = NetworkFault::from_u8(*i as u8) {
810 res.push(enum_val);
811 }
812 }
813 }
814 }
815 Ok(res)
816}
817
818pub fn decode_ext_address(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
820 if let tlv::TlvItemValue::Int(v) = inp {
821 Ok(Some(*v))
822 } else {
823 Ok(None)
824 }
825}
826
827pub fn decode_rloc16(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
829 if let tlv::TlvItemValue::Int(v) = inp {
830 Ok(Some(*v as u16))
831 } else {
832 Ok(None)
833 }
834}
835
836
837pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
849 if cluster_id != 0x0035 {
851 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0035, got {}\"}}", cluster_id);
852 }
853
854 match attribute_id {
855 0x0000 => {
856 match decode_channel(tlv_value) {
857 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
858 Err(e) => format!("{{\"error\": \"{}\"}}", e),
859 }
860 }
861 0x0001 => {
862 match decode_routing_role(tlv_value) {
863 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
864 Err(e) => format!("{{\"error\": \"{}\"}}", e),
865 }
866 }
867 0x0002 => {
868 match decode_network_name(tlv_value) {
869 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
870 Err(e) => format!("{{\"error\": \"{}\"}}", e),
871 }
872 }
873 0x0003 => {
874 match decode_pan_id(tlv_value) {
875 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
876 Err(e) => format!("{{\"error\": \"{}\"}}", e),
877 }
878 }
879 0x0004 => {
880 match decode_extended_pan_id(tlv_value) {
881 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
882 Err(e) => format!("{{\"error\": \"{}\"}}", e),
883 }
884 }
885 0x0005 => {
886 match decode_mesh_local_prefix(tlv_value) {
887 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
888 Err(e) => format!("{{\"error\": \"{}\"}}", e),
889 }
890 }
891 0x0006 => {
892 match decode_overrun_count(tlv_value) {
893 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
894 Err(e) => format!("{{\"error\": \"{}\"}}", e),
895 }
896 }
897 0x0007 => {
898 match decode_neighbor_table(tlv_value) {
899 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
900 Err(e) => format!("{{\"error\": \"{}\"}}", e),
901 }
902 }
903 0x0008 => {
904 match decode_route_table(tlv_value) {
905 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
906 Err(e) => format!("{{\"error\": \"{}\"}}", e),
907 }
908 }
909 0x0009 => {
910 match decode_partition_id(tlv_value) {
911 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
912 Err(e) => format!("{{\"error\": \"{}\"}}", e),
913 }
914 }
915 0x000A => {
916 match decode_weighting(tlv_value) {
917 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
918 Err(e) => format!("{{\"error\": \"{}\"}}", e),
919 }
920 }
921 0x000B => {
922 match decode_data_version(tlv_value) {
923 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
924 Err(e) => format!("{{\"error\": \"{}\"}}", e),
925 }
926 }
927 0x000C => {
928 match decode_stable_data_version(tlv_value) {
929 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
930 Err(e) => format!("{{\"error\": \"{}\"}}", e),
931 }
932 }
933 0x000D => {
934 match decode_leader_router_id(tlv_value) {
935 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
936 Err(e) => format!("{{\"error\": \"{}\"}}", e),
937 }
938 }
939 0x000E => {
940 match decode_detached_role_count(tlv_value) {
941 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
942 Err(e) => format!("{{\"error\": \"{}\"}}", e),
943 }
944 }
945 0x000F => {
946 match decode_child_role_count(tlv_value) {
947 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
948 Err(e) => format!("{{\"error\": \"{}\"}}", e),
949 }
950 }
951 0x0010 => {
952 match decode_router_role_count(tlv_value) {
953 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
954 Err(e) => format!("{{\"error\": \"{}\"}}", e),
955 }
956 }
957 0x0011 => {
958 match decode_leader_role_count(tlv_value) {
959 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
960 Err(e) => format!("{{\"error\": \"{}\"}}", e),
961 }
962 }
963 0x0012 => {
964 match decode_attach_attempt_count(tlv_value) {
965 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
966 Err(e) => format!("{{\"error\": \"{}\"}}", e),
967 }
968 }
969 0x0013 => {
970 match decode_partition_id_change_count(tlv_value) {
971 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
972 Err(e) => format!("{{\"error\": \"{}\"}}", e),
973 }
974 }
975 0x0014 => {
976 match decode_better_partition_attach_attempt_count(tlv_value) {
977 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
978 Err(e) => format!("{{\"error\": \"{}\"}}", e),
979 }
980 }
981 0x0015 => {
982 match decode_parent_change_count(tlv_value) {
983 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
984 Err(e) => format!("{{\"error\": \"{}\"}}", e),
985 }
986 }
987 0x0016 => {
988 match decode_tx_total_count(tlv_value) {
989 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
990 Err(e) => format!("{{\"error\": \"{}\"}}", e),
991 }
992 }
993 0x0017 => {
994 match decode_tx_unicast_count(tlv_value) {
995 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
996 Err(e) => format!("{{\"error\": \"{}\"}}", e),
997 }
998 }
999 0x0018 => {
1000 match decode_tx_broadcast_count(tlv_value) {
1001 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1002 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1003 }
1004 }
1005 0x0019 => {
1006 match decode_tx_ack_requested_count(tlv_value) {
1007 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1008 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1009 }
1010 }
1011 0x001A => {
1012 match decode_tx_acked_count(tlv_value) {
1013 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1014 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1015 }
1016 }
1017 0x001B => {
1018 match decode_tx_no_ack_requested_count(tlv_value) {
1019 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1020 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1021 }
1022 }
1023 0x001C => {
1024 match decode_tx_data_count(tlv_value) {
1025 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1026 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1027 }
1028 }
1029 0x001D => {
1030 match decode_tx_data_poll_count(tlv_value) {
1031 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1032 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1033 }
1034 }
1035 0x001E => {
1036 match decode_tx_beacon_count(tlv_value) {
1037 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1038 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1039 }
1040 }
1041 0x001F => {
1042 match decode_tx_beacon_request_count(tlv_value) {
1043 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1044 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1045 }
1046 }
1047 0x0020 => {
1048 match decode_tx_other_count(tlv_value) {
1049 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1050 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1051 }
1052 }
1053 0x0021 => {
1054 match decode_tx_retry_count(tlv_value) {
1055 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1056 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1057 }
1058 }
1059 0x0022 => {
1060 match decode_tx_direct_max_retry_expiry_count(tlv_value) {
1061 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1062 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1063 }
1064 }
1065 0x0023 => {
1066 match decode_tx_indirect_max_retry_expiry_count(tlv_value) {
1067 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1068 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1069 }
1070 }
1071 0x0024 => {
1072 match decode_tx_err_cca_count(tlv_value) {
1073 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1074 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1075 }
1076 }
1077 0x0025 => {
1078 match decode_tx_err_abort_count(tlv_value) {
1079 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1080 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1081 }
1082 }
1083 0x0026 => {
1084 match decode_tx_err_busy_channel_count(tlv_value) {
1085 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1086 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1087 }
1088 }
1089 0x0027 => {
1090 match decode_rx_total_count(tlv_value) {
1091 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1092 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1093 }
1094 }
1095 0x0028 => {
1096 match decode_rx_unicast_count(tlv_value) {
1097 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1098 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1099 }
1100 }
1101 0x0029 => {
1102 match decode_rx_broadcast_count(tlv_value) {
1103 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1104 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1105 }
1106 }
1107 0x002A => {
1108 match decode_rx_data_count(tlv_value) {
1109 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1110 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1111 }
1112 }
1113 0x002B => {
1114 match decode_rx_data_poll_count(tlv_value) {
1115 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1116 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1117 }
1118 }
1119 0x002C => {
1120 match decode_rx_beacon_count(tlv_value) {
1121 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1122 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1123 }
1124 }
1125 0x002D => {
1126 match decode_rx_beacon_request_count(tlv_value) {
1127 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1128 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1129 }
1130 }
1131 0x002E => {
1132 match decode_rx_other_count(tlv_value) {
1133 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1134 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1135 }
1136 }
1137 0x002F => {
1138 match decode_rx_address_filtered_count(tlv_value) {
1139 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1140 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1141 }
1142 }
1143 0x0030 => {
1144 match decode_rx_dest_addr_filtered_count(tlv_value) {
1145 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1146 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1147 }
1148 }
1149 0x0031 => {
1150 match decode_rx_duplicated_count(tlv_value) {
1151 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1152 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1153 }
1154 }
1155 0x0032 => {
1156 match decode_rx_err_no_frame_count(tlv_value) {
1157 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1158 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1159 }
1160 }
1161 0x0033 => {
1162 match decode_rx_err_unknown_neighbor_count(tlv_value) {
1163 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1164 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1165 }
1166 }
1167 0x0034 => {
1168 match decode_rx_err_invalid_src_addr_count(tlv_value) {
1169 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1170 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1171 }
1172 }
1173 0x0035 => {
1174 match decode_rx_err_sec_count(tlv_value) {
1175 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1176 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1177 }
1178 }
1179 0x0036 => {
1180 match decode_rx_err_fcs_count(tlv_value) {
1181 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1182 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1183 }
1184 }
1185 0x0037 => {
1186 match decode_rx_err_other_count(tlv_value) {
1187 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1188 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1189 }
1190 }
1191 0x0038 => {
1192 match decode_active_timestamp(tlv_value) {
1193 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1194 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1195 }
1196 }
1197 0x0039 => {
1198 match decode_pending_timestamp(tlv_value) {
1199 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1200 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1201 }
1202 }
1203 0x003A => {
1204 match decode_delay(tlv_value) {
1205 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1206 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1207 }
1208 }
1209 0x003B => {
1210 match decode_security_policy(tlv_value) {
1211 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1212 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1213 }
1214 }
1215 0x003C => {
1216 match decode_channel_page0_mask(tlv_value) {
1217 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1218 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1219 }
1220 }
1221 0x003D => {
1222 match decode_operational_dataset_components(tlv_value) {
1223 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1224 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1225 }
1226 }
1227 0x003E => {
1228 match decode_active_network_faults_list(tlv_value) {
1229 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1230 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1231 }
1232 }
1233 0x003F => {
1234 match decode_ext_address(tlv_value) {
1235 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1236 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1237 }
1238 }
1239 0x0040 => {
1240 match decode_rloc16(tlv_value) {
1241 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1242 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1243 }
1244 }
1245 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
1246 }
1247}
1248
1249pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
1254 vec![
1255 (0x0000, "Channel"),
1256 (0x0001, "RoutingRole"),
1257 (0x0002, "NetworkName"),
1258 (0x0003, "PanId"),
1259 (0x0004, "ExtendedPanId"),
1260 (0x0005, "MeshLocalPrefix"),
1261 (0x0006, "OverrunCount"),
1262 (0x0007, "NeighborTable"),
1263 (0x0008, "RouteTable"),
1264 (0x0009, "PartitionId"),
1265 (0x000A, "Weighting"),
1266 (0x000B, "DataVersion"),
1267 (0x000C, "StableDataVersion"),
1268 (0x000D, "LeaderRouterId"),
1269 (0x000E, "DetachedRoleCount"),
1270 (0x000F, "ChildRoleCount"),
1271 (0x0010, "RouterRoleCount"),
1272 (0x0011, "LeaderRoleCount"),
1273 (0x0012, "AttachAttemptCount"),
1274 (0x0013, "PartitionIdChangeCount"),
1275 (0x0014, "BetterPartitionAttachAttemptCount"),
1276 (0x0015, "ParentChangeCount"),
1277 (0x0016, "TxTotalCount"),
1278 (0x0017, "TxUnicastCount"),
1279 (0x0018, "TxBroadcastCount"),
1280 (0x0019, "TxAckRequestedCount"),
1281 (0x001A, "TxAckedCount"),
1282 (0x001B, "TxNoAckRequestedCount"),
1283 (0x001C, "TxDataCount"),
1284 (0x001D, "TxDataPollCount"),
1285 (0x001E, "TxBeaconCount"),
1286 (0x001F, "TxBeaconRequestCount"),
1287 (0x0020, "TxOtherCount"),
1288 (0x0021, "TxRetryCount"),
1289 (0x0022, "TxDirectMaxRetryExpiryCount"),
1290 (0x0023, "TxIndirectMaxRetryExpiryCount"),
1291 (0x0024, "TxErrCcaCount"),
1292 (0x0025, "TxErrAbortCount"),
1293 (0x0026, "TxErrBusyChannelCount"),
1294 (0x0027, "RxTotalCount"),
1295 (0x0028, "RxUnicastCount"),
1296 (0x0029, "RxBroadcastCount"),
1297 (0x002A, "RxDataCount"),
1298 (0x002B, "RxDataPollCount"),
1299 (0x002C, "RxBeaconCount"),
1300 (0x002D, "RxBeaconRequestCount"),
1301 (0x002E, "RxOtherCount"),
1302 (0x002F, "RxAddressFilteredCount"),
1303 (0x0030, "RxDestAddrFilteredCount"),
1304 (0x0031, "RxDuplicatedCount"),
1305 (0x0032, "RxErrNoFrameCount"),
1306 (0x0033, "RxErrUnknownNeighborCount"),
1307 (0x0034, "RxErrInvalidSrcAddrCount"),
1308 (0x0035, "RxErrSecCount"),
1309 (0x0036, "RxErrFcsCount"),
1310 (0x0037, "RxErrOtherCount"),
1311 (0x0038, "ActiveTimestamp"),
1312 (0x0039, "PendingTimestamp"),
1313 (0x003A, "Delay"),
1314 (0x003B, "SecurityPolicy"),
1315 (0x003C, "ChannelPage0Mask"),
1316 (0x003D, "OperationalDatasetComponents"),
1317 (0x003E, "ActiveNetworkFaultsList"),
1318 (0x003F, "ExtAddress"),
1319 (0x0040, "Rloc16"),
1320 ]
1321}
1322
1323#[derive(Debug, serde::Serialize)]
1324pub struct ConnectionStatusEvent {
1325 pub connection_status: Option<ConnectionStatus>,
1326}
1327
1328#[derive(Debug, serde::Serialize)]
1329pub struct NetworkFaultChangeEvent {
1330 pub current: Option<Vec<NetworkFault>>,
1331 pub previous: Option<Vec<NetworkFault>>,
1332}
1333
1334pub fn decode_connection_status_event(inp: &tlv::TlvItemValue) -> anyhow::Result<ConnectionStatusEvent> {
1338 if let tlv::TlvItemValue::List(_fields) = inp {
1339 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
1340 Ok(ConnectionStatusEvent {
1341 connection_status: item.get_int(&[0]).and_then(|v| ConnectionStatus::from_u8(v as u8)),
1342 })
1343 } else {
1344 Err(anyhow::anyhow!("Expected struct fields"))
1345 }
1346}
1347
1348pub fn decode_network_fault_change_event(inp: &tlv::TlvItemValue) -> anyhow::Result<NetworkFaultChangeEvent> {
1350 if let tlv::TlvItemValue::List(_fields) = inp {
1351 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
1352 Ok(NetworkFaultChangeEvent {
1353 current: {
1354 if let Some(tlv::TlvItemValue::List(l)) = item.get(&[0]) {
1355 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();
1356 Some(items)
1357 } else {
1358 None
1359 }
1360 },
1361 previous: {
1362 if let Some(tlv::TlvItemValue::List(l)) = item.get(&[1]) {
1363 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();
1364 Some(items)
1365 } else {
1366 None
1367 }
1368 },
1369 })
1370 } else {
1371 Err(anyhow::anyhow!("Expected struct fields"))
1372 }
1373}
1374